diff options
Diffstat (limited to 'game/code/presentation')
242 files changed, 73457 insertions, 0 deletions
diff --git a/game/code/presentation/allpresentation.cpp b/game/code/presentation/allpresentation.cpp new file mode 100644 index 0000000..94e3a71 --- /dev/null +++ b/game/code/presentation/allpresentation.cpp @@ -0,0 +1,12 @@ +#include <presentation/animplayer.cpp> +#include <presentation/blinker.cpp> +#include <presentation/cameraplayer.cpp> +#include <presentation/language.cpp> +#include <presentation/mouthflapper.cpp> +#include <presentation/nisplayer.cpp> +#include <presentation/playerdrawable.cpp> +#include <presentation/presentation.cpp> +#include <presentation/presentationanimator.cpp> +#include <presentation/simpleanimationplayer.cpp> +#include <presentation/transitionplayer.cpp> +#include <presentation/tutorialmanager.cpp>
\ No newline at end of file diff --git a/game/code/presentation/animplayer.cpp b/game/code/presentation/animplayer.cpp new file mode 100644 index 0000000..3c1e244 --- /dev/null +++ b/game/code/presentation/animplayer.cpp @@ -0,0 +1,356 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: animplayer.cpp +// +// Description: Implement AnimationPlayer +// +// History: 22/04/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <p3d/utility.hpp> + +//======================================== +// Project Includes +//======================================== + +#include <memory/srrmemory.h> + +#include <presentation/animplayer.h> +#include <interiors/interiormanager.h> +#include <render/rendermanager/rendermanager.h> +#include <render/RenderManager/RenderLayer.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// AnimationPlayer::AnimationPlayer +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +AnimationPlayer::AnimationPlayer() : + mState( ANIM_IDLE ), + mbPlayAfterLoad( true ), + mbExclusive( true ), + mbShowAlways ( false ), + mbKeepLayersFrozen( false ), + mbIsSkippable(true), + mpLoadDataCallback( NULL ) +{ +} + +//============================================================================== +// AnimationPlayer::~AnimationPlayer +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +AnimationPlayer::~AnimationPlayer() +{ +} + + +//============================================================================== +// AnimationPlayer::LoadData +//============================================================================== +// +// Description: +// +// Parameters: +// +// Return: +// +//============================================================================== +void AnimationPlayer::LoadData +( + const char* fileName, + bool bInInventory, + void* pUserData +) +{ + if( mState == ANIM_IDLE ) + { + mState = ANIM_LOADING; + + if( bInInventory ) + { + OnProcessRequestsComplete( NULL ); + mSection = 0; + } + else + { + if(!GetInteriorManager()->IsInside()) + { + GetLoadingManager()->AddRequest( FILEHANDLER_ANIMATION, + fileName, + GMA_CHARS_AND_GAGS, + fileName, + "Animation Player", + this ); + } + else + { + GetLoadingManager()->AddRequest( FILEHANDLER_ANIMATION, + fileName, + GMA_DEFAULT, + fileName, + "Animation Player", + this ); + } + + mSection = tEntity::MakeUID(fileName); + } + } +} + + +//============================================================================= +// AnimationPlayer::LoadData +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* fileName ) +// +// Return: void +// +//============================================================================= +void AnimationPlayer::LoadData +( + const char* fileName, + LoadDataCallBack* pCallback, + bool bInInventory, + void* pUserData +) +{ + mpLoadDataCallback = pCallback; + + this->LoadData( fileName, bInInventory, pUserData ); +} + +//============================================================================= +// AnimationPlayer::OnProcessRequestsComplete +//============================================================================= +// Description: Comment +// +// Parameters: ( void* pUserData ) +// +// Return: void +// +//============================================================================= +void AnimationPlayer::OnProcessRequestsComplete( void* pUserData ) +{ + p3d::inventory->PushSection(); + + p3d::inventory->SelectSection( mSection ); + bool currentOnly = p3d::inventory->GetCurrentSectionOnly( ); + p3d::inventory->SetCurrentSectionOnly( true ); + + mState = ANIM_LOADED; + + this->DoLoaded(); + + if( mpLoadDataCallback != NULL ) + { + mpLoadDataCallback->OnLoadDataComplete(); + } + + if( mbPlayAfterLoad ) + { + Play(); + } + + p3d::inventory->SetCurrentSectionOnly( currentOnly ); + + p3d::inventory->PopSection(); +} + +//============================================================================= +// AnimationPlayer::Play +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void AnimationPlayer::Play() +{ + if( mState == ANIM_STOPPED ) + { + mState = ANIM_PLAYING; + } + + if( mState == ANIM_LOADED ) + { + mState = ANIM_PLAYING; + + if( mbExclusive ) + { + EnterExclusive(); + } + } +/* DARWIN TODO: Why was this necessary? + else + { + mbPlayAfterLoad = true; + } +*/ +} + + +/* +//============================================================================= +// AnimationPlayer::StopAndCleanUp +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void AnimationPlayer::StopAndCleanUp() +{ + Stop(); +} +*/ + + +//============================================================================= +// AnimationPlayer::Render +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void AnimationPlayer::Render() +{ + if( (mState == ANIM_PLAYING) || mbShowAlways ) + { + DoRender(); + } +} + +//============================================================================= +// AnimationPlayer::Stop +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void AnimationPlayer::Stop() +{ + if( mbExclusive ) + { + LeaveExclusive(); + } + + // + // Hope this makes sense. Calling Stop() after ClearData() was causing + // the player to be stuck in the stopped state, since LoadData() wouldn't + // do anything. Added check for idle state. -- DE + // + if( mState != ANIM_IDLE ) + { + mState = ANIM_STOPPED; + } +} + +//============================================================================= +// AnimationPlayer::ClearData +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void AnimationPlayer::ClearData() +{ + mState = ANIM_IDLE; + p3d::inventory->DeleteSection( mSection ); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// AnimationPlayer::EnterExclusive +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void AnimationPlayer::EnterExclusive() +{ + GetRenderManager()->FreezeForPresentation(); + + RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + + if ( pLayer->IsDead() ) + { + pLayer->Resurrect(); + } + pLayer->Thaw(); +} + +//============================================================================= +// AnimationPlayer::LeaveExclusive +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void AnimationPlayer::LeaveExclusive() +{ + if( !mbKeepLayersFrozen ) + { + GetRenderManager()->ThawFromPresentation(); + + RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + + pLayer->Freeze(); + } +} diff --git a/game/code/presentation/animplayer.h b/game/code/presentation/animplayer.h new file mode 100644 index 0000000..f9d4088 --- /dev/null +++ b/game/code/presentation/animplayer.h @@ -0,0 +1,135 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 22/04/2002 + Created -- NAME +// +//============================================================================= + +#ifndef ANIMPLAYER_H +#define ANIMPLAYER_H + +//======================================== +// Nested Includes +//======================================== +#include <p3d/p3dtypes.hpp> +#include <loading/loadingmanager.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: Base class for all presentation players. A player is something +// that keeps an non-interactive animation going. +// +//============================================================================= + +class AnimationPlayer : public LoadingManager::ProcessRequestsCallback +{ + public: + AnimationPlayer(); + virtual ~AnimationPlayer(); + + + // Loads the data for this animation and sits on it + // Set bInInventory to true if the data is already loaded and + // in the p3d inventory. + // Clients must implement the callback if they want notification when + // the load is complete. + struct LoadDataCallBack + { + virtual void OnLoadDataComplete() = 0; + }; + virtual void LoadData( const char* fileName, + LoadDataCallBack* pCallback, + bool bInInventory, + void* pUserData ); + + virtual void LoadData( const char* fileName, + bool bInInventory, + void* pUserData ); + + // Tells it to start playing right away once it's done loading + void SetPlayAfterLoad( bool bPlay ) { mbPlayAfterLoad = bPlay; } + + void SetShowAlways(bool b) { mbShowAlways = b; } + + // Whee! + virtual void Play(); + virtual void Stop(); + + // TC: This just calls Stop(), so why do we need another function?? + // +// void StopAndCleanUp(); + + // Tells the player to enter "Exclusive Mode", which sets the + // Render Level to Presentation and should stop everything else + // in the game. + void SetExclusive( bool bIsExclusive ) { mbExclusive = bIsExclusive; } + + bool IsPlaying() { return((( mState != ANIM_IDLE ) && (mState != ANIM_STOPPED ))); } + bool IsFinished() { return mState == ANIM_STOPPED; } + virtual void Update( unsigned int elapsedTime ) = 0; + void Render(); + + virtual void ClearData(); + void Reset() { mState = ANIM_IDLE; } + + void OnProcessRequestsComplete( void* pUserData ); + bool GetKeepLayersFrozen( void ) const { return mbKeepLayersFrozen; } + void SetKeepLayersFrozen( bool IsKeepFrozen ) { mbKeepLayersFrozen = IsKeepFrozen; } + bool GetSkippable(void) const {return mbIsSkippable;} + void SetSkippable(bool IsSkippable) {mbIsSkippable = IsSkippable;} + + protected: + + enum AnimState + { + ANIM_IDLE, + ANIM_LOADING, + ANIM_LOADED, + ANIM_PLAYING, + ANIM_STOPPED, + NUM_STATES + }; + + AnimState GetState() { return( mState ); } + void SetState( AnimState state ) { mState = state; } + + // A sub-class must implement these + // DoLoaded is called once the data is ready (in the case on p3d + // stuff, this means it is in the inventory) + virtual void DoLoaded() = 0; + + // A sub-class should draw stuff here + virtual void DoRender() = 0; + + void EnterExclusive(); + void LeaveExclusive(); + private: + + //Prevent wasteful constructor creation. + AnimationPlayer( const AnimationPlayer& animPlayer ); + AnimationPlayer& operator=( const AnimationPlayer& animPlayer ); + + AnimState mState; + + bool mbPlayAfterLoad : 1; + bool mbExclusive : 1; + bool mbShowAlways : 1; + bool mbKeepLayersFrozen : 1; + bool mbIsSkippable : 1; + + tUID mSection; + + LoadDataCallBack* mpLoadDataCallback; +}; + + +#endif //ANIMPLAYER_H_H + diff --git a/game/code/presentation/blinker.cpp b/game/code/presentation/blinker.cpp new file mode 100644 index 0000000..3ed4577 --- /dev/null +++ b/game/code/presentation/blinker.cpp @@ -0,0 +1,243 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: Blinker.cpp +// +// Description: Implement Blinker +// +// History: 9/24/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <p3d/anim/multicontroller.hpp> +#include <p3d/anim/textureanimation.hpp> +#include <stdlib.h> + +//======================================== +// Project Includes +//======================================== + +#include <memory/srrmemory.h> +#include <presentation/blinker.h> +#include <worldsim/character/character.h> +#include <worldsim/character/charactermanager.h> +#include <main/game.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +static const int MIN_TIME = 2000; +static const int MAX_TIME = 4000; + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// Blinker::Blinker +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Blinker::Blinker(): + mCharacter( NULL ), + mController( NULL ) , + mState( STATE_BLINKING ) +{ +} + +//============================================================================== +// Blinker::~Blinker +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Blinker::~Blinker() +{ + if( mController != NULL ) + { + mController->Release(); + } +} + +//============================================================================= +// Blinker:SetCharacter +//============================================================================= +// Description: Comment +// +// Parameters: ( Character* pCharacter ) +// +// Return: void +// +//============================================================================= +void Blinker::SetCharacter( Character* pCharacter ) +{ +// if( mCharacter == pCharacter ) +// { +// return; +// } + mCharacter = pCharacter; + + if (pCharacter == 0) + { + if (mController) + { + mController->Release (); + mController = 0; + } + } + else + { + const char* modelName = GetCharacterManager()->GetModelName( mCharacter ); + tMultiController* multicontroller = 0; + if( tName::MakeUID( modelName ) != tName::MakeUID( "npd" ) ) + { + multicontroller = p3d::find< tMultiController >( modelName ); + } + tRefCounted::Assign( mController, multicontroller ); + } + + if( mController == NULL ) + { + return; + } + + mController->SetCycleMode( FORCE_NON_CYCLIC ); +} + +//============================================================================= +// Blinker::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( int elapsedTime ) +// +// Return: void +// +//============================================================================= +void Blinker::Update( int elapsedTime ) +{ + mTimeSinceBlink += elapsedTime; + + if( mController == NULL ) + { + if( (mCharacter->GetActiveFrame() & 0xf) == (GetGame()->GetFrameCount() & 0xf)) + { + mTimeSinceBlink = 0; + const char* modelName = GetCharacterManager()->GetModelName( mCharacter ); + tMultiController* multicontroller = 0; + if(tName::MakeUID(modelName) != tName::MakeUID("npd")) + { + multicontroller = p3d::find< tMultiController >( modelName ); + } + if( multicontroller != NULL ) + { + tRefCounted::Assign( mController, multicontroller ); + } + else + { + return; + } + } + else + { + return; + } + } + + switch( mState ) + { + case STATE_WAITING: + { + rAssert( mController != NULL ); + if( mTimeSinceBlink >= mTimeTarget ) + { + mController->Reset(); + mState = STATE_BLINKING; + } + + break; + } + case STATE_BLINKING: + { + rAssert( mController != NULL ); + + mController->Advance( static_cast<float>( elapsedTime ), true ); + + float frames = mController->GetNumFrames(); + float frame = mController->GetFrame(); + if( frame >= frames ) + { + mTimeTarget = MIN_TIME + (MAX_TIME - MIN_TIME) * rand() / RAND_MAX; + mTimeSinceBlink = 0; + mState = STATE_WAITING; + } + + break; + } + default: + { + break; + } + } +} + +//============================================================================= +// Blinker::StartBlinking +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void Blinker::StartBlinking() +{ + if( mState == STATE_INVALID ) + { + mState = STATE_BLINKING; + } +} + +//============================================================================= +// Blinker::StopBlinking +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void Blinker::StopBlinking() +{ + if( mState != STATE_INVALID ) + { + mState = STATE_INVALID; + } +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/presentation/blinker.h b/game/code/presentation/blinker.h new file mode 100644 index 0000000..ecefb82 --- /dev/null +++ b/game/code/presentation/blinker.h @@ -0,0 +1,68 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: blinker.h +// +// Description: Blahblahblah +// +// History: 9/24/2002 + Created -- NAME +// +//============================================================================= + +#ifndef BLINKER_H +#define BLINKER_H + +//======================================== +// Nested Includes +//======================================== + +//======================================== +// Forward References +//======================================== + +class Character; +class tMultiController; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class Blinker +{ +public: + Blinker(); + virtual ~Blinker(); + + void SetCharacter( Character* pCharacter ); + + void Update( int elapsedTime ); + + void StartBlinking(); + void StopBlinking(); + +private: + + //Prevent wasteful constructor creation. + Blinker( const Blinker& blinker ); + Blinker& operator=( const Blinker& blinker ); + + Character* mCharacter; + tMultiController* mController; + + int mTimeSinceBlink; + int mTimeTarget; + + enum BlinkState + { + STATE_INVALID, + STATE_WAITING, + STATE_BLINKING + }; + + BlinkState mState; +}; + + +#endif //BLINKER_H diff --git a/game/code/presentation/cameraplayer.cpp b/game/code/presentation/cameraplayer.cpp new file mode 100644 index 0000000..7abf052 --- /dev/null +++ b/game/code/presentation/cameraplayer.cpp @@ -0,0 +1,111 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: cameraplayer.cpp +// +// Description: Implement CameraPlayer +// +// History: 22/04/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <p3d/utility.hpp> + +//======================================== +// Project Includes +//======================================== +#include <presentation/cameraplayer.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// CameraPlayer::CameraPlayer +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +CameraPlayer::CameraPlayer() : + mpAnimation( NULL ) +{ + SetExclusive( false ); +} + +//============================================================================== +// CameraPlayer::~CameraPlayer +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +CameraPlayer::~CameraPlayer() +{ +} + +//============================================================================= +// CameraPlayer::ClearData +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void CameraPlayer::ClearData() +{ + SimpleAnimationPlayer::ClearData(); + + if( mpAnimation != NULL ) + { + mpAnimation->Release(); + mpAnimation = NULL; + } +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// CameraPlayer::DoLoaded +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void CameraPlayer::DoLoaded() +{ + SimpleAnimationPlayer::DoLoaded(); + + mpAnimation = p3d::find<tAnimation>( GetAnimationName() ); + rAssert( mpAnimation ); + mpAnimation->AddRef(); +} + diff --git a/game/code/presentation/cameraplayer.h b/game/code/presentation/cameraplayer.h new file mode 100644 index 0000000..24a8f82 --- /dev/null +++ b/game/code/presentation/cameraplayer.h @@ -0,0 +1,55 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 22/04/2002 + Created -- NAME +// +//============================================================================= + +#ifndef CAMERAPLAYER_H +#define CAMERAPLAYER_H + +//======================================== +// Nested Includes +//======================================== + +#include <presentation/simpleanimationplayer.h> + +//======================================== +// Forward References +//======================================== + +class tAnimation; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class CameraPlayer : public SimpleAnimationPlayer +{ + public: + CameraPlayer(); + virtual ~CameraPlayer(); + + virtual void ClearData(); + + protected: + virtual void DoLoaded(); + + private: + + //Prevent wasteful constructor creation. + CameraPlayer( const CameraPlayer& cameraPlayer ); + CameraPlayer& operator=( const CameraPlayer& cameraPlayer ); + + tAnimation* mpAnimation; +}; + + +#endif //CAMERAPLAYER_H + diff --git a/game/code/presentation/fmvplayer/allfmvplayergc.cpp b/game/code/presentation/fmvplayer/allfmvplayergc.cpp new file mode 100644 index 0000000..e753799 --- /dev/null +++ b/game/code/presentation/fmvplayer/allfmvplayergc.cpp @@ -0,0 +1,2 @@ +#include <presentation/fmvplayer/fmvplayer.cpp> +#include <presentation/fmvplayer/fmvuserinputhandler.cpp> diff --git a/game/code/presentation/fmvplayer/allfmvplayerps2.cpp b/game/code/presentation/fmvplayer/allfmvplayerps2.cpp new file mode 100644 index 0000000..e753799 --- /dev/null +++ b/game/code/presentation/fmvplayer/allfmvplayerps2.cpp @@ -0,0 +1,2 @@ +#include <presentation/fmvplayer/fmvplayer.cpp> +#include <presentation/fmvplayer/fmvuserinputhandler.cpp> diff --git a/game/code/presentation/fmvplayer/fmvplayer.cpp b/game/code/presentation/fmvplayer/fmvplayer.cpp new file mode 100644 index 0000000..4db5dc7 --- /dev/null +++ b/game/code/presentation/fmvplayer/fmvplayer.cpp @@ -0,0 +1,526 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: fmvplayer.cpp +// +// Description: Implement FMVPlayer +// +// History: 17/04/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> + +#include <radplatform.hpp> +#include <radsound.hpp> +#include <raddebug.hpp> +#include <radmovie2.hpp> +#include <radcontroller.hpp> +#include <radfile.hpp> +#include <radmemory.hpp> +//======================================== +// Project Includes +//======================================== +#include <main/game.h> +#include <main/platform.h> +#include <gameflow/gameflow.h> +#include <presentation/fmvplayer/FMVplayer.h> +#include <input/inputmanager.h> +#include <sound/soundmanager.h> +#include <memory/srrmemory.h> +#include <contexts/bootupcontext.h> +#include <presentation/fmvplayer/fmvplayer.h> +#include <presentation/fmvplayer/fmvuserinputhandler.h> +#include <presentation/presevents/fmvevent.h> +#include <presentation/gui/guitextbible.h> +#include <events/eventmanager.h> + +#include <render/RenderManager/RenderManager.h> +#include <p3d/utility.hpp> +#include <p3d/matrixstack.hpp> +#include <p3d/context.hpp> +#include <radmemory.hpp> +#include <radmemorymonitor.hpp> +#include <pddi/pddi.hpp> + +#include <string.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +#define MOVIE_MAX_WIDTH 640 +#ifdef PAL + #define MOVIE_MAX_HEIGHT 512 +#else + #define MOVIE_MAX_HEIGHT 480 +#endif +#define MOVIE_ENCODED_VIDEO_BUFFER_SIZE ( 512 * 1024 ) +#define MOVIE_PRIMARY_AUDIO_BUFFER_SIZE 2000 +#define MOVIE_SECONDARY_AUDIO_BUFFER_SIZE 1000 +#define MOVIE_AUDIO_BUFFER_SIZE_TYPE IRadSoundHalAudioFormat::Milliseconds + +#ifdef RAD_XBOX +static const float VOLUME_MULTIPLIER = 0.75f; +#else +static const float VOLUME_MULTIPLIER = 1.0f; +#endif + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// FMVPlayer::FMVPlayer +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +FMVPlayer::FMVPlayer() : + m_refIRadMoviePlayer( NULL ), + mElapsedTime( 0.0f ), + mFadeOut(-1.0f) +{ + m_UserInputHandler = new FMVUserInputHandler; + m_UserInputHandler->AddRef(); +} + +//============================================================================== +// FMVPlayer::~FMVPlayer +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +FMVPlayer::~FMVPlayer() +{ + m_UserInputHandler->Release(); + m_UserInputHandler = NULL; + + if( m_refIRadMoviePlayer != NULL ) + { + m_refIRadMoviePlayer->Unload( ); + m_refIRadMoviePlayer = NULL; + } +} + +//============================================================================= +// FMVPlayer::LoadData +//============================================================================= +// Description: Comment +// +// Parameters: ( const char* fileName, bool bInInventory ) +// +// Return: void +// +//============================================================================= +void FMVPlayer::LoadData( const char* fileName, bool bInInventory, void* pUserData ) +{ + if( GetState() == ANIM_IDLE || GetState() == ANIM_LOADING ) + { + GetSoundManager()->StopForMovie(); + while( !( GetSoundManager()->IsStoppedForMovie() ) ) + { + ::radMovieService2( ); + ::radFileService( ); + SoundManager::GetInstance()->Update(); + SoundManager::GetInstance()->UpdateOncePerFrame( 0, NUM_CONTEXTS, false ); + } + + GameMemoryAllocator allocator = GMA_LEVEL_MOVIE; + unsigned int audioIndex = 0; + FMVEvent::FMVEventData* data = reinterpret_cast<FMVEvent::FMVEventData*>(pUserData); + if( data ) + { + allocator = data->Allocator; + + if ( allocator >= GMA_ANYWHERE_IN_LEVEL ) + { + ::SetupAllocatorSearch( allocator ); + allocator = GMA_ALLOCATOR_SEARCH; + } + + audioIndex = data->AudioIndex; + + if( data->KillMusic ) + { + GetEventManager()->TriggerEvent( EVENT_STOP_THE_MUSIC ); + } + } + HeapMgr()->PushHeap( allocator ); + Initialize( allocator ); + m_refIRadMoviePlayer->Load( fileName, audioIndex ); + mDriveFinished = false; + Game::GetInstance()->GetPlatform()->GetHostDrive()->AddCompletionCallback( this, 0 ); + + while( !mDriveFinished ) + { + ::radMovieService2( ); + ::radFileService( ); + SoundManager::GetInstance()->Update(); + SoundManager::GetInstance()->UpdateOncePerFrame( 0, NUM_CONTEXTS, false ); + } + HeapMgr()->PopHeap(allocator); + SetState( ANIM_LOADED ); + } +} + +//============================================================================= +// FMVPlayer::Play +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void FMVPlayer::Play() +{ + if(( GetState() == ANIM_LOADED ) && ( m_refIRadMoviePlayer != NULL )) + { + AnimationPlayer::Play(); + FadeScreen(0.0f); + p3d::context->SwapBuffers(); + p3d::display->SetForceVSync(true); +#ifdef FINAL + m_UserInputHandler->SetEnabled(GetSkippable()); +#endif + // register GUI user input handler for all controllers + for( unsigned i = 0; i < GetInputManager()->GetMaxControllers(); i++ ) + { + GetInputManager()->RegisterMappable( i, m_UserInputHandler ); + } + mElapsedTime = 0.0f; + mFadeOut = -1.0f; + + mMovieVolume = VOLUME_MULTIPLIER; + if(GetGameFlow()->GetCurrentContext() != CONTEXT_BOOTUP) + { + mMovieVolume *= GetSoundManager()->GetDialogueVolume(); + } + + m_refIRadMoviePlayer->SetVolume(mMovieVolume); + m_refIRadMoviePlayer->Play( ); + } +} + +/*============================================================================= +Causes the movie to begin fading out. When it's finished fading out it stops. +Fade out time is hard coded right now to half a second. +=============================================================================*/ +void FMVPlayer::Abort(void) +{ + if(mFadeOut == -1.0f) + { + mFadeOut = 1.0f; + } +} + +//============================================================================= +// FMVPlayer::Stop +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void FMVPlayer::Stop() +{ + // Force a clear screen. + FadeScreen(0.0f); + p3d::context->SwapBuffers(); + p3d::display->SetForceVSync(false); + if( this->IsPlaying() && m_refIRadMoviePlayer != NULL ) + { + for( unsigned i = 0; i < GetInputManager()->GetMaxControllers(); i++ ) + { + GetInputManager()->UnregisterMappable( i, m_UserInputHandler ); + } + m_UserInputHandler->SetEnabled(true); + GetSoundManager()->ResumeAfterMovie(); + AnimationPlayer::Stop(); + + ClearData(); + } + mFadeOut = -1.0f; +} + +//============================================================================= +// FMVPlayer::ForceStop +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +#ifdef RAD_WIN32 +void FMVPlayer::ForceStop() +{ + // Force a clear screen. + if( this->IsPlaying() && m_refIRadMoviePlayer != NULL ) + { + for( unsigned i = 0; i < GetInputManager()->GetMaxControllers(); i++ ) + { + GetInputManager()->UnregisterMappable( i, m_UserInputHandler ); + } + m_UserInputHandler->SetEnabled(true); + GetSoundManager()->ResumeAfterMovie(); + AnimationPlayer::Stop(); + + ClearData(); + } +} +#endif + +//============================================================================= +// FMVPlayer::Pause +//============================================================================= +void FMVPlayer::Pause() +{ + if( this->IsPlaying() && m_refIRadMoviePlayer != NULL ) + { + m_refIRadMoviePlayer->Pause( ); + } +} + +//============================================================================= +// FMVPlayer::UnPause +//============================================================================= +void FMVPlayer::UnPause() +{ + if( this->IsPlaying() && m_refIRadMoviePlayer != NULL ) + { + m_refIRadMoviePlayer->Play( ); + } +} + + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// FMVPlayer::Initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void FMVPlayer::Initialize( radMemoryAllocator Allocator ) +{ + // + // Initialize the movie player. + // + // This is where all the memory will be allocated. + // + ref< IRadMovieRenderLoop > refIRadMovieRenderLoop = this; + ref< IRadMovieRenderStrategy > refIRadMovieRenderStrategy = + ::radMovieSimpleFullScreenRenderStrategyCreate( Allocator ); + + // Note that there is a problem if we start creating multiple movie players + //(why would we ever do this???). The allocator is stored as a single global + //value in the movieplayer (binkmovieplayer.cpp for instance) and it is set + //when you call ::radMoviePlayerCreate2(). So if you make multiple calls + //the most recent allocator you pass is the one used. + m_refIRadMoviePlayer = ::radMoviePlayerCreate2( Allocator ); + rAssert( m_refIRadMoviePlayer != NULL ); + +#if defined(RAD_XBOX) || defined(RAD_GAMECUBE) || defined(RAD_WIN32) + m_refIRadMoviePlayer->Initialize( + refIRadMovieRenderLoop, + refIRadMovieRenderStrategy ); +#else // PS2 + m_refIRadMoviePlayer->Initialize( + refIRadMovieRenderLoop, + refIRadMovieRenderStrategy, + MOVIE_MAX_WIDTH, MOVIE_MAX_HEIGHT, + MOVIE_ENCODED_VIDEO_BUFFER_SIZE, + MOVIE_PRIMARY_AUDIO_BUFFER_SIZE, + MOVIE_SECONDARY_AUDIO_BUFFER_SIZE, + MOVIE_AUDIO_BUFFER_SIZE_TYPE ); +#endif +} + +//============================================================================= +// FMVPlayer::DoRender +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void FMVPlayer::DoRender() +{ + IRadMoviePlayer2::State state = m_refIRadMoviePlayer->GetState( ); + + mFrameReady = false; + + while( !mFrameReady && (state != IRadMoviePlayer2::NoData)) + { + ::radMovieService2( ); + ::radSoundHalSystemGet( )->Service( ); +// ::radSoundHalSystemGet( )->ServiceOncePerFrame( ); + ::radFileService( ); + + state = m_refIRadMoviePlayer->GetState( ); + if ( state == IRadMoviePlayer2::ReadyToPlay ) + { + // [ps] Here we are paused, so fall out to the regular game. + break; + } + } + + if((mFadeOut <= 0.0f) && (mFadeOut != -1.0f)) + { + Stop(); + } + if( (state == IRadMoviePlayer2::NoData) || ( m_refIRadMoviePlayer == NULL) ) + { + Stop(); + } +} + +void FMVPlayer::IterateLoop( IRadMoviePlayer2* pIRadMoviePlayer ) +{ + rAssert( pIRadMoviePlayer != NULL ); + + pIRadMoviePlayer->Render(); + if(mFadeOut > 0.0f ) + { + pIRadMoviePlayer->SetVolume(mMovieVolume * mFadeOut); + FadeScreen(mFadeOut); + } + float deltaTime = mElapsedTime; + mElapsedTime = pIRadMoviePlayer->GetCurrentFrameNumber() / pIRadMoviePlayer->GetFrameRate(); + if(mFadeOut > 0.0f ) + { + deltaTime = mElapsedTime - deltaTime; + mFadeOut -= deltaTime * 2.0f; // Half second fade. + } + mFrameReady = true; +} + +//============================================================================= +// FMVPlayer::Finalize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void FMVPlayer::ClearData() +{ + // + // Free up the radmovie movie player stuff + // + if( m_refIRadMoviePlayer != NULL ) + { + // I think there is a case where the movie player doesn't shut down properly because the + //decode buffer is still in use as a texture in the draw pipeline, preventing it from being + //freed. + p3d::pddi->DrawSync(); + m_refIRadMoviePlayer->Unload( ); + m_refIRadMoviePlayer = NULL; + + mDriveFinished = false; + Game::GetInstance()->GetPlatform()->GetHostDrive()->AddCompletionCallback( this, 0 ); + + while( !mDriveFinished ) + { + ::radMovieService2( ); + ::radFileService( ); + SoundManager::GetInstance()->Update(); + SoundManager::GetInstance()->UpdateOncePerFrame( 0, NUM_CONTEXTS, false ); + } + } + + AnimationPlayer::ClearData(); +} + +void FMVPlayer::OnDriveOperationsComplete( void* pUserData ) +{ + mDriveFinished = true; +} + +void FMVPlayer::FadeScreen(float Alpha) +{ + tColour c; + c.Set( 0, 0, 0, int(0xFF * (1.0f - rmt::Clamp(Alpha, 0.0f, 1.0f))) ); + p3d::stack->Push(); + bool oldZWrite = p3d::pddi->GetZWrite(); + pddiCompareMode oldZComp = p3d::pddi->GetZCompare(); + if( oldZWrite ) + { + p3d::pddi->SetZWrite( false ); + } + if( oldZComp != PDDI_COMPARE_ALWAYS ) + { + p3d::pddi->SetZCompare( PDDI_COMPARE_ALWAYS ); + } + p3d::stack->LoadIdentity(); + p3d::pddi->SetProjectionMode( PDDI_PROJECTION_ORTHOGRAPHIC ); + pddiColour oldAmbient = p3d::pddi->GetAmbientLight(); + p3d::pddi->SetAmbientLight( pddiColour( 255, 255, 255 ) ); + + pddiPrimStream* overlay = 0; + + pddiShader* overlayShader = BootupContext::GetInstance()->GetSharedShader(); + rAssert( overlayShader ); + + overlayShader->SetInt( PDDI_SP_BLENDMODE, PDDI_BLEND_ALPHA ); + overlayShader->SetInt( PDDI_SP_ISLIT, 0 ); + overlayShader->SetInt( PDDI_SP_SHADEMODE, PDDI_SHADE_FLAT ); + + overlay = p3d::pddi->BeginPrims( overlayShader, PDDI_PRIM_TRISTRIP, PDDI_V_C, 4 ); + + overlay->Colour( c ); + overlay->Coord( 0.5f, -0.5f, 1.0f ); + overlay->Colour( c ); + overlay->Coord( -0.5f, -0.5f, 1.0f ); + overlay->Colour( c ); + overlay->Coord( 0.5f, 0.5f, 1.0f ); + overlay->Colour( c ); + overlay->Coord( -0.5f, 0.5f, 1.0f ); + + p3d::pddi->EndPrims( overlay ); + p3d::pddi->SetProjectionMode(PDDI_PROJECTION_PERSPECTIVE); + p3d::pddi->SetAmbientLight( oldAmbient ); + if( oldZWrite ) + { + p3d::pddi->SetZWrite( true ); + } + if( oldZComp != PDDI_COMPARE_ALWAYS ) + { + p3d::pddi->SetZCompare( oldZComp ); + } + p3d::stack->Pop(); +} diff --git a/game/code/presentation/fmvplayer/fmvplayer.h b/game/code/presentation/fmvplayer/fmvplayer.h new file mode 100644 index 0000000..663e091 --- /dev/null +++ b/game/code/presentation/fmvplayer/fmvplayer.h @@ -0,0 +1,108 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 17/04/2002 + Created -- NAME +// +//============================================================================= + +#ifndef FMVPLAYER_H +#define FMVPLAYER_H + +//======================================== +// Nested Includes +//======================================== + +#include <presentation/animplayer.h> +#include <radmovie2.hpp> + +//======================================== +// Forward References +//======================================== + +class FMVUserInputHandler; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class FMVPlayer : public AnimationPlayer, + public IRadMovieRenderLoop, + public IRadDriveCompletionCallback, + public radRefCount + +{ + IMPLEMENT_REFCOUNTED( "FMVPlayer" ) + +public: + + FMVPlayer(); + virtual ~FMVPlayer(); + + // playback control + virtual void Play(); + virtual void Abort(void); + virtual void Stop(); + virtual void Pause(); + virtual void UnPause(); + +#ifdef RAD_WIN32 + void ForceStop(); +#endif + + // loading + virtual void PreLoad(void) { SetState(ANIM_LOADING);} + virtual void LoadData( const char* fileName, bool bInInventory, void* pUserData ); + + // animation updating (doesn't need any) + virtual void Update( unsigned int elapsedTime ) {}; + + // IRadMovieRenderLoop interface, called by radMovie service eac time a frame is ready + void IterateLoop( IRadMoviePlayer2* pIRadMoviePlayer ); + + // reset all internal data + virtual void ClearData(); + + // How long the FMV has played in seconds. 0 if the movie hasn't played yet. + float GetElapsedTime() { return mElapsedTime; } + + inline FMVUserInputHandler* GetUserInputHandler() const + { + return m_UserInputHandler; + } + +protected: + void Initialize( radMemoryAllocator Allocator ); + + // AnimationPlayer interface + virtual void DoLoaded() {}; // Movies aren't loader by main game loader, so don't need to handle this + virtual void DoRender(); // render a frame (if one is avilible) + + // Implements IRadDriveCompletionCallback. We'll be called this when the movie finishes streaming. + //We need to wait for the drive to finish so the internal memory in radmovie is freed. + virtual void OnDriveOperationsComplete( void* pUserData ); + void FadeScreen(float Alpha); + +private: + //Prevent wasteful constructor creation. + FMVPlayer( const FMVPlayer& fmvPlayer ); + FMVPlayer& operator=( const FMVPlayer& fmvPlayer ); + + FMVUserInputHandler* m_UserInputHandler; + ref< IRadMoviePlayer2 > m_refIRadMoviePlayer; + + bool mFrameReady; + float mElapsedTime; // Elapsed playing time. So you know if you should let the player skip the movie. + bool mDriveFinished; + float mFadeOut; + float mMovieVolume; +}; + + +#endif //FMVPLAYER_H + diff --git a/game/code/presentation/fmvplayer/fmvuserinputhandler.cpp b/game/code/presentation/fmvplayer/fmvuserinputhandler.cpp new file mode 100644 index 0000000..08c0ddf --- /dev/null +++ b/game/code/presentation/fmvplayer/fmvuserinputhandler.cpp @@ -0,0 +1,257 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: FMVUserInputHandler +// +// Description: Implementation of the FMVUserInputHandler class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/10/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== + +#include <presentation/fmvplayer/fmvplayer.h> +#include <presentation/fmvplayer/fmvuserinputhandler.h> + +#include <presentation/presentation.h> +#include <presentation/gui/guiscreenmessage.h> +#include <input/inputmanager.h> +#include <gameflow/gameflow.h> +#include <contexts/context.h> +#include <main/game.h> +#include <main/platform.h> + +#include <raddebug.hpp> + +static const float MIN_MOVIE_TIME = 0.125f; + +// this will allow any buttons to skip FMV +// +//#define ANY_BUTTON_SKIP + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +struct ControlMap +{ + char* inputName; + FMVInput::FMVInputEnum inputID; +}; + +const ControlMap FMV_CONTROL_MAP[] = +{ +#ifdef RAD_GAMECUBE + { "Menu", FMVInput::Skip }, + { "A", FMVInput::Skip }, + #ifdef ANY_BUTTON_SKIP + { "LeftStickX", FMVInput::Skip }, + { "LeftStickY", FMVInput::Skip }, + { "RightStickX", FMVInput::Skip }, + { "RightStickY", FMVInput::Skip }, + { "DPadLeft", FMVInput::Skip }, + { "DPadRight", FMVInput::Skip }, + { "DPadUp", FMVInput::Skip }, + { "DPadDown", FMVInput::Skip }, + { "B", FMVInput::Skip }, + { "X", FMVInput::Skip }, + { "Y", FMVInput::Skip }, + { "Z", FMVInput::Skip }, + { "TriggerL", FMVInput::Skip }, + { "TriggerR", FMVInput::Skip }, + #endif +#endif // RAD_GAMECUBE + +#ifdef RAD_PS2 + { "Start", FMVInput::Start}, + { "X", FMVInput::Skip }, + { "DPadLeft", FMVInput::UNKNOWN }, + { "DPadRight", FMVInput::UNKNOWN }, + { "DPadUp", FMVInput::UNKNOWN }, + { "DPadDown", FMVInput::UNKNOWN }, + { "Select", FMVInput::UNKNOWN }, + { "Triangle", FMVInput::UNKNOWN }, + { "Circle", FMVInput::UNKNOWN }, + { "Square", FMVInput::UNKNOWN }, + { "L1", FMVInput::UNKNOWN }, + { "R1", FMVInput::UNKNOWN }, + { "L2", FMVInput::UNKNOWN }, + { "R2", FMVInput::UNKNOWN }, + #ifdef ANY_BUTTON_SKIP + { "LeftStickX", FMVInput::Skip }, + { "LeftStickY", FMVInput::Skip }, + { "RightStickX", FMVInput::Skip }, + { "RightStickY", FMVInput::Skip }, + #endif +#endif // RAD_PS2 + +#ifdef RAD_XBOX + { "A", FMVInput::Skip }, + { "Start", FMVInput::Start}, + #ifdef ANY_BUTTON_SKIP + { "LeftStickX", FMVInput::Skip }, + { "LeftStickY", FMVInput::Skip }, + { "RightStickX", FMVInput::Skip }, + { "RightStickY", FMVInput::Skip }, + { "DPadLeft", FMVInput::Skip }, + { "DPadRight", FMVInput::Skip }, + { "DPadUp", FMVInput::Skip }, + { "DPadDown", FMVInput::Skip }, + { "Back", FMVInput::Skip }, + { "B", FMVInput::Skip }, + { "X", FMVInput::Skip }, + { "Y", FMVInput::Skip }, + { "White", FMVInput::Skip }, + { "Black", FMVInput::Skip }, + { "LeftTrigger", FMVInput::Skip }, + { "RightTrigger", FMVInput::Skip }, + #endif +#endif // RAD_XBOX + +#ifdef RAD_WIN32 + { "feStart", FMVInput::Skip }, + { "feBack", FMVInput::Skip }, + { "feKeyboardBack", FMVInput::Skip }, + { "feSelect", FMVInput::Skip }, +#endif // RAD_WIN32 + + { "", FMVInput::UNKNOWN } +}; + +const int NUM_FMV_CONTROL_MAPPINGS = sizeof( FMV_CONTROL_MAP ) / + sizeof( FMV_CONTROL_MAP[ 0 ] ); + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// FMVUserInputHandler::FMVUserInputHandler +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +FMVUserInputHandler::FMVUserInputHandler( void ) +: m_isEnabled( true ), + m_controllerPromptShown( false ), + m_controllerReconnect( false ) +{ +} + + +//=========================================================================== +// FMVUserInputHandler::~FMVUserInputHandler +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +FMVUserInputHandler::~FMVUserInputHandler( void ) +{ +} + + + +//=========================================================================== +// FMVUserInputHandler::OnButton +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== + +////////////////////////////////////////////////////////////////////////////// +// IButtonedObject declarations +// +void FMVUserInputHandler::OnButton( int controllerId, int buttonId, const IButton* pButton ) +{ +} + +void FMVUserInputHandler::OnButtonUp( int controllerId, int buttonId, const IButton* pButton ) +{ +} + +void FMVUserInputHandler::OnControllerDisconnect( int id ) +{ +#ifndef RAD_GAMECUBE + int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 ); + if (GetGameFlow()->GetCurrentContext() == CONTEXT_GAMEPLAY + && controllerID == id ) + { + m_controllerPromptShown = true; + char str_buffer[256]; + CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255); + GetGame()->GetPlatform()->OnControllerError(str_buffer); + } +#endif +} +void FMVUserInputHandler::OnControllerConnect( int id ) +{ +#ifndef RAD_GAMECUBE + if (m_controllerPromptShown && id==GetInputManager()->GetControllerIDforPlayer( 0 )) + { + m_controllerReconnect = true; + } +#endif +} + + +void FMVUserInputHandler::OnButtonDown( int controllerId, int buttonId, const IButton* pButton ) +{ + bool button_skip = buttonId == FMVInput::Skip; + + if (buttonId==FMVInput::Start) // start also skip + button_skip = true; + + if (buttonId==FMVInput::Start && m_controllerReconnect) + { + m_controllerReconnect = false; + GetGame()->GetPlatform()->ClearControllerError(); + m_controllerPromptShown = false; + } + else if( m_isEnabled && button_skip ) + { + if( GetPresentationManager()->GetFMVPlayer()->IsPlaying() && + GetPresentationManager()->GetFMVPlayer()->GetElapsedTime() > MIN_MOVIE_TIME ) + { + GetPresentationManager()->GetFMVPlayer()->Abort(); + } + } +} + +void FMVUserInputHandler::LoadControllerMappings( unsigned int controllerId ) +{ + // now set controller mappings + for( int i = 0; i < NUM_FMV_CONTROL_MAPPINGS; i++ ) + { + this->Map( FMV_CONTROL_MAP[ i ].inputName, + FMV_CONTROL_MAP[ i ].inputID, + 0, + controllerId ); + } +} + diff --git a/game/code/presentation/fmvplayer/fmvuserinputhandler.h b/game/code/presentation/fmvplayer/fmvuserinputhandler.h new file mode 100644 index 0000000..aed8b8f --- /dev/null +++ b/game/code/presentation/fmvplayer/fmvuserinputhandler.h @@ -0,0 +1,91 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: FMVUserInputHandler +// +// Description: This class feeds the inputs received by the controller +// system into the GUI system. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/10/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef FMVUSERINPUTHANDLER_H +#define FMVUSERINPUTHANDLER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <input/mappable.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +namespace FMVInput +{ + // Definition of control points for an abstracted player controller + // + enum FMVInputEnum + { + UNKNOWN = -1, + + Skip, + Start, + + NUM_FMV_INPUTS + }; +}; + +class FMVUserInputHandler : public Mappable +{ +public: + + FMVUserInputHandler( void ); + virtual ~FMVUserInputHandler( void ); + + // Mappable interface declarations + // + virtual void OnButton( int controllerId, int buttonId, const IButton* pButton ); + virtual void OnButtonUp( int controllerId, int buttonId, const IButton* pButton ); + virtual void OnButtonDown( int controllerId, int buttonId, const IButton* pButton ); + + // Mappable interface declarations. + // Dispatch a message when controller is disconnected. + // + virtual void OnControllerDisconnect( int id ); + + // Mappable interface declarations. + // Dispatch a message when controller is connected. + // + virtual void OnControllerConnect( int id ); + + // Mappable interface declarations + // + virtual void LoadControllerMappings( unsigned int controllerId ); + + inline bool IsEnabled() const { return m_isEnabled; } + inline void SetEnabled( bool isEnabled ) { m_isEnabled = isEnabled; } + + +private: + // Disallow object copying or assigning until we know we need it + // + FMVUserInputHandler( const FMVUserInputHandler& original ); + FMVUserInputHandler& operator=( const FMVUserInputHandler& rhs ); + + bool m_isEnabled : 1; + bool m_controllerPromptShown : 1; + bool m_controllerReconnect; + +}; + +#endif // FMVUSERINPUTHANDLER_H diff --git a/game/code/presentation/gui/allgui.cpp b/game/code/presentation/gui/allgui.cpp new file mode 100644 index 0000000..48e0374 --- /dev/null +++ b/game/code/presentation/gui/allgui.cpp @@ -0,0 +1,13 @@ +#include <presentation/gui/guientity.cpp> +#include <presentation/gui/guimanager.cpp> +#include <presentation/gui/guimenu.cpp> +#include <presentation/gui/guimenuitem.cpp> +#include <presentation/gui/guiscreen.cpp> +#include <presentation/gui/guiscreenmemcardcheck.cpp> +#include <presentation/gui/guiscreenmemorycard.cpp> +#include <presentation/gui/guiscreenmessage.cpp> +#include <presentation/gui/guiscreenprompt.cpp> +#include <presentation/gui/guisystem.cpp> +#include <presentation/gui/guitextbible.cpp> +#include <presentation/gui/guiuserinputhandler.cpp> +#include <presentation/gui/guiwindow.cpp> diff --git a/game/code/presentation/gui/backend/allbackend.cpp b/game/code/presentation/gui/backend/allbackend.cpp new file mode 100644 index 0000000..9ef2fe2 --- /dev/null +++ b/game/code/presentation/gui/backend/allbackend.cpp @@ -0,0 +1,4 @@ +#include <presentation/gui/backend/guimanagerbackend.cpp> +#include <presentation/gui/backend/guiscreenloading.cpp> +#include <presentation/gui/backend/guiscreenloadingfe.cpp> +#include <presentation/gui/backend/guiscreendemo.cpp> diff --git a/game/code/presentation/gui/backend/guiloadingbar.h b/game/code/presentation/gui/backend/guiloadingbar.h new file mode 100644 index 0000000..7842105 --- /dev/null +++ b/game/code/presentation/gui/backend/guiloadingbar.h @@ -0,0 +1,61 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/22 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUILOADINGBAR_H +#define GUILOADINGBAR_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +//=========================================================================== +// External Constants +//=========================================================================== + +const int MB = 1024 * 1024; // bytes + +#ifdef RAD_GAMECUBE + const float TOTAL_INGAME_MEMORY_USAGE = 9.6f * MB; + const float TOTAL_FE_MEMORY_USAGE = 8.8f * MB; + const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 3.0f * MB; + const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE; +#endif + +#ifdef RAD_PS2 + const float TOTAL_INGAME_MEMORY_USAGE = 15.2f * MB; + const float TOTAL_FE_MEMORY_USAGE = 13.0f * MB; + const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 5.6f * MB; + const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE; +#endif + +#ifdef RAD_XBOX + const float TOTAL_INGAME_MEMORY_USAGE = 16.7f * MB; + const float TOTAL_FE_MEMORY_USAGE = 13.1f * MB; + const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 5.5f * MB; + const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE; +#endif + +#ifdef RAD_WIN32 + // These settings are for release mode, which has difft memory behaviour than Tune, + // only because Tune has debug information. + const float TOTAL_INGAME_MEMORY_USAGE = 1.3f * MB; + const float TOTAL_FE_MEMORY_USAGE = 1.9f * MB; + const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 1.3f * MB; + const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE; + + // Our system for windows because the memory tracking doesn't work. + const float TOTAL_INGAME_FILES = 56; + // no fe.. it doesn't work with this system. + const float TOTAL_SUPERSPRINT_FILES = 34; + const float LOAD_BLEND_FACTOR = 20; + const float LOAD_MIN_SPEED = 0.003f; +#endif + +#endif // GUILOADINGBAR_H diff --git a/game/code/presentation/gui/backend/guimanagerbackend.cpp b/game/code/presentation/gui/backend/guimanagerbackend.cpp new file mode 100644 index 0000000..7e65581 --- /dev/null +++ b/game/code/presentation/gui/backend/guimanagerbackend.cpp @@ -0,0 +1,296 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerBackEnd +// +// Description: Implementation of the CGuiManagerBackEnd class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/15 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/backend/guimanagerbackend.h> +#include <presentation/gui/backend/guiscreenloading.h> +#include <presentation/gui/backend/guiscreenloadingfe.h> +#include <presentation/gui/backend/guiscreendemo.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiwindow.h> // for window IDs + +#include <contexts/bootupcontext.h> + +#include <gameflow/gameflow.h> + +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManagerBackEnd::CGuiManagerBackEnd +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerBackEnd::CGuiManagerBackEnd +( + Scrooby::Project* pProject, + CGuiEntity* pParent +) +: CGuiManager( pProject, pParent ), + m_isQuittingDemo( false ), + m_isBackendPreRun( false ) +{ +} + + +//=========================================================================== +// CGuiManagerBackEnd::~CGuiManagerBackEnd +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerBackEnd::~CGuiManagerBackEnd() +{ + for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ ) + { + if( m_windows[ i ] != NULL ) + { + delete m_windows[ i ]; + m_windows[ i ] = NULL; + } + } +} + + +//=========================================================================== +// CGuiManagerBackEnd::Populate +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerBackEnd::Populate() +{ +MEMTRACK_PUSH_GROUP( "CGUIManagerBackEnd" ); + Scrooby::Screen* pScroobyScreen; + CGuiScreen* pScreen; + + pScroobyScreen = m_pScroobyProject->GetScreen( "Loading" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLoading( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LOADING, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "LoadingFE" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLoadingFE( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LOADING_FE, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Demo" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenDemo( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_DEMO, pScreen ); + } +MEMTRACK_POP_GROUP( "CGUIManagerBackEnd" ); +} + +void +CGuiManagerBackEnd::Start( CGuiWindow::eGuiWindowID initialWindow ) +{ + rAssert( m_state == GUI_FE_UNINITIALIZED ); + m_state = GUI_FE_SCREEN_RUNNING; +/* + m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ? + initialWindow : + CGuiWindow::GUI_SCREEN_ID_LOADING; + + m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen() + + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); +*/ +} + +//=========================================================================== +// CGuiManagerBackEnd::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerBackEnd::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_PRE_RUN_BACKEND: + { + this->GotoLoadingScreen( param1 ); + + m_isBackendPreRun = true; + + break; + } + + case GUI_MSG_RUN_BACKEND: + { + if( !m_isBackendPreRun ) + { + this->GotoLoadingScreen( param1 ); + } + + // load dynamic resources for loading screen + // + CGuiWindow* loadingScreen = this->FindWindowByID( m_nextScreen ); + rAssert( loadingScreen != NULL ); + loadingScreen->HandleMessage( GUI_MSG_LOAD_RESOURCES ); + + break; + } + + case GUI_MSG_QUIT_BACKEND: + { + m_isBackendPreRun = false; + + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + + // Go to a blank screen. + // + m_pScroobyProject->GotoScreen( "Blank", NULL ); + + break; + } + + case GUI_MSG_RUN_DEMO: + { + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_DEMO, + CLEAR_WINDOW_HISTORY | FORCE_WINDOW_RELOAD | FORCE_WINDOW_CHANGE_IMMEDIATE ); + + break; + } + + case GUI_MSG_QUIT_DEMO: + { + m_isQuittingDemo = true; + + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_LOADING_FE, + CLEAR_WINDOW_HISTORY ); + + break; + } + + case GUI_MSG_WINDOW_FINISHED: + { + if( GUI_FE_CHANGING_SCREENS == m_state ) + { + if( m_isQuittingDemo ) + { + m_isQuittingDemo = false; + + // switch to frontend context + // + GetGameFlow()->SetContext( CONTEXT_FRONTEND ); + } + + m_currentScreen = m_nextScreen; + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + } + + break; + } + + default: + { + if( m_state != GUI_FE_UNINITIALIZED && + m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + // Send the messages down to the current screen. + // + CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen ); + rAssert( pScreen ); + + pScreen->HandleMessage( message, param1, param2 ); + } + } + } + + // propogate message up the hierarchy + CGuiManager::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +void +CGuiManagerBackEnd::GotoLoadingScreen( unsigned int param1 ) +{ + bool isLoadingGameplay = (param1 == IS_LOADING_GAMEPLAY || + GetGameFlow()->GetNextContext() == CONTEXT_LOADING_GAMEPLAY); + + unsigned int loadingScreenID = isLoadingGameplay ? + CGuiWindow::GUI_SCREEN_ID_LOADING : + CGuiWindow::GUI_SCREEN_ID_LOADING_FE; +/* +#ifdef RAD_E3 + // always show I&S loading screen for E3 build + // + loadingScreenID = CGuiWindow::GUI_SCREEN_ID_LOADING_FE; +#endif +*/ + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + loadingScreenID, + CLEAR_WINDOW_HISTORY | FORCE_WINDOW_RELOAD | FORCE_WINDOW_CHANGE_IMMEDIATE ); +} + diff --git a/game/code/presentation/gui/backend/guimanagerbackend.h b/game/code/presentation/gui/backend/guimanagerbackend.h new file mode 100644 index 0000000..f297343 --- /dev/null +++ b/game/code/presentation/gui/backend/guimanagerbackend.h @@ -0,0 +1,69 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerBackEnd +// +// Description: Interface for the CGuiManagerBackEnd class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/15 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUIMANAGERBACKEND_H +#define GUIMANAGERBACKEND_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guimanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +const unsigned int IS_LOADING_GAMEPLAY = 1; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiManagerBackEnd : public CGuiManager +{ + public: + + CGuiManagerBackEnd( Scrooby::Project* pProject, + CGuiEntity* pParent ); + + virtual ~CGuiManagerBackEnd(); + + virtual void Populate(); + virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignment. Declare but don't define. + // + CGuiManagerBackEnd( const CGuiManagerBackEnd& ); + CGuiManagerBackEnd& operator= ( const CGuiManagerBackEnd& ); + + void GotoLoadingScreen( unsigned int param1 ); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + bool m_isQuittingDemo; + bool m_isBackendPreRun; + +}; + +#endif // GUIMANAGERBACKEND_H diff --git a/game/code/presentation/gui/backend/guiscreendemo.cpp b/game/code/presentation/gui/backend/guiscreendemo.cpp new file mode 100644 index 0000000..770f4ce --- /dev/null +++ b/game/code/presentation/gui/backend/guiscreendemo.cpp @@ -0,0 +1,210 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenDemo +// +// Description: Implementation of the CGuiScreenDemo class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/backend/guiscreendemo.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guisystem.h> + +#include <contexts/demo/democontext.h> + +#include <raddebug.hpp> // Foundation +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenDemo::CGuiScreenDemo +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenDemo::CGuiScreenDemo +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_DEMO ), + m_demoText( NULL ), + m_elapsedTime( 0 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "Demo" ); + rAssert( pPage ); + + Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" ); + rAssert( foreground != NULL ); + + m_demoText = foreground->GetText( "Demo" ); + rAssert( m_demoText ); +} + + +//=========================================================================== +// CGuiScreenDemo::~CGuiScreenDemo +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenDemo::~CGuiScreenDemo() +{ +} + + +//=========================================================================== +// CGuiScreenDemo::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDemo::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + m_elapsedTime += param1; + + const unsigned int BLINK_PERIOD = 250; + bool blinked = GuiSFX::Blink( m_demoText, + (float)m_elapsedTime, + (float)BLINK_PERIOD ); + if( blinked ) + { + m_elapsedTime %= BLINK_PERIOD; + } + + break; + } + + case GUI_MSG_CONTROLLER_CONNECT: + case GUI_MSG_CONTROLLER_DISCONNECT: + case GUI_MSG_CONTROLLER_START: + case GUI_MSG_CONTROLLER_SELECT: + { + GetDemoContext()->EndDemo(); +// m_pParent->HandleMessage( GUI_MSG_QUIT_DEMO ); + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenDemo::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDemo::InitIntro() +{ + rAssert( m_demoText ); + m_demoText->SetVisible( true ); + + m_elapsedTime = 0; +} + +//=========================================================================== +// CGuiScreenDemo::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDemo::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenDemo::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDemo::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/backend/guiscreendemo.h b/game/code/presentation/gui/backend/guiscreendemo.h new file mode 100644 index 0000000..7f28c45 --- /dev/null +++ b/game/code/presentation/gui/backend/guiscreendemo.h @@ -0,0 +1,52 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenDemo +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENDEMO_H +#define GUISCREENDEMO_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenDemo : public CGuiScreen +{ +public: + CGuiScreenDemo( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenDemo(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + Scrooby::Text* m_demoText; + unsigned int m_elapsedTime; + +}; + +#endif // GUISCREENDEMO_H diff --git a/game/code/presentation/gui/backend/guiscreenloading.cpp b/game/code/presentation/gui/backend/guiscreenloading.cpp new file mode 100644 index 0000000..486a72b --- /dev/null +++ b/game/code/presentation/gui/backend/guiscreenloading.cpp @@ -0,0 +1,624 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLoading +// +// Description: Implementation of the CGuiScreenLoading class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <camera/animatedcam.h> +#include <camera/supercammanager.h> +#include <presentation/gui/backend/guiscreenloading.h> +#include <presentation/gui/backend/guiloadingbar.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guitextbible.h> + +#include <gameflow/gameflow.h> +#include <memory/createheap.h> +#include <memory/memoryutilities.h> +#include <mission/gameplaymanager.h> +#include <mission/missionmanager.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> +#include <sound/soundmanager.h> + +#include <raddebug.hpp> // Foundation +#include <p3d/sprite.hpp> +#include <p3d/utility.hpp> +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <sprite.h> +#include <polygon.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#define ENABLE_DYNA_LOADED_IMAGES +//#define LOADING_BAR_EXPLOSION + +#ifdef ENABLE_DYNA_LOADED_IMAGES + const char* DYNAMIC_RESOURCES_DIR = "art\\frontend\\dynaload\\images\\loading\\"; + const char* DYNA_LOAD_INVENTORY_SECTION = "LoadingScreenImages"; +#endif + +// this is to correct the original reduced scale in the source image +// +#ifdef RAD_WIN32 + const float LOADING_BGD0_CORRECTION_SCALE = 1.05f; +#else + const float LOADING_BGD0_CORRECTION_SCALE = 4.2f; +#endif + +#ifdef RAD_WIN32 + const float LOADING_BGD1_CORRECTION_SCALE = 1.75f; +#else + const float LOADING_BGD1_CORRECTION_SCALE = 8.4f; +#endif + +#ifdef RAD_PS2 + const float LOADING_IMAGE_CORRECTION_SCALE = 1.95f; +#elif defined( RAD_WIN32 ) + const float LOADING_IMAGE_CORRECTION_SCALE = 0.925f; +#else + const float LOADING_IMAGE_CORRECTION_SCALE = 1.85f; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLoading::CGuiScreenLoading +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLoading::CGuiScreenLoading +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LOADING ), + m_elapsedTime( 0 ), + m_elapsedSpiralTime( 0 ), + m_loadingBarGroup( NULL ), + m_currentMemoryUsage( 0.0f ), + m_startingMemoryAvailable( 0 ), + m_elapsedFireTime( 0 ), + m_loadingImage( NULL ), + m_isSpirallingDone( false ), + m_loadingImageSprite( NULL ), + m_explosionLayer( NULL ), + m_explosion( NULL ), + m_elapsedExplosionTime( 0 ) +{ + memset( m_loadingImageName, 0, sizeof( m_loadingImageName ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "Loading" ); + rAssert( pPage ); + + Scrooby::Layer* newspaperLayer = pPage->GetLayer( "Newspaper" ); + rAssert( newspaperLayer != NULL ); + m_loadingImage = newspaperLayer->GetSprite( "Loading" ); + m_loadingImage->SetVisible( false ); + + if( this->IsWideScreenDisplay() ) + { + newspaperLayer->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( newspaperLayer ); + } + + Scrooby::Layer* foregroundLayer = pPage->GetLayer( "Foreground" ); + + for( int i = 0; i < NUM_LOADING_OVERLAYS; i++ ) + { + char overlayName[ 32 ]; + sprintf( overlayName, "Overlay%d", i ); + m_loadingOverlays[ i ] = foregroundLayer->GetSprite( overlayName ); + rAssert( m_loadingOverlays[ i ] != NULL ); + } + + // get loading bar + // + m_loadingBarGroup = pPage->GetGroup( "LoadingBar" ); + rAssert( m_loadingBarGroup != NULL ); + m_loadingBar.m_type = Slider::HORIZONTAL_SLIDER_RIGHT; + m_loadingBar.SetScroobyPolygon( m_loadingBarGroup->GetPolygon( "Wick" ), + m_loadingBarGroup->GetSprite( "Fire" ) ); + + Scrooby::Sprite* loadingBgd = pPage->GetSprite( "Background" ); + if( loadingBgd != NULL ) + { + loadingBgd->ScaleAboutCenter( LOADING_BGD0_CORRECTION_SCALE ); + } + +/* + // XBOX ONLY: show loading text to satisfy Xbox TCR requirement (C01-07) + // +#ifndef RAD_XBOX + // otherwise, hide it for all other platforms + // + Scrooby::Text* loadingText = pPage->GetText( "Loading" ); + if( loadingText != NULL ) + { + loadingText->SetVisible( false ); + } +#endif // !RAD_XBOX +*/ + + // get explosion overlay (from Explosion.pag) + // + pPage = m_pScroobyScreen->GetPage( "Explosion" ); + if( pPage != NULL ) + { + m_explosionLayer = pPage->GetLayer( "Explosion" ); + rAssert( m_explosionLayer != NULL ); + + m_explosion = m_explosionLayer->GetPolygon( "Explosion0" ); + rAssert( m_explosion != NULL ); + } + +#ifdef ENABLE_DYNA_LOADED_IMAGES + // add inventory section for dynamically loaded resources + // + p3d::inventory->AddSection( DYNA_LOAD_INVENTORY_SECTION ); +#endif +} + + +//=========================================================================== +// CGuiScreenLoading::~CGuiScreenLoading +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLoading::~CGuiScreenLoading() +{ +#ifdef ENABLE_DYNA_LOADED_IMAGES + // delete inventory section for dynamically loaded resources + // + p3d::inventory->DeleteSection( DYNA_LOAD_INVENTORY_SECTION ); +#endif +} + + +//=========================================================================== +// CGuiScreenLoading::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoading::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_UPDATE: + { + // update elapsed time + m_elapsedTime += param1; + + if( !m_isSpirallingDone ) + { + // update loading image + // + static float SPIRAL_DURATION_TIME = 1800.0f; // in msec + static float SPIRAL_ROTATION_TIME = 60.0f; // in msec + + m_elapsedSpiralTime += param1; + m_isSpirallingDone = GuiSFX::Spiral( m_loadingImage, + (float)m_elapsedSpiralTime, + SPIRAL_DURATION_TIME, + SPIRAL_ROTATION_TIME, + 0.25f, // LOADING_IMAGE_CORRECTION_SCALE * 2.0f, + LOADING_IMAGE_CORRECTION_SCALE ); + } + + static float ROTATION_PERIOD = 20000; // in msec + float currentAngle = ((float)m_elapsedTime / ROTATION_PERIOD) * 360.0f; + + for( int i = 0; i < NUM_LOADING_OVERLAYS; i++ ) + { + rAssert( m_loadingOverlays[ i ] ); + m_loadingOverlays[ i ]->ResetTransformation(); + m_loadingOverlays[ i ]->ScaleAboutCenter( LOADING_BGD1_CORRECTION_SCALE ); + m_loadingOverlays[ i ]->RotateAboutCenter( currentAngle ); + + currentAngle *= -1.0f; // reverse rotation direction + } + + if( GetGameFlow()->GetCurrentContext() == CONTEXT_LOADING_GAMEPLAY ) + { + // update loading bar + // + rAssert( m_loadingBarGroup != NULL ); + m_loadingBarGroup->SetVisible( true ); + +#if defined( RAD_XBOX ) + float newMemoryUsage = (m_startingMemoryAvailable - Memory::GetTotalMemoryFree()) / TOTAL_INGAME_MEMORY_USAGE; +#elif defined( RAD_WIN32 ) + // this sucks but i just want to finish it. + float memUsage = float( GetLoadingManager()->GetNumRequestsProcessed() ) / TOTAL_INGAME_FILES; + float newMemoryUsage = m_currentMemoryUsage; + if( memUsage - newMemoryUsage < LOAD_MIN_SPEED ) + { + newMemoryUsage = memUsage; + } + else + { + float delta = (memUsage - newMemoryUsage) / LOAD_BLEND_FACTOR; + newMemoryUsage += delta > LOAD_MIN_SPEED ? delta : LOAD_MIN_SPEED; + } +#else + float newMemoryUsage = (m_startingMemoryAvailable - GetTotalMemoryFreeInAllHeaps()) / TOTAL_INGAME_MEMORY_USAGE; +#endif + // don't allow loading bar to go backwards + // + if( newMemoryUsage > m_currentMemoryUsage ) + { + m_currentMemoryUsage = newMemoryUsage; + + if( m_currentMemoryUsage < 1.0f ) + { + m_loadingBar.SetValue( 1.0f - m_currentMemoryUsage ); + } + else + { +#ifdef LOADING_BAR_EXPLOSION + if( m_explosionLayer != NULL && m_explosion != NULL ) + { + m_explosionLayer->SetVisible( true ); + + m_elapsedExplosionTime += param1; +/* + float explosionScale = EXPLOSION_SCALE_START + m_elapsedExplosionTime / 1000.0f * EXPLOSION_SCALE_RATE; + m_explosion->ResetTransformation(); + m_explosion->ScaleAboutCenter( explosionScale ); +*/ + const unsigned int EXPLOSION_FLICKER_PERIOD = 50; + bool isBlinked = GuiSFX::Blink( m_explosion, + (float)m_elapsedExplosionTime, + (float)EXPLOSION_FLICKER_PERIOD ); + + if( isBlinked ) + { + m_elapsedExplosionTime %= EXPLOSION_FLICKER_PERIOD; + } +/* + tColour currentColour; + GuiSFX::ModulateColour( ¤tColour, + (float)m_elapsedExplosionTime, + 100.0f, + tColour( 255, 255, 0 ), + tColour( 255, 0, 0 ) ); + + for( int i = 0; i < m_explosion->GetNumOfVertexes(); i++ ) + { + m_explosion->SetVertexColour( i, currentColour ); + } +*/ + } +#else + #ifndef RAD_DEBUG + rReleaseWarningMsg( false, "Current memory usage for loading bar exceeds 100%!" ); + #endif +#endif // LOADING_BAR_EXPLOSION + } + } + + // flicker loading bar flame + // + const unsigned int LOADING_BAR_FIRE_TIME = 50; // in msec + m_elapsedFireTime += param1; + if( m_elapsedFireTime > LOADING_BAR_FIRE_TIME ) + { + rAssert( m_loadingBar.m_pImage != NULL ); + m_loadingBar.m_pImage->SetIndex( 1 - m_loadingBar.m_pImage->GetIndex() ); + + m_elapsedFireTime %= LOADING_BAR_FIRE_TIME; + } + } + + break; + } + case GUI_MSG_LOAD_RESOURCES: + { + this->LoadResources(); + +#ifdef RAD_XBOX + m_startingMemoryAvailable = Memory::GetTotalMemoryFree(); +#else + m_startingMemoryAvailable = GetTotalMemoryFreeInAllHeaps(); +#endif + rReleasePrintf( "Starting Memory Available = %.2f MB\n", (float)m_startingMemoryAvailable / MB ); + +#ifdef RAD_WIN32 + GetLoadingManager()->ResetRequestsProcessed(); +#endif + break; + } + default: + { + break; + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenLoading::LoadResources() +{ + int currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + +#ifdef ENABLE_DYNA_LOADED_IMAGES + char languageDir[ 16 ]; + languageDir[ 0 ] = '\0'; + +#ifdef PAL + switch( CGuiTextBible::GetCurrentLanguage() ) + { + case Scrooby::XL_FRENCH: + { + strcpy( languageDir, "french\\" ); + + break; + } + case Scrooby::XL_GERMAN: + { + strcpy( languageDir, "german\\" ); + + break; + } + case Scrooby::XL_SPANISH: + { + strcpy( languageDir, "spanish\\" ); + + break; + } + default: + { + rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH ); + + break; + } + } +#endif // PAL + + sprintf( m_loadingImageName, "loading%d.png", currentLevel + 1 ); + + char loadingImageFile[ 256 ]; + sprintf( loadingImageFile, "%s%sloading%d.p3d", + DYNAMIC_RESOURCES_DIR, + languageDir, + currentLevel + 1 ); + + // add request to loading manager to load image file + // + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + loadingImageFile, + GMA_LEVEL_OTHER, + DYNA_LOAD_INVENTORY_SECTION, + DYNA_LOAD_INVENTORY_SECTION, + this ); +#else + // set the current level loading image + // + rAssert( m_loadingImage ); + m_loadingImage->SetIndex( currentLevel ); +#endif + + // reset elapsed spiralling time + // + m_elapsedSpiralTime = 0; +} + +void +CGuiScreenLoading::OnProcessRequestsComplete( void* pUserData ) +{ +#ifdef ENABLE_DYNA_LOADED_IMAGES + // push and select inventory section for searching + // + p3d::inventory->PushSection(); + p3d::inventory->SelectSection( DYNA_LOAD_INVENTORY_SECTION ); + bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly(); + p3d::inventory->SetCurrentSectionOnly( true ); + + // search for the loading image sprite + // + rAssert( m_loadingImageSprite == NULL ); + m_loadingImageSprite = p3d::find<tSprite>( m_loadingImageName ); + rAssert( m_loadingImageSprite ); + m_loadingImageSprite->AddRef(); + + // pop inventory section and restore states + // + p3d::inventory->SetCurrentSectionOnly( currentSectionOnly ); + p3d::inventory->PopSection(); + + // set the raw sprite to the Scrooby loading image + // + rAssert( m_loadingImage ); + m_loadingImage->SetRawSprite( m_loadingImageSprite, true ); + m_loadingImage->SetVisible( true ); + m_loadingImage->ScaleAboutCenter( 0.0f ); + + m_isSpirallingDone = false; +#endif +} + + +//=========================================================================== +// CGuiScreenLoading::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoading::InitIntro() +{ + RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot ); + if( levelLayer != NULL ) + { + levelLayer->Freeze(); + } + + // reset loading overlay scale + // + for( int i = 0; i < NUM_LOADING_OVERLAYS; i++ ) + { + rAssert( m_loadingOverlays[ i ] ); + m_loadingOverlays[ i ]->ResetTransformation(); + m_loadingOverlays[ i ]->ScaleAboutCenter( LOADING_BGD1_CORRECTION_SCALE ); + } + + m_loadingBar.SetValue( 1.0f ); + + // reset current memory usage + // + m_currentMemoryUsage = 0.0f; + + // hide loading bar by default + // + rAssert( m_loadingBarGroup != NULL ); + m_loadingBarGroup->SetVisible( false ); + + // hide explosion overlay + // + if( m_explosionLayer != NULL && m_explosion != NULL ) + { + m_explosionLayer->SetVisible( false ); + m_explosion->SetVisible( true ); + + m_elapsedExplosionTime = 0; + } + + // + // Sound ducking, but only for intra-mission stuff. If we're coming + // from the FE, we want to play the newspaper spin music. + // + if( GetGameFlow()->GetCurrentContext() != CONTEXT_FRONTEND ) + { + GetSoundManager()->OnPauseStart(); + } +} + + +//=========================================================================== +// CGuiScreenLoading::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoading::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenLoading::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoading::InitOutro() +{ + RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot ); + if( levelLayer != NULL && levelLayer->IsFrozen() ) + { + levelLayer->Thaw(); + } + +#ifdef ENABLE_DYNA_LOADED_IMAGES + p3d::pddi->DrawSync(); + + if( m_loadingImageSprite != NULL ) + { + rAssert( m_loadingImage ); + m_loadingImage->SetRawSprite( NULL, true ); + m_loadingImage->SetVisible( false ); + + // remove and release the loading image sprite + // + p3d::inventory->RemoveSectionElements( DYNA_LOAD_INVENTORY_SECTION ); + m_loadingImageSprite->ReleaseVerified(); + m_loadingImageSprite = NULL; + } +#endif + + rReleasePrintf( "Final memory usage value for loading bar = %.3f\n", m_currentMemoryUsage ); + m_loadingBar.SetValue( 0.0f ); + + m_isSpirallingDone = true; + + // reset elapsed time for any loading animations + // + m_elapsedTime = 0; + m_elapsedFireTime = 0; + + GetSoundManager()->ResetDucking(); + AnimatedCam::CheckPendingCameraSwitch(); + GetSuperCamManager()->GetSCC( 0 )->NoTransition(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/backend/guiscreenloading.h b/game/code/presentation/gui/backend/guiscreenloading.h new file mode 100644 index 0000000..1961864 --- /dev/null +++ b/game/code/presentation/gui/backend/guiscreenloading.h @@ -0,0 +1,84 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLoading +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLOADING_H +#define GUISCREENLOADING_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/utility/slider.h> + +#include <loading/loadingmanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class tSprite; +namespace Scrooby +{ + class Group; +} + +const int NUM_LOADING_OVERLAYS = 2; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLoading : public CGuiScreen, + public LoadingManager::ProcessRequestsCallback +{ +public: + CGuiScreenLoading( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenLoading(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void LoadResources(); + virtual void OnProcessRequestsComplete( void* pUserData ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + unsigned int m_elapsedTime; + unsigned int m_elapsedSpiralTime; + + Scrooby::Group* m_loadingBarGroup; + Slider m_loadingBar; + float m_currentMemoryUsage; // in percent + int m_startingMemoryAvailable; // in bytes + unsigned int m_elapsedFireTime; + + Scrooby::Sprite* m_loadingImage; + Scrooby::Sprite* m_loadingOverlays[ NUM_LOADING_OVERLAYS ]; + bool m_isSpirallingDone : 1; + + tSprite* m_loadingImageSprite; + char m_loadingImageName[ 32 ]; + + Scrooby::Layer* m_explosionLayer; + Scrooby::Polygon* m_explosion; + unsigned int m_elapsedExplosionTime; + +}; + +#endif // GUISCREENLOADING_H diff --git a/game/code/presentation/gui/backend/guiscreenloadingfe.cpp b/game/code/presentation/gui/backend/guiscreenloadingfe.cpp new file mode 100644 index 0000000..7435003 --- /dev/null +++ b/game/code/presentation/gui/backend/guiscreenloadingfe.cpp @@ -0,0 +1,566 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLoadingFE +// +// Description: Implementation of the CGuiScreenLoadingFE class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/backend/guiscreenloadingfe.h> +#include <presentation/gui/backend/guiloadingbar.h> +#include <presentation/gui/utility/specialfx.h> + +#include <gameflow/gameflow.h> +#include <memory/createheap.h> +#include <memory/memoryutilities.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> +#include <sound/soundmanager.h> + +#include <p3d/drawable.hpp> +#include <p3d/camera.hpp> +#include <p3d/anim/multicontroller.hpp> + +#include <raddebug.hpp> // Foundation +#include <screen.h> +#include <layer.h> +#include <page.h> +#include <group.h> +#include <text.h> +#include <sprite.h> +#include <polygon.h> +#include <pure3dobject.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#define ENABLE_DYNA_LOADED_RESOURCES +//#define LOADING_BAR_FE_EXPLOSION + +#ifdef ENABLE_DYNA_LOADED_RESOURCES + const char* LOADING_FE_PURE3D_FILE = "art\\frontend\\scrooby\\resource\\pure3d\\loading.p3d"; + const char* LOADING_FE_INVENTORY = "LoadingFEScreen"; + + const char* LOADING_FE_DRAWABLE = "loading_screen"; + const char* LOADING_FE_CAMERA = "loading_screen_cameraShape"; + const char* LOADING_FE_MULTICONTROLLER = "loading_screen_MasterController"; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLoadingFE::CGuiScreenLoadingFE +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLoadingFE::CGuiScreenLoadingFE +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LOADING_FE ), + m_loadingText( NULL ), + m_itchyAndScratchy( NULL ), + m_elapsedTime( 0 ), + m_loadingBarGroup( NULL ), + m_currentMemoryUsage( 0.0f ), + m_startingMemoryAvailable( 0 ), + m_elapsedFireTime( 0 ), + m_explosionLayer( NULL ), + m_explosion( NULL ), + m_elapsedExplosionTime( 0 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LoadingFE" ); + rAssert( pPage != NULL ); + + Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" ); + Scrooby::Layer* background = pPage->GetLayer( "Background" ); + + m_loadingText = foreground->GetText( "Loading" ); + rAssert( m_loadingText != NULL ); + + m_itchyAndScratchy = background->GetPure3dObject( "Loading" ); + if( m_itchyAndScratchy != NULL ) + { + m_itchyAndScratchy->SetDrawable( NULL ); + m_itchyAndScratchy->SetCamera( NULL ); + m_itchyAndScratchy->SetMultiController( NULL ); + + m_itchyAndScratchy->SetClearDepthBuffer( true ); + } + + // get loading bar + // + m_loadingBarGroup = pPage->GetGroup( "LoadingBar" ); + rAssert( m_loadingBarGroup != NULL ); + m_loadingBar.m_type = Slider::HORIZONTAL_SLIDER_RIGHT; + m_loadingBar.SetScroobyPolygon( m_loadingBarGroup->GetPolygon( "Wick" ), + m_loadingBarGroup->GetSprite( "Fire" ) ); + + // get explosion overlay (from Explosion.pag) + // + pPage = m_pScroobyScreen->GetPage( "Explosion" ); + if( pPage != NULL ) + { + m_explosionLayer = pPage->GetLayer( "Explosion" ); + rAssert( m_explosionLayer != NULL ); + + m_explosion = m_explosionLayer->GetPolygon( "Explosion0" ); + rAssert( m_explosion != NULL ); + } + +#ifdef ENABLE_DYNA_LOADED_RESOURCES + p3d::inventory->AddSection( LOADING_FE_INVENTORY ); +#endif +} + + +//=========================================================================== +// CGuiScreenLoadingFE::~CGuiScreenLoadingFE +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLoadingFE::~CGuiScreenLoadingFE() +{ +#ifdef ENABLE_DYNA_LOADED_RESOURCES + p3d::inventory->DeleteSection( LOADING_FE_INVENTORY ); +#endif +} + + +//=========================================================================== +// CGuiScreenLoadingFE::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadingFE::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_UPDATE: + { + // update loading text + // + const unsigned int LOADING_TEXT_LOOP_TIME = 500; // in msec + m_elapsedTime += param1; + if( m_elapsedTime > LOADING_TEXT_LOOP_TIME ) + { + rAssert( m_loadingText != NULL ); + int nextIndex = (m_loadingText->GetIndex() + 1) % m_loadingText->GetNumOfStrings(); + m_loadingText->SetIndex( nextIndex ); + + m_elapsedTime %= LOADING_TEXT_LOOP_TIME; + } + + ContextEnum currentContext = GetGameFlow()->GetCurrentContext(); + if( currentContext == CONTEXT_FRONTEND || + currentContext == CONTEXT_LOADING_DEMO || + currentContext == CONTEXT_LOADING_SUPERSPRINT || + currentContext == CONTEXT_LOADING_GAMEPLAY ) + { + // update loading bar + // + rAssert( m_loadingBarGroup != NULL ); + m_loadingBarGroup->SetVisible( true ); + + float newMemoryUsage = this->GetCurrentMemoryUsage( currentContext ); + + // don't allow loading bar to go backwards + // + if( newMemoryUsage > m_currentMemoryUsage ) + { + m_currentMemoryUsage = newMemoryUsage; + + if( m_currentMemoryUsage < 1.0f ) + { + m_loadingBar.SetValue( 1.0f - m_currentMemoryUsage ); + } + else + { +#ifdef LOADING_BAR_FE_EXPLOSION + if( m_explosionLayer != NULL && m_explosion != NULL ) + { + m_explosionLayer->SetVisible( true ); + + m_elapsedExplosionTime += param1; +/* + float explosionScale = EXPLOSION_SCALE_START + m_elapsedExplosionTime / 1000.0f * EXPLOSION_SCALE_RATE; + m_explosion->ResetTransformation(); + m_explosion->ScaleAboutCenter( explosionScale ); +*/ + const unsigned int EXPLOSION_FLICKER_PERIOD = 50; + bool isBlinked = GuiSFX::Blink( m_explosion, + (float)m_elapsedExplosionTime, + (float)EXPLOSION_FLICKER_PERIOD ); + + if( isBlinked ) + { + m_elapsedExplosionTime %= EXPLOSION_FLICKER_PERIOD; + } +/* + tColour currentColour; + GuiSFX::ModulateColour( ¤tColour, + (float)m_elapsedExplosionTime, + 100.0f, + tColour( 255, 255, 0 ), + tColour( 255, 0, 0 ) ); + + for( int i = 0; i < m_explosion->GetNumOfVertexes(); i++ ) + { + m_explosion->SetVertexColour( i, currentColour ); + } +*/ + } +#else + #ifndef RAD_DEBUG + rReleaseWarningMsg( false, "Current memory usage for loading bar exceeds 100%!" ); + #endif +#endif // LOADING_BAR_FE_EXPLOSION + } + } + + // flicker loading bar flame + // + const unsigned int LOADING_BAR_FIRE_TIME = 50; // in msec + m_elapsedFireTime += param1; + if( m_elapsedFireTime > LOADING_BAR_FIRE_TIME ) + { + rAssert( m_loadingBar.m_pImage != NULL ); + m_loadingBar.m_pImage->SetIndex( 1 - m_loadingBar.m_pImage->GetIndex() ); + + m_elapsedFireTime %= LOADING_BAR_FIRE_TIME; + } + } + + break; + } + case GUI_MSG_LOAD_RESOURCES: + { + this->LoadResources(); + +#ifdef RAD_XBOX + m_startingMemoryAvailable = Memory::GetTotalMemoryFree(); +#else + m_startingMemoryAvailable = GetTotalMemoryFreeInAllHeaps(); +#endif + rReleasePrintf( "Starting Memory Available = %.2f MB\n", (float)m_startingMemoryAvailable / MB ); + +#ifdef RAD_WIN32 + GetLoadingManager()->ResetRequestsProcessed(); +#endif + break; + } + default: + { + break; + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenLoadingFE::LoadResources() +{ +#ifdef ENABLE_DYNA_LOADED_RESOURCES + if( m_itchyAndScratchy != NULL ) + { + m_itchyAndScratchy->SetDrawable( NULL ); + } + + GameMemoryAllocator heapAllocator = GMA_DEFAULT; + + ContextEnum nextContext = GetGameFlow()->GetNextContext(); + switch( nextContext ) + { + case CONTEXT_FRONTEND: + { + heapAllocator = GMA_LEVEL_MOVIE; + + break; + } + case CONTEXT_LOADING_GAMEPLAY: + case CONTEXT_LOADING_DEMO: + { + heapAllocator = GMA_LEVEL_OTHER; + + break; + } + case CONTEXT_LOADING_SUPERSPRINT: + case CONTEXT_SUPERSPRINT_FE: + { + heapAllocator = GMA_LEVEL_HUD; + + break; + } + default: + { + break; + } + } + + rAssert( heapAllocator != GMA_DEFAULT ); + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + LOADING_FE_PURE3D_FILE, + heapAllocator, + LOADING_FE_INVENTORY, + LOADING_FE_INVENTORY, + this ); +#endif +} + +void +CGuiScreenLoadingFE::OnProcessRequestsComplete( void* pUserData ) +{ + if( m_itchyAndScratchy != NULL ) + { + // push and select inventory section for searching + // + p3d::inventory->PushSection(); + p3d::inventory->SelectSection( LOADING_FE_INVENTORY ); + bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly(); + p3d::inventory->SetCurrentSectionOnly( true ); + + // search for drawable, camera, and multicontroller, and assign + // them to the itchy & scratchy pure3d object + // + tDrawable* drawable = p3d::find<tDrawable>( LOADING_FE_DRAWABLE ); + m_itchyAndScratchy->SetDrawable( drawable ); + + tCamera* camera = p3d::find<tCamera>( LOADING_FE_CAMERA ); + m_itchyAndScratchy->SetCamera( camera ); + + tMultiController* multiController = p3d::find<tMultiController>( LOADING_FE_MULTICONTROLLER ); + m_itchyAndScratchy->SetMultiController( multiController ); + + // pop inventory section and restore states + // + p3d::inventory->SetCurrentSectionOnly( currentSectionOnly ); + p3d::inventory->PopSection(); + } +} + + +//=========================================================================== +// CGuiScreenLoadingFE::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadingFE::InitIntro() +{ + RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot ); + if( levelLayer != NULL ) + { + levelLayer->Freeze(); + } + + m_loadingBar.SetValue( 1.0f ); + + // reset current memory usage + // + m_currentMemoryUsage = 0.0f; + + // hide loading bar by default + // + rAssert( m_loadingBarGroup != NULL ); + m_loadingBarGroup->SetVisible( false ); + + // hide explosion overlay + // + if( m_explosionLayer != NULL && m_explosion != NULL ) + { + m_explosionLayer->SetVisible( false ); + m_explosion->SetVisible( true ); + + m_elapsedExplosionTime = 0; + } +} + +//=========================================================================== +// CGuiScreenLoadingFE::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadingFE::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenLoadingFE::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadingFE::InitOutro() +{ + RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot ); + if( levelLayer != NULL && levelLayer->IsFrozen() ) + { + levelLayer->Thaw(); + } + +#ifdef ENABLE_DYNA_LOADED_RESOURCES + p3d::pddi->DrawSync(); + + if( m_itchyAndScratchy != NULL ) + { + m_itchyAndScratchy->SetDrawable( NULL ); + m_itchyAndScratchy->SetCamera( NULL ); + m_itchyAndScratchy->SetMultiController( NULL ); + } + + p3d::inventory->RemoveSectionElements( LOADING_FE_INVENTORY ); +#endif + + rReleasePrintf( "Final memory usage value for loading bar = %.3f\n", m_currentMemoryUsage ); + m_loadingBar.SetValue( 0.0f ); + + // reset loading text animation + // + m_elapsedTime = 0; + rAssert( m_loadingText != NULL ); + m_loadingText->SetIndex( 0 ); + + m_elapsedFireTime = 0; + + GetSoundManager()->ResetDucking(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +float +CGuiScreenLoadingFE::GetCurrentMemoryUsage( ContextEnum currentContext ) const +{ + float currentMemoryUsage = 0.0f; + +#ifdef RAD_XBOX + int totalMemoryFree = Memory::GetTotalMemoryFree(); +#else + int totalMemoryFree = GetTotalMemoryFreeInAllHeaps(); +#endif + + if( totalMemoryFree > 0 ) + { + switch( currentContext ) + { + case CONTEXT_LOADING_GAMEPLAY: + { + currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_INGAME_MEMORY_USAGE; + + break; + } + case CONTEXT_LOADING_DEMO: + { + currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_DEMO_MEMORY_USAGE; + + break; + } + case CONTEXT_LOADING_SUPERSPRINT: + { +#ifndef RAD_WIN32 + currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_SUPERSPRINT_MEMORY_USAGE; +#else + // this sucks but i just want to finish it. + float memUsage = float( GetLoadingManager()->GetNumRequestsProcessed() ) / TOTAL_SUPERSPRINT_FILES; + currentMemoryUsage = m_currentMemoryUsage; + if( memUsage - currentMemoryUsage < LOAD_MIN_SPEED ) + { + currentMemoryUsage = memUsage; + } + else + { + float delta = (memUsage - currentMemoryUsage) / LOAD_BLEND_FACTOR; + currentMemoryUsage += delta > LOAD_MIN_SPEED ? delta : LOAD_MIN_SPEED; + } +#endif + break; + } + case CONTEXT_FRONTEND: + { + currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_FE_MEMORY_USAGE; + + break; + } + default: + { + rWarningMsg( false, "Invalid context!" ); + + break; + } + } + } + else + { + rWarningMsg( false, "Why is total memory free negative??" ); + } + + return currentMemoryUsage; +} + diff --git a/game/code/presentation/gui/backend/guiscreenloadingfe.h b/game/code/presentation/gui/backend/guiscreenloadingfe.h new file mode 100644 index 0000000..3800810 --- /dev/null +++ b/game/code/presentation/gui/backend/guiscreenloadingfe.h @@ -0,0 +1,79 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLoadingFE +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLOADINGFE_H +#define GUISCREENLOADINGFE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/utility/slider.h> + +#include <contexts/contextenum.h> +#include <loading/loadingmanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLoadingFE : public CGuiScreen, + public LoadingManager::ProcessRequestsCallback +{ +public: + CGuiScreenLoadingFE( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenLoadingFE(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void LoadResources(); + virtual void OnProcessRequestsComplete( void* pUserData ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + float GetCurrentMemoryUsage( ContextEnum currentContext ) const; + + Scrooby::Text* m_loadingText; + Scrooby::Pure3dObject* m_itchyAndScratchy; + + unsigned int m_elapsedTime; + + Scrooby::Group* m_loadingBarGroup; + Slider m_loadingBar; + float m_currentMemoryUsage; // in percent + int m_startingMemoryAvailable; // in bytes + unsigned int m_elapsedFireTime; + + Scrooby::Layer* m_explosionLayer; + Scrooby::Polygon* m_explosion; + unsigned int m_elapsedExplosionTime; + +}; + +#endif // GUISCREENLOADINGFE_H diff --git a/game/code/presentation/gui/bootup/allbootup.cpp b/game/code/presentation/gui/bootup/allbootup.cpp new file mode 100644 index 0000000..4fffd7c --- /dev/null +++ b/game/code/presentation/gui/bootup/allbootup.cpp @@ -0,0 +1,5 @@ +#include <presentation/gui/bootup/guimanagerbootup.cpp> +#include <presentation/gui/bootup/guimanagerlanguage.cpp> +#include <presentation/gui/bootup/guiscreenbootupload.cpp> +#include <presentation/gui/bootup/guiscreenlicense.cpp> +#include <presentation/gui/bootup/guiscreenlanguage.cpp> diff --git a/game/code/presentation/gui/bootup/guimanagerbootup.cpp b/game/code/presentation/gui/bootup/guimanagerbootup.cpp new file mode 100644 index 0000000..b42d853 --- /dev/null +++ b/game/code/presentation/gui/bootup/guimanagerbootup.cpp @@ -0,0 +1,403 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerBootUp +// +// Description: Implementation of the CGuiManagerBootUp class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/15 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/bootup/guimanagerbootup.h> +#include <presentation/gui/bootup/guiscreenbootupload.h> +#include <presentation/gui/bootup/guiscreenlicense.h> +#include <presentation/gui/bootup/guiscreenlanguage.h> +#include <presentation/gui/frontend/guiscreenloadgame.h> +#include <presentation/gui/guiscreenmemcardcheck.h> +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiwindow.h> // for window IDs + +#include <contexts/bootupcontext.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> + +#ifdef RAD_PS2 + #include <main/ps2platform.h> +#endif + +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#ifdef RAD_PS2 + #ifndef PAL + #define ENABLE_PROGRESSIVE_SCAN_PROMPT + #endif +#endif + +#ifdef RAD_PS2 + #define ENABLE_MEMCARD_CHECK_DURING_BOOTUP +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManagerBootUp::CGuiManagerBootUp +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerBootUp::CGuiManagerBootUp +( + Scrooby::Project* pProject, + CGuiEntity* pParent +) +: CGuiManager( pProject, pParent ) +{ + if( CommandLineOptions::Get( CLO_SKIP_MEMCHECK ) ) + { + s_memcardCheckState = MEM_CARD_CHECK_COMPLETED; + } + +#ifdef RAD_DEMO + // no memory card checking for demos + // + s_memcardCheckState = MEM_CARD_CHECK_COMPLETED; +#endif +} + + +//=========================================================================== +// CGuiManagerBootUp::~CGuiManagerBootUp +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerBootUp::~CGuiManagerBootUp() +{ + for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ ) + { + if( m_windows[ i ] != NULL ) + { + delete m_windows[ i ]; + m_windows[ i ] = NULL; + } + } +} + + +//=========================================================================== +// CGuiManagerBootUp::Populate +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerBootUp::Populate() +{ +MEMTRACK_PUSH_GROUP( "CGuiManagerBootUp" ); + Scrooby::Screen* pScroobyScreen; + CGuiScreen* pScreen; + +#ifdef RAD_PS2 + pScroobyScreen = m_pScroobyProject->GetScreen( "BootupLoad" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenBootupLoad( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_BOOTUP_LOAD, pScreen ); + } +#endif + + pScroobyScreen = m_pScroobyProject->GetScreen( "License" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLicense( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LICENSE, pScreen ); + } +/* + pScroobyScreen = m_pScroobyProject->GetScreen( "Language" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLanguage( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LANGUAGE, pScreen ); + } +*/ + pScroobyScreen = m_pScroobyProject->GetScreen( "MemCardCheck" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMemCardCheck( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenAutoLoad( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_AUTO_LOAD, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Message" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMessage( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPrompt( pScroobyScreen, this, + CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ); + + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ErrorPrompt" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPrompt( pScroobyScreen, this, + CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT ); + + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT, pScreen ); + } +MEMTRACK_POP_GROUP("CGuiManagerBootUp"); +} + +void +CGuiManagerBootUp::Start( CGuiWindow::eGuiWindowID initialWindow ) +{ + rAssert( m_state == GUI_FE_UNINITIALIZED ); + + if( initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + m_bootupScreenQueue.push( initialWindow ); + } + +#ifdef ENABLE_PROGRESSIVE_SCAN_PROMPT + // add progressive scan screen to bootup screen queue + // + if( GetInputManager()->IsProScanButtonsPressed() ) + { + m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ); + } +#endif + +#ifdef ENABLE_MEMCARD_CHECK_DURING_BOOTUP + // add memcard checking screen to bootup screen queue + // + if( s_memcardCheckState == MEM_CARD_CHECK_NOT_DONE ) + { + m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK ); + } +#endif + +#ifdef RAD_PS2 + // for PS2 only, start off w/ a loading screen + // + m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_BOOTUP_LOAD ); +#endif + + // add license screen to bootup screen queue + // + m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_LICENSE ); + + + // alright, letz bring up the first screen of the game!! + // + m_nextScreen = this->PopNextScreenInQueue(); + if( m_nextScreen == CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) + { + // special case for progressive scan prompt + // + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_YES, + CGuiMenuPrompt::RESPONSE_NO + }; + + CGuiScreenPrompt::Display( PROMPT_DISPLAY_PROGRESSIVE_SCAN, this, 2, responses ); + CGuiScreenPrompt::EnableDefaultToNo( false ); + } + + m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen() + + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); +} + +//=========================================================================== +// CGuiManagerBootUp::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerBootUp::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_QUIT_BOOTUP: + { + rAssert( GUI_FE_SCREEN_RUNNING == m_state ); + + rAssertMsg( m_bootupScreenQueue.empty(), + "Why are we quitting when there's still screens in the bootup queue??" ); + + m_state = GUI_FE_SHUTTING_DOWN; + +#ifdef RAD_WIN32 + GetBootupContext()->LoadConfig(); +#endif + + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + + break; + } + case GUI_MSG_WINDOW_FINISHED: + { + if( GUI_FE_CHANGING_SCREENS == m_state ) + { + m_currentScreen = m_nextScreen; + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + } + else if( GUI_FE_SHUTTING_DOWN == m_state ) + { + m_state = GUI_FE_TERMINATED; + + // start intro movies + // + GetBootupContext()->StartMovies(); + } + + break; + } + case GUI_MSG_MENU_PROMPT_RESPONSE: + { + rAssert( param1 == PROMPT_DISPLAY_PROGRESSIVE_SCAN ); + + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { + // enable progressive scan + // +#ifdef RAD_PS2 + PS2Platform::GetInstance()->SetProgressiveMode( true ); +#endif + } + + // follow-thru + // + } + case GUI_MSG_BOOTUP_LOAD_COMPLETED: + case GUI_MSG_LANGUAGE_SELECTION_DONE: + case GUI_MSG_MEMCARD_CHECK_COMPLETED: + { + CGuiWindow::eGuiWindowID nextScreen = this->PopNextScreenInQueue(); + + if( nextScreen == CGuiWindow::GUI_SCREEN_ID_BOOTUP_LOAD && + GetGuiSystem()->GetCurrentState() == CGuiSystem::BOOTUP_ACTIVE ) + { + // FE is already loaded, no need to display extra loading screen + // + nextScreen = this->PopNextScreenInQueue(); // pop off next screen in queue + } + + if( nextScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + nextScreen, + CLEAR_WINDOW_HISTORY ); + } + else + { + this->HandleMessage( GUI_MSG_QUIT_BOOTUP ); + } + + break; + } + default: + { + if( m_state != GUI_FE_UNINITIALIZED && + m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + // Send the messages down to the current screen. + // + CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen ); + rAssert( pScreen ); + + pScreen->HandleMessage( message, param1, param2 ); + } + } + } + + // propogate message up the hierarchy + CGuiManager::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +CGuiWindow::eGuiWindowID +CGuiManagerBootUp::PopNextScreenInQueue() +{ + CGuiWindow::eGuiWindowID nextScreen = CGuiWindow::GUI_WINDOW_ID_UNDEFINED; + + if( !m_bootupScreenQueue.empty() ) + { + nextScreen = m_bootupScreenQueue.front(); + m_bootupScreenQueue.pop(); + + if( nextScreen == CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK ) + { + s_memcardCheckState = MEM_CARD_CHECK_IN_PROGRESS; + } + } + + return nextScreen; +} + diff --git a/game/code/presentation/gui/bootup/guimanagerbootup.h b/game/code/presentation/gui/bootup/guimanagerbootup.h new file mode 100644 index 0000000..a307206 --- /dev/null +++ b/game/code/presentation/gui/bootup/guimanagerbootup.h @@ -0,0 +1,66 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerBootUp +// +// Description: Interface for the CGuiManagerBootUp class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/15 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUIMANAGERBOOTUP_H +#define GUIMANAGERBOOTUP_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guimanager.h> +#include <memory\srrmemory.h> // Needed for my STL allocations to go on the right heap + +#include <queue> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiManagerBootUp : public CGuiManager +{ +public: + CGuiManagerBootUp( Scrooby::Project* pProject, CGuiEntity* pParent ); + virtual ~CGuiManagerBootUp(); + + virtual void Populate(); + virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignment. Declare but don't define. + // + CGuiManagerBootUp( const CGuiManagerBootUp& ); + CGuiManagerBootUp& operator= ( const CGuiManagerBootUp& ); + + CGuiWindow::eGuiWindowID PopNextScreenInQueue(); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + typedef std::deque< CGuiWindow::eGuiWindowID, s2alloc<CGuiWindow::eGuiWindowID> > WindowIDVector; + std::queue<CGuiWindow::eGuiWindowID, WindowIDVector> m_bootupScreenQueue; + +}; + +#endif // GUIMANAGERBOOTUP_H diff --git a/game/code/presentation/gui/bootup/guimanagerlanguage.cpp b/game/code/presentation/gui/bootup/guimanagerlanguage.cpp new file mode 100644 index 0000000..b70cb16 --- /dev/null +++ b/game/code/presentation/gui/bootup/guimanagerlanguage.cpp @@ -0,0 +1,287 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerLanguage +// +// Description: Implementation of the CGuiManagerLanguage class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/07/08 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/bootup/guimanagerlanguage.h> +#include <presentation/gui/bootup/guiscreenlanguage.h> +#include <presentation/gui/guiwindow.h> // for window IDs +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/language.h> + +#include <memory/srrmemory.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> + +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManagerLanguage::CGuiManagerLanguage +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerLanguage::CGuiManagerLanguage +( + Scrooby::Project* pProject, + CGuiEntity* pParent +) +: CGuiManager( pProject, pParent ) +{ +} + + +//=========================================================================== +// CGuiManagerLanguage::~CGuiManagerLanguage +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerLanguage::~CGuiManagerLanguage() +{ + for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ ) + { + if( m_windows[ i ] != NULL ) + { + delete m_windows[ i ]; + m_windows[ i ] = NULL; + } + } +} + + +//=========================================================================== +// CGuiManagerLanguage::Populate +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerLanguage::Populate() +{ +MEMTRACK_PUSH_GROUP( "CGuiManagerLanguage" ); + Scrooby::Screen* pScroobyScreen; + CGuiScreen* pScreen; + + pScroobyScreen = m_pScroobyProject->GetScreen( "Language" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLanguage( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LANGUAGE, pScreen ); + } +MEMTRACK_POP_GROUP("CGuiManagerLanguage"); +} + +void +CGuiManagerLanguage::Start( CGuiWindow::eGuiWindowID initialWindow ) +{ + rAssert( m_state == GUI_FE_UNINITIALIZED ); + + rAssertMsg( initialWindow == CGuiWindow::GUI_WINDOW_ID_UNDEFINED, + "Can't specify another initial window! Not supported by this manager." ); + + bool isLanguageSupported = this->CheckLanguage(); + + if( !isLanguageSupported || CommandLineOptions::Get( CLO_LANG_PROMPT ) ) + { + m_nextScreen = CGuiWindow::GUI_SCREEN_ID_LANGUAGE; + + m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen() + + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + + // thaw frontend render layer + // + GetRenderManager()->mpLayer(RenderEnums::GUI)->Thaw(); + } + else + { + m_state = GUI_FE_TERMINATED; + + GetGuiSystem()->HandleMessage( GUI_MSG_INIT_BOOTUP ); + } +} + +//=========================================================================== +// CGuiManagerLanguage::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerLanguage::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_LANGUAGE_SELECTION_DONE: + { + rAssert( GUI_FE_SCREEN_RUNNING == m_state ); + + m_state = GUI_FE_SHUTTING_DOWN; + + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + + break; + } + case GUI_MSG_WINDOW_FINISHED: + { + if( GUI_FE_CHANGING_SCREENS == m_state ) + { + m_currentScreen = m_nextScreen; + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + } + else if( GUI_FE_SHUTTING_DOWN == m_state ) + { + m_state = GUI_FE_TERMINATED; + + GetGuiSystem()->HandleMessage( GUI_MSG_INIT_BOOTUP ); + } + + break; + } + default: + { + if( m_state != GUI_FE_UNINITIALIZED && + m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + // Send the messages down to the current screen. + // + CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen ); + rAssert( pScreen ); + + pScreen->HandleMessage( message, param1, param2 ); + } + } + } + + // propogate message up the hierarchy + CGuiManager::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +bool +CGuiManagerLanguage::CheckLanguage() +{ + bool isLanguageSupported = true; + + switch( Language::GetHardwareLanguage() ) + { + case Language::ENGLISH: + { + CGuiTextBible::SetCurrentLanguage( Scrooby::XL_ENGLISH ); + + rReleasePrintf( "Localization language automatically set to: ENGLISH\n" ); + + break; + } + case Language::FRENCH: + { + CGuiTextBible::SetCurrentLanguage( Scrooby::XL_FRENCH ); + + rReleasePrintf( "Localization language automatically set to: FRENCH\n" ); + + break; + } + case Language::GERMAN: + { + CGuiTextBible::SetCurrentLanguage( Scrooby::XL_GERMAN ); + + rReleasePrintf( "Localization language automatically set to: GERMAN\n" ); + + break; + } +/* + case Language::ITALIAN: + { + CGuiTextBible::SetCurrentLanguage( Scrooby::XL_ITALIAN ); + + rReleasePrintf( "Localization language automatically set to: ITALIAN\n" ); + + break; + } +*/ +#ifndef RAD_GAMECUBE + case Language::SPANISH: + { + CGuiTextBible::SetCurrentLanguage( Scrooby::XL_SPANISH ); + + rReleasePrintf( "Localization language automatically set to: SPANISH\n" ); + + break; + } +#endif // !RAD_GAMECUBE + default: + { +#ifdef RAD_XBOX + // default to English, if unsupported language detected + // + CGuiTextBible::SetCurrentLanguage( Scrooby::XL_ENGLISH ); +#else + isLanguageSupported = false; +#endif + rReleasePrintf( "Unsupported hardware language detected.\n" ); + + break; + } + } + + return isLanguageSupported; +} + diff --git a/game/code/presentation/gui/bootup/guimanagerlanguage.h b/game/code/presentation/gui/bootup/guimanagerlanguage.h new file mode 100644 index 0000000..d34b227 --- /dev/null +++ b/game/code/presentation/gui/bootup/guimanagerlanguage.h @@ -0,0 +1,60 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerLanguage +// +// Description: Interface for the CGuiManagerLanguage class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/07/08 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUIMANAGERLANGUAGE_H +#define GUIMANAGERLANGUAGE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guimanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiManagerLanguage : public CGuiManager +{ +public: + CGuiManagerLanguage( Scrooby::Project* pProject, CGuiEntity* pParent ); + virtual ~CGuiManagerLanguage(); + + virtual void Populate(); + virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +private: + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignment. Declare but don't define. + // + CGuiManagerLanguage( const CGuiManagerLanguage& ); + CGuiManagerLanguage& operator= ( const CGuiManagerLanguage& ); + + bool CheckLanguage(); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + +}; + +#endif // GUIMANAGERLANGUAGE_H diff --git a/game/code/presentation/gui/bootup/guiscreenbootupload.cpp b/game/code/presentation/gui/bootup/guiscreenbootupload.cpp new file mode 100644 index 0000000..2c4223c --- /dev/null +++ b/game/code/presentation/gui/bootup/guiscreenbootupload.cpp @@ -0,0 +1,200 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenBootupLoad +// +// Description: Implementation of the CGuiScreenBootupLoad class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/bootup/guiscreenbootupload.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guisystem.h> + +#include <raddebug.hpp> // Foundation + +#include <screen.h> +#include <page.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenBootupLoad::CGuiScreenBootupLoad +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenBootupLoad::CGuiScreenBootupLoad +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_BOOTUP_LOAD ), + m_loadingText( NULL ), + m_elapsedIdleTime( 0 ) +{ + // get loading text + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LoadingText" ); + if( pPage != NULL ) + { + m_loadingText = pPage->GetText( "Loading" ); + rAssert( m_loadingText != NULL ); + m_loadingText->SetVisible( false ); // hide by default + } +} + + +//=========================================================================== +// CGuiScreenBootupLoad::~CGuiScreenBootupLoad +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenBootupLoad::~CGuiScreenBootupLoad() +{ +} + + +//=========================================================================== +// CGuiScreenBootupLoad::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenBootupLoad::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( message == GUI_MSG_UPDATE ) + { + m_elapsedIdleTime += param1; + + if( m_loadingText != NULL ) + { + // blink loading text if idling here on this screen to satisfy + // TRC/TCR requirements + // + const unsigned int BLINKING_PERIOD = 250; + bool isBlinked = GuiSFX::Blink( m_loadingText, + static_cast<float>( m_elapsedIdleTime ), + static_cast<float>( BLINKING_PERIOD ) ); + if( isBlinked ) + { + m_elapsedIdleTime %= BLINKING_PERIOD; + } + } + + if( GetGuiSystem()->GetCurrentState() == CGuiSystem::BOOTUP_ACTIVE ) + { + m_pParent->HandleMessage( GUI_MSG_BOOTUP_LOAD_COMPLETED ); + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenBootupLoad::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenBootupLoad::InitIntro() +{ +} + + +//=========================================================================== +// CGuiScreenBootupLoad::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenBootupLoad::InitRunning() +{ + m_elapsedIdleTime = 0; +} + + +//=========================================================================== +// CGuiScreenBootupLoad::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenBootupLoad::InitOutro() +{ + if( m_loadingText != NULL ) + { + // hide loading text + // + m_loadingText->SetVisible( false ); + } +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/bootup/guiscreenbootupload.h b/game/code/presentation/gui/bootup/guiscreenbootupload.h new file mode 100644 index 0000000..72c8b4f --- /dev/null +++ b/game/code/presentation/gui/bootup/guiscreenbootupload.h @@ -0,0 +1,52 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenBootupLoad +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENBOOTUPLOAD_H +#define GUISCREENBOOTUPLOAD_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenBootupLoad : public CGuiScreen +{ +public: + CGuiScreenBootupLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenBootupLoad(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + Scrooby::Text* m_loadingText; + unsigned int m_elapsedIdleTime; + +}; + +#endif // GUISCREENBOOTUPLOAD_H diff --git a/game/code/presentation/gui/bootup/guiscreenlanguage.cpp b/game/code/presentation/gui/bootup/guiscreenlanguage.cpp new file mode 100644 index 0000000..9c18074 --- /dev/null +++ b/game/code/presentation/gui/bootup/guiscreenlanguage.cpp @@ -0,0 +1,224 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLanguage +// +// Description: Implementation of the CGuiScreenLanguage class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/bootup/guiscreenlanguage.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guiscreenmessage.h> + +#include <raddebug.hpp> // Foundation + +#include <app.h> +#include <group.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLanguage::CGuiScreenLanguage +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLanguage::CGuiScreenLanguage +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LANGUAGE ), + m_pMenu( NULL ) +{ + // retrieve Scrooby drawing elements + // + rAssert( m_pScroobyScreen != NULL ); + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Language" ); + rAssert( pPage != NULL ); + + m_pMenu = new CGuiMenu( this, NUM_SRR2_LANGUAGES ); + rAssert( m_pMenu != NULL ); + + Scrooby::Group* menu = pPage->GetGroup( "Menu" ); + rAssert( menu != NULL ); + + for( int i = 0; i < NUM_SRR2_LANGUAGES; i++ ) + { + char name[ 32 ]; + sprintf( name, "Language%d", i ); + m_pMenu->AddMenuItem( menu->GetText( name ) ); + } + +#ifdef RAD_GAMECUBE + m_pMenu->SetMenuItemEnabled( 3, false, true ); // no Spanish on GC PAL +#endif // RAD_GAMECUBE + + Scrooby::Page* messageBoxPage = m_pScroobyScreen->GetPage( "MessageBox" ); + if( messageBoxPage != NULL ) + { + this->AutoScaleFrame( messageBoxPage ); + + Scrooby::Sprite* messageIcon = messageBoxPage->GetSprite( "ErrorIcon" ); + if( messageIcon != NULL ) + { + messageIcon->ResetTransformation(); + messageIcon->ScaleAboutCenter( MESSAGE_ICON_CORRECTION_SCALE ); + } + } +} + + +//=========================================================================== +// CGuiScreenLanguage::~CGuiScreenLanguage +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLanguage::~CGuiScreenLanguage() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenLanguage::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLanguage::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( static_cast<int>( param1 ) < NUM_SRR2_LANGUAGES ); + CGuiTextBible::SetCurrentLanguage( SRR2_LANGUAGE[ param1 ] ); + + m_pParent->HandleMessage( GUI_MSG_LANGUAGE_SELECTION_DONE ); + + break; + } + default: + { + break; + } + } + + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenLanguage::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLanguage::InitIntro() +{ +} + + +//=========================================================================== +// CGuiScreenLanguage::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLanguage::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenLanguage::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLanguage::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/bootup/guiscreenlanguage.h b/game/code/presentation/gui/bootup/guiscreenlanguage.h new file mode 100644 index 0000000..c12d928 --- /dev/null +++ b/game/code/presentation/gui/bootup/guiscreenlanguage.h @@ -0,0 +1,55 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLanguage +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLANGUAGE_H +#define GUISCREENLANGUAGE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLanguage : public CGuiScreen +{ +public: + CGuiScreenLanguage( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenLanguage(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + CGuiMenu* m_pMenu; + +}; + +#endif // GUISCREENLANGUAGE_H diff --git a/game/code/presentation/gui/bootup/guiscreenlicense.cpp b/game/code/presentation/gui/bootup/guiscreenlicense.cpp new file mode 100644 index 0000000..e6262e4 --- /dev/null +++ b/game/code/presentation/gui/bootup/guiscreenlicense.cpp @@ -0,0 +1,202 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLicense +// +// Description: Implementation of the CGuiScreenLicense class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/bootup/guiscreenlicense.h> + +#include <contexts/bootupcontext.h> + +#include <screen.h> +#include <page.h> +#include <group.h> + +#include <p3d/utility.hpp> +#include <p3d/sprite.hpp> +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float LICENSE_SCREEN_FADE_TIME = 500.0f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLicense::CGuiScreenLicense +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLicense::CGuiScreenLicense +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LICENSE ) +{ + // retrieve Scrooby drawing elements + // + rAssert( m_pScroobyScreen != NULL ); + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "License" ); + rAssert( pPage != NULL ); + + // set platform-specific license screen image + // +#ifdef RAD_GAMECUBE + tSprite* pSprite = p3d::find<tSprite>( "licenseG.png" ); +#endif +#ifdef RAD_PS2 + tSprite* pSprite = p3d::find<tSprite>( "licenseP.png" ); +#endif +#ifdef RAD_XBOX + tSprite* pSprite = p3d::find<tSprite>( "licenseX.png" ); +#endif +#ifdef RAD_WIN32 + tSprite* pSprite = p3d::find<tSprite>( "licensePC.png" ); +#endif + rAssert( pSprite != NULL ); + + Scrooby::Sprite* licenseImage = pPage->GetSprite( "License" ); + rAssert( licenseImage != NULL ); + licenseImage->SetRawSprite( pSprite ); + + // set fade time for license screen (in milliseconds) + // + this->SetFadeTime( LICENSE_SCREEN_FADE_TIME ); + +#ifdef RAD_GAMECUBE + // skip screen fade in (on Gamecube only) + // + this->SetFadeTime( 0.0f ); +#endif +} + + +//=========================================================================== +// CGuiScreenLicense::~CGuiScreenLicense +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLicense::~CGuiScreenLicense() +{ +} + + +//=========================================================================== +// CGuiScreenLicense::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLicense::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenLicense::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLicense::InitIntro() +{ + // start loading sound files + // + GetBootupContext()->StartLoadingSound(); +} + + +//=========================================================================== +// CGuiScreenLicense::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLicense::InitRunning() +{ +#ifdef RAD_GAMECUBE + // allow screen fade out (on Gamecube only) + this->SetFadeTime( LICENSE_SCREEN_FADE_TIME ); +#endif + + GetBootupContext()->ResetLicenseScreenDisplayTime(); +} + + +//=========================================================================== +// CGuiScreenLicense::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLicense::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/bootup/guiscreenlicense.h b/game/code/presentation/gui/bootup/guiscreenlicense.h new file mode 100644 index 0000000..219c82c --- /dev/null +++ b/game/code/presentation/gui/bootup/guiscreenlicense.h @@ -0,0 +1,48 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLicense +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLICENSE_H +#define GUISCREENLICENSE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLicense : public CGuiScreen +{ +public: + CGuiScreenLicense( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenLicense(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENLICENSE_H diff --git a/game/code/presentation/gui/frontend/allfrontend.cpp b/game/code/presentation/gui/frontend/allfrontend.cpp new file mode 100644 index 0000000..57979b6 --- /dev/null +++ b/game/code/presentation/gui/frontend/allfrontend.cpp @@ -0,0 +1,19 @@ +#include <presentation/gui/frontend/guimanagerfrontend.cpp> +#include <presentation/gui/frontend/guiscreencardgallery.cpp> +#include <presentation/gui/frontend/guiscreencontroller.cpp> +#include <presentation/gui/frontend/guiscreenloadgame.cpp> +#include <presentation/gui/frontend/guiscreenmainmenu.cpp> +#include <presentation/gui/frontend/guiscreenmissiongallery.cpp> +#include <presentation/gui/frontend/guiscreenskingallery.cpp> +#include <presentation/gui/frontend/guiscreenvehiclegallery.cpp> +//#include <presentation/gui/frontend/guiscreenmultichoosechar.cpp> +//#include <presentation/gui/frontend/guiscreenmultisetup.cpp> +#include <presentation/gui/frontend/guiscreenoptions.cpp> +#include <presentation/gui/frontend/guiscreenplaymovie.cpp> +#include <presentation/gui/frontend/guiscreenscrapbook.cpp> +#include <presentation/gui/frontend/guiscreenscrapbookcontents.cpp> +#include <presentation/gui/frontend/guiscreenscrapbookstats.cpp> +#include <presentation/gui/frontend/guiscreensound.cpp> +#include <presentation/gui/frontend/guiscreensplash.cpp> +#include <presentation/gui/frontend/guiscreenviewcredits.cpp> +#include <presentation/gui/frontend/guiscreenviewmovies.cpp> diff --git a/game/code/presentation/gui/frontend/guimanagerfrontend.cpp b/game/code/presentation/gui/frontend/guimanagerfrontend.cpp new file mode 100644 index 0000000..1a7e146 --- /dev/null +++ b/game/code/presentation/gui/frontend/guimanagerfrontend.cpp @@ -0,0 +1,829 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerFrontEnd +// +// Description: Implementation of the CGuiManagerFrontEnd class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/21 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guimanagerfrontend.h> +#include <presentation/gui/guiwindow.h> // for window IDs +#include <presentation/gui/guisystem.h> + +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guiscreenmemorycard.h> +#include <presentation/gui/guiscreenmemcardcheck.h> + +#include <presentation/gui/frontend/guiscreensplash.h> +#include <presentation/gui/frontend/guiscreenmainmenu.h> +#include <presentation/gui/frontend/guiscreenloadgame.h> +#include <presentation/gui/frontend/guiscreenscrapbook.h> +#include <presentation/gui/frontend/guiscreenscrapbookcontents.h> +#include <presentation/gui/frontend/guiscreenscrapbookstats.h> +#include <presentation/gui/frontend/guiscreencardgallery.h> +#include <presentation/gui/frontend/guiscreenmissiongallery.h> +#include <presentation/gui/frontend/guiscreenskingallery.h> +#include <presentation/gui/frontend/guiscreenvehiclegallery.h> +#include <presentation/gui/frontend/guiscreenmultisetup.h> +#include <presentation/gui/frontend/guiscreenmultichoosechar.h> +#include <presentation/gui/frontend/guiscreenoptions.h> +#ifdef RAD_WIN32 +#include <presentation/gui/frontend/guiscreencontrollerWin32.h> +#else +#include <presentation/gui/frontend/guiscreencontroller.h> +#endif +#include <presentation/gui/frontend/guiscreensound.h> +#include <presentation/gui/frontend/guiscreenviewcredits.h> +#include <presentation/gui/frontend/guiscreenviewmovies.h> +#include <presentation/gui/frontend/guiscreenplaymovie.h> +#include <presentation/gui/frontend/guiscreendisplay.h> + +#include <presentation/presentation.h> +#include <presentation/fmvplayer/fmvplayer.h> +#include <presentation/fmvplayer/fmvuserinputhandler.h> + +#include <data/gamedatamanager.h> +#include <events/eventmanager.h> +#include <gameflow/gameflow.h> +#include <input/inputmanager.h> +#include <mission/gameplaymanager.h> +//#include <mission/headtoheadmanager.h> +#include <mission/missionmanager.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <supersprint/supersprintmanager.h> +#include <main/platform.h> +#include <main/game.h> +#include <sound/soundmanager.h> + +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + + +#define SHOW_SPLASH_SCREEN + +#ifdef RAD_RELEASE + #ifndef RAD_E3 + #define SHOW_INTRO_MOVIE + #endif +#endif + +//#define SKIP_INTRO_MOVIE_IF_GAME_LOADED + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManagerFrontEnd::CGuiManagerFrontEnd +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerFrontEnd::CGuiManagerFrontEnd +( + Scrooby::Project* pProject, + CGuiEntity* pParent +) +: CGuiManager( pProject, pParent ), + m_levelNum( 1 ), + m_disconnectedController(-1), + m_quittingToDemo( false ), + m_controllerPromptShown ( false ), + m_quittingToMiniGame( false ), + m_isControllerReconnected( false ), + m_wasFMVInputHandlerEnabled( false ) +{ +#ifdef RAD_WIN32 + m_quittingGame = false; +#endif +} + + +//=========================================================================== +// CGuiManagerFrontEnd::~CGuiManagerFrontEnd +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerFrontEnd::~CGuiManagerFrontEnd() +{ +} + + + +//=========================================================================== +// CGuiManagerFrontEnd::Populate +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerFrontEnd::Populate() +{ +MEMTRACK_PUSH_GROUP( "CGUIManagerFrontEnd" ); + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + Scrooby::Screen* pScroobyScreen; + CGuiScreen* pScreen; + + pScroobyScreen = m_pScroobyProject->GetScreen( "Message3D" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMessage( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt3D" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPrompt( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ErrorPrompt3D" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPrompt( pScroobyScreen, this, + CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT ); + + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MemoryCard3D" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMemoryCard( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Splash" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenSplash( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SPLASH, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MemCardCheck" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMemCardCheck( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MainMenu" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenIntroTransition( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MainMenu" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMainMenu( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MAIN_MENU, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "LoadGame" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLoadGame( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LOAD_GAME, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenAutoLoad( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_AUTO_LOAD, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ScrapBook" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenScrapBook( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SCRAP_BOOK, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ScrapBookContents" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenScrapBookContents( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ScrapBookStats" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenScrapBookStats( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SCRAP_BOOK_STATS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "CardGallery" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenCardGallery( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_CARD_GALLERY, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MissionGallery" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMissionGallery( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_GALLERY, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "SkinGallery" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenSkinGallery( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SKIN_GALLERY, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "VehicleGallery" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenVehicleGallery( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VEHICLE_GALLERY, pScreen ); + } +/* + pScroobyScreen = m_pScroobyProject->GetScreen( "MultiSetup" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMultiSetup( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MULTIPLAYER_SETUP, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MultiChooseCharacter" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMultiChooseChar( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER, pScreen ); + } +*/ + pScroobyScreen = m_pScroobyProject->GetScreen( "Options" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenOptions( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_OPTIONS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Controller" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenController( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_CONTROLLER, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Sound" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenSound( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SOUND, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ViewCredits" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenViewCredits( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_CREDITS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ViewMovies" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenViewMovies( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_MOVIES, pScreen ); + } + +#ifdef RAD_WIN32 + pScroobyScreen = m_pScroobyProject->GetScreen( "Display" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenDisplay( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_DISPLAY, pScreen ); + } +#endif + + pScroobyScreen = m_pScroobyProject->GetScreen( "PlayMovie" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Demo" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this, + CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_DEMO ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_DEMO, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this, + CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this, + CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME, pScreen ); + } + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); +MEMTRACK_POP_GROUP( "CGUIManagerFrontEnd" ); +} + +void +CGuiManagerFrontEnd::Start( CGuiWindow::eGuiWindowID initialWindow ) +{ + rAssert( GUI_FE_UNINITIALIZED == m_state ); + + m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ? + initialWindow : + CGuiWindow::GUI_SCREEN_ID_MAIN_MENU; + +// On PC never show the splash screen.. it is very console-ish... +#if defined(SHOW_SPLASH_SCREEN) && !defined(RAD_WIN32) + bool skipSplashScreen = CommandLineOptions::Get( CLO_NO_SPLASH ); +#else + bool skipSplashScreen = true; +#endif + if( skipSplashScreen && + initialWindow == CGuiWindow::GUI_SCREEN_ID_SPLASH ) + { + if( s_memcardCheckState != MEM_CARD_CHECK_COMPLETED ) + { + m_nextScreen = CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK; + } + else + { + m_nextScreen = CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION; + } + + GetGuiSystem()->SetSplashScreenFinished(); + } + + if( s_memcardCheckState != MEM_CARD_CHECK_COMPLETED ) + { + CGuiScreen* messageScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE ) ); + if( messageScreen != NULL ) + { + messageScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Message" ) ); + } + + CGuiScreen* errorPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT ) ); + if( errorPromptScreen != NULL ) + { + errorPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "ErrorPrompt" ) ); + } + + CGuiScreen* genericPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) ); + if( genericPromptScreen != NULL ) + { + genericPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Prompt" ) ); + } + + } + + m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen() + + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); +} + +void +CGuiManagerFrontEnd::OnControllerConnected( int controllerID ) +{ +#ifdef RAD_PS2 + if( m_controllerPromptShown + && m_disconnectedController == controllerID ) +#else + if( m_controllerPromptShown + && GetGuiSystem()->GetPrimaryController() == controllerID ) +#endif + { + m_isControllerReconnected = true; + m_disconnectedController = -1; + + GetGame()->GetPlatform()->ClearControllerError(); + } +} + +void +CGuiManagerFrontEnd::OnControllerDisconnected( int controllerID ) +{ + if( !m_controllerPromptShown ) + { + m_controllerPromptShown = true; + + // disable FMV user input handler + // + FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler(); + rAssert( userInputHandler != NULL ); + m_wasFMVInputHandlerEnabled = userInputHandler->IsEnabled(); + userInputHandler->SetEnabled( false ); + + // this->DisplayMessage( CGuiScreenMessage::MSG_ID_CONTROLLER_DISCONNECTED_GC + PLATFORM_TEXT_INDEX ); + char str_buffer[256]; + CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255); + GetGame()->GetPlatform()->OnControllerError(str_buffer); + } +} + +//=========================================================================== +// CGuiManagerFrontEnd::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerFrontEnd::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_WINDOW_FINISHED: + { + if( GUI_FE_CHANGING_SCREENS == m_state ) + { + m_currentScreen = m_nextScreen; + + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + } +/* + else if( GUI_FE_HIDING_POPUP == m_state ) + { + m_state = GUI_FE_SCREEN_RUNNING; + + // Tell the current screen to resume. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_RESUME ); + } +*/ + else if( GUI_FE_SHUTTING_DOWN == m_state ) + { + m_state = GUI_FE_TERMINATED; + + CGuiScreen::Reset3dFEMultiController(); + + if( m_quittingToDemo ) + { + if ( CommandLineOptions::Get( CLO_SEQUENTIAL_DEMO ) ) + { + RenderEnums::LevelEnum oldLevel = GetGameplayManager()->GetCurrentLevelIndex(); + + unsigned int whichLevel = (oldLevel + 1) % RenderEnums::numLevels; + GetGameplayManager()->SetLevelIndex( (RenderEnums::LevelEnum)whichLevel ); + + if ( whichLevel == 0 ) + { + RenderEnums::MissionEnum oldMisssion = GetGameplayManager()->GetCurrentMissionForDemo(); + unsigned int whichMission = (oldMisssion + 1) % RenderEnums::numMissions; + GetGameplayManager()->SetMissionIndex( (RenderEnums::MissionEnum)whichMission ); + } + } + else + { + +#ifdef NEALL_DEMOTEST + unsigned int whichLevel = RenderEnums::L1; //All seven levels + GetGameplayManager()->SetLevelIndex( (RenderEnums::LevelEnum)whichLevel ); + + unsigned int whichMission = RenderEnums::M1; //Why not. + GetGameplayManager()->SetMissionIndex( (RenderEnums::MissionEnum)whichMission ); +#else + unsigned int whichLevel = rand() % RenderEnums::numLevels; //All seven levels + GetGameplayManager()->SetLevelIndex( (RenderEnums::LevelEnum)whichLevel ); + + unsigned int whichMission = rand() % RenderEnums::numMissions; //Why not. + GetGameplayManager()->SetMissionIndex( (RenderEnums::MissionEnum)whichMission ); +#endif + } + + GetInputManager()->RegisterControllerID( 0, 0 ); + + // let's go to demo mode + // + GetGameFlow()->SetContext( CONTEXT_LOADING_DEMO ); + } + else if( m_quittingToMiniGame ) + { + // let's go to mini-game mode + // + GetGameFlow()->SetContext( CONTEXT_SUPERSPRINT_FE ); + } +#ifdef RAD_WIN32 + else if( m_quittingGame ) + { + // let's begin the quit procedure + // + GetGameFlow()->SetContext( CONTEXT_EXIT ); + } +#endif + else + { + CurrentMissionStruct currentMission = GetCharacterSheetManager()->QueryCurrentMission(); + + // Set the current level and mission to load + // + GetGameplayManager()->SetLevelIndex( currentMission.mLevel ); + GetGameplayManager()->SetMissionIndex( static_cast<RenderEnums::MissionEnum>( currentMission.mMissionNumber ) ); + + // let's go to normal gameplay mode + // + GetGameFlow()->SetContext( CONTEXT_LOADING_GAMEPLAY ); + } + } + + break; + } + + case GUI_MSG_SPLASH_SCREEN_DONE: + { + GetGuiSystem()->SetSplashScreenFinished(); + + if( s_memcardCheckState == CGuiManager::MEM_CARD_CHECK_NOT_DONE ) + { + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK, + CLEAR_WINDOW_HISTORY ); + } + else + { + rAssert( s_memcardCheckState == CGuiManager::MEM_CARD_CHECK_COMPLETED ); + + this->StartIntroMovie(); + } + + break; + } + + case GUI_MSG_MEMCARD_CHECK_COMPLETED: + { + CGuiScreen* messageScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE ) ); + if( messageScreen != NULL ) + { + messageScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Message3D" ) ); + } + + CGuiScreen* errorPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT ) ); + if( errorPromptScreen != NULL ) + { + errorPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "ErrorPrompt3D" ) ); + } + + CGuiScreen* genericPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) ); + if( genericPromptScreen != NULL ) + { + genericPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Prompt3D" ) ); + } + + this->StartIntroMovie(); + + break; + } + + case GUI_MSG_QUIT_FRONTEND: + { + rAssert( GUI_FE_SCREEN_RUNNING == m_state ); + + GetEventManager()->TriggerEvent( EVENT_FE_START_GAME_SELECTED ); + GetSoundManager()->DuckEverythingButMusicBegin(); + + // Set appropriate gameplay manager depending on number of players + // + switch( param1 ) + { + case 0: // single player demo mode + { + m_quittingToDemo = true; + + // follow-through + } + case 1: // single player story mode + { + SetGameplayManager( MissionManager::GetInstance() ); + + break; + } + case 2: + { + m_quittingToMiniGame = true; + + SetGameplayManager( SuperSprintManager::GetInstance() ); + + break; + } + /* + case 2: // two players head-to-head + { + SetGameplayManager( HeadToHeadManager::GetInstance() ); + + break; + } + */ + default: + { + rAssertMsg( 0, "ERROR: *** Invalid Number of Players!\n" ); + + break; + } + } + + m_state = GUI_FE_SHUTTING_DOWN; + + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + + break; + } + + case GUI_MSG_QUIT_GAME: + { +#ifdef RAD_WIN32 + rAssert( GUI_FE_SCREEN_RUNNING == m_state ); + + m_state = GUI_FE_SHUTTING_DOWN; + + m_quittingGame = true; + + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); +#endif // RAD_WIN32 + + break; + } + + + case GUI_MSG_CONTROLLER_DISCONNECT: + { +#ifdef RAD_PS2 + if( !m_controllerPromptShown ) + { + // show controller disconnected message on PS2 only if: + // + // - primary controller hasn't been established yet and ANY controller is disconnected; OR + // - the controller disconnected is the primary controller + // + int primaryControllerID = GetGuiSystem()->GetPrimaryController(); + if( primaryControllerID == -1 || primaryControllerID == static_cast<int>( param1 ) ) + { + m_disconnectedController = static_cast<int>( param1 ); + } + } +#endif // RAD_PS2 + + break; + } + + default: + { + if( message == GUI_MSG_UPDATE && m_isControllerReconnected ) + { + m_isControllerReconnected = false; + m_controllerPromptShown = false; + + // re-enable FMV user input handler + // + FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler(); + rAssert( userInputHandler != NULL ); + userInputHandler->SetEnabled( m_wasFMVInputHandlerEnabled ); + } + + if( m_controllerPromptShown ) + { + if (message==GUI_MSG_CONTROLLER_START) // start trigger reconnection + { + this->OnControllerConnected( static_cast<int>( param1 ) ); + } + break; // don't pass event if controller error + } + + if( m_state != GUI_FE_UNINITIALIZED && m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + // Send the messages down to the current screen. + // + CGuiScreen* pScreen = static_cast<CGuiScreen*>(this->FindWindowByID( m_currentScreen )); + rAssert( pScreen ); + if (pScreen->IsIgnoringControllerInputs() && pScreen->IsControllerMessage(message)) + ; // don't pass to screen + else + pScreen->HandleMessage( message, param1, param2 ); + } + + if( message == GUI_MSG_UPDATE ) + { +#ifndef RAD_GAMECUBE +#ifdef RAD_PS2 + int controllerID = m_disconnectedController; +#else + int controllerID = GetGuiSystem()->GetPrimaryController(); +#endif + if( controllerID >=0 && !GetInputManager()->GetController( controllerID )->IsConnected() ) + { + this->OnControllerDisconnected( controllerID ); + } +#endif + } + + break; + } + } + + // propogate message up the hierarchy + CGuiManager::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +void +CGuiManagerFrontEnd::StartIntroMovie() +{ +#ifdef SKIP_INTRO_MOVIE_IF_GAME_LOADED + if( GetGameDataManager()->IsGameLoaded() ) + { + // skip intro fmv and go straight to main menu + // + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION, + CLEAR_WINDOW_HISTORY ); + } + else +#endif // SKIP_INTRO_MOVIE_IF_GAME_LOADED + { +#ifdef SHOW_INTRO_MOVIE + // start the intro fmv + // + CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO ) ); + rAssert( playMovieScreen != NULL ); + playMovieScreen->SetMovieToPlay( MovieNames::INTROFMV, true, false, false ); + + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO, + CLEAR_WINDOW_HISTORY ); +#else + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION, + CLEAR_WINDOW_HISTORY ); +#endif // SHOW_INTRO_MOVIE + } +} + diff --git a/game/code/presentation/gui/frontend/guimanagerfrontend.h b/game/code/presentation/gui/frontend/guimanagerfrontend.h new file mode 100644 index 0000000..dbd1460 --- /dev/null +++ b/game/code/presentation/gui/frontend/guimanagerfrontend.h @@ -0,0 +1,82 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerFrontEnd +// +// Description: Interface for the CGuiManagerFrontEnd class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUIMANAGERFRONTEND_H +#define GUIMANAGERFRONTEND_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guimanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +const unsigned int FOR_THE_FIRST_TIME = 1; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiManagerFrontEnd : public CGuiManager +{ +public: + CGuiManagerFrontEnd( Scrooby::Project* pProject, + CGuiEntity* pParent ); + + virtual ~CGuiManagerFrontEnd(); + + virtual void Populate(); + virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +private: + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignment. Declare but don't define. + // + CGuiManagerFrontEnd( const CGuiManagerFrontEnd& ); + CGuiManagerFrontEnd& operator= ( const CGuiManagerFrontEnd& ); + + void OnControllerDisconnected( int controllerID ); + void OnControllerConnected( int controllerID ); + + void StartIntroMovie(); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + int m_levelNum; + int m_disconnectedController; + bool m_quittingToDemo : 1; + bool m_controllerPromptShown : 1; + bool m_quittingToMiniGame : 1; + bool m_isControllerReconnected : 1; + bool m_wasFMVInputHandlerEnabled : 1; + +#ifdef RAD_WIN32 + bool m_quittingGame : 1; +#endif + +}; + +#endif // GUIMANAGERFRONTEND_H diff --git a/game/code/presentation/gui/frontend/guiscreencardgallery.cpp b/game/code/presentation/gui/frontend/guiscreencardgallery.cpp new file mode 100644 index 0000000..c14a76e --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencardgallery.cpp @@ -0,0 +1,767 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenCardGallery +// +// Description: Implementation of the CGuiScreenCardGallery class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreencardgallery.h> +#include <presentation/gui/frontend/guiscreenscrapbookcontents.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/utility/scrollingtext.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guimenu.h> + +#include <cards/card.h> +#include <cards/cardsdb.h> +#include <events/eventmanager.h> +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation + +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <sprite.h> +#include <text.h> +#include <pure3dobject.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const unsigned int NUM_CARD_ROWS = 2; +const unsigned int NUM_CARD_COLUMNS = 4; +const float CARD_TRANSITION_TIME = 250.0f; // in msec +const float CARD_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms + +#ifdef RAD_WIN32 +const float CARD_THUMBNAIL_SCALE = 0.44f; +const float CARD_DESCRIPTION_TEXT_SCALE = 0.9f; +const float CARD_QUESTION_CORRECTION_SCALE = 2.0f / 3.0f; +const float CARD_GREY_CORRECTION_SCALE = 2.0f / 3.0f; +#else +const float CARD_THUMBNAIL_SCALE = 0.44f; +const float CARD_DESCRIPTION_TEXT_SCALE = 0.9f; +const float CARD_QUESTION_CORRECTION_SCALE = 2.0f; +const float CARD_GREY_CORRECTION_SCALE = 2.0f; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenCardGallery::CGuiScreenCardGallery +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenCardGallery::CGuiScreenCardGallery +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID windowID +) +: CGuiScreen( pScreen, pParent, windowID ), + m_cardGalleryState( STATE_BROWSING_CARDS ), + m_cardScaleSmall( CARD_THUMBNAIL_SCALE ), + m_cardScaleLarge( 1.0f ), + m_pMenu( NULL ), + m_viewCard( NULL ), + m_viewCardDistX( 0 ), + m_viewCardDistY( 0 ), + m_cardBrowseLayer( NULL ), + m_cardViewLayer( NULL ), + m_cardSFXLayer( NULL ), + m_elapsedTime( 0 ), + m_currentCard( NULL ), + m_cardTitle( NULL ), + m_cardEpisode( NULL ), + m_cardDescription( NULL ), + m_currentQuote( -1 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "CardGallery" ); + if( windowID == GUI_SCREEN_ID_VIEW_CARDS ) + { + pPage = m_pScroobyScreen->GetPage( "PauseViewCards" ); + } + rAssert( pPage != NULL ); + + char cardName[ 8 ]; + + // create a 2D sprite menu + // + m_pMenu = new CGuiMenu2D( this, NUM_CARDS_PER_LEVEL, 4, GUI_SPRITE_MENU, MENU_SFX_NONE ); + rAssert( m_pMenu != NULL ); + m_pMenu->SetGreyOutEnabled( false ); + + Scrooby::Group* pGroup = pPage->GetGroup( "CollectedCards" ); + rAssert( pGroup != NULL ); + + // add sprites to menu + // + for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ ) + { + sprintf( cardName, "Card%d", i ); + m_pMenu->AddMenuItem( pGroup->GetSprite( cardName ) ); + } + + // add menu cursor + // + m_pMenu->SetCursor( pGroup->GetSprite( "CardFrame" ) ); + + m_cardBrowseLayer = pPage->GetLayer( "Foreground" ); + rAssert( m_cardBrowseLayer ); + + // from ViewCard page + // + pPage = m_pScroobyScreen->GetPage( "ViewCard" ); + rAssert( pPage != NULL ); + + this->AutoScaleFrame( pPage ); + + for( unsigned int j = 0; j < NUM_CARDS_PER_LEVEL; j++ ) + { + sprintf( cardName, "Card%d", j ); + Scrooby::Sprite* greyCard = pPage->GetSprite( cardName ); + if( greyCard != NULL ) + { + greyCard->ResetTransformation(); + greyCard->ScaleAboutCenter( CARD_GREY_CORRECTION_SCALE ); + } + } + + m_cardViewLayer = pPage->GetLayer( "ViewCard" ); + rAssert( m_cardViewLayer ); + m_cardViewLayer->SetVisible( false ); + + m_cardTitle = pPage->GetText( "CardTitle" ); + rAssert( m_cardTitle ); + m_cardTitle->SetTextMode( Scrooby::TEXT_WRAP ); + + m_cardEpisode = pPage->GetText( "CardEpisode" ); + rAssert( m_cardEpisode ); + m_cardEpisode->SetTextMode( Scrooby::TEXT_WRAP ); + + m_cardDescription = pPage->GetText( "CardDescription" ); + rAssert( m_cardDescription ); + m_cardDescription->SetTextMode( Scrooby::TEXT_WRAP ); + m_cardDescription->ScaleAboutPoint( CARD_DESCRIPTION_TEXT_SCALE, 0, 0 ); + + for( unsigned int i = 0; i < MAX_NUM_QUOTES; i++ ) + { + char name[ 32 ]; + sprintf( name, "Quote%d", i ); + + m_quoteIcon[ i ] = pPage->GetSprite( name ); + rAssert( m_quoteIcon[ i ] ); + + m_quote[ i ] = new( GMA_LEVEL_FE ) ScrollingText( pPage->GetText( name ) ); + rAssert( m_quote[ i ] ); + } + + if( windowID == GUI_SCREEN_ID_CARD_GALLERY ) + { + // from HighResCard page + // + pPage = m_pScroobyScreen->GetPage( "HighResCard" ); + } + else + { + // from LowResCard page + // + pPage = m_pScroobyScreen->GetPage( "LowResCard" ); + } + + rAssert( pPage != NULL ); + Scrooby::Layer* cardLayer = pPage->GetLayer( "Card" ); + rAssert( cardLayer != NULL ); + + m_viewCard = cardLayer->GetSprite( "Card" ); + rAssert( m_viewCard ); + m_viewCard->SetVisible( false ); + + m_cardSFXLayer = pPage->GetLayer( "SFX" ); + if( m_cardSFXLayer != NULL ) + { + m_cardSFXLayer->SetVisible( false ); + } + + if( this->IsWideScreenDisplay() ) + { + if( m_cardSFXLayer != NULL ) + { + Scrooby::Pure3dObject* cardSparkle = m_cardSFXLayer->GetPure3dObject( "CardSparkle" ); + if( cardSparkle != NULL ) + { + cardSparkle->SetWideScreenCorrectionEnabled( true ); + } + } + + cardLayer->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( cardLayer ); + + m_cardViewLayer->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( m_cardViewLayer ); + } +} + + +//=========================================================================== +// CGuiScreenCardGallery::~CGuiScreenCardGallery +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenCardGallery::~CGuiScreenCardGallery() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } + + for( unsigned int i = 0; i < MAX_NUM_QUOTES; i++ ) + { + if( m_quote[ i ] != NULL ) + { + delete m_quote[ i ]; + m_quote[ i ] = NULL; + } + } +} + + +//=========================================================================== +// CGuiScreenCardGallery::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCardGallery::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_cardGalleryState != STATE_BROWSING_CARDS ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( m_cardGalleryState == STATE_GOTO_VIEW_CARD ) + { + this->UpdateCardTransition( param1, true ); + } + else if( m_cardGalleryState == STATE_BACK_VIEW_CARD ) + { + this->UpdateCardTransition( param1, false ); + } + else + { + rAssert( m_cardGalleryState == STATE_VIEWING_CARD ); + this->UpdateViewCard( param1 ); + } + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + if( m_cardGalleryState == STATE_VIEWING_CARD ) + { + if( m_cardSFXLayer != NULL ) + { + m_cardSFXLayer->SetVisible( false ); + } + + m_cardGalleryState = STATE_BACK_VIEW_CARD; + m_elapsedTime = 0; + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect + } + + break; + } + + default: + { + break; + } + } + + return; + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + // pulse cursor alpha + // + Scrooby::Drawable* cursor = m_pMenu->GetCursor(); + if( cursor != NULL ) + { + const unsigned int PULSE_PERIOD = 1000; + + float alpha = GuiSFX::Pulse( (float)m_elapsedTime, + (float)PULSE_PERIOD, + 0.75f, + 0.25f, + -rmt::PI_BY2 ); + + cursor->SetAlpha( alpha ); + + m_elapsedTime += param1; + m_elapsedTime %= PULSE_PERIOD; + } + + break; + } +/* + case GUI_MSG_CONTROLLER_LEFT: + { + int newSelection = m_currentSelection - 1; + if( newSelection < 0 ) + { + newSelection += NUM_CARDS_PER_LEVEL; + } + + this->MoveCursor( m_currentSelection, newSelection ); + m_currentSelection = newSelection; + + break; + } + + case GUI_MSG_CONTROLLER_RIGHT: + { + int newSelection = (m_currentSelection + 1) % NUM_CARDS_PER_LEVEL; + this->MoveCursor( m_currentSelection, newSelection ); + m_currentSelection = newSelection; + + break; + } + + case GUI_MSG_CONTROLLER_UP: + { + int newSelection = m_currentSelection - NUM_CARD_COLUMNS; + if( newSelection < 0 ) + { + newSelection += NUM_CARDS_PER_LEVEL; + } + + this->MoveCursor( m_currentSelection, newSelection ); + m_currentSelection = newSelection; + + break; + } + + case GUI_MSG_CONTROLLER_DOWN: + { + int newSelection = (m_currentSelection + NUM_CARD_COLUMNS) % NUM_CARDS_PER_LEVEL; + + this->MoveCursor( m_currentSelection, newSelection ); + m_currentSelection = newSelection; + + break; + } +*/ + case GUI_MSG_MENU_SELECTION_MADE: + { + Scrooby::Sprite* currentCardSelection = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( param1 )->GetItem() ); + rAssert( currentCardSelection != NULL ); + + int cardID = currentCardSelection->GetIndex() - 1; + if( cardID != -1 ) + { + this->SetCurrentViewCard( cardID ); + + int smallPosX, smallPosY; + currentCardSelection->GetOriginPosition( smallPosX, smallPosY ); + + int bigPosX, bigPosY; + m_viewCard->GetOriginPosition( bigPosX, bigPosY ); + + m_viewCardDistX = smallPosX - bigPosX; + m_viewCardDistY = smallPosY - bigPosY; + + m_cardVelocity.x = m_viewCardDistX / CARD_TRANSITION_TIME; + m_cardVelocity.y = (m_viewCardDistY - 0.5f * CARD_PROJECTILE_GRAVITY * CARD_TRANSITION_TIME * CARD_TRANSITION_TIME) / CARD_TRANSITION_TIME; + m_cardVelocity.z = 0.0f; + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + + // hide level bar + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + if( scrapBookContents != NULL ) + { + scrapBookContents->SetLevelBarVisible( false ); + } + + m_viewCard->SetVisible( true ); + m_cardViewLayer->SetVisible( true ); + m_cardGalleryState = STATE_GOTO_VIEW_CARD; + m_elapsedTime = 0; + + this->UpdateCardTransition( 0, true ); + } + + break; + } + + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenCardGallery::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCardGallery::InitIntro() +{ + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + this->UpdateCards( scrapBookContents->GetCurrentLevel() ); +} + + +//=========================================================================== +// CGuiScreenCardGallery::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCardGallery::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenCardGallery::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCardGallery::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +/* +void +CGuiScreenCardGallery::MoveCursor( unsigned int from, + unsigned int to ) +{ + if( m_cursor != NULL ) + { + rAssert( from < NUM_CARDS_PER_LEVEL && to < NUM_CARDS_PER_LEVEL ); + + int posX = 0; + int posY = 0; + m_collectedCards[ to ]->GetOriginPosition( posX, posY ); + + m_cursor->SetPosition( posX, posY ); + } + + // turn on/off 'accept' button + // + bool isSelectable = (m_collectedCards[ to ]->GetIndex() != 0); + this->SetButtonVisible( BUTTON_ICON_ACCEPT, isSelectable ); +} +*/ + +void +CGuiScreenCardGallery::UpdateCards( unsigned int currentLevel ) +{ + // update the cards + // + const CardList* collectedCards = GetCardGallery()->GetCollectedCards( currentLevel ); + rAssert( collectedCards != NULL ); + rAssert( m_pMenu != NULL ); + + // hide accept button by default (unless there is at least one collected card to view) + // + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + + for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ ) + { + Scrooby::Sprite* cardSelection = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( cardSelection != NULL ); + cardSelection->ResetTransformation(); + + bool isCardCollected = ( collectedCards->m_cards[ i ] != NULL ); + m_pMenu->SetMenuItemEnabled( i, isCardCollected ); + + if( isCardCollected ) + { + unsigned int cardID = collectedCards->m_cards[ i ]->GetID(); + rAssert( cardID < static_cast<unsigned int>( cardSelection->GetNumOfImages() ) ); + cardSelection->SetIndex( cardID + 1 ); + cardSelection->ScaleAboutCenter( m_cardScaleSmall ); + +// m_pMenu->Reset(); + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + } + else + { + cardSelection->SetIndex( 0 ); + cardSelection->ScaleAboutCenter( CARD_QUESTION_CORRECTION_SCALE ); + } + } +} + +void +CGuiScreenCardGallery::UpdateCardTransition( unsigned int elapsedTime, bool toViewCard ) +{ + rAssert( m_viewCard ); + m_viewCard->ResetTransformation(); + + if( m_elapsedTime < CARD_TRANSITION_TIME ) + { + float t = toViewCard ? (float)m_elapsedTime / CARD_TRANSITION_TIME : + 1.0f - (float)m_elapsedTime / CARD_TRANSITION_TIME; + + // scale card + // + float scale = t * (m_cardScaleLarge - m_cardScaleSmall) + m_cardScaleSmall; + m_viewCard->ScaleAboutCenter( scale ); + +/* + // translate card + // + int translateX = static_cast<int>( (1.0f - t) * m_viewCardDistX ); + int translateY = static_cast<int>( (1.0f - t) * m_viewCardDistY ); + m_viewCard->Translate( translateX, translateY ); +*/ + + GuiSFX::Projectile( m_viewCard, + (float)m_elapsedTime, + CARD_TRANSITION_TIME, + m_cardVelocity, + toViewCard, + CARD_PROJECTILE_GRAVITY ); + + // fade in/out foreground layers (non-linearly) + // + m_cardBrowseLayer->SetAlpha( (1.0f - t) * (1.0f - t) ); + m_cardViewLayer->SetAlpha( t * t ); + + m_elapsedTime += elapsedTime; + } + else + { + // transition completed + // + if( toViewCard ) + { + m_viewCard->ScaleAboutCenter( m_cardScaleLarge ); + + m_cardGalleryState = STATE_VIEWING_CARD; + + m_cardBrowseLayer->SetAlpha( 0.0f ); + m_cardViewLayer->SetAlpha( 1.0f ); + + if( m_cardSFXLayer != NULL ) + { + m_cardSFXLayer->SetVisible( true ); + } + } + else + { + m_viewCard->ScaleAboutCenter( m_cardScaleSmall ); + + m_cardViewLayer->SetVisible( false ); + m_viewCard->SetVisible( false ); + m_cardGalleryState = STATE_BROWSING_CARDS; + + m_cardBrowseLayer->SetAlpha( 1.0f ); + m_cardViewLayer->SetAlpha( 0.0f ); + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + + // show level bar + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + if( scrapBookContents != NULL ) + { + scrapBookContents->SetLevelBarVisible( true ); + } + } + } +} + +void +CGuiScreenCardGallery::UpdateViewCard( unsigned int elapsedTime ) +{ + rAssert( m_currentCard ); + + if( m_currentQuote != -1 ) + { + // update current scrolling quote + // + rAssert( m_quote[ m_currentQuote ] ); + m_quote[ m_currentQuote ]->Update( elapsedTime ); + + if( m_quote[ m_currentQuote ]->GetCurrentState() == ScrollingText::STATE_IDLE ) + { + // turn off current quote icon + // + m_quoteIcon[ m_currentQuote ]->SetVisible( false ); + + // start next quote (and wrap to first one) + // + m_currentQuote = (m_currentQuote + 1) % m_currentCard->GetNumQuotes(); + m_quote[ m_currentQuote ]->Start(); + + // turn on new quote icon + // + m_quoteIcon[ m_currentQuote ]->SetVisible( true ); + } + } +} + +void +CGuiScreenCardGallery::SetCurrentViewCard( unsigned int cardID ) +{ + // set current card reference + // + m_currentCard = GetCardGallery()->GetCardsDB()->GetCardByID( cardID ); + rAssert( m_currentCard ); + + // set card image + // + rAssert( m_viewCard ); + rAssert( cardID < static_cast<unsigned int>( m_viewCard->GetNumOfImages() ) ); + m_viewCard->SetIndex( cardID ); + + // set card title + // + rAssert( m_cardTitle ); + rAssert( cardID < static_cast<unsigned int>( m_cardTitle->GetNumOfStrings() ) ); + m_cardTitle->SetIndex( cardID ); + + // set card episode + // + rAssert( m_cardEpisode ); + rAssert( cardID < static_cast<unsigned int>( m_cardEpisode->GetNumOfStrings() ) ); + m_cardEpisode->SetIndex( cardID ); + + // set card description + // + rAssert( m_cardDescription ); + rAssert( cardID < static_cast<unsigned int>( m_cardDescription->GetNumOfStrings() ) ); + m_cardDescription->SetIndex( cardID ); + + // stop current quote + // + if( m_currentQuote != -1 ) + { + m_quote[ m_currentQuote ]->Stop(); + } + + // set card quotes + // + for( unsigned int i = 0; i < MAX_NUM_QUOTES; i++ ) + { + m_quoteIcon[ i ]->SetVisible( false ); + + eQuoteID quoteID = m_currentCard->GetQuoteID( i ); + if( quoteID != EMPTY_QUOTE ) + { + m_quoteIcon[ i ]->SetIndex( static_cast<int>( quoteID ) ); + } + + m_quote[ i ]->SetTextIndex( cardID ); + } + + if( m_currentCard->GetNumQuotes() > 0 ) + { + // start scrolling first quote + // + m_currentQuote = 0; + m_quote[ m_currentQuote ]->Start(); + m_quoteIcon[ m_currentQuote ]->SetVisible( true ); + } + else + { + m_currentQuote = -1; + } +} + diff --git a/game/code/presentation/gui/frontend/guiscreencardgallery.h b/game/code/presentation/gui/frontend/guiscreencardgallery.h new file mode 100644 index 0000000..d3284fe --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencardgallery.h @@ -0,0 +1,104 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenCardGallery +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENCARDGALLERY_H +#define GUISCREENCARDGALLERY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <cards/cardgallery.h> +#include <cards/card.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu2D; +class ScrollingText; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenCardGallery : public CGuiScreen +{ +public: + CGuiScreenCardGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent, + eGuiWindowID windowID = GUI_SCREEN_ID_CARD_GALLERY ); + virtual ~CGuiScreenCardGallery(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void UpdateCards( unsigned int currentLevel ); + + enum eScreenState + { + STATE_BROWSING_CARDS, + STATE_GOTO_VIEW_CARD, + STATE_VIEWING_CARD, + STATE_BACK_VIEW_CARD, + + NUM_SCREEN_STATES + }; + + eScreenState m_cardGalleryState; + + float m_cardScaleSmall; + float m_cardScaleLarge; + + CGuiMenu2D* m_pMenu; + +private: +// void MoveCursor( unsigned int from, unsigned int to ); + void UpdateCardTransition( unsigned int elapsedTime, bool toViewCard ); + void UpdateViewCard( unsigned int elapsedTime ); + void SetCurrentViewCard( unsigned int cardID ); + + Scrooby::Sprite* m_viewCard; + int m_viewCardDistX; + int m_viewCardDistY; + rmt::Vector m_cardVelocity; + + Scrooby::Layer* m_cardBrowseLayer; + Scrooby::Layer* m_cardViewLayer; + Scrooby::Layer* m_cardSFXLayer; + + unsigned int m_elapsedTime; + + // for viewing card + // + Card* m_currentCard; + + Scrooby::Text* m_cardTitle; + Scrooby::Text* m_cardEpisode; + Scrooby::Text* m_cardDescription; + + Scrooby::Sprite* m_quoteIcon[ MAX_NUM_QUOTES ]; + ScrollingText* m_quote[ MAX_NUM_QUOTES ]; + int m_currentQuote; + +}; + +#endif // GUISCREENCARDGALLERY_H diff --git a/game/code/presentation/gui/frontend/guiscreencontroller.cpp b/game/code/presentation/gui/frontend/guiscreencontroller.cpp new file mode 100644 index 0000000..3ffd076 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencontroller.cpp @@ -0,0 +1,401 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenController +// +// Description: Implementation of the CGuiScreenController class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreencontroller.h> +#include <presentation/gui/guimenu.h> + +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +#include <strings/unicodestring.h> +#include <p3d/unicode.hpp> +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +enum eMenuItem +{ + MENU_ITEM_CONFIGURATION, + MENU_ITEM_DISPLAY, + MENU_ITEM_VIBRATION, + + NUM_MENU_ITEMS +}; + +static const char* MENU_ITEMS[] = +{ + "Configuration", + "Display", + "Vibration" +}; + +const int NUM_DISPLAY_MODES = 2; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenController::CGuiScreenController +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenController::CGuiScreenController +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_CONTROLLER ), + m_pMenu( NULL ), + m_numLabels( 0 ), + m_currentConfig( 0 ), + m_currentDisplay( 0 ), + m_currentControllerID( 0 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "Controller" ); + rAssert( pPage ); + + // create a menu + // + m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // add menu items + // + Scrooby::Group* menu = pPage->GetGroup( "Menu" ); + for( int j = 0; j < NUM_MENU_ITEMS; j++ ) + { + char objectName[ 32 ]; + sprintf( objectName, "%s_Value", MENU_ITEMS[ j ] ); + m_pMenu->AddMenuItem( menu->GetText( MENU_ITEMS[ j ] ), + menu->GetText( objectName ), + NULL, + NULL, + NULL, + NULL, + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + } + +#ifdef RAD_GAMECUBE + // change "Vibration" text to "Rumble" + // + Scrooby::Text* vibrationText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_VIBRATION )->GetItem() ); + rAssert( vibrationText ); + vibrationText->SetIndex( 1 ); +#endif // RAD_GAMECUBE + + // disable configuration until there are multiple configurations from + // which to choose + // + m_pMenu->SetMenuItemEnabled( MENU_ITEM_CONFIGURATION, false, true ); + + // get the platform-specific Controller page + // +#ifdef RAD_GAMECUBE + pPage = m_pScroobyScreen->GetPage( "ControllerGC" ); + rAssert( pPage ); +#endif // RAD_GAMECUBE + +#ifdef RAD_PS2 + pPage = m_pScroobyScreen->GetPage( "ControllerPS2" ); + rAssert( pPage ); +#endif // RAD_PS2 + +#ifdef RAD_XBOX + pPage = m_pScroobyScreen->GetPage( "ControllerXBOX" ); + rAssert( pPage ); +#endif // RAD_XBOX + +#ifdef RAD_WIN32 + pPage = m_pScroobyScreen->GetPage( "ControllerPC" ); + rAssert( pPage ); +#endif // RAD_WIN32 + + // and make it visible + // + pPage->GetLayerByIndex( 0 )->SetVisible( true ); + + // get text labels + // + Scrooby::Group* textLabels = pPage->GetGroup( "TextLabels" ); + rAssert( textLabels != NULL ); + for( int i = 0; i < MAX_NUM_LABELS; i++ ) + { + char objectName[ 32 ]; + sprintf( objectName, "Label%02d", i ); + + Scrooby::Text* textLabel = textLabels->GetText( objectName ); + if( textLabel != NULL ) + { +#ifdef PAL + textLabel->StretchBoundingBox( 30, 0 ); +#endif // PAL + + textLabel->SetTextMode( Scrooby::TEXT_WRAP ); + m_labels[ i ] = textLabel; + m_numLabels++; + + // TC: this is now done in the text bible + // +/* + // convert text label strings to all caps + // + for( int j = 0; j < NUM_DISPLAY_MODES; j++ ) + { + rAssert( j < textLabel->GetNumOfStrings() ); + + p3d::UnicodeStrUpr( textLabel->GetStringBuffer( j ) ); + } +*/ + } + else + { + // assume no more labels, which means they all must have + // been numbered sequentially without any gaps + // + break; + } + } + +#ifdef PAL + // scale down controller image and text labels a bit so that + // all localized versions will fit on screen + // + #ifdef RAD_PS2 + const float SCALE_FACTOR = 0.95f; + #else + const float SCALE_FACTOR = 0.9f; + #endif + + textLabels->ResetTransformation(); + textLabels->ScaleAboutCenter( SCALE_FACTOR ); + + pPage = m_pScroobyScreen->GetPage( "ControllerImage" ); + if( pPage != NULL ) + { + Scrooby::Sprite* controllerImage = pPage->GetSprite( "Controller" ); + if( controllerImage != NULL ) + { + controllerImage->ResetTransformation(); + controllerImage->ScaleAboutCenter( SCALE_FACTOR ); + } + } +#endif // PAL +} + + +//=========================================================================== +// CGuiScreenController::~CGuiScreenController +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenController::~CGuiScreenController() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenController::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_LEFT: + case GUI_MSG_CONTROLLER_RIGHT: + { + if( m_pMenu->GetSelection() == MENU_ITEM_VIBRATION ) + { + m_currentControllerID = static_cast<int>( param1 ); + } + + break; + } + + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + if( param1 == MENU_ITEM_CONFIGURATION ) + { + m_currentConfig = param2; + + this->UpdateLabels(); + } + else if( param1 == MENU_ITEM_DISPLAY ) + { + m_currentDisplay = param2; + + this->UpdateLabels(); + } + else if( param1 == MENU_ITEM_VIBRATION ) + { + if( param2 == 0 ) // vibration turned ON + { + // send vibration pulse to controller + // + GetInputManager()->TriggerRumblePulse( m_currentControllerID ); + } + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 560, 590 ); + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenController::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitIntro() +{ + // update controller settings on menu + // + bool vibrationOn = GetInputManager()->IsRumbleEnabled(); + m_pMenu->SetSelectionValue( MENU_ITEM_VIBRATION, + vibrationOn ? 0 : 1 ); +} + + +//=========================================================================== +// CGuiScreenController::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenController::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitOutro() +{ + bool vibrationOn = (m_pMenu->GetSelectionValue( MENU_ITEM_VIBRATION ) == 0); + GetInputManager()->SetRumbleEnabled( vibrationOn ); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenController::UpdateLabels() +{ + int labelIndex = m_currentConfig * NUM_DISPLAY_MODES + m_currentDisplay; + for( int i = 0; i < m_numLabels; i++ ) + { + rAssert( m_labels[ i ] ); + m_labels[ i ]->SetIndex( labelIndex ); + } +} + diff --git a/game/code/presentation/gui/frontend/guiscreencontroller.h b/game/code/presentation/gui/frontend/guiscreencontroller.h new file mode 100644 index 0000000..9c56c19 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencontroller.h @@ -0,0 +1,65 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenController +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/30 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENCONTROLLER_H +#define GUISCREENCONTROLLER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenController : public CGuiScreen +{ +public: + CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenController(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void UpdateLabels(); + + static const int MAX_NUM_LABELS = 32; + + CGuiMenu* m_pMenu; + + Scrooby::Text* m_labels[ MAX_NUM_LABELS ]; + int m_numLabels; + + int m_currentConfig; + int m_currentDisplay; + int m_currentControllerID; + +}; + +#endif // GUISCREENCONTROLLER_H diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32.cpp b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.cpp new file mode 100644 index 0000000..eb17100 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.cpp @@ -0,0 +1,1200 @@ +/****************************************************************************** + File: GuiScreenControllerWin32.cpp + Desc: Defines the CGuiScreenController class. + Author: Neil Haran + Date: July 31, 2003 + History: +*****************************************************************************/ +#include <presentation/gui/frontend/guiscreencontrollerWin32.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guimanager.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <data/config/gameconfigmanager.h> +#include <presentation/tutorialmanager.h> +#include <events/eventmanager.h> +#include <camera/supercammanager.h> +#include <camera/supercamcentral.h> + +#include <group.h> +#include <layer.h> +#include <page.h> +#include <screen.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* szMainControllerPage = "ControllerPC"; +const char* szCCPage = "CharacterControls"; +const char* szVCPage = "VehicleControls"; +const char* szGSPage = "GameSettings"; +const char* szNotAssigned = "---"; + +const int NUM_DISPLAY_MODES = 2; +const int MAX_INPUTNAME_LENGTH = 10; + +const tColour DEFAULT_SELECTED_ITEM_COLOUR( 255, 255, 0 ); +const tColour DEFAULT_INPUTMAPPED_ITEM_COLOUR( 255, 0, 0 ); // the same as in guiscreenmemorycard.cpp + +const float SLIDER_ICON_SCALE = 0.5f; + +/****************************************************************************** + Construction/Destruction +*****************************************************************************/ +CGuiScreenController::CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent ) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_CONTROLLER ), + m_pMenu( NULL ), + m_currentPage( MENU_PAGE_MAIN ), + m_currentControllerID( 0 ), + m_bMapInput( false ), + m_currentTextLabel(NULL), + m_bDisableBack(false), + m_numControllerGroups(0) +{ + memset( m_menuGroupStartIndex, 0 , sizeof( m_menuGroupStartIndex ) ); + m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Add main menu items + SetGroups( m_pMenuLabels, NUM_MAINMENU_LABELS, szMainControllerPage, "Menu", "Label", ALL_ATTRIBUTES_ON ); + m_numControllerGroups = 1; // The first page is the MENU_PAGE_MAIN with an index of 0. + + // Add map items + SetGroups( m_pCCLabels[MAP_PRIMARY], NUM_CHARACTERCONTROL_LABELS, szCCPage, "Map1", "Map1Label" ); + SetGroups( m_pCCLabels[MAP_SECONDARY], NUM_CHARACTERCONTROL_LABELS, szCCPage, "Map2", "Map2Label" ); + SetGroups( m_pVCLabels[MAP_PRIMARY], NUM_VEHICLECONTROL_LABELS, szVCPage, "Map1", "Map1Label" ); + SetGroups( m_pVCLabels[MAP_SECONDARY], NUM_VEHICLECONTROL_LABELS, szVCPage, "Map2", "Map2Label" ); + + // Add game setting items + SetGroups( m_pMSLabels, NUM_GAMESETTING_LABELS, szGSPage, "Menu", + "Label", (SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED) ); + + //Turn off the controller page that shows up for the consoles. + SetPageVisiblility( "Controller", false ); + SetPageVisiblility( szMainControllerPage, true ); + SetPageVisiblility( szCCPage, false ); + SetPageVisiblility( szVCPage, false ); + SetPageVisiblility( szGSPage, false ); + + // Size the slider icons in the game settings page. + Scrooby::Group* group = pScreen->GetPage( szGSPage )->GetGroup( "Menu" ); + if( group != NULL ) + { + group->GetSprite( "MouseXSliderIcon" )->ScaleAboutCenter( SLIDER_ICON_SCALE ); + group->GetSprite( "MouseYSliderIcon" )->ScaleAboutCenter( SLIDER_ICON_SCALE ); + group->GetSprite( "WheelSliderIcon" )->ScaleAboutCenter( SLIDER_ICON_SCALE ); + } +} + +CGuiScreenController::~CGuiScreenController() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + +//=========================================================================== +// CGuiScreenController::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + static bool bRelayMessage = true; + + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + switch( param1 ) + { + case PROMPT_CONFIRM_RESTOREALLDEFAULTS: + { + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + GetInputManager()->GetController(m_currentControllerID)->LoadDefaults(); + this->InitIntro(); + this->ReloadScreen(); + + break; + } + + case (CGuiMenuPrompt::RESPONSE_NO): + { + this->ReloadScreen(); + + break; + } + + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + } + break; + default: break; + } + } + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + rAssert( m_pMenu ); + GuiMenuItem* currentItem = m_pMenu->GetMenuItem( param1 ); + rAssert( currentItem ); + + switch( m_currentPage ) + { + case MENU_PAGE_GAMESETTINGS: + { + // convert to Gamesetting specific items. + int menuItem = param1-NUM_CHARACTERCONTROL_LABELS-NUM_VEHICLECONTROL_LABELS; + UserController* pController = GetInputManager()->GetController( m_currentControllerID ); + + switch( menuItem ) + { + case GS_MOUSELOOK: + { + pController->SetMouseLook( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES ); + + GetSuperCamManager()->GetSCC( 0 )->SelectSuperCam( SuperCam::ON_FOOT_CAM, SuperCamCentral::CUT, 0 ); + GetSuperCamManager()->GetSCC( 0 )->Update( 0 ); + } + break; + case GS_MOUSESENSITIVITY_X: + { + pController->SetMouseSensitivityX( m_pMenu->GetMenuItem( param1 )->m_slider.m_value ); + } + break; + case GS_MOUSESENSITIVITY_Y: + { + pController->SetMouseSensitivityY( m_pMenu->GetMenuItem( param1 )->m_slider.m_value ); + } + break; + case GS_INVERTMOUSEX: + { + pController->SetInvertMouseX( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES ); + } + break; + case GS_INVERTMOUSEY: + { + pController->SetInvertMouseY( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES ); + } + break; + case GS_FORCEFEEDBACK: + { + pController->SetForceFeedback( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES ); + } + break; + case GS_WHEELSENSITIVITY: + { + pController->SetWheelSensitivityX( m_pMenu->GetMenuItem( param1 )->m_slider.m_value ); + } + break; + default: + break; + } + } + break; + default: + break; + } + + break; + } + case GUI_MSG_CONTROLLER_UP: + { + // Basically a wrap around system when you reach the top. + // Just jumps to the last element. + switch(m_currentPage) + { + case MENU_PAGE_MAIN: + if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage] ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1)); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + break; + case MENU_PAGE_CHARACTERCONTROLS: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on keyboard Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage] ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS-1)); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_CHARACTERCONTROL_LABELS ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS*2)-1); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + case MENU_PAGE_VEHICLECONTROLS: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on gamepad Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage] ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS-1)); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_VEHICLECONTROL_LABELS ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS*2)-1); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + case MENU_PAGE_GAMESETTINGS: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on gamepad Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage] ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_GAMESETTING_LABELS-1)); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + break; + default: + break; + } + break; + } + case GUI_MSG_CONTROLLER_DOWN: + { + // Basically a wrap around system when you reach the bottom. + // Just jumps to the first element. + switch(m_currentPage) + { + case MENU_PAGE_MAIN: + if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1) ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + break; + case MENU_PAGE_CHARACTERCONTROLS: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on keyboard Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS-1) ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS*2)-1 ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_CHARACTERCONTROL_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + case MENU_PAGE_VEHICLECONTROLS: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on gamepad Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS-1) ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS*2)-1 ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_VEHICLECONTROL_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + + case MENU_PAGE_GAMESETTINGS: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on gamepad Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_GAMESETTING_LABELS-1 ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + break; + default: + break; + } + break; + } + case GUI_MSG_CONTROLLER_LEFT: + case GUI_MSG_CONTROLLER_RIGHT: + { + // Basically a wrap around system when you go left or right. + switch(m_currentPage) + { + case MENU_PAGE_CHARACTERCONTROLS: + { + int menuItem = m_pMenu->GetSelection(); + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_CHARACTERCONTROL_LABELS ) + { + m_pMenu->Reset(menuItem+NUM_CHARACTERCONTROL_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else // On Map 2 + { + m_pMenu->Reset(menuItem-NUM_CHARACTERCONTROL_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + case MENU_PAGE_VEHICLECONTROLS: + { + int menuItem = m_pMenu->GetSelection(); + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_VEHICLECONTROL_LABELS ) + { + m_pMenu->Reset(menuItem+NUM_VEHICLECONTROL_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else // On Map 2 + { + m_pMenu->Reset(menuItem-NUM_VEHICLECONTROL_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + default: + break; + } + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + // guiscreencontrollerwin32 is a circumvention of normal ENTER/EXIT + // WINDOW front-end scheme. Since we are disabling the mouse + // each time a selection has been made, we need to re-enable + // it for this situation, when you transit from some screen to + // one of these screens, so the mouse continues to function normally. + // + GetInputManager()->GetFEMouse()->SetSelectable( true ); + + switch( m_currentPage ) + { + case MENU_PAGE_MAIN: + { + switch( param1 ) + { + case MENU_ITEM_CHARACTERCONTROLS: + { + GetInputManager()->GetFEMouse()->SetClickStopMode( true ); + SetPageVisiblility( szMainControllerPage, false ); + SetPageVisiblility( szCCPage, true ); + m_currentPage = MENU_PAGE_CHARACTERCONTROLS; + break; + } + case MENU_ITEM_VEHICLECONTROLS: + { + GetInputManager()->GetFEMouse()->SetClickStopMode( true ); + SetPageVisiblility( szMainControllerPage, false ); + SetPageVisiblility( szVCPage, true ); + m_currentPage = MENU_PAGE_VEHICLECONTROLS; + break; + } + case MENU_ITEM_GAMESETTINGS: + { + SetPageVisiblility( szMainControllerPage, false ); + SetPageVisiblility( szGSPage, true ); + m_currentPage = MENU_PAGE_GAMESETTINGS; + break; + } + case MENU_ITEM_RESTOREALLDEFAULTS: + { + rAssert( m_guiManager ); + GetInputManager()->GetFEMouse()->SetSelectable( true ); + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_RESTOREALLDEFAULTS, this ); + break; + } + default: + { + break; + } + } + } break; + case MENU_PAGE_CHARACTERCONTROLS: + { + // if we're on Map 1 or Map 2 + if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] ) + { + int menuItem = param1; + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_CHARACTERCONTROL_LABELS ) + { + // We know what map it is so just convert this into a value between 0 - NUM_CHARACTERCONTROL_LABELS-1 + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage]; + RemapButton( MAP_PRIMARY, menuItem ); + break; + } + else // On Map 2 + { + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_CHARACTERCONTROL_LABELS; + RemapButton( MAP_SECONDARY, menuItem ); + break; + } + } + } break; + case MENU_PAGE_VEHICLECONTROLS: + { + if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] ) + { + int menuItem = param1; + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_VEHICLECONTROL_LABELS ) + { + // We know what map it is so just convert this into a value between 0 - NUM_CHARACTERCONTROL_LABELS-1 + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage]; + RemapButton( MAP_PRIMARY, menuItem ); + break; + } + else // On Map 2 + { + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_VEHICLECONTROL_LABELS; + RemapButton( MAP_SECONDARY, menuItem ); + break; + } + } + } break; + default: break; + } + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + // mapping an input, so any key to trigger this event should be ignored. + if( !m_bDisableBack ) + { + switch( m_currentPage ) + { + case MENU_PAGE_CHARACTERCONTROLS: + GetInputManager()->GetFEMouse()->SetClickStopMode( false ); + SetPageVisiblility( szCCPage, false ); + SetPageVisiblility( szMainControllerPage, true ); + m_currentPage = MENU_PAGE_MAIN; + bRelayMessage = false; + break; + case MENU_PAGE_VEHICLECONTROLS: + GetInputManager()->GetFEMouse()->SetClickStopMode( false ); + SetPageVisiblility( szVCPage, false ); + SetPageVisiblility( szMainControllerPage, true ); + m_currentPage = MENU_PAGE_MAIN; + bRelayMessage = false; + break; + case MENU_PAGE_GAMESETTINGS: + SetPageVisiblility( szGSPage, false ); + SetPageVisiblility( szMainControllerPage, true ); + m_currentPage = MENU_PAGE_MAIN; + bRelayMessage = false; + break; + + default: + this->StartTransitionAnimation( 560, 590 ); + bRelayMessage = true; + } + } + else + { + m_bDisableBack = false; + bRelayMessage = false; + } + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL && !m_bMapInput ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + if( bRelayMessage ) + CGuiScreen::HandleMessage( message, param1, param2 ); + else + bRelayMessage = true; +} + +//=========================================================================== +// CGuiScreen::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreenController::CheckCursorAgainstHotspots( float x, float y ) +{ + if( m_bMapInput ) return HOTSPOT_NONE; + else return CGuiScreen::CheckCursorAgainstHotspots( x, y ); +} + +void CGuiScreenController::RemapButton( eControllerColumn column, int menuItem ) +{ + switch(m_currentPage) + { + case MENU_PAGE_CHARACTERCONTROLS: + m_currentTextLabel = m_pCCLabels[column][menuItem]; + break; + case MENU_PAGE_VEHICLECONTROLS: + m_currentTextLabel = m_pVCLabels[column][menuItem]; + break; + default: + break; + } + if( m_currentTextLabel ) + m_currentTextLabel->SetColour(DEFAULT_INPUTMAPPED_ITEM_COLOUR); + + GetInputManager()->GetController(m_currentControllerID)->RemapButton( column, + GetVirtualKey(m_currentPage, menuItem), + this ); + GetInputManager()->GetFEMouse()->SetSelectable( false ); + m_bMapInput = true; +} + +//=========================================================================== +// CGuiScreenController::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitIntro() +{ + // Init the page labels. + InitPageLabels(MENU_PAGE_CHARACTERCONTROLS); + InitPageLabels(MENU_PAGE_VEHICLECONTROLS); + + UserController* pController = GetInputManager()->GetController( m_currentControllerID ); + GuiMenuItem* pMenuItem = NULL; + // This is the real menuItem index. + int menuItem = m_menuGroupStartIndex[MENU_PAGE_GAMESETTINGS]; + + // This is relative to the enum section for GAME SETTINGS. + int relMenuItem = m_menuGroupStartIndex[MENU_PAGE_GAMESETTINGS] - + NUM_CHARACTERCONTROL_LABELS - + NUM_VEHICLECONTROL_LABELS; + + rAssert( m_pMenu ); + + for( int i = 0; i < NUM_GAMESETTING_LABELS; i++, menuItem++, relMenuItem++ ) + { + switch( relMenuItem ) + { + case GS_MOUSELOOK: + { + m_pMenu->SetSelectionValue( menuItem, pController->IsMouseLookOn() == PROMPT_YES ); + } + break; + case GS_MOUSESENSITIVITY_X: + { + pMenuItem = m_pMenu->GetMenuItem( menuItem ); + rAssert( pMenuItem ); + pMenuItem->m_slider.SetValue( pController->GetMouseSensitivityX() ); + } + break; + case GS_MOUSESENSITIVITY_Y: + { + pMenuItem = m_pMenu->GetMenuItem( menuItem ); + rAssert( pMenuItem ); + pMenuItem->m_slider.SetValue( pController->GetMouseSensitivityY() ); + } + break; + case GS_INVERTMOUSEX: + { + m_pMenu->SetSelectionValue( menuItem, pController->IsMouseXInverted() == PROMPT_YES ); + } + break; + case GS_INVERTMOUSEY: + { + m_pMenu->SetSelectionValue( menuItem, pController->IsMouseYInverted() == PROMPT_YES ); + } + break; + case GS_FORCEFEEDBACK: + { + m_pMenu->SetSelectionValue( menuItem, pController->IsForceFeedbackOn() == PROMPT_YES ); + } + break; + case GS_WHEELSENSITIVITY: + { + pMenuItem = m_pMenu->GetMenuItem( menuItem ); + rAssert( pMenuItem ); + pMenuItem->m_slider.SetValue( pController->GetWheelSensitivityX() ); + } + break; + default: + break; + } + } +} + + +//=========================================================================== +// CGuiScreenController::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenController::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitOutro() +{ + GetInputManager()->GetFEMouse()->SetClickStopMode( false ); + + // Save the new controller mappings to the config file. + GetGameConfigManager()->SaveConfigFile(); +} + +//=========================================================================== +// CGuiScreenController::OnButtonMapped +//=========================================================================== +// Description: Gets called back by the UserController when a button is +// mapped. +// +// Constraints: None. +// +// Parameters: szNewInput - The new input that just got mapped. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::OnButtonMapped( const char* szNewInput, eControllerType cont, int num_dirs, eDirectionType direction ) +{ + char szText[255]; + memset( szText, 0, sizeof( szText) ); + + if( !szNewInput ) //user cancelled the mapper event. + { + m_bDisableBack = true; + } + else + { + // Reset flags we changed. + if( m_currentTextLabel ) + m_currentTextLabel->SetColour(DEFAULT_SELECTED_ITEM_COLOUR); + + strcpy( szText, szNewInput ); + GetAppropriateInputName( szText, cont, direction, num_dirs ); + + //Update the page labels. + UpdatePageLabels( m_currentPage, szText ); + + //Disable the tutorials if controls are changed. + GetInputManager()->GetController(0)->SetTutorialDisabled( true ); + GetTutorialManager()->EnableTutorialMode( false ); + } + + GetInputManager()->GetFEMouse()->SetSelectable( true ); + m_bMapInput = false; + m_currentTextLabel = NULL; +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- +void CGuiScreenController::UpdatePageLabels( eMenuPages page, const char* szNewInput ) +{ + switch( page ) + { + case MENU_PAGE_CHARACTERCONTROLS: + if( szNewInput ) + { + //Search for this text in the array of texts to see if it already exists. + for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ ) + { + for( int itemCount = 0; itemCount < NUM_CHARACTERCONTROL_LABELS; itemCount++ ) + { + UnicodeString uniStrTemp = m_pCCLabels[mapCount][itemCount]->GetString(); + char tempStr[255]; + memset( tempStr, 0, sizeof( tempStr ) ); + uniStrTemp.MakeAscii( tempStr, uniStrTemp.Length() + 1 ); + if( strcmp( szNewInput, tempStr ) == 0 ) + { + m_pCCLabels[mapCount][itemCount]->SetString(0, szNotAssigned); + break; + } + } + } + } + + break; + case MENU_PAGE_VEHICLECONTROLS: + if( szNewInput ) + { + //Search for this text in the array of texts to see if it already exists. + for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ ) + { + for( int itemCount = 0; itemCount < NUM_VEHICLECONTROL_LABELS; itemCount++ ) + { + UnicodeString uniStrTemp = m_pVCLabels[mapCount][itemCount]->GetString(); + char tempStr[255]; + memset( tempStr, 0, sizeof( tempStr ) ); + uniStrTemp.MakeAscii( tempStr, uniStrTemp.Length() + 1 ); + if( strcmp( szNewInput, tempStr ) == 0 ) + { + m_pVCLabels[mapCount][itemCount]->SetString(0, szNotAssigned); + break; + } + } + } + } + + break; + default: + break; + } + if( m_currentTextLabel ) + m_currentTextLabel->SetString(0, szNewInput); +} + +void CGuiScreenController::InitPageLabels( eMenuPages page ) +{ + UserController* pController = GetInputManager()->GetController(m_currentControllerID); + + switch( page ) + { + case MENU_PAGE_CHARACTERCONTROLS: + { + // Go through the elements and set the maps. + for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ ) + { + eControllerType controllerType; + int ndirections; + eDirectionType dir; + + for( int i = 0; i < NUM_CONTROLLERTYPES; i++ ) + { + for( int ccItem = 0; ccItem < NUM_CHARACTERCONTROL_LABELS; ccItem++ ) + { + const char* szName = pController->GetMap( mapCount, + GetVirtualKey(MENU_PAGE_CHARACTERCONTROLS,ccItem), + ndirections, controllerType, dir ); + if( szName ) + { + char szText[255]; + memset( szText, 0, sizeof( szText) ); + + strcpy( szText, szName ); + GetAppropriateInputName( szText, controllerType, dir, ndirections ); + m_pCCLabels[mapCount][ccItem]->SetString(0, szText); + } + else + { + m_pCCLabels[mapCount][ccItem]->SetString(0, szNotAssigned); + } + } + } + } + } break; + case MENU_PAGE_VEHICLECONTROLS: + { + // Go through the elements and set the maps. + for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ ) + { + eControllerType controllerType; + int ndirections; + eDirectionType dir; + + for( int i = 0; i < NUM_CONTROLLERTYPES; i++ ) + { + for( int ccItem = 0; ccItem < NUM_VEHICLECONTROL_LABELS; ccItem++ ) + { + const char* szName = pController->GetMap( mapCount, + GetVirtualKey(MENU_PAGE_VEHICLECONTROLS,ccItem), + ndirections, controllerType, dir ); + if( szName ) + { + char szText[255]; + memset( szText, 0, sizeof( szText) ); + + strcpy( szText, szName ); + GetAppropriateInputName( szText, controllerType, dir, ndirections ); + m_pVCLabels[mapCount][ccItem]->SetString(0, szText); + } + else + { + m_pVCLabels[mapCount][ccItem]->SetString(0, szNotAssigned); + } + } + } + } + } break; + default: + break; + } + +} + +void CGuiScreenController::SetGroups( Scrooby::Text** pLabels, + int numMenuItems, + const char* strPage, + char* strGroup, + char* szLabel, + int attributes ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage ); + rAssert( pPage ); + + + // if this is a controller page set the start index of its menu items. + if( m_numControllerGroups < NUM_MENU_PAGES ) + { + if( strcmp( strGroup, "Map1" ) == 0 || strcmp( strPage, szGSPage ) == 0 ) + { + m_menuGroupStartIndex[m_numControllerGroups++] = m_pMenu->GetNumItems(); + } + } + + // Add main menu items + Scrooby::Group* pMenuGroup = pPage->GetGroup( strGroup ); + for( int itemCount = 0; itemCount < numMenuItems; itemCount++ ) + { + char objectName[ 32 ]; + sprintf( objectName, "%s%02d", szLabel, itemCount ); + Scrooby::Text* pMenuItemText = pMenuGroup->GetText( objectName ); + if( pMenuItemText != NULL ) + { + pMenuItemText->SetTextMode( Scrooby::TEXT_WRAP ); + + char itemName[32]; + sprintf( itemName, "%s%02d_Value", szLabel, itemCount ); + Scrooby::Text* pTextValue = pMenuGroup->GetText( itemName ); + + sprintf( itemName, "%s%02d_ArrowL", szLabel, itemCount ); + Scrooby::Sprite* pLArrow = pMenuGroup->GetSprite( itemName ); + + sprintf( itemName, "%s%02d_ArrowR", szLabel, itemCount ); + Scrooby::Sprite* pRArrow = pMenuGroup->GetSprite( itemName ); + + sprintf( itemName, "%s%02d_Slider", szLabel, itemCount ); + Scrooby::Sprite* pSlider = pMenuGroup->GetSprite( itemName ); + + GuiMenuItem* pMenuItem = m_pMenu->AddMenuItem( pMenuItemText, + pTextValue, + NULL, + pSlider, + pLArrow, + pRArrow, + attributes ); + pLabels[itemCount] = pMenuItemText; + + if( pSlider ) + pMenuItem->m_slider.m_type = Slider::HORIZONTAL_SLIDER_ABOUT_CENTER; + } + else + { + break; + } + } +} + +void CGuiScreenController::SetPageVisiblility( const char* strPage, bool bVisible ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage ); + rAssert( pPage ); + pPage->GetLayerByIndex( 0 )->SetVisible( bVisible ); + + //if it is any of our pages, set all their menu items to bVisible. + if( strcmp( strPage, szMainControllerPage ) == 0 ) + { + for( int i = 0; i < NUM_MAINMENU_LABELS; i++ ) + m_pMenuLabels[i]->SetVisible( bVisible ); + if( bVisible ) + m_pMenu->Reset( MENU_ITEM_CHARACTERCONTROLS ); + } + else if( strcmp( strPage, szGSPage ) == 0 ) + { + for( int i = 0; i < NUM_GAMESETTING_LABELS; i++ ) + m_pMSLabels[i]->SetVisible( bVisible ); + if( bVisible ) + m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_GAMESETTINGS] ); + } + else if( strcmp( strPage, szCCPage ) == 0 ) + { + for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ ) + for( int labelCount = 0; labelCount < NUM_CHARACTERCONTROL_LABELS; labelCount++ ) + m_pCCLabels[columnCount][labelCount]->SetVisible( bVisible ); + if( bVisible ) + m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_CHARACTERCONTROLS] ); + } + else if( strcmp( strPage, szVCPage ) == 0 ) + { + for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ ) + for( int labelCount = 0; labelCount < NUM_VEHICLECONTROL_LABELS; labelCount++ ) + m_pVCLabels[columnCount][labelCount]->SetVisible( bVisible ); + if( bVisible ) + m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_VEHICLECONTROLS] ); + } +} + +int CGuiScreenController::GetVirtualKey( eMenuPages page, int menuItem ) +{ + // We have to start the menuitem off at the correct index. + // This is simple, just add the menuitem with the correct start index. + switch(page) + { + case MENU_PAGE_CHARACTERCONTROLS: + menuItem += CC_MOVEUP; + break; + case MENU_PAGE_VEHICLECONTROLS: + menuItem += VC_ACCELERATE; + break; + default: + break; + } + + switch(menuItem) + { + case CC_MOVEUP: + return InputManager::MoveUp; + case CC_MOVEDOWN: + return InputManager::MoveDown; + case CC_MOVELEFT: + return InputManager::MoveLeft; + case CC_MOVERIGHT: + return InputManager::MoveRight; + case CC_ATTACK: + return InputManager::Attack; + case CC_JUMP: + return InputManager::Jump; + case CC_SPRINT: + return InputManager::Sprint; + case CC_ACTION: + return InputManager::DoAction; + case CC_CAMERALEFT: + return InputManager::CameraLeft; + case CC_CAMERARIGHT: + return InputManager::CameraRight; + case CC_CAMERAMOVEIN: + return InputManager::CameraMoveIn; + case CC_CAMERAMOVEOUT: + return InputManager::CameraMoveOut; + case CC_LOOKUP: + return InputManager::CameraLookUp; + case CC_ZOOM: + return InputManager::CameraZoom; + + case VC_ACCELERATE: + return InputManager::Accelerate; + case VC_REVERSE: + return InputManager::Reverse; + case VC_STEERLEFT: + return InputManager::SteerLeft; + case VC_STEERRIGHT: + return InputManager::SteerRight; + case VC_EBRAKE: + return InputManager::HandBrake; + case VC_ACTION: + return InputManager::GetOutCar; + case VC_HORN: + return InputManager::Horn; + case VC_RESET: + return InputManager::ResetCar; + case VC_LOOKLEFT: + return InputManager::CameraCarLeft; + case VC_LOOKRIGHT: + return InputManager::CameraCarRight; + case VC_LOOKUP: + return InputManager::CameraCarLookUp; + case VC_LOOKBACK: + return InputManager::CameraCarLookBack; + case VC_CHANGECAMERA: + return InputManager::CameraToggle; + default: + return 0; + } +} + +void CGuiScreenController::GetAppropriateInputName( char* szInputName, + eControllerType controllerType, + eDirectionType direction, + int numDirections ) +{ + char szText[255]; + memset( szText, 0, sizeof( szText) ); + + if( szInputName ) + { + // Do some hacky special casing here. + // Only done for the keyboard atm. + switch( controllerType ) + { + case KEYBOARD: + { + // Special cases. + if( strcmp( szInputName, "Right Shift" ) == 0 ) + strcpy( szInputName, "R. Shift" ); + else if( strcmp( szInputName, "Left Shift" ) == 0 ) + strcpy( szInputName, "L. Shift" ); + } + + break; + } + // truncate the name to the max allowed letters. + if( strlen(szInputName) > MAX_INPUTNAME_LENGTH ) + { + szInputName[MAX_INPUTNAME_LENGTH-1] = '\0'; + } + switch( controllerType ) + { + case GAMEPAD: + case STEERINGWHEEL: + { + switch( numDirections ) + { + case 2: + switch( direction ) + { + case DIR_UP: + strcat( szInputName, " +"); + break; + case DIR_DOWN: + strcat( szInputName, " -"); + break; + default: + break; + } + break; + case 4: // It is a POV hat... + switch( direction ) + { + case DIR_UP: + strcpy( szInputName,"POV Up" ); + break; + case DIR_DOWN: + strcpy( szInputName,"POV Down" ); + break; + case DIR_LEFT: + strcpy( szInputName,"POV Left" ); + break; + case DIR_RIGHT: + strcpy( szInputName,"POV Right" ); + break; + } + break; + } + + switch( controllerType ) + { + case GAMEPAD: + sprintf( szText,"J %s", szInputName ); + strcpy( szInputName, szText ); + break; + case STEERINGWHEEL: + sprintf( szText,"S %s", szInputName ); + strcpy( szInputName, szText ); + break; + } + + break; + } + case MOUSE: + { + if( strchr( szInputName, '0' ) ) + strcpy( szInputName,"Left Mouse" ); + else if( strchr( szInputName, '1' ) ) + strcpy( szInputName,"Right Mouse" ); + else if( strchr( szInputName, '2' ) ) + strcpy( szInputName,"Mid Mouse" ); + else if( strchr( szInputName, '3' ) ) + strcpy( szInputName,"Shoulder L" ); + else if( strchr( szInputName, '4' ) ) + strcpy( szInputName,"Shoulder R" ); + else if( strchr( szInputName, '5' ) ) + strcpy( szInputName,"Side Left" ); + else if( strchr( szInputName, '6' ) ) + strcpy( szInputName,"Side Right" ); + } + + break; + default: + break; + } + } +}
\ No newline at end of file diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32.h b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.h new file mode 100644 index 0000000..d90a005 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.h @@ -0,0 +1,163 @@ +/****************************************************************************** + + File: GuiScreenControllerWin32.h + Desc: Interface for the CGuiScreenController class. + + Date: July 31, 2003 + Author: Neil Haran + History: + +*****************************************************************************/ + +#ifndef GUISCREENCONTROLLER_H +#define GUISCREENCONTROLLER_H + +#include <presentation/gui/guiscreen.h> +#include <input/usercontrollerWin32.h> + +class CGuiScreenController : public CGuiScreen, + public ButtonMappedCallback +{ +public: + CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenController(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); + virtual void OnButtonMapped( const char* InputName, eControllerType cont, int num_dirs, eDirectionType direction ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + enum eControllerPromptResponse + { + PROMPT_NO, + PROMPT_YES, + NUM_CONTROLLER_PROMPT_RESPONSES + }; + + enum eControllerColumn + { + MAP_PRIMARY = 0, + MAP_SECONDARY, + NUM_COLUMNS, + }; + + enum eMenuPages + { + MENU_PAGE_MAIN, + MENU_PAGE_CHARACTERCONTROLS, + MENU_PAGE_VEHICLECONTROLS, + MENU_PAGE_GAMESETTINGS, + NUM_MENU_PAGES, + NUM_CONTROLLER_PAGES = NUM_MENU_PAGES - 1, + MENU_PAGE_NONE + }; + + enum eMenuItem + { + // MAIN CONTROLLER MENU ITEMS + MENU_ITEM_CHARACTERCONTROLS = 0, + MENU_ITEM_VEHICLECONTROLS, + MENU_ITEM_GAMESETTINGS, + MENU_ITEM_RESTOREALLDEFAULTS, + MENU_ITEM_NONE, + NUM_MAINMENU_LABELS = MENU_ITEM_NONE, + + // Character Control ITEMS + CC_MOVEUP = MENU_ITEM_NONE, + CC_MOVEDOWN, + CC_MOVELEFT, + CC_MOVERIGHT, + CC_ATTACK, + CC_JUMP, + CC_SPRINT, + CC_ACTION, + CC_CAMERALEFT, + CC_CAMERARIGHT, + CC_CAMERAMOVEIN, + CC_CAMERAMOVEOUT, + CC_ZOOM, + CC_LOOKUP, + CC_NONE, + NUM_CHARACTERCONTROL_LABELS = CC_NONE - MENU_ITEM_NONE, + + // Vehicle Control ITEMS + VC_ACCELERATE = CC_NONE, + VC_REVERSE, + VC_STEERLEFT, + VC_STEERRIGHT, + VC_EBRAKE, + VC_ACTION, + VC_HORN, + VC_RESET, + VC_LOOKLEFT, + VC_LOOKRIGHT, + VC_LOOKUP, + VC_LOOKBACK, + VC_CHANGECAMERA, + + VC_NONE, + NUM_VEHICLECONTROL_LABELS = VC_NONE - CC_NONE, + + // Game Setting Items + GS_MOUSELOOK = VC_NONE, + GS_MOUSESENSITIVITY_X, + GS_MOUSESENSITIVITY_Y, + GS_INVERTMOUSEX, + GS_INVERTMOUSEY, + GS_FORCEFEEDBACK, + GS_WHEELSENSITIVITY, + GS_NONE, + NUM_GAMESETTING_LABELS = GS_NONE - VC_NONE, + + NUM_MENU_ITEMS = NUM_MAINMENU_LABELS + + NUM_CHARACTERCONTROL_LABELS*NUM_COLUMNS + + NUM_VEHICLECONTROL_LABELS*NUM_COLUMNS + + NUM_GAMESETTING_LABELS + }; + +private: + void InitPageLabels( eMenuPages page ); + void UpdatePageLabels( eMenuPages page, const char* szNewInput ); + void SetGroups( Scrooby::Text** pLabels, + int numMenuItems, + const char* strPage, + char* strGroup = "Menu", + char* szLabel = "Label", + int attributes = SELECTION_ENABLED | SELECTABLE | VALUES_WRAPPED ); + + void SetPageVisiblility( const char* strPage, bool bVisible ); + int GetVirtualKey( eMenuPages page, int menuItem ); + void RemapButton( eControllerColumn column, int menuItem ); + void GetAppropriateInputName( char* szInputName, + eControllerType controllerType, + eDirectionType direction, + int numDirections ); + +private: + CGuiMenu* m_pMenu; + Scrooby::Text* m_pMenuLabels[ NUM_MAINMENU_LABELS ]; + Scrooby::Text* m_pCCLabels[ NUM_COLUMNS ][ NUM_CHARACTERCONTROL_LABELS ]; + Scrooby::Text* m_pVCLabels[ NUM_COLUMNS ][ NUM_VEHICLECONTROL_LABELS ]; + Scrooby::Text* m_pMSLabels[ NUM_GAMESETTING_LABELS ]; + Scrooby::Text* m_currentTextLabel; + + // These arrays are for the screen mappings. + eMenuPages m_currentPage; + int m_currentControllerID; + bool m_bMapInput; + bool m_bDisableBack; + int m_menuGroupStartIndex[NUM_MENU_PAGES]; + int m_numControllerGroups; +}; + +#endif diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.cpp b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.cpp new file mode 100644 index 0000000..5309702 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.cpp @@ -0,0 +1,867 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenController +// +// Description: Implementation of the CGuiScreenController class. +// +// Authors: Tony Chu, +// Neil Haran +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreencontrollerWin32.h> +#include <presentation/gui/guimenu.h> + +#include <data/config/gameconfigmanager.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <events/eventmanager.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* szMainControllerPage = "ControllerPC"; +const char* szKeyboardMousePage = "PCKeyboardConfig"; +const char* szGamepadPage = "PCGamepadConfig"; + +const int NUM_DISPLAY_MODES = 2; +extern const char* gVirtualInputs[]; + + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +const tColour DEFAULT_SELECTED_ITEM_COLOUR( 255, 255, 0 ); +const tColour DEFAULT_INPUTMAPPED_ITEM_COLOUR( 255, 0, 0 ); // the same as in guiscreenmemorycard.cpp + + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenController::CGuiScreenController +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenController::CGuiScreenController +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_CONTROLLER ), + m_pMenu( NULL ), + m_currentPage( MENU_PAGE_MAIN ), + m_currentControllerID( 0 ), + m_bMapInput( false ), + m_currentTextLabel(NULL), + m_bDisableBack(false), + m_numControllerGroups(0) +{ + memset( m_menuGroupStartIndex, 0 , sizeof( m_menuGroupStartIndex ) ); + m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Add main menu items + SetSingleItemMenuPage( m_pMenuLabels, NUM_MAINMENU_LABELS, szMainControllerPage, "Menu", "Label", ALL_ATTRIBUTES_ON ); + m_numControllerGroups = 1; // The first page is the MENU_PAGE_MAIN with an index of 0. + + // Add master list items + SetSingleItemMenuPage( m_pKMLabels[MASTER_LIST], NUM_KEYBOARDMOUSE_LABELS, szKeyboardMousePage, "Menu", "Label", ALL_ATTRIBUTES_OFF ); + SetSingleItemMenuPage( m_pGamepadLabels[MASTER_LIST], NUM_GAMEPAD_LABELS, szGamepadPage, "Menu", "Label", ALL_ATTRIBUTES_OFF ); + // Add map items + SetSingleItemMenuPage( m_pKMLabels[MAP_PRIMARY], NUM_KEYBOARDMOUSE_LABELS, szKeyboardMousePage, "Map1", "Map1Label" ); + SetSingleItemMenuPage( m_pKMLabels[MAP_SECONDARY], NUM_KEYBOARDMOUSE_LABELS, szKeyboardMousePage, "Map2", "Map2Label" ); + SetSingleItemMenuPage( m_pGamepadLabels[MAP_PRIMARY], NUM_GAMEPAD_LABELS, szGamepadPage, "Map1", "Map1Label" ); + SetSingleItemMenuPage( m_pGamepadLabels[MAP_SECONDARY], NUM_GAMEPAD_LABELS, szGamepadPage, "Map2", "Map2Label" ); + + + //Turn off the controller page that shows up for the consoles. + SetPageVisiblility( "Controller", false ); + SetPageVisiblility( szMainControllerPage, true ); +} + + +//=========================================================================== +// CGuiScreenController::~CGuiScreenController +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenController::~CGuiScreenController() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenController::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + static bool bRelayMessage = true; + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_UP: + { + // Basically a wrap around system when you reach the top. + // Just jumps to the last element. + switch(m_currentPage) + { + case MENU_PAGE_MAIN: + if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage] ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1)); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + break; + case MENU_PAGE_KM: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on keyboard Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage] ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS-1)); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_KEYBOARDMOUSE_LABELS ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS*2)-1); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + case MENU_PAGE_GAMEPAD: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on gamepad Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage] ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS-1)); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_GAMEPAD_LABELS ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS*2)-1); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + default: + break; + } + break; + } + case GUI_MSG_CONTROLLER_DOWN: + { + // Basically a wrap around system when you reach the bottom. + // Just jumps to the first element. + switch(m_currentPage) + { + case MENU_PAGE_MAIN: + if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1) ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + break; + case MENU_PAGE_KM: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on keyboard Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS-1) ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS*2)-1 ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_KEYBOARDMOUSE_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + case MENU_PAGE_GAMEPAD: + { + int menuItem = m_pMenu->GetSelection(); + // On the first element on gamepad Map 1 + if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS-1) ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS*2)-1 ) + { + m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_GAMEPAD_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + default: + break; + } + break; + } + case GUI_MSG_CONTROLLER_LEFT: + case GUI_MSG_CONTROLLER_RIGHT: + { + // Basically a wrap around system when you go left or right. + switch(m_currentPage) + { + case MENU_PAGE_KM: + { + int menuItem = m_pMenu->GetSelection(); + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_KEYBOARDMOUSE_LABELS ) + { + m_pMenu->Reset(menuItem+NUM_KEYBOARDMOUSE_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else // On Map 2 + { + m_pMenu->Reset(menuItem-NUM_KEYBOARDMOUSE_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + case MENU_PAGE_GAMEPAD: + { + int menuItem = m_pMenu->GetSelection(); + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_GAMEPAD_LABELS ) + { + m_pMenu->Reset(menuItem+NUM_GAMEPAD_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + else // On Map 2 + { + m_pMenu->Reset(menuItem-NUM_GAMEPAD_LABELS); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + return; + } + } + + break; + default: + break; + } + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + switch( m_currentPage ) + { + case MENU_PAGE_MAIN: + { + switch( param1 ) + { + case MENU_ITEM_KEYMOUSECONFIG: + { + GetInputManager()->GetFEMouse()->SetClickStopMode( true ); + SetPageVisiblility( szMainControllerPage, false ); + SetPageVisiblility( szKeyboardMousePage, true ); + m_currentPage = MENU_PAGE_KM; + break; + } + case MENU_ITEM_GAMEPADCONFIG: + { + GetInputManager()->GetFEMouse()->SetClickStopMode( true ); + SetPageVisiblility( szMainControllerPage, false ); + SetPageVisiblility( szGamepadPage, true ); + m_currentPage = MENU_PAGE_GAMEPAD; + break; + } + default: + { + break; + } + } + } break; + case MENU_PAGE_KM: + { + // if we're on Map 1 or Map 2 + if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] ) + { + int menuItem = param1; + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_KEYBOARDMOUSE_LABELS ) + { + // We know what map it is so just convert this into a value between 0 - NUM_KEYBOARDMOUSE_LABELS-1 + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage]; + RemapButton( MAP_PRIMARY, KEYBOARD, menuItem ); + break; + } + else // On Map 2 + { + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_KEYBOARDMOUSE_LABELS; + RemapButton( MAP_SECONDARY, KEYBOARD, menuItem ); + break; + } + } + } break; + case MENU_PAGE_GAMEPAD: + { + if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] ) + { + int menuItem = param1; + // On Map 1 + if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_GAMEPAD_LABELS ) + { + // We know what map it is so just convert this into a value between 0 - NUM_KEYBOARDMOUSE_LABELS-1 + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage]; + RemapButton( MAP_PRIMARY, GAMEPAD, menuItem ); + break; + } + else // On Map 2 + { + menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_GAMEPAD_LABELS; + RemapButton( MAP_SECONDARY, GAMEPAD, menuItem ); + break; + } + } + } break; + default: break; + } + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + // mapping an input, so any key to trigger this event should be ignored. + if( !m_bDisableBack ) + { + switch( m_currentPage ) + { + case MENU_PAGE_KM: + GetInputManager()->GetFEMouse()->SetClickStopMode( false ); + SetPageVisiblility( szKeyboardMousePage, false ); + SetPageVisiblility( szMainControllerPage, true ); + m_currentPage = MENU_PAGE_MAIN; + bRelayMessage = false; + break; + case MENU_PAGE_GAMEPAD: + GetInputManager()->GetFEMouse()->SetClickStopMode( false ); + SetPageVisiblility( szGamepadPage, false ); + SetPageVisiblility( szMainControllerPage, true ); + m_currentPage = MENU_PAGE_MAIN; + bRelayMessage = false; + break; + + default: + this->StartTransitionAnimation( 560, 590 ); + bRelayMessage = true; + } + } + else + { + m_bDisableBack = false; + bRelayMessage = false; + } + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL && !m_bMapInput ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + if( bRelayMessage) + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void CGuiScreenController::RemapButton( eControllerColumn column, eControllerType type, int menuItem ) +{ + switch(m_currentPage) + { + case MENU_PAGE_KM: + m_currentTextLabel = m_pKMLabels[column][menuItem]; + break; + case MENU_PAGE_GAMEPAD: + m_currentTextLabel = m_pGamepadLabels[column][menuItem]; + break; + default: + break; + } + if( m_currentTextLabel ) + m_currentTextLabel->SetColour(DEFAULT_INPUTMAPPED_ITEM_COLOUR); + GetInputManager()->GetController(m_currentControllerID)->RemapButton( type, + (column == MAP_PRIMARY) ? SLOT_PRIMARY : SLOT_SECONDARY, + GetVirtualKey(menuItem), + this ); + GetInputManager()->GetFEMouse()->SetSelectable( false ); + m_bMapInput = true; +} + +//=========================================================================== +// CGuiScreenController::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreenController::CheckCursorAgainstHotspots( float x, float y ) +{ + eFEHotspotType hotSpotType = HOTSPOT_NONE; + CGuiMenu* pCurrentMenu = HasMenu(); + int numMenuItems = 0; + GuiMenuItem* pMenuItem = NULL; + + + if( pCurrentMenu ) + { + numMenuItems = pCurrentMenu->GetNumItems(); + + for( int i = 0; i < numMenuItems; i++ ) + { + bool bIsMenuItemEnabled = pCurrentMenu->IsMenuItemEnabled(i); + pMenuItem = pCurrentMenu->GetMenuItem( i ); + + if( pMenuItem && bIsMenuItemEnabled ) + { + if( pMenuItem->GetItem()->IsVisible() ) + { + // Just tests if the point is in the bounding rect of the sprite. + if( pMenuItem->GetItem()->IsPointInBoundingRect( x, y ) ) + { + //rDebugPrintf( "Cursor is inside Sprite %d rectangle!\n", i ); + pCurrentMenu->HandleMessage( GUI_MSG_MOUSE_OVER, i ); + hotSpotType = HOTSPOT_BUTTON; + + //After taking care of all the events for this menu item, just bail out. + break; + } + } + } + } + } + + return hotSpotType; +} + +void CGuiScreenController::OnButtonMapped( const char* szNewInput ) +{ + if( szNewInput ) + { + if( m_currentTextLabel ) + m_currentTextLabel->SetString(0, szNewInput); + } + else //user cancelled the mapper event. + { + m_bDisableBack = true; + } + + // Reset flags we changed. + if( m_currentTextLabel ) + m_currentTextLabel->SetColour(DEFAULT_SELECTED_ITEM_COLOUR); + + //Update the page labels. + UpdatePageLabels(m_currentPage); + GetInputManager()->GetFEMouse()->SetSelectable( true ); + m_bMapInput = false; + m_currentTextLabel = NULL; +} + +//=========================================================================== +// CGuiScreenController::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitIntro() +{ + // Init the page labels. + UpdatePageLabels(MENU_PAGE_KM); + UpdatePageLabels(MENU_PAGE_GAMEPAD); +} + + +//=========================================================================== +// CGuiScreenController::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenController::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenController::InitOutro() +{ + GetInputManager()->GetFEMouse()->SetClickStopMode( false ); + + // Save the new controller mappings to the config file. + GetGameConfigManager()->SaveConfigFile(); +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void CGuiScreenController::UpdatePageLabels( eMenuPages page ) +{ + UserController* pController = GetInputManager()->GetController(m_currentControllerID); + const char* szNotAssigned = "---"; + switch( page ) + { + case MENU_PAGE_KM: + { + RealController* pKeyBoard = pController->GetRealController( KEYBOARD ); + + int diMap[NUM_MAPS][NUM_KEYBOARDMOUSE_LABELS] = + { + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveUp ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveDown ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveLeft ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveRight ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::CameraFirstPerson ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Attack ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Jump ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Sprint ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::DoAction ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::CameraZoom ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Accelerate ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::HandBrake ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Horn ), + pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::ResetCar ), + + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveUp ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveDown ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveLeft ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveRight ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::CameraFirstPerson ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Attack ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Jump ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Sprint ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::DoAction ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::CameraZoom ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Accelerate ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::HandBrake ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Horn ), + pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::ResetCar ), + }; + + //Input::INVALID_CONTROLLERID + + for( int column = MAP_PRIMARY, mapCount = 0; column < NUM_COLUMNS; column++, mapCount++ ) + { + for( int kmItem = 0; kmItem < NUM_KEYBOARDMOUSE_LABELS; kmItem++ ) + { + RADCONTROLLER pRadController = pKeyBoard->getController(); + IRadControllerInputPoint* pInputPoint = NULL; + const char* szText = szNotAssigned; + int vKey = diMap[mapCount][kmItem]; + if( vKey != Input::INVALID_CONTROLLERID ) + { + pInputPoint = pRadController->GetInputPointByTypeAndIndex("Button", VirtualKeyToIndex[vKey]); + if( pInputPoint ) szText = pInputPoint->GetName(); + } + + m_pKMLabels[column][kmItem]->SetString(0, szText); + } + } + } break; + case MENU_PAGE_GAMEPAD: + { + RealController* pGamepad = pController->GetRealController( GAMEPAD ); + RADCONTROLLER pRadController = pGamepad->getController(); + if( pGamepad && pRadController ) + { + int diMap[NUM_MAPS][NUM_GAMEPAD_LABELS] = + { + pGamepad->GetMap( SLOT_PRIMARY, InputManager::CameraFirstPerson ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::Attack ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::Jump ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::Sprint ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::DoAction ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::CameraZoom ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::Accelerate ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::HandBrake ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::Horn ), + pGamepad->GetMap( SLOT_PRIMARY, InputManager::ResetCar ), + + pGamepad->GetMap( SLOT_SECONDARY, InputManager::CameraFirstPerson ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::Attack ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::Jump ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::Sprint ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::DoAction ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::CameraZoom ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::Accelerate ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::HandBrake ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::Horn ), + pGamepad->GetMap( SLOT_SECONDARY, InputManager::ResetCar ), + }; + + //Input::INVALID_CONTROLLERID + + for( int column = MAP_PRIMARY, mapCount = 0; column < NUM_COLUMNS; column++, mapCount++ ) + { + for( int gamepadItem = 0; gamepadItem < NUM_GAMEPAD_LABELS; gamepadItem++ ) + { + IRadControllerInputPoint* pInputPoint = NULL; + const char* szText = szNotAssigned; + int vKey = diMap[mapCount][gamepadItem]; + if( vKey != Input::INVALID_CONTROLLERID ) + { + pInputPoint = pRadController->GetInputPointByTypeAndIndex("Button", VirtualJoyKeyToIndex[vKey]); + if( pInputPoint ) szText = pInputPoint->GetName(); + } + + m_pGamepadLabels[column][gamepadItem]->SetString(0, szText); + } + } + } + else + { + m_pMenu->SetMenuItemEnabled( MENU_ITEM_GAMEPADCONFIG, false ); + } + } break; + default: + break; + } + +} + +void CGuiScreenController::SetSingleItemMenuPage( Scrooby::Text** pLabels, + int numMenuItems, + const char* strPage, + char* strGroup, + char* szLabel, + int attributes ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage ); + rAssert( pPage ); + + + // if this is a controller page set the start index of its menu items. + if( !strcmp( strGroup, "Map1" ) && m_numControllerGroups < NUM_MENU_PAGES ) + { + m_menuGroupStartIndex[m_numControllerGroups++] = m_pMenu->GetNumItems(); + } + + // Add main menu items + Scrooby::Group* pMenuGroup = pPage->GetGroup( strGroup ); + for( int itemCount = 0; itemCount < numMenuItems; itemCount++ ) + { + char objectName[ 32 ]; + sprintf( objectName, "%s%02d", szLabel, itemCount ); + Scrooby::Text* pMenuItemText = pMenuGroup->GetText( objectName ); + if( pMenuItemText != NULL ) + { + pMenuItemText->SetTextMode( Scrooby::TEXT_WRAP ); + m_pMenu->AddMenuItem( pMenuItemText, + NULL, + NULL, + NULL, + NULL, + NULL, + attributes ); + pLabels[itemCount] = pMenuItemText; + } + else + { + break; + } + } +} + +void CGuiScreenController::SetPageVisiblility( const char* strPage, bool bVisible ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage ); + rAssert( pPage ); + pPage->GetLayerByIndex( 0 )->SetVisible( bVisible ); + + //if it is any of our pages, set all their menu items to bVisible. + if( !strcmp( strPage, szMainControllerPage ) ) + { + for( int i = 0; i < NUM_MAINMENU_LABELS; i++ ) + m_pMenuLabels[i]->SetVisible( bVisible ); + if( bVisible ) + m_pMenu->Reset( MENU_ITEM_KEYMOUSECONFIG ); + } + else if( !strcmp( strPage, szKeyboardMousePage ) ) + { + for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ ) + for( int labelCount = 0; labelCount < NUM_KEYBOARDMOUSE_LABELS; labelCount++ ) + m_pKMLabels[columnCount][labelCount]->SetVisible( bVisible ); + if( bVisible ) + m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_KM] ); + } + else if( !strcmp( strPage, szGamepadPage ) ) + { + for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ ) + for( int labelCount = 0; labelCount < NUM_GAMEPAD_LABELS; labelCount++ ) + m_pGamepadLabels[columnCount][labelCount]->SetVisible( bVisible ); + if( bVisible ) + m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_GAMEPAD] ); + } +} + +int CGuiScreenController::GetVirtualKey( int menuItem ) +{ + // We have to start the menuitem off at the correct index. + // This is simple, just add the menuitem with the correct start index. + switch(m_currentPage) + { + case MENU_PAGE_KM: + menuItem += KM_MOVEUP; + break; + case MENU_PAGE_GAMEPAD: + menuItem += GAMEPAD_FIRSTPERSON; + break; + default: + break; + } + + switch(menuItem) + { + case KM_MOVEUP: + return InputManager::MoveUp; + case KM_MOVEDOWN: + return InputManager::MoveDown; + case KM_MOVELEFT: + return InputManager::MoveLeft; + case KM_MOVERIGHT: + return InputManager::MoveRight; + case KM_FIRSTPERSON: + case GAMEPAD_FIRSTPERSON: + return InputManager::CameraFirstPerson; + case KM_ATTACK: + case GAMEPAD_ATTACK: + return InputManager::Attack; + case KM_JUMP: + case GAMEPAD_JUMP: + return InputManager::Jump; + case KM_SPRINT: + case GAMEPAD_SPRINT: + return InputManager::Sprint; + case KM_DOACTION: + case GAMEPAD_DOACTION: + return InputManager::DoAction; + case KM_CAMERAZOOM: + case GAMEPAD_CAMERAZOOM: + return InputManager::CameraZoom; + case KM_ACCELERATE: + case GAMEPAD_ACCELERATE: + return InputManager::Accelerate; + case KM_EBRAKE: + case GAMEPAD_EBRAKE: + return InputManager::HandBrake; + case KM_HORN: + case GAMEPAD_HORN: + return InputManager::Horn; + case KM_RESETCAR: + case GAMEPAD_RESETCAR: + return InputManager::ResetCar; + default: + return 0; + } +}
\ No newline at end of file diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.h b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.h new file mode 100644 index 0000000..2328afc --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.h @@ -0,0 +1,147 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenController +// +// Description: +// +// +// Authors: Tony Chu, +// Neil Haran +// +// Revisions Date Author Revision +// 2002/07/30 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENCONTROLLER_H +#define GUISCREENCONTROLLER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <input/usercontrollerWin32.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenController : public CGuiScreen, + public ButtonMappedCallback +{ +public: + CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenController(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); + virtual void OnButtonMapped( const char* szNewInput ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + enum eControllerColumn + { + MASTER_LIST = 0, + MAP_PRIMARY, + MAP_SECONDARY, + NUM_COLUMNS, + NUM_MAPS = NUM_COLUMNS - 1 + }; + + enum eMenuPages + { + MENU_PAGE_MAIN, + MENU_PAGE_KM, + MENU_PAGE_GAMEPAD, + NUM_MENU_PAGES, + NUM_CONTROLLER_PAGES = NUM_MENU_PAGES - 1, + MENU_PAGE_NONE + }; + + enum eMenuItem + { + // MAIN CONTROLLER MENU ITEMS + MENU_ITEM_KEYMOUSECONFIG = 0, + MENU_ITEM_GAMEPADCONFIG, + MENU_ITEM_NONE, + NUM_MAINMENU_LABELS = MENU_ITEM_NONE, + + // KEYBOARD/MOUSE ITEMS + KM_MOVEUP = MENU_ITEM_NONE, + KM_MOVEDOWN, + KM_MOVELEFT, + KM_MOVERIGHT, + KM_FIRSTPERSON, + KM_ATTACK, + KM_JUMP, + KM_SPRINT, + KM_DOACTION, + KM_CAMERAZOOM, + KM_ACCELERATE, + KM_EBRAKE, + KM_HORN, + KM_RESETCAR, + KM_NONE, + NUM_KEYBOARDMOUSE_LABELS = KM_NONE - MENU_ITEM_NONE, + + // GAMEPAD ITEMS + GAMEPAD_FIRSTPERSON = KM_NONE, + GAMEPAD_ATTACK, + GAMEPAD_JUMP, + GAMEPAD_SPRINT, + GAMEPAD_DOACTION, + GAMEPAD_CAMERAZOOM, + GAMEPAD_ACCELERATE, + GAMEPAD_EBRAKE, + GAMEPAD_HORN, + GAMEPAD_RESETCAR, + GAMEPAD_NONE, + NUM_GAMEPAD_LABELS = GAMEPAD_NONE - KM_NONE, + + NUM_LABELS = NUM_MAINMENU_LABELS + NUM_KEYBOARDMOUSE_LABELS + NUM_GAMEPAD_LABELS, + NUM_MENU_ITEMS = NUM_MAINMENU_LABELS + NUM_KEYBOARDMOUSE_LABELS*NUM_COLUMNS + NUM_GAMEPAD_LABELS*NUM_COLUMNS + }; + +private: + void UpdatePageLabels( eMenuPages page ); + void SetSingleItemMenuPage( Scrooby::Text** pLabels, + int numMenuItems, + const char* strPage, + char* strGroup = "Menu", + char* szLabel = "Label", + int attributes = SELECTION_ENABLED | SELECTABLE | VALUES_WRAPPED ); + + void SetPageVisiblility( const char* strPage, bool bVisible ); + int GetVirtualKey( int menuItem ); + void RemapButton( eControllerColumn column, eControllerType type, int menuItem ); + +private: + CGuiMenu* m_pMenu; + Scrooby::Text* m_pMenuLabels[ NUM_MAINMENU_LABELS ]; + Scrooby::Text* m_pKMLabels[ NUM_COLUMNS ][ NUM_KEYBOARDMOUSE_LABELS ]; + Scrooby::Text* m_pGamepadLabels[ NUM_COLUMNS ][ NUM_GAMEPAD_LABELS ]; + Scrooby::Text* m_currentTextLabel; + + eMenuPages m_currentPage; + int m_currentControllerID; + bool m_bMapInput; + bool m_bDisableBack; + int m_menuGroupStartIndex[NUM_MENU_PAGES]; + int m_numControllerGroups; +}; + +#endif // GUISCREENCONTROLLER_H diff --git a/game/code/presentation/gui/frontend/guiscreendisplay.cpp b/game/code/presentation/gui/frontend/guiscreendisplay.cpp new file mode 100644 index 0000000..6a92fd4 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreendisplay.cpp @@ -0,0 +1,346 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenDisplay +// +// Description: Implementation of the CGuiScreenDisplay class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/06/16 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreendisplay.h> +#include <presentation/gui/guimenu.h> + +#include <data/config/gameconfigmanager.h> +#include <main/win32platform.h> +#include <memory/srrmemory.h> +#include <render/RenderFlow/renderflow.h> + +#include <raddebug.hpp> // Foundation +#include <screen.h> +#include <page.h> +#include <group.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + + +const char* DISPLAY_MENU_ITEMS[] = +{ + "Resolution", + "ColourDepth", + "DisplayMode", + "Gamma", + "ApplyChanges", + + "" +}; + +const float SLIDER_ICON_SCALE = 0.5f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenDisplay::CGuiScreenDisplay +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenDisplay::CGuiScreenDisplay +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_DISPLAY ), + m_pMenu( NULL ), + m_changedGamma( false ) +{ +MEMTRACK_PUSH_GROUP( "CGuiScreenDisplay" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Display" ); + rAssert( pPage != NULL ); + + // Create a menu. + // + m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + char itemName[ 32 ]; + + for( int i = 0; i < MENU_ITEM_GAMMA; i++ ) + { + Scrooby::Group* group = pPage->GetGroup( DISPLAY_MENU_ITEMS[ i ] ); + rAssert( group != NULL ); + + sprintf( itemName, "%s_Value", DISPLAY_MENU_ITEMS[ i ] ); + Scrooby::Text* pTextValue = group->GetText( itemName ); + + sprintf( itemName, "%s_ArrowL", DISPLAY_MENU_ITEMS[ i ] ); + Scrooby::Sprite* pLArrow = group->GetSprite( itemName ); + + sprintf( itemName, "%s_ArrowR", DISPLAY_MENU_ITEMS[ i ] ); + Scrooby::Sprite* pRArrow = group->GetSprite( itemName ); + + m_pMenu->AddMenuItem( group->GetText( DISPLAY_MENU_ITEMS[ i ] ), + pTextValue, + NULL, + NULL, + pLArrow, + pRArrow, + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + } + + // Add the gamma slider + Scrooby::Group* pgroup = pPage->GetGroup( "Gamma" ); + rAssert(pgroup != NULL ); + + Scrooby::Text* pText = pgroup->GetText( "Gamma" ); + + Scrooby::Group* sliderGroup = pgroup->GetGroup( "Gamma_Slider" ); + rAssert( sliderGroup != NULL ); + + sliderGroup->ResetTransformation(); + + m_pMenu->AddMenuItem( pText, + NULL, + NULL, + sliderGroup->GetSprite( "Gamma_Slider" ), + NULL, + NULL, + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + + m_pMenu->GetMenuItem( MENU_ITEM_GAMMA )->m_slider.m_type = Slider::HORIZONTAL_SLIDER_ABOUT_CENTER; + + Scrooby::Sprite* soundOnIcon = pgroup->GetSprite( "Gamma_Icon" ); + soundOnIcon->ScaleAboutCenter( SLIDER_ICON_SCALE ); + + // Add the apply changes button + + pgroup = pPage->GetGroup( "Menu" ); + rAssert( pgroup != NULL ); + + m_pMenu->AddMenuItem( pgroup->GetText( "ApplyChanges" ) ); + +MEMTRACK_POP_GROUP("CGuiScreenDisplay"); +} + + +//=========================================================================== +// CGuiScreenDisplay::~CGuiScreenDisplay +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenDisplay::~CGuiScreenDisplay() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenDisplay::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDisplay::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + switch( param1 ) + { + case MENU_ITEM_APPLY_CHANGES: + { + ApplySettings(); + break; + } + } + break; + } + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + rAssert( m_pMenu ); + GuiMenuItem* currentItem = m_pMenu->GetMenuItem( param1 ); + rAssert( currentItem ); + + switch( param1 ) + { + case MENU_ITEM_GAMMA: + { + float gamma = 2 * currentItem->m_slider.m_value + 0.5f; + GetRenderFlow()->SetGamma( gamma ); + m_changedGamma = true; + + break; + } + } + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenDisplay::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDisplay::InitIntro() +{ + // update settings + // + Win32Platform* plat = Win32Platform::GetInstance(); + + Win32Platform::Resolution res = plat->GetResolution(); + m_pMenu->SetSelectionValue( MENU_ITEM_RESOLUTION, + res ); + + int bpp = plat->GetBPP(); + m_pMenu->SetSelectionValue( MENU_ITEM_COLOUR_DEPTH, + bpp == 16 ? 0: 1 ); + + bool fullscreen = plat->IsFullscreen(); + m_pMenu->SetSelectionValue( MENU_ITEM_DISPLAY_MODE, + fullscreen ? 1 : 0 ); + + GuiMenuItem* menuItem = m_pMenu->GetMenuItem( MENU_ITEM_GAMMA ); + rAssert( menuItem ); + menuItem->m_slider.SetValue( ( GetRenderFlow()->GetGamma() - 0.5f ) / 2.0f ); +} + + +//=========================================================================== +// CGuiScreenDisplay::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDisplay::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenDisplay::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDisplay::InitOutro() +{ + // Save the config if we've changed the gamma settings + if( m_changedGamma ) + { + GetGameConfigManager()->SaveConfigFile(); + m_changedGamma = false; + } +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +//=========================================================================== +// CGuiScreenDisplay::ApplySettings +//=========================================================================== +// Description: Applies the current display settings to teh game. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenDisplay::ApplySettings() +{ + // Retrieve the settings. + // + Win32Platform::Resolution res = static_cast< Win32Platform::Resolution >( m_pMenu->GetSelectionValue( MENU_ITEM_RESOLUTION ) ); + + int bpp = m_pMenu->GetSelectionValue( MENU_ITEM_COLOUR_DEPTH ) ? 32: 16; + + bool fullscreen = m_pMenu->GetSelectionValue( MENU_ITEM_DISPLAY_MODE ) == 1; + + // Set the resolution. + Win32Platform::GetInstance()->SetResolution( res, bpp, fullscreen ); + + // Save the change to the config file. + GetGameConfigManager()->SaveConfigFile(); + m_changedGamma = false; +} diff --git a/game/code/presentation/gui/frontend/guiscreendisplay.h b/game/code/presentation/gui/frontend/guiscreendisplay.h new file mode 100644 index 0000000..8b56a72 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreendisplay.h @@ -0,0 +1,68 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenDisplay +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/06/16 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENDISPLAY_H +#define GUISCREENDISPLAY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenDisplay : public CGuiScreen +{ +public: + CGuiScreenDisplay( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenDisplay(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void ApplySettings(); + +private: + enum eMenuItem + { + MENU_ITEM_RESOLUTION, + MENU_ITEM_COLOUR_DEPTH, + MENU_ITEM_DISPLAY_MODE, + MENU_ITEM_GAMMA, + MENU_ITEM_APPLY_CHANGES, + + NUM_MENU_ITEMS + }; + + CGuiMenu* m_pMenu; + bool m_changedGamma; +}; + +#endif // GUISCREENDISPLAY_H diff --git a/game/code/presentation/gui/frontend/guiscreenloadgame.cpp b/game/code/presentation/gui/frontend/guiscreenloadgame.cpp new file mode 100644 index 0000000..0e49bc4 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenloadgame.cpp @@ -0,0 +1,1034 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLoadGame +// +// Description: Implementation of the CGuiScreenLoadGame class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenloadgame.h> +#include <presentation/gui/frontend/guiscreenmainmenu.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guiscreenprompt.h> + +#include <data/gamedatamanager.h> +#include <data/savegameinfo.h> +#include <data/memcard/memorycardmanager.h> +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +#ifdef RAD_XBOX + char gGameFileName[NUM_GAME_SLOTS][radFileFilenameMax+1]; +#endif + +#ifdef RAD_PS2 + const unsigned int AUTO_LOAD_MINIMUM_DISPLAY_TIME = 5000; // in msec +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLoadGame::CGuiScreenLoadGame +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLoadGame::CGuiScreenLoadGame +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID windowID +) +: CGuiScreen( pScreen, pParent, windowID ), + CGuiScreenLoadSave( pScreen ), + m_pMenu( NULL ), + m_pFullText( NULL ), + m_StatusPromptShown(false) + +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenLoadGame" ); + if( windowID == GUI_SCREEN_ID_LOAD_GAME ) + { + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "GameSlots" ); + rAssert( pPage ); + + // hide full text field + m_pFullText = pPage->GetText( "FullMessage" ); + rAssert( m_pFullText != NULL ); + m_pFullText->SetVisible(false); + m_pFullText->SetTextMode( Scrooby::TEXT_WRAP ); + + // Create a menu. + // + m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_GAME_SLOTS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ ) + { + char objectName[ 32 ]; + sprintf( objectName, "Slot%d", i ); + + m_pMenu->AddMenuItem( pPage->GetText( objectName ) ); + } + } +MEMTRACK_POP_GROUP( "CGUIScreenLoadGame" ); +} + + +//=========================================================================== +// CGuiScreenLoadGame::~CGuiScreenLoadGame +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLoadGame::~CGuiScreenLoadGame() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenLoadGame::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadGame::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if (message == GUI_MSG_MESSAGE_UPDATE) + { + if (m_formatState) + { + m_elapsedFormatTime += param1; + + if (m_elapsedFormatTime > m_minimumFormatTime && m_formatDone) + { + m_StatusPromptShown = true; + if( m_formatResult == Success ) + { + m_guiManager->DisplayPrompt(PROMPT_FORMAT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format success + m_formatState = false; + } + else + { + m_guiManager->DisplayPrompt(PROMPT_FORMAT_FAIL_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format fail + m_formatState = false; + } + } + } + } + else if (message == GUI_MSG_PROMPT_UPDATE) + { + // update so status up to date + GetMemoryCardManager()->Update( param1 ); + if (m_StatusPromptShown==false) { // check for user unplugging memcard if not showing status + int currentDrive = GetMemoryCardManager()->GetCurrentDriveIndex(); + if( !GetMemoryCardManager()->IsCurrentDrivePresent(currentDrive) ) + ReloadScreen(); + } + } + else if( message == GUI_MSG_ON_DISPLAY_MESSAGE ) + { + if (m_operation==LOAD) + { + // start the load game process + // + rAssert( m_currentSlot != -1 ); +#ifdef RAD_XBOX + GetGameDataManager()->LoadGame( m_currentSlot, this, gGameFileName[m_currentSlot] ); +#else + GetGameDataManager()->LoadGame( m_currentSlot, this ); +#endif + } + else + { + FormatCurrentDrive(); + } + } + else if ( message == GUI_MSG_ERROR_PROMPT_RESPONSE ) + { + this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) ); + } + else if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + switch( param1 ) + { + case PROMPT_LOAD_CARD_EMPTY_GC: + case PROMPT_LOAD_CARD_EMPTY_PS2: + case PROMPT_LOAD_CARD_EMPTY_XBOX: + case PROMPT_LOAD_CARD_EMPTY_XBOX_HD: + this->GotoMemoryCardScreen( true ); + break; + + case PROMPT_LOAD_DELETE_CORRUPT_GC: + case PROMPT_LOAD_DELETE_CORRUPT_PS2: + case PROMPT_LOAD_DELETE_CORRUPT_XBOX: + case PROMPT_LOAD_DELETE_CORRUPT_XBOX_HD: + { + if (param2==CGuiMenuPrompt::RESPONSE_NO) + { + this->ReloadScreen(); + } + else if (param2==CGuiMenuPrompt::RESPONSE_YES) + { + // get the filename + char filename[ radFileFilenameMax + 1 ]; +#ifdef RAD_XBOX + strcpy(filename, gGameFileName[m_currentSlot]); +#else + GetGameDataManager()->FormatSavedGameFilename( filename, + sizeof( filename ), + m_currentSlot ); +#endif + radFileError err = GetGameDataManager()->DeleteGame(filename); + if (err==Success) + m_guiManager->DisplayPrompt(PROMPT_DELETE_CORRUPT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this, + PROMPT_TYPE_CONTINUE); + else + m_guiManager->DisplayPrompt(PROMPT_DELETE_CORRUPT_FAIL_GC + PLATFORM_TEXT_INDEX, this, + PROMPT_TYPE_CONTINUE); + + } + + break; + } + case PROMPT_DELETE_CORRUPT_SUCCESS_GC: + case PROMPT_DELETE_CORRUPT_SUCCESS_PS2: + case PROMPT_DELETE_CORRUPT_SUCCESS_XBOX: + + case PROMPT_DELETE_CORRUPT_FAIL_GC: + case PROMPT_DELETE_CORRUPT_FAIL_PS2: + case PROMPT_DELETE_CORRUPT_FAIL_XBOX: + this->ReloadScreen(); + break; + + case PROMPT_FORMAT_CONFIRM2_GC: + case PROMPT_FORMAT_CONFIRM2_PS2: + case PROMPT_FORMAT_CONFIRM2_XBOX: // really format + { + if (param2==CGuiMenuPrompt::RESPONSE_YES) + { + m_operation = FORMAT; + m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this); + } + else + { + this->GotoMemoryCardScreen( true ); + } + + break; + } + case PROMPT_FORMAT_SUCCESS_GC: + case PROMPT_FORMAT_SUCCESS_PS2: + case PROMPT_FORMAT_SUCCESS_XBOX: // format ok + { + this->GotoMemoryCardScreen( true ); + + break; + } + case PROMPT_FORMAT_FAIL_GC: + case PROMPT_FORMAT_FAIL_PS2: + case PROMPT_FORMAT_FAIL_XBOX: // format fail + { + GetMemoryCardManager()->ClearCurrentDrive(); + this->GotoMemoryCardScreen( true ); + + break; + } + case PROMPT_LOAD_CONFIRM_GC: + case PROMPT_LOAD_CONFIRM_PS2: + case PROMPT_LOAD_CONFIRM_XBOX: + { + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { + this->LoadGame(); + } + else + { + rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO ); + + this->ReloadScreen(); + } + + break; + } + + case PROMPT_LOAD_SUCCESSFUL: + { + CGuiScreen* promptScreen = (CGuiScreen*)m_guiManager->FindWindowByID( GUI_SCREEN_ID_GENERIC_PROMPT ); + rAssert( promptScreen ); + promptScreen->StartTransitionAnimation( 230, 260 ); + + // re-init main menu and default to "resume game" selection + // + CGuiScreenMainMenu* pScreen = + static_cast<CGuiScreenMainMenu*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_MAIN_MENU ) ); + rAssert( pScreen != NULL ); + pScreen->InitMenu(); + + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); + + break; + } + + default: + { + // handle normal menu condition, "continue", "retry" + this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) ); + + break; + } + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + m_currentSlot = param1; // // param1 = slot + + SaveGameInfo saveGameInfo; + bool corrupt; + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo, &corrupt ); + + if (corrupt) + { +#ifdef RAD_GAMECUBE + int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_LOADING ); + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE ); + m_operation = LOAD; +#endif +#ifdef RAD_PS2 + rAssertMsg( false, "Corrupted save games should not have been selectable!" ); +#endif +#ifdef RAD_XBOX + // for xbox don't ask to delete just put up a message + int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_LOADING ); + m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE ); +#endif + } + else + { + #ifdef RAD_GAMECUBE + m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_GC, this ); + #endif + + #ifdef RAD_PS2 + m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_PS2, this ); + #endif + + #ifdef RAD_XBOX + m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_XBOX, this ); + #endif + + #ifdef RAD_WIN32 + m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_XBOX, this ); // parallel xbox for now. + #endif + } + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { +#ifdef RAD_XBOX + s_forceGotoMemoryCardScreen = true; + this->GotoMemoryCardScreen(); +#else + this->StartTransitionAnimation( 230, 260 ); +#endif + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + + if( m_ID == GUI_SCREEN_ID_LOAD_GAME ) + { + CGuiScreenLoadSave::HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +void +CGuiScreenLoadGame::OnLoadGameComplete( radFileError errorCode ) +{ + m_lastError = errorCode; + m_StatusPromptShown = true; + + if( errorCode == Success ) + { + m_guiManager->DisplayPrompt( PROMPT_LOAD_SUCCESSFUL, this, PROMPT_TYPE_CONTINUE ); + } + else + { + int errorMessage = GetErrorMessageIndex( errorCode, ERROR_DURING_LOADING ); + +#ifdef RAD_GAMECUBE + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } + case MediaEncodingErr: + case MediaNotFormatted: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT ); + + } + case DataCorrupt: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE ); + + break; + } + default: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY ); + + break; + } + } +#endif // RAD_GAMECUBE + +#ifdef RAD_PS2 + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } +/* + case DataCorrupt: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_YES | ERROR_RESPONSE_NO ); + + break; + } +*/ + default: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE ); + + break; + } + } +#endif // RAD_PS2 + +#ifdef RAD_XBOX + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } + default: + { + if (errorCode==DataCorrupt) // no delete corrupt for xbox loading + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE ); + else + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE ); + + break; + } + } +#endif // RAD_XBOX + +#ifdef RAD_WIN32 + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } + default: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE ); + break; + } + } +#endif // RAD_WIN32 + } +} + + +void +CGuiScreenLoadGame::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ) +{ + switch( response ) + { + case (CGuiMenuPrompt::RESPONSE_CONTINUE): + { + if( m_operation == LOAD ) + { + this->ReloadScreen(); + } + else if( m_operation == FORMAT ) + { + this->ReloadScreen(); + } + else + { + this->GotoMemoryCardScreen( true ); + } + + break; + } + case (CGuiMenuPrompt::RESPONSE_RETRY): + { + if( m_operation == LOAD ) + { + this->LoadGame(); + } + else if( m_operation == FORMAT ) + { + m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this); + } + else + { + this->ReloadScreen(); + } + + break; + } + +#ifdef RAD_GAMECUBE + case (CGuiMenuPrompt::RESPONSE_DELETE): + { + m_guiManager->DisplayPrompt( PROMPT_LOAD_DELETE_CORRUPT_GC, this ); + + break; + } +#endif // RAD_GAMECUBE + +#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 ) + case (CGuiMenuPrompt::RESPONSE_YES): + { + // YES to delete corrupted file + // + char filename[ radFileFilenameMax + 1 ]; +#ifdef RAD_XBOX + strcpy( filename, gGameFileName[ m_currentSlot ] ); +#else + GetGameDataManager()->FormatSavedGameFilename( filename, + sizeof( filename ), + m_currentSlot ); +#endif + radFileError err = GetGameDataManager()->DeleteGame( filename ); + if( err == Success ) + { + m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_SUCCESS_GC + PLATFORM_TEXT_INDEX, + this, PROMPT_TYPE_CONTINUE ); + } + else + { + m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_FAIL_GC + PLATFORM_TEXT_INDEX, + this, PROMPT_TYPE_CONTINUE ); + } + + break; + } + case (CGuiMenuPrompt::RESPONSE_NO): + { + // NO to delete corrupted file + // + this->ReloadScreen(); + + break; + } +#endif // RAD_GAMECUBE || RAD_PS2 + + case (CGuiMenuPrompt::RESPONSE_FORMAT_GC): + case (CGuiMenuPrompt::RESPONSE_FORMAT_XBOX): + case (CGuiMenuPrompt::RESPONSE_FORMAT_PS2): + { + m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this); + + break; + } + default: + { + rTunePrintf( "*** WARNING: Unhandled response for error [%d]!\n", m_lastError ); + rAssert( false ); + + this->ReloadScreen(); + + break; + } + } + + CGuiScreenLoadSave::HandleErrorResponse( response ); +} + +//=========================================================================== +// CGuiScreenLoadGame::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadGame::InitIntro() +{ + bool unformatted = false; + bool file_corrupt = false; + SaveGameInfo saveGameInfo; + m_StatusPromptShown = false; + m_operation = SCREEN_OP_IDLE; + + m_pFullText->SetVisible(false); + + IRadDrive::MediaInfo::MediaState mediaState; + if( s_forceGotoMemoryCardScreen || !GetMemoryCardManager()->IsCurrentDriveReady( true, &unformatted, &mediaState ) ) + { + if (unformatted && !s_forceGotoMemoryCardScreen) + { +#ifdef RAD_GAMECUBE + int errorMessage = GetErrorMessageIndex( mediaState ); + m_guiManager->DisplayErrorPrompt( errorMessage, + this, + ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT ); + + m_numTransitionsPending = -1; // disable all transitions + + return; +#endif + } + else + { + this->GotoMemoryCardScreen(); + m_numTransitionsPending = -1; // disable all transitions + + return; + } + } + + this->UpdateCurrentMemoryDevice(); + + rAssert( m_pMenu ); + m_pMenu->Reset(); + + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + + radDate mostRecentTimestamp; + mostRecentTimestamp.m_Year = 0; + bool has_savegame = false; + bool has_4_saves = false; + + // update all save game slots display info + // + for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ ) + { + bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, i, &saveGameInfo, &file_corrupt ); +// saveGameExists = saveGameExists && saveGameInfo.CheckData(); + + Scrooby::Text* slotText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( slotText != NULL ); + + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + if( saveGameExists ) + { + if (i == NUM_GAME_SLOTS-1) + { + has_4_saves = true; + } + has_savegame = true; + if (file_corrupt) + { + UnicodeString corruptSlot; +#ifdef RAD_XBOX + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) ); +#endif +#ifdef RAD_WIN32 + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) ); +#endif +#ifdef RAD_PS2 + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(PS2)" ) ); +#endif +#ifdef RAD_GAMECUBE + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(GC)" ) ); +#endif + slotText->SetString(0,corruptSlot); + } + else + { + #ifdef RAD_XBOX + strcpy(gGameFileName[i], saveGameInfo.m_displayFilename); // cache the slot filename + #endif + slotText->SetString( 0, saveGameInfo.m_displayFilename ); + } + + // default to slot with most recent saved game file + // + const SaveGameInfoData* pData = saveGameInfo.GetData(); + rAssert( pData != NULL ); + if( SaveGameInfo::CompareTimeStamps( pData->m_timeStamp, mostRecentTimestamp ) > 0 ) + { + memcpy( &mostRecentTimestamp, &pData->m_timeStamp, sizeof( radDate ) ); + + m_pMenu->Reset( i ); + } + } + else + { + UnicodeString emptySlot; + emptySlot.ReadUnicode( GetTextBibleString( "EMPTY_SLOT" ) ); + slotText->SetString( 0, emptySlot ); + } + HeapMgr()->PopHeap(GMA_LEVEL_FE); + + // enable slot selection only if save game exists + // +#ifdef RAD_PS2 + m_pMenu->SetMenuItemEnabled( i, saveGameExists && !file_corrupt ); +#else + m_pMenu->SetMenuItemEnabled( i, saveGameExists ); +#endif // RAD_PS2 + } + + if (has_savegame==false) // no file in card + { + int prompt_id = PROMPT_LOAD_CARD_EMPTY_GC+PLATFORM_TEXT_INDEX; +#ifdef RAD_XBOX + if (GetMemoryCardManager()->GetCurrentDriveIndex()==0) + prompt_id = PROMPT_LOAD_CARD_EMPTY_XBOX_HD; +#endif + m_guiManager->DisplayPrompt(prompt_id,this,PROMPT_TYPE_CONTINUE); + m_numTransitionsPending = -1; // disable all transitions + } + else + { +#ifdef RAD_XBOX + // check if there are more than 4 files on hd + if ( has_4_saves + && GetGameDataManager()->GetSaveGameInfo( currentDrive, NUM_GAME_SLOTS, &saveGameInfo, &file_corrupt ) + ) + { + m_pFullText->SetIndex( 8 ); + m_pFullText->SetVisible(true); + + } +#endif + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + } +} + +//=========================================================================== +// CGuiScreenLoadGame::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadGame::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenLoadGame::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLoadGame::InitOutro() +{ +} + +void +CGuiScreenLoadGame::GotoMemoryCardScreen( bool isFromPrompt ) +{ +#ifdef RAD_WIN32 + if( isFromPrompt ) + { + CGuiScreen* pScreen = static_cast<CGuiScreen*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_GENERIC_PROMPT ) ); + rAssert( pScreen != NULL ); + pScreen->StartTransitionAnimation( 230, 260 ); + } + else + { + this->StartTransitionAnimation( 230, 260 ); + } + + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); +#else + if( isFromPrompt ) + { + s_forceGotoMemoryCardScreen = true; + this->ReloadScreen(); + } + else + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MEMORY_CARD ); + } +#endif // RAD_WIN32 +} + +void CGuiScreenLoadGame::LoadGame() +{ + m_operation = LOAD; + +#ifdef RAD_GAMECUBE + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_GC, this ); +#endif + +#ifdef RAD_PS2 + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_PS2, this ); +#endif + +#ifdef RAD_XBOX + if( m_currentDriveIndex == 0 ) // xbox hard disk + { + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_XBOX_HD, this ); + } + else // xbox memory unit + { + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_XBOX, this ); + } +#endif + +#ifdef RAD_WIN32 + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_PC, this ); +#endif +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + + +//=========================================================================== +// Public Member Functions (for CGuiScreenAutoLoad) +//=========================================================================== + +int CGuiScreenAutoLoad::s_autoLoadGameSlot = -1; + +CGuiScreenAutoLoad::CGuiScreenAutoLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent ) +: CGuiScreenLoadGame( pScreen, pParent, GUI_SCREEN_ID_AUTO_LOAD ) +{ +} + +CGuiScreenAutoLoad::~CGuiScreenAutoLoad() +{ +} + +void +CGuiScreenAutoLoad::OnLoadGameComplete( radFileError errorCode ) +{ + GetGameDataManager()->RestoreDefaultMinimumLoadSaveTime(); + + if( errorCode == Success ) + { + m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED ); + } + else + { + CGuiScreenLoadGame::OnLoadGameComplete( errorCode ); + } +} + +void +CGuiScreenAutoLoad::InitIntro() +{ +} + +void +CGuiScreenAutoLoad::InitRunning() +{ + m_currentDriveIndex = GetMemoryCardManager()->GetCurrentDriveIndex(); + rAssert( m_currentDriveIndex != -1 ); + + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + if( currentDrive != NULL ) + { + rReleasePrintf( "Auto-loading most recent saved game from drive %s\n", + currentDrive->GetDriveName() ); + } + + rAssert( s_autoLoadGameSlot != -1 ); + m_currentSlot = s_autoLoadGameSlot; +#ifdef RAD_XBOX + // for xbox we need to get the filename from slot information first before loading + SaveGameInfo saveGameInfo; + gGameFileName[m_currentSlot][0] = 0; // initialize to empty string + rAssert(m_currentSlot < NUM_GAME_SLOTS); + bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo ); + if( saveGameExists ) // game filename is cached in gGameFileName global + { + strcpy( gGameFileName[m_currentSlot], saveGameInfo.m_displayFilename); + } + +#endif + + this->LoadGame(); +} + +void +CGuiScreenAutoLoad::InitOutro() +{ +} + +void +CGuiScreenAutoLoad::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ) +{ + switch( response ) + { + case (CGuiMenuPrompt::RESPONSE_CONTINUE): + { + m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED ); + + break; + } + case (CGuiMenuPrompt::RESPONSE_RETRY): + { + this->LoadGame(); + + break; + } + default: + { + rTunePrintf( "*** WARNING: Unhandled response for error [%d]!\n", m_lastError ); + rAssert( false ); + + m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED ); + + break; + } + } + + CGuiScreenLoadSave::HandleErrorResponse( response ); +} + +void +CGuiScreenAutoLoad::LoadGame() +{ + m_operation = LOAD; + +#ifdef RAD_GAMECUBE + // TC: GC does not require an auto-loading screen + // +// m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_GC, this ); + GetGameDataManager()->LoadGame( m_currentSlot, this ); + GetGameDataManager()->SetMinimumLoadSaveTime( 0 ); +#endif + +#ifdef RAD_PS2 + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_PS2, this ); + GetGameDataManager()->SetMinimumLoadSaveTime( AUTO_LOAD_MINIMUM_DISPLAY_TIME ); +#endif + +#ifdef RAD_XBOX + if( m_currentDriveIndex == 0 ) // xbox hard disk + { + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_XBOX_HD, this ); + } + else // xbox memory unit + { + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_XBOX, this ); + } +#endif + +#ifdef RAD_WIN32 + rAssert( m_currentDriveIndex == 0 ); + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_PC, this ); +#endif +} + diff --git a/game/code/presentation/gui/frontend/guiscreenloadgame.h b/game/code/presentation/gui/frontend/guiscreenloadgame.h new file mode 100644 index 0000000..f7902f6 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenloadgame.h @@ -0,0 +1,92 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLoadGame +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/30 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLOADGAME_H +#define GUISCREENLOADGAME_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/guiscreenmemorycard.h> +#include <data/gamedatamanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLoadGame : public CGuiScreen, + public CGuiScreenLoadSave, + public GameDataLoadCallback + +{ +public: + CGuiScreenLoadGame( Scrooby::Screen* pScreen, CGuiEntity* pParent, + eGuiWindowID windowID = GUI_SCREEN_ID_LOAD_GAME ); + virtual ~CGuiScreenLoadGame(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + // Implements GameDataLoadCallback + // + virtual void OnLoadGameComplete( radFileError errorCode ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void GotoMemoryCardScreen( bool isFromPrompt = false ); + virtual void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ); + virtual void LoadGame(); + +private: + CGuiMenu* m_pMenu; + Scrooby::Text* m_pFullText; + bool m_StatusPromptShown; +}; + +class CGuiScreenAutoLoad : public CGuiScreenLoadGame +{ +public: + CGuiScreenAutoLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenAutoLoad(); + + virtual void OnLoadGameComplete( radFileError errorCode ); + + static void SetGameSlot( int slot ) { s_autoLoadGameSlot = slot; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + virtual void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ); + virtual void LoadGame(); + +private: + static int s_autoLoadGameSlot; + +}; + +#endif // GUISCREENLOADGAME_H diff --git a/game/code/presentation/gui/frontend/guiscreenmainmenu.cpp b/game/code/presentation/gui/frontend/guiscreenmainmenu.cpp new file mode 100644 index 0000000..405ed42 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmainmenu.cpp @@ -0,0 +1,1649 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMainMenu +// +// Description: Implementation of the CGuiScreenMainMenu class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenmainmenu.h> +#include <presentation/gui/frontend/guiscreenplaymovie.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiscreenmemorycard.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guiscreenprompt.h> + +#include <constants/movienames.h> +#include <data/gamedatamanager.h> +#include <data/persistentworldmanager.h> +#include <events/eventmanager.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> + +#include <p3d/view.hpp> + +#include <raddebug.hpp> // Foundation +#include <radtime.hpp> +#include <radkey.hpp> +#include <radmath/random.hpp> +#include <p3d/anim/multicontroller.hpp> + +#include <stdlib.h> +#include <group.h> +#include <layer.h> +#include <page.h> +#include <pure3dobject.h> +#include <screen.h> +#include <text.h> + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//#define PLAY_GAGS_SEQUENTIALLY +//#define PLAY_ONLY_HOMER_GAGS + +const float FIRST_TIME_FADE_IN_TIME = 500.0f; + +const unsigned int MIN_GAGS_CYCLE_TIME = 15; // in seconds +const unsigned int MAX_GAGS_CYCLE_TIME = 30; // in seconds +const unsigned int GAGS_RANDOM_NUMBER_MODULO = 97; + +const tColour FE_BLUE_SKY_COLOUR( 128, 255, 255 ); + +struct HomerGagAnimation +{ + float startFrame; + float endFrame; +}; + +HomerGagAnimation HOMER_GAG_ANIMATION[] = +{ + { 0.0f, 75.0f }, + { 75.0f, 145.0f }, + { 145.0f, 215.0f }, + { 215.0f, 355.0f }, + { 355.0f, 475.0f }, + + { -1.0f, -1.0f } // dummy terminator +}; + +int NUM_HOMER_GAG_ANIMATIONS = + sizeof( HOMER_GAG_ANIMATION ) / sizeof( HOMER_GAG_ANIMATION[ 0 ] ) - 1; + +const radKey32 FE_GAGS[] = +{ + ::radMakeKey32( "FE_Gag_Homer" ), + ::radMakeKey32( "FE_Gag_Grandpa" ), + ::radMakeKey32( "FE_Gag_Moleman" ), + ::radMakeKey32( "FE_Gag_Frink" ), + ::radMakeKey32( "FE_Gag_Barney" ), + ::radMakeKey32( "FE_Gag_Nick" ), + ::radMakeKey32( "FE_Gag_Snake" ), + ::radMakeKey32( "FE_Gag_Maggie" ), + + ::radMakeKey32( "FE_Gag_UNKNOWN" ) +}; + +const radKey32 FE_GAGS_FOR_HOMER[] = +{ + ::radMakeKey32( "FE_Gag_Homer_ScratchHead" ), + ::radMakeKey32( "FE_Gag_Homer_ScratchBum" ), + ::radMakeKey32( "FE_Gag_Homer_Yawn" ), + ::radMakeKey32( "FE_Gag_Homer_Nightmare" ), + ::radMakeKey32( "FE_Gag_Homer_Stretch" ), + + ::radMakeKey32( "FE_Gag_UNKNOWN" ) +}; + +enum eMainMenuItem +{ + MENU_ITEM_MAIN_MENU, +/* + MENU_ITEM_NEW_GAME, + MENU_ITEM_RESUME_GAME, + MENU_ITEM_LOAD_GAME, + MENU_ITEM_COLLECTIBLE_CARDS, + MENU_ITEM_OPTIONS, +*/ + +#ifdef SRR2_LEVEL_SELECTION + MENU_ITEM_LEVEL, +#endif + + NUM_MAIN_MENU_ITEMS +}; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMainMenu::CGuiScreenMainMenu +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMainMenu::CGuiScreenMainMenu +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MAIN_MENU ), + m_pMenu( NULL ), + m_gags( NULL ), + m_currentGagIndex( -1 ), + m_nextGagIndex( -1 ), + m_nextHomerGagIndex( -1 ), + m_gagsElapsedTime( 0 ), + m_gagsCycleTime( 1000 * MIN_GAGS_CYCLE_TIME ), + m_homer( NULL ), + m_raceCar( NULL ), + m_homerIdleAnim( NULL ), + m_tvFrame( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenMainMenu" ); + memset( m_glowingItems, 0, sizeof( m_glowingItems ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MainMenu" ); + rAssert( pPage != NULL ); + +/* + // get accept button icon + // + if( m_buttonIcons[ BUTTON_ICON_ACCEPT ] == NULL ) + { + m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "AcceptLabel" ); + rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL ); + } +*/ + + // Create a menu. + // + m_pMenu = new CGuiMenu( this, NUM_MAIN_MENU_ITEMS, GUI_TEXT_MENU ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + Scrooby::Text* otherMainMenu = NULL; + +#ifdef RAD_WIN32 + m_pMenu->AddMenuItem( pPage->GetText( "MainMenu_PC" ), + pPage->GetText( "MainMenu_PC" ), + NULL, + NULL, + pPage->GetSprite( "MainMenu_LArrow" ), + pPage->GetSprite( "MainMenu_RArrow" ) ); + + otherMainMenu = pPage->GetText( "MainMenu" ); +#else + m_pMenu->AddMenuItem( pPage->GetText( "MainMenu" ), + pPage->GetText( "MainMenu" ), + NULL, + NULL, + pPage->GetSprite( "MainMenu_LArrow" ), + pPage->GetSprite( "MainMenu_RArrow" ) ); + + otherMainMenu = pPage->GetText( "MainMenu_PC" ); +#endif + + if( otherMainMenu != NULL ) + { + otherMainMenu->SetVisible( false ); + } + + // wrap main menu text + // + Scrooby::Text* mainMenuText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItem() ); + rAssert( mainMenuText != NULL ); + mainMenuText->SetTextMode( Scrooby::TEXT_WRAP ); + +#ifdef RAD_DEMO + m_pMenu->SetSelectionValueCount( MENU_ITEM_MAIN_MENU, NUM_MAIN_MENU_SELECTIONS ); + m_pMenu->SetSelectionValue( MENU_ITEM_MAIN_MENU, MAIN_MENU_PLAY_LEVEL_2 ); + + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + mainMenuText->SetString( MAIN_MENU_PLAY_LEVEL_2, "PLAY LEVEL 2" ); // TC: [TODO] localization?? + mainMenuText->SetString( MAIN_MENU_PLAY_LEVEL_7, "PLAY LEVEL 7" ); // TC: [TODO] localization?? + HeapMgr()->PopHeap( GMA_LEVEL_FE ); +#endif + + // scale up main menu text a bit + // +// m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItem()->ScaleAboutCenter( 1.2f ); + + Scrooby::Page* levelPage = m_pScroobyScreen->GetPage( "Level" ); + if( levelPage != NULL ) + { +#ifdef SRR2_LEVEL_SELECTION + m_pMenu->AddMenuItem( levelPage->GetText( "Level" ), + levelPage->GetText( "Level" ), + NULL, + NULL, + NULL, + NULL, + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + + #ifndef RAD_DEBUG + // hide level/car selection menu by default + // in Tune and Release builds + // + this->ToggleLevelMenu(); + #endif +#else + Scrooby::Group* levelMenu = levelPage->GetGroup( "Menu" ); + rAssert( levelMenu != NULL ); + levelMenu->SetVisible( false ); +#endif + } + + // Retrieve drawing elements from 3dFE page + // + pPage = m_pScroobyScreen->GetPage( "3dFE" ); + rAssert( pPage != NULL ); + m_homer = pPage->GetPure3dObject( "Homer" ); + m_raceCar = pPage->GetPure3dObject( "RaceCar" ); + + // get glowing items + // +#ifdef RAD_DEMO + m_glowingItems[ MAIN_MENU_PLAY_LEVEL_2 ] = pPage->GetPure3dObject( "Glow4" ); + m_glowingItems[ MAIN_MENU_PLAY_LEVEL_7 ] = pPage->GetPure3dObject( "Glow4" ); + m_glowingItems[ MAIN_MENU_OPTIONS ] = pPage->GetPure3dObject( "Glow2" ); + + Scrooby::Pure3dObject* glowingItem = NULL; + + glowingItem = pPage->GetPure3dObject( "Glow0" ); + rAssert( glowingItem != NULL ); + glowingItem->SetVisible( false ); + + glowingItem = pPage->GetPure3dObject( "Glow1" ); + rAssert( glowingItem != NULL ); + glowingItem->SetVisible( false ); + + glowingItem = pPage->GetPure3dObject( "Glow3" ); + rAssert( glowingItem != NULL ); + glowingItem->SetVisible( false ); + + glowingItem = pPage->GetPure3dObject( "Glow5" ); + rAssert( glowingItem != NULL ); + glowingItem->SetVisible( false ); +#else + for( int i = 0; i < NUM_MAIN_MENU_SELECTIONS; i++ ) + { + char name[ 16 ]; + sprintf( name, "Glow%d", i ); + m_glowingItems[ i ] = pPage->GetPure3dObject( name ); + } +#endif + + this->TurnOnGlowItems( 0 ); // all off, by default + + // 3D FE Gags + // + m_gags = m_pScroobyScreen->GetPage( "3dFEGags" ); + rAssert( m_gags ); + + // Retrieve drawing elements from TVFrame page + // + pPage = m_pScroobyScreen->GetPage( "TVFrame" ); + rAssert( pPage ); + m_tvFrame = pPage->GetLayer( "TVFrame" ); + + // correct TV frame proportion and size on GC and PS2 and pc + // + Scrooby::Sprite* tvFrame = pPage->GetSprite( "TVFrame" ); + if( tvFrame != NULL ) + { + tvFrame->ResetTransformation(); + +#ifdef RAD_GAMECUBE + tvFrame->ScaleAboutCenter( 1.1f, 1.0f, 1.0f ); +#endif + +#ifdef RAD_PS2 + tvFrame->ScaleAboutCenter( 1.07f ); +#endif + +#ifdef RAD_WIN32 + tvFrame->ScaleAboutCenter( 1.03f ); +#endif + } +MEMTRACK_POP_GROUP( "CGUIScreenMainMenu" ); +} + + +//=========================================================================== +// CGuiScreenMainMenu::~CGuiScreenMainMenu +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMainMenu::~CGuiScreenMainMenu() +{ + if( m_nextGagIndex == -1 ) + { + // stop any FE gag dialog that was triggered and may still be playing + // + GetEventManager()->TriggerEvent( EVENT_FE_GAG_STOP ); + } + + if( m_homerIdleAnim != NULL ) + { + m_homerIdleAnim->Release(); + m_homerIdleAnim = NULL; + } + + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } + + // restore black clear colour + // + GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) ); +} + + +//=========================================================================== +// CGuiScreenMainMenu::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { +#ifndef RAD_WIN32 + rAssert( param1 == PROMPT_CONFIRM_NEW_GAME ); +#endif + + if( param1 == PROMPT_CONFIRM_NEW_GAME ) + { + switch( param2 ) + { + case CGuiMenuPrompt::RESPONSE_YES: + { +#ifdef SRR2_LEVEL_SELECTION + int level = m_pMenu->GetSelectionValue( MENU_ITEM_LEVEL ); + this->OnNewGameSelected( static_cast<RenderEnums::LevelEnum>( level ) ); +#else + this->OnNewGameSelected(); +#endif // SRR2_LEVEL_SELECTION + + CGuiScreen* pScreen = static_cast<CGuiScreen*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_GENERIC_PROMPT ) ); + rAssert( pScreen != NULL ); + pScreen->StartTransitionAnimation( 0, 53 ); + + break; + } + case CGuiMenuPrompt::RESPONSE_NO: + { + this->ReloadScreen(); + + break; + } + default: + { + rAssertMsg( false, "Invalid prompt response!" ); + + break; + } + } + } +#ifdef RAD_WIN32 + else if( param1 == PROMPT_CONFIRM_QUIT ) + { + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + // send message to front-end manager to quit front-end and + // exit the game. + // + m_pParent->HandleMessage( GUI_MSG_QUIT_GAME ); + + break; + } + + case (CGuiMenuPrompt::RESPONSE_NO): + { + this->ReloadScreen(); + + break; + } + + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + } +#endif + } + + if( m_firstTimeEntered && + message == GUI_MSG_WINDOW_ENTER ) + { + if( CGuiScreenIntroTransition::s_introTransitionPlayed ) + { + this->SetFadingEnabled( false ); + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->UpdateRunning( param1 ); + + break; + } +#ifdef SRR2_LEVEL_SELECTION + // show/hide level and car selection menu (for Tune and Release) + // + case GUI_MSG_CONTROLLER_L1: + case GUI_MSG_CONTROLLER_R1: + { + this->ToggleLevelMenu(); + + break; + } + case GUI_MSG_CONTROLLER_START: + { + if( m_pMenu->GetSelection() == MENU_ITEM_LEVEL ) + { + rAssert( m_pMenu != NULL ); + m_pMenu->Reset(); + m_pMenu->SetSelectionValue( 0, MAIN_MENU_NEW_GAME ); + } + + break; + } +#endif + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + if( param1 == MENU_ITEM_MAIN_MENU ) + { + // turn on new glow item + // + this->TurnOnGlowItems( (1 << param2) ); + +#ifndef RAD_DEMO + if( param2 == MAIN_MENU_MINI_GAME ) // special case for mini-game + { + if( !GetCharacterSheetManager()->IsMiniGameUnlocked() && + !CommandLineOptions::Get( CLO_SKIP_FE ) ) + { + // don't turn on glowing track + // + this->TurnOnGlowItems( 0 ); + + // grey out selection + // + m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItemValue()->SetColour( tColour( 128, 128, 128 ) ); + + // hide accept button icon + // + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetClickable( false ); +#endif + + } + } + else + { + // restore menu selection colour and accept button icon + // + tColour menuHighlightColour = m_pMenu->GetHighlightColour(); + m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItemValue()->SetColour( menuHighlightColour ); + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetClickable( true ); +#endif + } +#endif // !RAD_DEMO + } + + break; + } + case GUI_MSG_CONTROLLER_SELECT: + { + if( !this->IsButtonVisible( BUTTON_ICON_ACCEPT ) ) + { + return; + } +#ifdef RAD_DEMO + if( m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_PLAY_LEVEL_2 || + m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_PLAY_LEVEL_7 ) +#else + if( m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_NEW_GAME || + m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_RESUME_GAME ) +#endif + { + GetInputManager()->RegisterControllerID( 0, param1 ); + GetGuiSystem()->SetPrimaryController(param1); + } + +#ifndef RAD_DEMO + if( m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_MINI_GAME ) + { + GetGuiSystem()->SetPrimaryController(param1); + } +#endif // !RAD_DEMO + + break; + } +#ifdef RAD_WIN32 + case GUI_MSG_CONTROLLER_BACK: + { + this->OnQuitGameSelected(); + + break; + } +#endif + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( param1 == MENU_ITEM_MAIN_MENU ); + rAssert( m_pMenu != NULL ); + int menuSelection = m_pMenu->GetSelectionValue( param1 ); + + switch( menuSelection ) + { +#ifdef RAD_DEMO + case MAIN_MENU_PLAY_LEVEL_2: + { + this->OnNewGameSelected( RenderEnums::L2, RenderEnums::M1 ); + + break; + } + case MAIN_MENU_PLAY_LEVEL_7: + { + this->OnNewGameSelected( RenderEnums::L7, RenderEnums::M1 ); + + break; + } +#else + case MAIN_MENU_NEW_GAME: + { + if( GetGameDataManager()->IsGameLoaded() ) + { + // prompt user to confirm first + // + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_NEW_GAME, this ); + } + else + { +#ifdef SRR2_LEVEL_SELECTION + int level = m_pMenu->GetSelectionValue( MENU_ITEM_LEVEL ); + this->OnNewGameSelected( static_cast<RenderEnums::LevelEnum>( level ) ); +#else + this->OnNewGameSelected(); +#endif // SRR2_LEVEL_SELECTION + } + + break; + } + case MAIN_MENU_RESUME_GAME: + { + this->OnResumeGameSelected(); + + break; + } + case MAIN_MENU_MINI_GAME: + { + this->OnMiniGameSelected(); + + break; + } + case MAIN_MENU_LOAD_GAME: + { +#ifdef RAD_XBOX + // Xbox TCR Requirement: always prompt user to select memory + // device before loading/saving + // + CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = true; +#endif // RAD_XBOX + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_LOAD_GAME ); + + this->StartTransitionAnimation( 200, 230 ); + + break; + } + case MAIN_MENU_CARD_GALLERY: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SCRAP_BOOK ); + + this->StartTransitionAnimation( 320, 350 ); + + break; + } +#endif // RAD_DEMO + case MAIN_MENU_OPTIONS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_OPTIONS ); + + this->StartTransitionAnimation( 80, 110 ); + + break; + } +#ifdef RAD_WIN32 + case MAIN_MENU_QUIT_GAME: + { + this->OnQuitGameSelected(); + + break; + } +#endif + default: + { + rAssertMsg( false, "Invalid main menu selection!" ); + + break; + } + } + + break; + } + default: + { + break; + } + } + + if( m_pMenu != NULL ) + { + // relay message to menu + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + else if( m_state == GUI_WINDOW_STATE_INTRO ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->UpdateIntro( param1 ); + + break; + } + default: + { + break; + } + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->UpdateOutro( param1 ); + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenMainMenu::InitMenu() +{ +#ifndef RAD_DEMO + bool isGameLoaded = GetGameDataManager()->IsGameLoaded(); + + rAssert( m_pMenu != NULL ); + m_pMenu->SetSelectionValueCount( MENU_ITEM_MAIN_MENU, + isGameLoaded ? NUM_MAIN_MENU_SELECTIONS : NUM_MAIN_MENU_SELECTIONS - 1 ); + + m_pMenu->SetSelectionValue( MENU_ITEM_MAIN_MENU, + isGameLoaded ? MAIN_MENU_RESUME_GAME : MAIN_MENU_NEW_GAME ); +#endif // !RAD_DEMO +} + +//=========================================================================== +// CGuiScreenMainMenu::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::InitIntro() +{ + if( m_firstTimeEntered ) + { + this->SetFadeTime( FIRST_TIME_FADE_IN_TIME ); + this->InitMenu(); + + // set clear colour to a blue sky colour + // + GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( FE_BLUE_SKY_COLOUR ); + } +} + +//=========================================================================== +// CGuiScreenMainMenu::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::InitRunning() +{ + if( m_firstTimeEntered ) + { + this->SetFadingEnabled( true ); + this->RestoreDefaultFadeTime(); + + m_screenCover = NULL; + } + + // turn on current glow item + // + rAssert( m_pMenu != NULL ); + this->TurnOnGlowItems( (1 << m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU )) ); +} + +//=========================================================================== +// CGuiScreenMainMenu::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::InitOutro() +{ + if( m_nextGagIndex == -1 ) + { + // stop any FE gag dialog that was triggered and may still be playing + // + GetEventManager()->TriggerEvent( EVENT_FE_GAG_STOP ); + } + + // turn off all glow items + // + this->TurnOnGlowItems( 0 ); +} + +//=========================================================================== +// CGuiScreenMainMenu::UpdateIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::UpdateIntro( unsigned int elapsedTime ) +{ + if( m_firstTimeEntered ) + { + // hide duplicate homer + // + if( m_gags != NULL ) + { + Scrooby::Pure3dObject* p3dGag = m_gags->GetPure3dObject( "Gag0" ); + rAssert( p3dGag ); + if( p3dGag->GetMultiController() != NULL ) + { + p3dGag->SetVisible( false ); + } + } + } +} + +//=========================================================================== +// CGuiScreenMainMenu::UpdateRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::UpdateRunning( unsigned int elapsedTime ) +{ + GetMemoryCardManager()->Update( elapsedTime ); + this->UpdateGags( elapsedTime ); +} + +//=========================================================================== +// CGuiScreenMainMenu::UpdateOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::UpdateOutro( unsigned int elapsedTime ) +{ + int currentMenuSelection = m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ); + +#ifdef RAD_DEMO + if( currentMenuSelection == MAIN_MENU_PLAY_LEVEL_2 || + currentMenuSelection == MAIN_MENU_PLAY_LEVEL_7 ) +#else + if( currentMenuSelection == MAIN_MENU_NEW_GAME || + currentMenuSelection == MAIN_MENU_RESUME_GAME || + currentMenuSelection == MAIN_MENU_MINI_GAME ) +#endif + { + rAssert( m_p3dObject != NULL ); + + tMultiController* multiController = m_p3dObject->GetMultiController(); + if( multiController != NULL ) + { + const float NUM_FADE_OUT_FRAMES = 15.0f; + float currentFrame = multiController->GetFrame(); + float numRemainingFrames = multiController->GetNumFrames() - currentFrame; + + if( numRemainingFrames < NUM_FADE_OUT_FRAMES ) + { + // fade out TV frame + // + if( m_tvFrame != NULL ) + { + float alpha = numRemainingFrames / NUM_FADE_OUT_FRAMES; + + // decrease fade rate for low alpha values + alpha *= alpha; + + if( alpha > 0.0f && alpha < 1.0f ) + { + m_tvFrame->SetAlpha( alpha ); + } + else + { + m_tvFrame->SetAlpha( 0.0f ); + } + } + + // TC [HACK]: To prevent any clipping in homer's mouth + // in the last few frames. + // + if( numRemainingFrames < 1.0f ) + { + this->RestoreScreenCover(); + } + } + +#ifndef RAD_DEMO + if( currentMenuSelection == MAIN_MENU_MINI_GAME ) + { + const float NUM_RACE_CAR_FRAMES_FOR_BLENDING = 11.0f; + + rAssert( m_raceCar != NULL ); + if( currentFrame < 1.0f ) + { + // get number of frames remaining in race car animation + // + tMultiController* raceMultiController = m_raceCar->GetMultiController(); + rAssert( raceMultiController != NULL ); + + int currentRaceFrame = (int)raceMultiController->GetFrame() % (int)raceMultiController->GetNumFrames(); + float numRemainingRaceFrames = raceMultiController->GetNumFrames() - currentRaceFrame; + raceMultiController->SetRelativeSpeed( numRemainingRaceFrames / NUM_RACE_CAR_FRAMES_FOR_BLENDING ); + } + else if( currentFrame > NUM_RACE_CAR_FRAMES_FOR_BLENDING ) + { + // hide duplicate race car + // + m_raceCar->SetVisible( false ); + } + } +#endif // !RAD_DEMO + } + } +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +//=========================================================================== +// CGuiScreenMainMenu::UpdateGags +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::UpdateGags( unsigned int elapsedTime ) +{ + static float NUM_BLEND_FRAMES = 10.0f; + + // if the homer gag animation is running + // + if( m_homerIdleAnim != NULL && m_homer != NULL ) + { + // check if homer gag animation is done + // + tMultiController* homerMultiController = m_homer->GetMultiController(); + if( homerMultiController != NULL ) + { + tAnimationFrameController* homerFrameController = + (tAnimationFrameController*)homerMultiController->GetTrack( 0 ); + rAssert( homerFrameController ); + + if( homerFrameController->LastFrameReached() > 0 ) + { + // ok, last frame has been reached on homer gag animation; + // restore the homer idle animation + // + if( m_homerIdleAnim != NULL ) + { + homerFrameController->SetAnimation( m_homerIdleAnim, 0.0f, 0.0f ); + + m_homerIdleAnim->Release(); + m_homerIdleAnim = NULL; + } + + // restore homer idle animation frame range + // + homerMultiController->SetFrameRange( 0.0f, 60.0f ); + homerMultiController->Reset(); + } + } + } + + // advance gag timer + // + m_gagsElapsedTime += elapsedTime; + + const unsigned int FE_GAG_PREP_TIME = 2000; // in msec + if( m_gagsElapsedTime > (m_gagsCycleTime - FE_GAG_PREP_TIME) ) + { + if( m_nextGagIndex == -1 ) + { + // prepare for next gag + // +#ifdef PLAY_ONLY_HOMER_GAGS + m_nextGagIndex = 0; +#else + #ifdef PLAY_GAGS_SEQUENTIALLY + m_nextGagIndex = (m_currentGagIndex + 1) % m_gags->GetNumberOfLayers(); + #else + int random = (rand() / 10) % GAGS_RANDOM_NUMBER_MODULO; + m_nextGagIndex = random % m_gags->GetNumberOfLayers(); + + if( CommandLineOptions::Get( CLO_FE_GAGS_TEST ) ) + { + rReleasePrintf( "Next FE Gag Index = %d (Random Number = %d)\n", m_nextGagIndex, random ); + } + #endif +#endif + if( m_nextGagIndex != 0 ) + { + GetEventManager()->TriggerEvent( EVENT_FE_GAG_INIT, reinterpret_cast<void*>( FE_GAGS[ m_nextGagIndex ] ) ); + } + else // multiple homer gags + { + // pick a random homer animation + // +#ifdef PLAY_GAGS_SEQUENTIALLY + m_nextHomerGagIndex = (m_nextHomerGagIndex + 1) % NUM_HOMER_GAG_ANIMATIONS; +#else + int random = (rand() / 10) % GAGS_RANDOM_NUMBER_MODULO; + m_nextHomerGagIndex = random % NUM_HOMER_GAG_ANIMATIONS; + + if( CommandLineOptions::Get( CLO_FE_GAGS_TEST ) ) + { + rReleasePrintf( " Next Homer Gag Index = %d (Random Number = %d)\n", m_nextHomerGagIndex, random ); + } +#endif + + GetEventManager()->TriggerEvent( EVENT_FE_GAG_INIT, reinterpret_cast<void*>( FE_GAGS_FOR_HOMER[ m_nextHomerGagIndex ] ) ); + } + } + } + + if( m_gagsElapsedTime > m_gagsCycleTime ) + { + if( m_gags != NULL ) + { + Scrooby::Layer* currentGagLayer = NULL; + + // hide previous gag layer, if exists + // + if( m_currentGagIndex != -1 ) + { + currentGagLayer = m_gags->GetLayerByIndex( m_currentGagIndex ); + currentGagLayer->SetVisible( false ); + } + + m_currentGagIndex = m_nextGagIndex; + m_nextGagIndex = -1; + + // get the pure3d gag + // + char objectName[ 8 ]; + sprintf( objectName, "Gag%d", m_currentGagIndex ); + Scrooby::Pure3dObject* p3dGag = m_gags->GetPure3dObject( objectName ); + + // reset gag animation + // + rAssert( p3dGag ); + tMultiController* multiController = p3dGag->GetMultiController(); + if( multiController != NULL ) + { + multiController->Reset(); + } + + // show current gag layer + // + currentGagLayer = m_gags->GetLayerByIndex( m_currentGagIndex ); + rAssert( currentGagLayer ); + currentGagLayer->SetVisible( true ); + + // start FE gag dialog + // + GetEventManager()->TriggerEvent( EVENT_FE_GAG_START ); + + if( m_currentGagIndex == 0 ) + { + // special case for homer gag animation + // + if( m_homer != NULL && multiController != NULL ) + { + tAnimationFrameController* frameController = + (tAnimationFrameController*)multiController->GetTrack( 0 ); + rAssert( frameController ); + + // get homer gag animation + tAnimation* homerAnim = frameController->GetAnimation(); + rAssert( homerAnim ); + homerAnim->SetCyclic( false ); // don't cycle when done + + tMultiController* homerMultiController = m_homer->GetMultiController(); + if( homerMultiController != NULL ) + { + homerMultiController->SetFrameRange( HOMER_GAG_ANIMATION[ m_nextHomerGagIndex ].startFrame, + HOMER_GAG_ANIMATION[ m_nextHomerGagIndex ].endFrame ); + + tAnimationFrameController* homerFrameController = + (tAnimationFrameController*)homerMultiController->GetTrack( 0 ); + rAssert( homerFrameController ); + + // save reference to homer idle animation + // + m_homerIdleAnim = homerFrameController->GetAnimation(); + rAssert( m_homerIdleAnim != NULL ); + m_homerIdleAnim->AddRef(); + + // switch to the homer gag animation + homerFrameController->SetAnimation( homerAnim, 0.0f, NUM_BLEND_FRAMES ); + } + } + } + } + + // set new random gag cycle time + // + if( CommandLineOptions::Get( CLO_FE_GAGS_TEST ) ) + { + m_gagsCycleTime = 1000 * MIN_GAGS_CYCLE_TIME; + } + else + { + m_gagsCycleTime = 1000 * (MIN_GAGS_CYCLE_TIME + rand() % (MAX_GAGS_CYCLE_TIME - MIN_GAGS_CYCLE_TIME + 1)); + } + + // reset gag timer + // + m_gagsElapsedTime = 0; + } +} + +//=========================================================================== +// CGuiScreenMainMenu::StopHomerIdleAnimation +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::StopHomerIdleAnimation() +{ +/* + if( m_homer != NULL ) + { + // reset Homer's snoring animation so that the camera + // can pan right into his mouth + // + tMultiController* multiController = m_homer->GetMultiController(); + if( multiController != NULL ) + { + tAnimationFrameController* frameController = (tAnimationFrameController*)multiController->GetTrack( 0 ); + rAssert( frameController ); + + if( m_homerIdleAnim == NULL ) + { + m_homerIdleAnim = frameController->GetAnimation(); + rAssert( m_homerIdleAnim ); + } + + m_homerIdleAnim->SetCyclic( false ); + + static float NUM_BLEND_FRAMES = 10.0f; + frameController->SetAnimation( m_homerIdleAnim, + m_homerIdleAnim->GetNumFrames() - NUM_BLEND_FRAMES, + NUM_BLEND_FRAMES ); + + m_homerIdleAnim = NULL; + } + } +*/ +} + +//=========================================================================== +// CGuiScreenMainMenu::TurnOnGlowItems +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: items - bitmask representing which ones to turn on glowing +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMainMenu::TurnOnGlowItems( unsigned int items ) +{ +#ifdef RAD_DEMO + if( items > 0 ) + { + bool isOptionsSelected = ( (items & (1 << MAIN_MENU_OPTIONS)) > 0 ); + m_glowingItems[ MAIN_MENU_PLAY_LEVEL_2 ]->SetVisible( !isOptionsSelected ); + m_glowingItems[ MAIN_MENU_OPTIONS ]->SetVisible( isOptionsSelected ); + + return; + } +#endif + +#ifdef RAD_WIN32 + for( int i = 0; i < NUM_MAIN_MENU_SELECTIONS; i++ ) + { + bool isOn = (items & (1 << i)) > 0; + int which = i < MAIN_MENU_QUIT_GAME ? i : i - 1; + if( m_glowingItems[ which ] != NULL && i != MAIN_MENU_QUIT_GAME ) + { + m_glowingItems[ which ]->SetVisible( isOn ); + } + } +#else + for( int i = 0; i < NUM_MAIN_MENU_SELECTIONS; i++ ) + { + bool isOn = (items & (1 << i)) > 0; + if( m_glowingItems[ i ] != NULL ) + { + m_glowingItems[ i ]->SetVisible( isOn ); + } + } +#endif +} + +void +CGuiScreenMainMenu::OnNewGameSelected( RenderEnums::LevelEnum level, + RenderEnums::MissionEnum mission ) +{ + bool showNewGameMovie = false; + +#ifdef RAD_RELEASE + #ifndef RAD_DEMO + showNewGameMovie = !CommandLineOptions::Get( CLO_SKIP_MOVIE ); + #endif +#endif + + if( showNewGameMovie ) + { + // play new game movie + // + rAssert( m_guiManager ); + CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME ) ); + rAssert( playMovieScreen ); + + playMovieScreen->SetMovieToPlay( MovieNames::MOVIE1, false, true ); + + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME ); + } + else + { + // send message to front-end manager to quit front-end and + // start single player story mode + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player + } + + this->StartTransitionAnimation( 0, 53 ); + + this->StopHomerIdleAnimation(); + + if( GetGameDataManager()->IsGameLoaded() ) + { + // reset all game data + // + GetGameDataManager()->ResetGame(); + + //reset the rewards manager and relock the rewards + // + GetRewardsManager()->ClearRewards(); + } + + GetCharacterSheetManager()->SetCurrentMission( level, mission ); + + // restore black clear colour + // + GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) ); +} + +void +CGuiScreenMainMenu::OnResumeGameSelected() +{ + // send message to front-end manager to quit front-end and + // start single player story mode + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player + + this->StartTransitionAnimation( 140, 170 ); +} + +void +CGuiScreenMainMenu::OnMiniGameSelected() +{ + // send message to front-end manager to quit front-end and + // start mini-game mode + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 2 ); // 2 = mini-game + + this->StartTransitionAnimation( 880, 913 ); +} + +#ifdef RAD_WIN32 +void +CGuiScreenMainMenu::OnQuitGameSelected() +{ + rAssert( m_guiManager != NULL ); + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT, this ); +} +#endif + +#ifdef SRR2_LEVEL_SELECTION +void +CGuiScreenMainMenu::ToggleLevelMenu() +{ + Scrooby::Page* levelPage = m_pScroobyScreen->GetPage( "Level" ); + if( levelPage != NULL ) + { + Scrooby::Group* levelMenu = levelPage->GetGroup( "Menu" ); + rAssert( levelMenu ); + + bool toggle = !levelMenu->IsVisible(); + + // display menu on/off + levelMenu->SetVisible( toggle ); + + // enable/disable menu selections + for( int i = MENU_ITEM_LEVEL; i <= MENU_ITEM_LEVEL; i++ ) + { + m_pMenu->SetMenuItemEnabled( i, toggle ); + } + } +} +#endif // SRR2_LEVEL_SELECTION + +//=========================================================================== +// Public Member Functions (for CGuiScreenIntroTransition) +//=========================================================================== + +bool CGuiScreenIntroTransition::s_introTransitionPlayed = false; + +//=========================================================================== +// CGuiScreenIntroTransition::CGuiScreenIntroTransition +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenIntroTransition::CGuiScreenIntroTransition +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_INTRO_TRANSITION ), + m_introState( WAITING_FOR_MULTICONTROLLER ), + m_homer( NULL ), + m_tvFrame( NULL ), + m_gags( NULL ) +{ + this->SetFadingEnabled( false ); + + // Retrieve drawing elements from 3dFE page + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "3dFE" ); + rAssert( pPage ); + m_homer = pPage->GetPure3dObject( "Homer" ); + + // Retrieve drawing elements from TVFrame page + // + pPage = m_pScroobyScreen->GetPage( "TVFrame" ); + rAssert( pPage ); + m_tvFrame = pPage->GetLayer( "TVFrame" ); + + // 3D FE Gags + // + m_gags = m_pScroobyScreen->GetPage( "3dFEGags" ); + rAssert( m_gags ); + + s_introTransitionPlayed = false; +} + + +//=========================================================================== +// CGuiScreenIntroTransition::~CGuiScreenIntroTransition +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenIntroTransition::~CGuiScreenIntroTransition() +{ +} + + +//=========================================================================== +// CGuiScreenIntroTransition::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIntroTransition::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); + + if( m_state == GUI_WINDOW_STATE_INTRO && + message == GUI_MSG_UPDATE ) + { + switch( m_introState ) + { + case WAITING_FOR_MULTICONTROLLER: + { + if( s_p3dMultiController != NULL ) + { + m_numTransitionsPending--; + + this->StartTransitionAnimation( 721, 770, false ); + + if( m_screenCover != NULL ) + { + m_screenCover->SetVisible( false ); + } + + m_introState = RUNNING_INTRO_ANIMATION; + } + else + { + if( m_screenCover != NULL ) + { + m_screenCover->SetAlpha( 1.0f ); + } + } + + break; + } + + default: + { + if( m_tvFrame != NULL ) + { + rAssert( m_p3dObject ); + + tMultiController* multiController = m_p3dObject->GetMultiController(); + rAssert( multiController ); + + const float NUM_FADE_IN_FRAMES = 20.0f; + float numRemainingFrames = multiController->GetNumFrames() - + multiController->GetFrame(); + + if( numRemainingFrames < NUM_FADE_IN_FRAMES ) + { + float alpha = 1.0f - numRemainingFrames / NUM_FADE_IN_FRAMES; + + // decrease fade rate for low alpha values + alpha *= alpha; + + if( alpha < 1.0f ) + { + // fade in TV frame + // + if( m_tvFrame != NULL ) + { + m_tvFrame->SetAlpha( alpha ); + } + + // fade in foreground layers + // + this->SetAlphaForLayers( alpha, + m_foregroundLayers, + m_numForegroundLayers ); + } + } + } + + break; + } + } + + // hide duplicate homer + // + if( m_gags != NULL ) + { + Scrooby::Pure3dObject* p3dGag = m_gags->GetPure3dObject( "Gag0" ); + rAssert( p3dGag ); + if( p3dGag->GetMultiController() != NULL ) + { + p3dGag->SetVisible( false ); + } + } + } +} + + +//=========================================================================== +// CGuiScreenIntroTransition::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIntroTransition::InitIntro() +{ + // wait for retrieval of pure3d multicontroller + m_numTransitionsPending++; + + if( m_tvFrame != NULL ) + { + m_tvFrame->SetAlpha( 0.0f ); + + this->SetAlphaForLayers( 0.0f, + m_foregroundLayers, + m_numForegroundLayers ); + } + + CGuiScreenMainMenu* pScreen = static_cast<CGuiScreenMainMenu*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_MAIN_MENU ) ); + rAssert( pScreen != NULL ); + pScreen->InitMenu(); +} + + +//=========================================================================== +// CGuiScreenIntroTransition::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIntroTransition::InitRunning() +{ + s_introTransitionPlayed = true; + + if( m_tvFrame != NULL ) + { + m_tvFrame->SetAlpha( 1.0f ); + + this->SetAlphaForLayers( 1.0f, + m_foregroundLayers, + m_numForegroundLayers ); + } + + // goto main menu + // + rAssert( m_pParent ); + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_MAIN_MENU, + CLEAR_WINDOW_HISTORY ); +} + + +//=========================================================================== +// CGuiScreenIntroTransition::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIntroTransition::InitOutro() +{ +} + diff --git a/game/code/presentation/gui/frontend/guiscreenmainmenu.h b/game/code/presentation/gui/frontend/guiscreenmainmenu.h new file mode 100644 index 0000000..733fa58 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmainmenu.h @@ -0,0 +1,157 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMainMenu +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMAINMENU_H +#define GUISCREENMAINMENU_H + +#ifndef FINAL + #ifndef RAD_DEMO + #define SRR2_LEVEL_SELECTION // for SRR2 level selection + #endif +#endif + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +#include <render/enums/renderenums.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; +class tAnimation; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMainMenu : public CGuiScreen +{ +public: + CGuiScreenMainMenu( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMainMenu(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void InitMenu(); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void UpdateIntro( unsigned int elapsedTime ); + void UpdateRunning( unsigned int elapsedTime ); + void UpdateOutro( unsigned int elapsedTime ); + +private: + enum eMainMenuSelection + { +#ifdef RAD_DEMO + MAIN_MENU_PLAY_LEVEL_2, + MAIN_MENU_PLAY_LEVEL_7, + MAIN_MENU_OPTIONS, +#else + MAIN_MENU_LOAD_GAME, + MAIN_MENU_CARD_GALLERY, + MAIN_MENU_OPTIONS, + MAIN_MENU_MINI_GAME, + #ifdef RAD_WIN32 + MAIN_MENU_QUIT_GAME, + #endif + MAIN_MENU_NEW_GAME, + MAIN_MENU_RESUME_GAME, +#endif + + NUM_MAIN_MENU_SELECTIONS + }; + + void UpdateGags( unsigned int elapsedTime ); + void StopHomerIdleAnimation(); + void TurnOnGlowItems( unsigned int items ); + + void OnNewGameSelected( RenderEnums::LevelEnum level = RenderEnums::L1, + RenderEnums::MissionEnum mission = RenderEnums::M1 ); + + void OnResumeGameSelected(); + void OnMiniGameSelected(); + +#ifdef RAD_WIN32 + void OnQuitGameSelected(); +#endif + +#ifdef SRR2_LEVEL_SELECTION + void ToggleLevelMenu(); +#endif + + CGuiMenu* m_pMenu; + + Scrooby::Page* m_gags; + int m_currentGagIndex; + int m_nextGagIndex; + int m_nextHomerGagIndex; + unsigned int m_gagsElapsedTime; + unsigned int m_gagsCycleTime; + + Scrooby::Pure3dObject* m_homer; + Scrooby::Pure3dObject* m_raceCar; + tAnimation* m_homerIdleAnim; + Scrooby::Layer* m_tvFrame; + + Scrooby::Pure3dObject* m_glowingItems[ NUM_MAIN_MENU_SELECTIONS ]; + +}; + + +class CGuiScreenIntroTransition: public CGuiScreen +{ +public: + CGuiScreenIntroTransition( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenIntroTransition(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + static bool s_introTransitionPlayed; + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + enum eState + { + WAITING_FOR_MULTICONTROLLER, + RUNNING_INTRO_ANIMATION, + + NUM_STATES + }; + + eState m_introState; + Scrooby::Pure3dObject* m_homer; + Scrooby::Layer* m_tvFrame; + Scrooby::Page* m_gags; + +}; + +#endif // GUISCREENMAINMENU_H diff --git a/game/code/presentation/gui/frontend/guiscreenmissiongallery.cpp b/game/code/presentation/gui/frontend/guiscreenmissiongallery.cpp new file mode 100644 index 0000000..e0d9113 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmissiongallery.cpp @@ -0,0 +1,860 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionGallery +// +// Description: Implementation of the CGuiScreenMissionGallery class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/19 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenmissiongallery.h> +#include <presentation/gui/frontend/guiscreenscrapbookcontents.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guiscreenprompt.h> + +#include <cheats/cheatinputsystem.h> +#include <events/eventmanager.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> + +#include <p3d/inventory.hpp> +#include <raddebug.hpp> // Foundation + +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* MISSION_GALLERY_IMAGES_DIR = "art\\frontend\\dynaload\\images\\scrapbook\\"; +const char* MISSION_GALLERY_INVENTORY_SECTION = "FE_MissionGallery"; +const float MISSION_IMAGE_SCALE = 0.4f; +const float MISSION_VIEW_TRANSITION_TIME = 250.0f; // in msec +const float MISSION_VIEW_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms +const int MISSION_VIEW_POS_X = 180; +const int MISSION_VIEW_POS_Y = 120; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMissionGallery::CGuiScreenMissionGallery +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionGallery::CGuiScreenMissionGallery +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MISSION_GALLERY ), + m_pMenu( NULL ), + m_menuGroup( NULL ), + m_isMissionImagesLoaded( false ), + m_screenState( SCREEN_STATE_NORMAL ), + m_elapsedTime( 0 ), + m_projectileVelocity( 0.0f, 0.0f, 0.0f ), + m_missionInfo( NULL ), + m_missionNum( NULL ), + m_missionTitle( NULL ), + m_selectedMission( -1 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MissionGallery" ); + rAssert( pPage != NULL ); + + // create a 2D sprite menu + // + m_pMenu = new CGuiMenu2D( this, NUM_MISSIONS_PER_LEVEL, 4, GUI_SPRITE_MENU, MENU_SFX_NONE ); + rAssert( m_pMenu != NULL ); + m_pMenu->SetGreyOutEnabled( false ); + + m_menuGroup = pPage->GetGroup( "Menu" ); + rAssert( m_menuGroup != NULL ); + + // add sprites to menu + // + for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ ) + { + char name[ 16 ]; + sprintf( name, "Mission%d", i ); + + m_pMenu->AddMenuItem( m_menuGroup->GetSprite( name ) ); + } + + // add menu cursor + // + m_pMenu->SetCursor( m_menuGroup->GetSprite( "MissionFrame" ) ); + + // TC: [TEMP] due to placeholder image + // + m_menuGroup->GetSprite( "MissionFrame" )->RotateAboutCenter( 90.0f ); + + // get view mission layer and text drawables + // + m_missionInfo = pPage->GetLayer( "ViewMission" ); + m_missionNum = pPage->GetText( "MissionNum" ); + m_missionTitle = pPage->GetText( "MissionTitle" ); + + // add view mission layer to list of foreground layers + // + if( m_numForegroundLayers < MAX_FOREGROUND_LAYERS ) + { + m_foregroundLayers[ m_numForegroundLayers ] = m_missionInfo; + m_numForegroundLayers++; + } + + if( this->IsWideScreenDisplay() ) + { + m_missionInfo->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( m_missionInfo ); + } + + // wrap mission title + // + rAssert( m_missionTitle != NULL ); + m_missionTitle->SetTextMode( Scrooby::TEXT_WRAP ); + + // add outline to mission number and title + // + Scrooby::Text* missionNum = pPage->GetText( "MissionNum" ); + if( missionNum != NULL ) + { + missionNum->SetDisplayOutline( true ); + } + m_missionTitle->SetDisplayOutline( true ); + + // create inventory section for mission galllery resources + // + p3d::inventory->AddSection( MISSION_GALLERY_INVENTORY_SECTION ); +} + + +//=========================================================================== +// CGuiScreenMissionGallery::~CGuiScreenMissionGallery +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionGallery::~CGuiScreenMissionGallery() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } + + // destroy mission gallery inventory section + // + p3d::inventory->DeleteSection( MISSION_GALLERY_INVENTORY_SECTION ); +} + + +//=========================================================================== +// CGuiScreenMissionGallery::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionGallery::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + rAssert( param1 == PROMPT_CONFIRM_START_MISSION ); + + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { + this->OnStartMission(); + } + else + { + rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO ); + +// m_selectedMission = -1; + GetInputManager()->UnregisterControllerID( 0 ); + this->ReloadScreen(); + } + } + + if( m_screenState == SCREEN_STATE_GOTO_VIEW || + m_screenState == SCREEN_STATE_BACK_VIEW ) + { + if( message == GUI_MSG_UPDATE ) + { + this->OnUpdate( param1 ); + } + + return; + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( m_screenState == SCREEN_STATE_VIEWING ) + { + if( message == GUI_MSG_CONTROLLER_SELECT ) + { + if( this->IsButtonVisible( BUTTON_ICON_ACCEPT ) ) + { + GetInputManager()->RegisterControllerID( 0, param1 ); + + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_START_MISSION, this ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect + } + } + else if( message == GUI_MSG_CONTROLLER_BACK ) + { + m_screenState = SCREEN_STATE_BACK_VIEW; + m_elapsedTime = 0; + + m_selectedMission = -1; + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect + } + + if( this->IsControllerMessage( message ) ) + { + return; + } + } + + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->OnUpdate( param1 ); + + break; + } +/* + case GUI_MSG_MENU_SELECTION_CHANGED: + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, static_cast<int>( param1 ) != MISSION_8 ); + + break; + } +*/ + case GUI_MSG_MENU_SELECTION_MADE: + { + m_selectedMission = static_cast<int>( param1 ); + +// m_guiManager->DisplayPrompt( PROMPT_CONFIRM_START_MISSION, this ); + this->OnMenuSelectionMade( param1 ); +#ifdef RAD_WIN32 + // Hide/disable all other menu items. + this->SetVisibilityForAllOtherMenuItems( false ); +#endif + break; + } +/* + case GUI_MSG_CONTROLLER_SELECT: + { + if( this->IsButtonVisible( BUTTON_ICON_ACCEPT ) ) + { + GetInputManager()->RegisterControllerID( 0, param1 ); + } + else + { + return; + } + + break; + } +*/ + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL && m_screenState == SCREEN_STATE_NORMAL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + if( message == GUI_MSG_UPDATE && m_numTransitionsPending <= 0 ) + { + if( m_isMissionImagesLoaded && m_selectedMission == -1 ) + { + this->UnloadMissionImages(); + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMissionGallery::OnProcessRequestsComplete +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiScreenMissionGallery::OnProcessRequestsComplete( void* pUserData ) +{ + m_numTransitionsPending--; + + // show mission images + // + m_menuGroup->SetAlpha( 1.0f ); + + p3d::pddi->DrawSync(); + + // push and select inventory section for searching + // + p3d::inventory->PushSection(); + p3d::inventory->SelectSection( MISSION_GALLERY_INVENTORY_SECTION ); + bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly(); + p3d::inventory->SetCurrentSectionOnly( true ); + + // update all mission images + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + + rAssert( m_pMenu != NULL ); + for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ ) + { + if( (m_pMenu->GetMenuItem( i )->m_attributes & SELECTION_ENABLED) > 0 ) + { + char name[ 16 ]; + sprintf( name, "mis%02d_%02d.png", scrapBookContents->GetCurrentLevel() + 1, i + 1 ); + tSprite* pSprite = p3d::find<tSprite>( name ); + if( pSprite != NULL ) + { + Scrooby::Sprite* missionImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( missionImage != NULL ); + missionImage->SetRawSprite( pSprite, true ); + + missionImage->ResetTransformation(); + missionImage->ScaleAboutCenter( MISSION_IMAGE_SCALE ); + } + else + { + rAssertMsg( false, "Mission bitmap not found!" ); + } + } + } + + // pop inventory section and restore states + // + p3d::inventory->SetCurrentSectionOnly( currentSectionOnly ); + p3d::inventory->PopSection(); + + m_isMissionImagesLoaded = true; +} + +//=========================================================================== +// CGuiScreenMissionGallery::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionGallery::InitIntro() +{ + if( !m_isMissionImagesLoaded ) + { + int numImagesToLoad = this->LoadMissionImages(); + } +/* + // reset menu to first selection + // + if( numImagesToLoad > 0 ) + { + rAssert( m_pMenu != NULL ); + m_pMenu->Reset(); + } +*/ + m_elapsedTime = 0; +} + + +//=========================================================================== +// CGuiScreenMissionGallery::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionGallery::InitRunning() +{ + if( m_screenState != SCREEN_STATE_VIEWING ) + { + // hide mission info layer by default + // + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetVisible( false ); + m_missionInfo->SetAlpha( 0.0f ); + } +} + + +//=========================================================================== +// CGuiScreenMissionGallery::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionGallery::InitOutro() +{ +// this->UnloadMissionImages(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMissionGallery::OnUpdate( unsigned int elapsedTime ) +{ + if( m_screenState == SCREEN_STATE_NORMAL ) + { + // pulse cursor alpha + // + Scrooby::Drawable* cursor = m_pMenu->GetCursor(); + if( cursor != NULL ) + { + const unsigned int PULSE_PERIOD = 1000; + + float alpha = GuiSFX::Pulse( (float)m_elapsedTime, + (float)PULSE_PERIOD, + 0.75f, + 0.25f, + -rmt::PI_BY2 ); + + cursor->SetAlpha( alpha ); + + m_elapsedTime += elapsedTime; + m_elapsedTime %= PULSE_PERIOD; + } + } + else if( m_screenState == SCREEN_STATE_GOTO_VIEW ) + { + // transition mission image from normal menu position + // to viewing position + // + m_elapsedTime += elapsedTime; + + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem(); + rAssert( pDrawable != NULL ); + + pDrawable->ResetTransformation(); + + if( m_elapsedTime < (unsigned int)MISSION_VIEW_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / MISSION_VIEW_TRANSITION_TIME; + + pDrawable->ScaleAboutCenter( MISSION_IMAGE_SCALE + percentageDone * (1.0f - MISSION_IMAGE_SCALE) ); + + GuiSFX::Projectile( pDrawable, + (float)m_elapsedTime, + MISSION_VIEW_TRANSITION_TIME, + m_projectileVelocity, + false, + MISSION_VIEW_PROJECTILE_GRAVITY ); + + // fade out rest of the menu items + // + this->SetMenuAlpha( 1.0f - rmt::Sqrt( percentageDone ) ); + + // fade in mission info layer + // + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetAlpha( percentageDone * percentageDone ); + } + else + { + GuiSFX::Projectile( pDrawable, + MISSION_VIEW_TRANSITION_TIME, + MISSION_VIEW_TRANSITION_TIME, + m_projectileVelocity, + false, + MISSION_VIEW_PROJECTILE_GRAVITY ); + + this->SetMenuAlpha( 0.0f ); + + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetAlpha( 1.0f ); + + m_screenState = SCREEN_STATE_VIEWING; + } + } + else if( m_screenState == SCREEN_STATE_BACK_VIEW ) + { + // transition mission image from viewing position back to + // normal menu position + // + m_elapsedTime += elapsedTime; + + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem(); + rAssert( pDrawable != NULL ); + + pDrawable->ResetTransformation(); + + if( m_elapsedTime < (unsigned int)MISSION_VIEW_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / MISSION_VIEW_TRANSITION_TIME; + + pDrawable->ScaleAboutCenter( MISSION_IMAGE_SCALE + (1.0f - percentageDone) * (1.0f - MISSION_IMAGE_SCALE) ); + + GuiSFX::Projectile( pDrawable, + (float)m_elapsedTime, + MISSION_VIEW_TRANSITION_TIME, + m_projectileVelocity, + true, + MISSION_VIEW_PROJECTILE_GRAVITY ); + + // fade back in rest of the menu items + // + this->SetMenuAlpha( percentageDone * percentageDone ); + + // fade in mission info layer + // + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetAlpha( 1.0f - rmt::Sqrt( percentageDone ) ); + } + else + { + pDrawable->ScaleAboutCenter( MISSION_IMAGE_SCALE ); + + GuiSFX::Projectile( pDrawable, + MISSION_VIEW_TRANSITION_TIME, + MISSION_VIEW_TRANSITION_TIME, + m_projectileVelocity, + true, + MISSION_VIEW_PROJECTILE_GRAVITY ); + + // show menu cursor + // + rAssert( m_pMenu != NULL ); + m_pMenu->GetCursor()->SetVisible( true ); + + // show level bar + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + scrapBookContents->SetLevelBarVisible( true ); + + this->SetMenuAlpha( 1.0f ); + + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetAlpha( 0.0f ); + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + + // hide mission info layer + // + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetVisible( false ); + + m_elapsedTime = 0; + m_screenState = SCREEN_STATE_NORMAL; + +#ifdef RAD_WIN32 + // Show/enable all hidden menu items. + this->SetVisibilityForAllOtherMenuItems( true ); +#endif + } + } +} + +void +CGuiScreenMissionGallery::SetMenuAlpha( float alpha ) +{ + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ ) + { + if( i != currentSelection ) + { + Scrooby::Drawable* missionImage = m_pMenu->GetMenuItem( i )->GetItem(); + rAssert( missionImage != NULL ); + missionImage->SetAlpha( alpha ); + } + } +} + +void +CGuiScreenMissionGallery::OnMenuSelectionMade( int selection ) +{ + m_screenState = SCREEN_STATE_GOTO_VIEW; + m_elapsedTime = 0; + + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + + // hide menu cursor + // + rAssert( m_pMenu != NULL ); + m_pMenu->GetCursor()->SetVisible( false ); + + // hide level bar + // + scrapBookContents->SetLevelBarVisible( false ); + + // show mission info layer + // + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetVisible( true ); + + if( selection == MISSION_8 ) // bonus mission + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + } + + // update mission number and title + // + rAssert( m_missionNum != NULL ); + m_missionNum->SetIndex( selection ); + + int missionTitleIndex = scrapBookContents->GetCurrentLevel() * NUM_MISSIONS_PER_LEVEL + selection; + rAssert( m_missionTitle != NULL ); + m_missionTitle->SetIndex( missionTitleIndex ); + + // calculate the initial projectile velocity + // + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( selection )->GetItem(); + rAssert( pDrawable != NULL ); + + int startPosX = 0; + int startPosY = 0; + pDrawable->GetOriginPosition( startPosX, startPosY ); + + m_projectileVelocity.x = (MISSION_VIEW_POS_X - startPosX) / MISSION_VIEW_TRANSITION_TIME; + m_projectileVelocity.y = (MISSION_VIEW_POS_Y - startPosY - 0.5f * MISSION_VIEW_PROJECTILE_GRAVITY * MISSION_VIEW_TRANSITION_TIME * MISSION_VIEW_TRANSITION_TIME) / MISSION_VIEW_TRANSITION_TIME; +} + +void +CGuiScreenMissionGallery::OnStartMission() +{ + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + unsigned int level = scrapBookContents->GetCurrentLevel(); + + int mission = m_selectedMission; + + // special case for level 1 due to tutorial mission being m0 + // + if( level == 0 ) + { + mission++; + } + + GetCharacterSheetManager()->SetCurrentMission( static_cast<RenderEnums::LevelEnum>( level ), + static_cast<RenderEnums::MissionEnum>( mission ) ); + + // hide mission info layer + // + rAssert( m_missionInfo != NULL ); + m_missionInfo->SetVisible( false ); + + if( m_isMissionImagesLoaded ) + { + this->UnloadMissionImages(); + } + + // send message to front-end manager to quit front-end and + // start single player story mode + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player +} + +int +CGuiScreenMissionGallery::LoadMissionImages() +{ + // load mission bitmaps for current level + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + + int numImagesToLoad = 0; + + rAssert( m_pMenu != NULL ); + + for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ ) + { + Scrooby::BoundedDrawable* missionImage = m_pMenu->GetMenuItem( i )->GetItem(); + rAssert( missionImage != NULL ); + missionImage->SetAlpha( 1.0f ); // restore alpha by default + + bool isUnlocked = false; + + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) ) + { + isUnlocked = true; + } + else + { + if( i == NUM_MISSIONS_PER_LEVEL - 1 ) + { + isUnlocked = GetCharacterSheetManager()->QueryBonusMissionCompleted( static_cast<RenderEnums::LevelEnum>( scrapBookContents->GetCurrentLevel() ) ); + } + else + { + int missionIndex = scrapBookContents->GetCurrentLevel() == 0 ? i + 1 : i; + MissionRecord* pMissionRecord = GetCharacterSheetManager()->QueryMissionStatus( static_cast<RenderEnums::LevelEnum>( scrapBookContents->GetCurrentLevel() ), missionIndex ); + rAssert( pMissionRecord != NULL ); + if( pMissionRecord->mCompleted ) + { + isUnlocked = true; + } + else if( pMissionRecord->mSkippedMission ) + { + isUnlocked = true; + + missionImage->SetAlpha( 0.5f ); // 50% alpha for skipped missions + } + } + } + + m_pMenu->SetMenuItemEnabled( i, isUnlocked ); + + if( isUnlocked ) + { + char filename[ 64 ]; + sprintf( filename, "%smis%02d_%02d.p3d", + MISSION_GALLERY_IMAGES_DIR, + scrapBookContents->GetCurrentLevel() + 1, + i + 1 ); + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + filename, + GMA_LEVEL_FE, + MISSION_GALLERY_INVENTORY_SECTION, + MISSION_GALLERY_INVENTORY_SECTION ); + + numImagesToLoad++; + } + } + + if( numImagesToLoad > 0 ) + { + GetLoadingManager()->AddCallback( this ); + + // hide images until they're loaded + // + m_menuGroup->SetAlpha( 0.0f ); + + m_numTransitionsPending++; + } + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, numImagesToLoad > 0 ); + + return numImagesToLoad; +} + +void +CGuiScreenMissionGallery::UnloadMissionImages() +{ + p3d::pddi->DrawSync(); + + // clear all mission images + // + rAssert( m_pMenu != NULL ); + for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ ) + { + Scrooby::Sprite* missionImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( missionImage != NULL ); + missionImage->SetRawSprite( NULL, true ); + missionImage->ResetTransformation(); + + m_pMenu->SetMenuItemEnabled( i, false ); + } + + // unload mission bitmaps + // + p3d::inventory->RemoveSectionElements( MISSION_GALLERY_INVENTORY_SECTION ); + + m_isMissionImagesLoaded = false; +} + +#ifdef RAD_WIN32 +void CGuiScreenMissionGallery::SetVisibilityForAllOtherMenuItems( bool bVisible ) +{ + for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ ) + { + if( i != m_selectedMission ) + m_pMenu->GetMenuItem(i)->GetItem()->SetVisible( bVisible ); + } +} +#endif diff --git a/game/code/presentation/gui/frontend/guiscreenmissiongallery.h b/game/code/presentation/gui/frontend/guiscreenmissiongallery.h new file mode 100644 index 0000000..7f1a112 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmissiongallery.h @@ -0,0 +1,108 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionGallery +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/19 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMISSIONGALLERY_H +#define GUISCREENMISSIONGALLERY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <loading/loadingmanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu2D; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMissionGallery : public CGuiScreen, + public LoadingManager::ProcessRequestsCallback +{ +public: + CGuiScreenMissionGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMissionGallery(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + // Implements LoadingManager::ProcessRequestsCallback + // + virtual void OnProcessRequestsComplete( void* pUserData ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void OnUpdate( unsigned int elapsedTime ); + void SetMenuAlpha( float alpha ); + void OnMenuSelectionMade( int selection ); + void OnStartMission(); +#ifdef RAD_WIN32 + void SetVisibilityForAllOtherMenuItems( bool bDisable ); +#endif + + int LoadMissionImages(); + void UnloadMissionImages(); + + enum eMenuItem + { + MISSION_1, + MISSION_2, + MISSION_3, + MISSION_4, + MISSION_5, + MISSION_6, + MISSION_7, + MISSION_8, + + NUM_MISSIONS_PER_LEVEL + }; + + CGuiMenu2D* m_pMenu; + Scrooby::Group* m_menuGroup; + + bool m_isMissionImagesLoaded : 1; + + enum eScreenState + { + SCREEN_STATE_NORMAL, + SCREEN_STATE_GOTO_VIEW, + SCREEN_STATE_VIEWING, + SCREEN_STATE_BACK_VIEW, + + NUM_SCREEN_STATES + }; + + eScreenState m_screenState; + unsigned int m_elapsedTime; + rmt::Vector m_projectileVelocity; + + Scrooby::Layer* m_missionInfo; + Scrooby::Text* m_missionNum; + Scrooby::Text* m_missionTitle; + + int m_selectedMission; + +}; + +#endif // GUISCREENMISSIONGALLERY_H diff --git a/game/code/presentation/gui/frontend/guiscreenmultichoosechar.cpp b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.cpp new file mode 100644 index 0000000..3370019 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.cpp @@ -0,0 +1,349 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMultiChooseChar +// +// Description: Implementation of the CGuiScreenMultiChooseChar class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenmultichoosechar.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guisystem.h> + +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +/* +static const char* MENU_ITEMS[] = +{ + "Character" +}; + +static const int NUM_MENU_ITEMS = sizeof( MENU_ITEMS ) / sizeof( MENU_ITEMS[ 0 ] ); + +/* +static const char* MENU_CURSOR = "Cursor"; +*/ + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMultiChooseChar::CGuiScreenMultiChooseChar +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMultiChooseChar::CGuiScreenMultiChooseChar +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER ) +{ + memset( m_pMenu, 0, sizeof( m_pMenu ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "MultiChooseCharacter" ); + rAssert( pPage ); + + // Get character selection for all players + // + char itemName[ 32 ]; + for( int i = 0; i < MAX_PLAYERS; i++ ) + { + sprintf( itemName, "Character%d", i ); + m_pCharacter[ i ] = pPage->GetSprite( itemName ); + + rAssert( m_pCharacter[ i ] ); + } + +/* + Scrooby::Text* pText = NULL; + char menuItemName[ 32 ]; + + // Create and add menu items for all players + // + for( int i = 0; i < MAX_PLAYERS; i++ ) + { + m_pMenu[ i] = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu[ i ] != NULL ); + + for( int j = 0; j < NUM_MENU_ITEMS; j++ ) + { + sprintf( menuItemName, "%s%d", MENU_ITEMS[ j ], i ); + pText = pPage->GetText( menuItemName ); + rAssert( pText ); + + m_pMenu[ i ]->AddMenuItem( pText ); + } + } + +/* + // Set menu cursor + // + Scrooby::Sprite* pSprite = pPage->GetSprite( MENU_CURSOR ); + rAssert( pSprite != NULL ); + m_pMenu->SetCursor( pSprite ); +*/ +} + + +//=========================================================================== +// CGuiScreenMultiChooseChar::~CGuiScreenMultiChooseChar +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMultiChooseChar::~CGuiScreenMultiChooseChar() +{ + for( int i = 0; i < MAX_PLAYERS; i++ ) + { + if( m_pMenu[ i ] != NULL ) + { + delete m_pMenu[ i ]; + m_pMenu[ i ] = NULL; + } + } +} + + +//=========================================================================== +// CGuiScreenMultiChooseChar::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiChooseChar::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + // send message to front-end manager to quit front-end and + // start multiplayer head-to-head + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 2 ); // 2 = two players + + this->StartTransitionAnimation( 600, 640 ); + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 420, 450 ); + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( this->IsControllerMessage( message ) ) + { + int controllerId = param1; +/* + // register player 2, if not already done so and if controller ID different from player 1 + if( GetGuiSystem()->GetControllerId( PLAYER_2 ) == -1 && + GetGuiSystem()->GetControllerId( PLAYER_1 ) != controllerId ) + { + GetGuiSystem()->RegisterControllerId( PLAYER_2, controllerId ); + } +*/ + // send controller messages only to corresponding player menu + for( int i = 0; i < MAX_PLAYERS; i++ ) + { + if( GetGuiSystem()->GetControllerId( static_cast<ePlayer>( i ) ) == controllerId ) + { +/* + rAssert( m_pMenu[ i ] != NULL ); + m_pMenu[ i ]->HandleMessage( message, param1, param2 ); +*/ + this->HandleControllerMessage( i, message ); + + break; + } + } + } +/* + else + { + // send all other messages to all menus + for( int i = 0; i < MAX_PLAYERS; i++ ) + { + rAssert( m_pMenu[ i ] != NULL ); + m_pMenu[ i ]->HandleMessage( message, param1, param2 ); + } + } +*/ + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMultiChooseChar::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiChooseChar::InitIntro() +{ + // get character selection (for all players) + for( int i = 0; i < MAX_PLAYERS; i++ ) + { + } +} + + +//=========================================================================== +// CGuiScreenMultiChooseChar::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiChooseChar::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenMultiChooseChar::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiChooseChar::InitOutro() +{ + // set character selection (for all players) + for( int i = 0; i < MAX_PLAYERS; i++ ) + { + } +} + + +//=========================================================================== +// CGuiScreenMultiChooseChar::HandleControllerMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiChooseChar::HandleControllerMessage( int player, eGuiMessage message ) +{ + switch( message ) + { + case GUI_MSG_CONTROLLER_LEFT: + { + // decrement character selection + rAssert( m_pCharacter[ player ] ); + + int newIndex = m_pCharacter[ player ]->GetIndex() - 1; + if( newIndex < 0 ) + { + newIndex = m_pCharacter[ player ]->GetNumOfImages() - 1; + } + + m_pCharacter[ player ]->SetIndex( newIndex ); + + break; + } + + case GUI_MSG_CONTROLLER_RIGHT: + { + // increment character selection + rAssert( m_pCharacter[ player ] ); + + int newIndex = (m_pCharacter[ player ]->GetIndex() + 1) % m_pCharacter[ player ]->GetNumOfImages(); + + m_pCharacter[ player ]->SetIndex( newIndex ); + + break; + } + + default: + { + break; + } + } +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/frontend/guiscreenmultichoosechar.h b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.h new file mode 100644 index 0000000..b206e2c --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.h @@ -0,0 +1,62 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMultiChooseChar +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMULTICHOOSECHAR_H +#define GUISCREENMULTICHOOSECHAR_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +#include <constants/maxplayers.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +namespace Scrooby +{ + class Screen; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMultiChooseChar : public CGuiScreen +{ +public: + CGuiScreenMultiChooseChar( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMultiChooseChar(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void HandleControllerMessage( int player, eGuiMessage message ); + +private: + CGuiMenu* m_pMenu[ MAX_PLAYERS ]; + Scrooby::Sprite* m_pCharacter[ MAX_PLAYERS ]; + +}; + +#endif // GUISCREENMULTICHOOSECHAR_H diff --git a/game/code/presentation/gui/frontend/guiscreenmultisetup.cpp b/game/code/presentation/gui/frontend/guiscreenmultisetup.cpp new file mode 100644 index 0000000..1fd3aff --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmultisetup.cpp @@ -0,0 +1,235 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMultiSetup +// +// Description: Implementation of the CGuiScreenMultiSetup class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/16 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenmultisetup.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guisystem.h> + +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +static const char* MULTI_SETUP_MENU_ITEMS[] = +{ + "NumFlags", + "Base" +}; + +static const int NUM_MULTI_SETUP_MENU_ITEMS = sizeof( MULTI_SETUP_MENU_ITEMS ) / sizeof( MULTI_SETUP_MENU_ITEMS[ 0 ] ); + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMultiSetup::CGuiScreenMultiSetup +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMultiSetup::CGuiScreenMultiSetup +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MULTIPLAYER_SETUP ), + m_pMenu( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenMultiSetup" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "MultiSetup" ); + rAssert( pPage ); + + // Create a menu. + // + m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MULTI_SETUP_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + Scrooby::Text* pText = NULL; + Scrooby::Text* pTextValue = NULL; + char itemValue[ 32 ]; + + for( int i = 0; i < NUM_MULTI_SETUP_MENU_ITEMS; i++ ) + { + pText = pPage->GetText( MULTI_SETUP_MENU_ITEMS[ i ] ); + rAssert( pText ); + + // if text value exists + sprintf( itemValue, "%s_Value", MULTI_SETUP_MENU_ITEMS[ i ] ); + pTextValue = pPage->GetText( itemValue ); + + m_pMenu->AddMenuItem( pText, pTextValue ); + } +MEMTRACK_POP_GROUP(); +} + + +//=========================================================================== +// CGuiScreenMultiSetup::~CGuiScreenMultiSetup +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMultiSetup::~CGuiScreenMultiSetup() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenMultiSetup::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiSetup::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER ); + + this->StartTransitionAnimation( 390, 420 ); + + // register controller ID for player 1 + GetGuiSystem()->RegisterControllerId( PLAYER_1, param1 ); + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 290, 320 ); + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMultiSetup::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiSetup::InitIntro() +{ +} + + +//=========================================================================== +// CGuiScreenMultiSetup::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiSetup::InitRunning() +{ + // unregister all player controller ID's + GetGuiSystem()->UnregisterControllerId( ALL_PLAYERS ); +} + + +//=========================================================================== +// CGuiScreenMultiSetup::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiSetup::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/frontend/guiscreenmultisetup.h b/game/code/presentation/gui/frontend/guiscreenmultisetup.h new file mode 100644 index 0000000..41287fb --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenmultisetup.h @@ -0,0 +1,58 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMultiSetup +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/16 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMULTISETUP_H +#define GUISCREENMULTISETUP_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +namespace Scrooby +{ + class Screen; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMultiSetup : public CGuiScreen +{ +public: + CGuiScreenMultiSetup( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMultiSetup(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + CGuiMenu* m_pMenu; + +}; + +#endif // GUISCREENMULTISETUP_H diff --git a/game/code/presentation/gui/frontend/guiscreenoptions.cpp b/game/code/presentation/gui/frontend/guiscreenoptions.cpp new file mode 100644 index 0000000..261b030 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenoptions.cpp @@ -0,0 +1,609 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenOptions +// +// Description: Implementation of the CGuiScreenOptions class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenoptions.h> +#include <presentation/gui/frontend/guiscreenplaymovie.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guiscreenprompt.h> + +#include <cheats/cheatinputsystem.h> +#include <cheats/cheats.h> +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <group.h> +#include <text.h> + +#ifdef RAD_PS2 + #include <main/ps2platform.h> +#endif + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const unsigned int NUM_CHEAT_DISPLAY_LINES = 16; +const int PROGRESSIVE_MODE_TEST_TIME = 5000; // in msec + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenOptions::CGuiScreenOptions +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenOptions::CGuiScreenOptions +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_OPTIONS ), + m_pMenu( NULL ), + m_cheatsPage( NULL ), + m_cheatsOverlay( NULL ), + m_startingCheatID( 0 ), + m_elapsedProgressiveModeTestTime( -1 ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenOptions" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Options" ); + rAssert( pPage != NULL ); + + // Create a menu. + // + m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + Scrooby::Group* pGroup = pPage->GetGroup( "Menu" ); + rAssert( pGroup != NULL ); + +#ifdef RAD_WIN32 + m_pMenu->AddMenuItem( pGroup->GetText( "Display" ) ); +#endif + m_pMenu->AddMenuItem( pGroup->GetText( "Controller" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "Sound" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "ViewMovies" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "ViewCredits" ) ); + +#ifndef RAD_WIN32 + Scrooby::Text* display = pGroup->GetText( "Display" ); + if( display != NULL ) + { + display->SetVisible( false ); + } +#endif + + m_pMenu->AddMenuItem( pGroup->GetText( "DisplayMode" ), + pGroup->GetText( "DisplayMode_Value" ), + NULL, + NULL, + pGroup->GetSprite( "DisplayMode_ArrowL" ), + pGroup->GetSprite( "DisplayMode_ArrowR" ), + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + +#ifdef RAD_DEMO + m_pMenu->SetMenuItemEnabled( MENU_ITEM_VIEW_MOVIES, false ); + m_pMenu->SetMenuItemEnabled( MENU_ITEM_VIEW_CREDITS, false ); +#endif + +/* +#ifdef RAD_RELEASE + // hide 'view movies' in release build + // + m_pMenu->SetMenuItemEnabled( MENU_ITEM_VIEW_MOVIES, false, true ); +#else + // center menu items + // + pGroup->ResetTransformation(); + pGroup->Translate( 0, 30 ); +#endif +*/ + + // TC: no more display mode menu item on PS2, this is now done during bootup + // w/ specific button combo pressed and a display prompt + // +//#ifndef RAD_PS2 + // hide display mode menu item for non-PS2 platforms + // + m_pMenu->SetMenuItemEnabled( MENU_ITEM_DISPLAY_MODE, false, true ); + + #ifndef RAD_WIN32 + // re-center menu items + // + pGroup->ResetTransformation(); + pGroup->Translate( 0, -30 ); + #endif +//#endif // !RAD_PS2 + + // get cheats page, if included + // + m_cheatsPage = m_pScroobyScreen->GetPage( "Cheats" ); + if( m_cheatsPage != NULL ) + { + m_cheatsOverlay = m_cheatsPage->GetLayerByIndex( 0 ); + } + + // register self as cheat callback + // + GetCheatInputSystem()->RegisterCallback( this ); +MEMTRACK_POP_GROUP( "CGUIScreenOptions" ); +} + + +//=========================================================================== +// CGuiScreenOptions::~CGuiScreenOptions +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenOptions::~CGuiScreenOptions() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } + + // unregister self as cheat callback + // + GetCheatInputSystem()->UnregisterCallback( this ); +} + + +//=========================================================================== +// CGuiScreenOptions::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenOptions::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_MOTHER_OF_ALL_CHEATS ) ) + { + if( m_cheatsOverlay != NULL ) + { + // show/hide cheats overlay, depending on whether or not + // cheat input is activated on any of the controllers + // + bool isCheatInputActivated = false; + int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers(); + for( int i = 0; i < numUserInputHandlers; i++ ) + { + if( GetGuiSystem()->GetUserInputHandler( i ) != NULL && + GetCheatInputSystem()->IsActivated( i ) ) + { + isCheatInputActivated = true; + + break; + } + } + + m_cheatsOverlay->SetVisible( isCheatInputActivated ); + } + + if( message == GUI_MSG_CONTROLLER_RIGHT && + GetCheatInputSystem()->IsActivated( param1 ) ) + { + // toggle cheat list + // + m_startingCheatID += NUM_CHEAT_DISPLAY_LINES; + if( m_startingCheatID >= NUM_CHEATS ) + { + // wrap to the beginning + m_startingCheatID = 0; + } + + this->UpdateCheatsDisplay( m_startingCheatID ); + } + } + + if( this->IsControllerMessage( message ) && + GetCheatInputSystem()->IsActivated( param1 ) ) + { + // ignore all controller inputs when cheat input system is activated + return; + } + + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + if( param1 == PROMPT_DISPLAY_PROGRESSIVE_SCAN_PS2 ) + { + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { + // begin progressive scan test + // + this->ProgressiveModeTestBegin(); + } + else + { + // don't switch display mode and return to options screen + // + this->ReloadScreen(); + } + } + else if( param1 == PROMPT_DISPLAY_PROGRESSIVE_SCAN_CONFIRM ) + { + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { +#ifdef RAD_PS2 + PS2Platform::GetInstance()->SetProgressiveMode( true ); +#endif + rTunePrintf( "Current display mode confirmed: PROGRESSIVE.\n" ); + } + else + { + rTunePrintf( "Current display mode confirmed: INTERLACED.\n" ); + } + + // return to options screen + // + this->ReloadScreen(); + } + else + rTuneAssert(!"not handled"); + } + else if( message == GUI_MSG_MESSAGE_UPDATE || message == GUI_MSG_PROMPT_UPDATE ) // update from message/prompt screen + { + if( m_elapsedProgressiveModeTestTime != -1 ) + { + m_elapsedProgressiveModeTestTime += static_cast<int>( param1 ); + + if( m_elapsedProgressiveModeTestTime > PROGRESSIVE_MODE_TEST_TIME ) + { + this->OnProgressiveModeTestEnd(); + } + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_CHANGED: + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, param1 != MENU_ITEM_DISPLAY_MODE ); + + break; + } + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + if( param1 == MENU_ITEM_DISPLAY_MODE ) + { + if( param2 == 1 ) // progressive mode + { + // display confirmation prompt + // + m_guiManager->DisplayPrompt( PROMPT_DISPLAY_PROGRESSIVE_SCAN_PS2, this ); + } + else // interlaced mode + { +#ifdef RAD_PS2 + PS2Platform::GetInstance()->SetProgressiveMode( false ); +#endif + } + } + + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + switch( param1 ) + { + case MENU_ITEM_CONTROLLER: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_CONTROLLER ); + + this->StartTransitionAnimation( 530, 560 ); + + break; + } + case MENU_ITEM_SOUND: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SOUND ); + + this->StartTransitionAnimation( 660, 690 ); + + break; + } + case MENU_ITEM_VIEW_MOVIES: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VIEW_MOVIES ); + + this->StartTransitionAnimation( 914, 944 ); + + break; + } + case MENU_ITEM_VIEW_CREDITS: + { +/* + rAssert( m_guiManager ); + CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_VIEW_CREDITS ) ); + rAssert( playMovieScreen ); + playMovieScreen->SetMovieToPlay( MovieNames::CREDITS ); +*/ + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VIEW_CREDITS ); + + this->StartTransitionAnimation( 600, 630 ); + + break; + } +#ifdef RAD_WIN32 + case MENU_ITEM_DISPLAY: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_DISPLAY ); + + break; + } +#endif + default: + { + break; + } + } + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 110, 140 ); + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenOptions::OnCheatEntered +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiScreenOptions::OnCheatEntered( eCheatID cheatID, bool isEnabled ) +{ + this->UpdateCheatsDisplay( m_startingCheatID ); + + if( cheatID == CHEAT_ID_MOTHER_OF_ALL_CHEATS && !isEnabled ) + { + if( m_cheatsOverlay != NULL ) + { + m_cheatsOverlay->SetVisible( false ); + } + } +} + + +//=========================================================================== +// CGuiScreenOptions::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenOptions::InitIntro() +{ +#ifndef RAD_E3 + GetCheatInputSystem()->SetEnabled( true ); +#endif + + rAssert( m_pMenu != NULL ); + if( m_pMenu->GetSelection() == MENU_ITEM_DISPLAY_MODE ) + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + } + +#ifdef RAD_PS2 + // update current display mode + // + m_pMenu->SetSelectionValue( MENU_ITEM_DISPLAY_MODE, + PS2Platform::GetInstance()->GetProgressiveMode() ? 1 : 0 ); +#endif +} + + +//=========================================================================== +// CGuiScreenOptions::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenOptions::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenOptions::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenOptions::InitOutro() +{ +#ifndef RAD_E3 + GetCheatInputSystem()->SetEnabled( false ); +#endif +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenOptions::UpdateCheatsDisplay( int cheatID ) +{ + if( m_cheatsPage != NULL ) + { + // update cheats info + // + CheatsDB* cheatsDB = GetCheatInputSystem()->GetCheatsDB(); + rAssert( cheatsDB != NULL ); + + for( unsigned int i = 0; i < NUM_CHEAT_DISPLAY_LINES; i++ ) + { + char name[ 32 ]; + sprintf( name, "Cheat%d", i ); + Scrooby::Text* pText = m_cheatsPage->GetText( name ); + rAssert( pText != NULL ); + + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + if( cheatID < NUM_CHEATS ) + { + char cheatInfo[ 64 ]; + + const Cheat* cheat = cheatsDB->GetCheat( static_cast<eCheatID>( cheatID ) ); + if( cheat != NULL ) + { + CheatsDB::PrintCheatInfo( cheat, cheatInfo ); + + if( GetCheatInputSystem()->IsCheatEnabled( static_cast<eCheatID>( cheatID ) ) ) + { + strcat( cheatInfo, " (!)" ); // exclamation mark denotes cheat enabled + } + } + else + { + // display un-registered cheat + // + sprintf( cheatInfo, + "Cheat ID [%02d]: *** Not Registered! ***", cheatID ); +/* + // ignore/skip un-registered cheat and don't display anything + // + pText->SetString( 0, " " ); + i--; +*/ + } + + pText->SetString( 0, cheatInfo ); + } + else + { + pText->SetString( 0, " " ); + } + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); + + cheatID++; + } + } +} + +void +CGuiScreenOptions::ProgressiveModeTestBegin() +{ + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_PROGRESSIVE_SCAN_TEST, this ); + m_elapsedProgressiveModeTestTime = 0; + + rTunePrintf( "Testing progressive scan display ... ...\n" ); + +#ifdef RAD_PS2 + PS2Platform::GetInstance()->SetProgressiveMode( true ); +#endif +} + +void +CGuiScreenOptions::OnProgressiveModeTestEnd() +{ + m_guiManager->DisplayPrompt( PROMPT_DISPLAY_PROGRESSIVE_SCAN_CONFIRM, this ); + m_elapsedProgressiveModeTestTime = -1; + + rTunePrintf( "Progressive scan test completed.\n" ); + +#ifdef RAD_PS2 + PS2Platform::GetInstance()->SetProgressiveMode( false ); +#endif +} + diff --git a/game/code/presentation/gui/frontend/guiscreenoptions.h b/game/code/presentation/gui/frontend/guiscreenoptions.h new file mode 100644 index 0000000..a625163 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenoptions.h @@ -0,0 +1,82 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenOptions +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENOPTIONS_H +#define GUISCREENOPTIONS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <cheats/cheatinputsystem.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenOptions : public CGuiScreen, + public ICheatEnteredCallback +{ +public: + CGuiScreenOptions( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenOptions(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual void OnCheatEntered( eCheatID cheatID, bool isEnabled ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void UpdateCheatsDisplay( int cheatID ); + + void ProgressiveModeTestBegin(); + void OnProgressiveModeTestEnd(); + + enum eMenuItem + { +#ifdef RAD_WIN32 + MENU_ITEM_DISPLAY, +#endif + MENU_ITEM_CONTROLLER, + MENU_ITEM_SOUND, + MENU_ITEM_VIEW_MOVIES, + MENU_ITEM_VIEW_CREDITS, + MENU_ITEM_DISPLAY_MODE, + + NUM_MENU_ITEMS + }; + + CGuiMenu* m_pMenu; + + Scrooby::Page* m_cheatsPage; + Scrooby::Layer* m_cheatsOverlay; + int m_startingCheatID; + + int m_elapsedProgressiveModeTestTime; + +}; + +#endif // GUISCREENOPTIONS_H diff --git a/game/code/presentation/gui/frontend/guiscreenplaymovie.cpp b/game/code/presentation/gui/frontend/guiscreenplaymovie.cpp new file mode 100644 index 0000000..ca74357 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenplaymovie.cpp @@ -0,0 +1,460 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPlayMovie +// +// Description: Implementation of the CGuiScreenPlayMovie class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenplaymovie.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/utility/specialfx.h> + +#include <presentation/presentation.h> +#include <presentation/fmvplayer/fmvplayer.h> +#include <presentation/fmvplayer/fmvuserinputhandler.h> + +#include <memory/srrmemory.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> + +#include <screen.h> +#include <page.h> +#include <text.h> + +#include <p3d/view.hpp> + +#include <raddebug.hpp> // Foundation +#include <radmovie2.hpp> + +#include <sound/soundmanager.h> + +#include <input/inputmanager.h> + + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPlayMovie::CGuiScreenPlayMovie +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPlayMovie::CGuiScreenPlayMovie +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID windowID +) +: CGuiScreen( pScreen, pParent, windowID ), + m_demoText( NULL ), + m_elapsedTime( 0 ), + m_IsSkippable(true) +// m_tvFrame( NULL ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Demo" ); + if( pPage != NULL ) + { + m_demoText = pPage->GetText( "Demo" ); + rAssert( m_demoText != NULL ); + } + +/* + // background TV frame layer + // + m_tvFrame = pPage->GetLayer( "TVFrame" ); +*/ + + if( windowID == GUI_SCREEN_ID_PLAY_MOVIE ) + { + // invert fading; ie. fade out during transition in, and vice versa + // + m_inverseFading = true; + } +} + + +//=========================================================================== +// CGuiScreenPlayMovie::~CGuiScreenPlayMovie +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPlayMovie::~CGuiScreenPlayMovie() +{ +} + + +//=========================================================================== +// CGuiScreenPlayMovie::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPlayMovie::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + GetPresentationManager()->Update( param1 ); + + if( m_demoText != NULL ) + { + m_elapsedTime += param1; + + const unsigned int BLINK_PERIOD = 250; + bool blinked = GuiSFX::Blink( m_demoText, + (float)m_elapsedTime, + (float)BLINK_PERIOD ); + if( blinked ) + { + m_elapsedTime %= BLINK_PERIOD; + } + } +/* + if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + if( m_numTransitionsPending <= 0 ) + { + // restore the background TV frame + // + if( m_tvFrame != NULL ) + { + m_tvFrame->SetVisible( true ); + } + } + } +*/ + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + // don't allow user to back out of screen, must be done + // by skipping movie + // + return; + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +void +CGuiScreenPlayMovie::SetMovieToPlay( const char* movieName, bool IsSkippable, bool KillMusic, bool IsLocalized ) +{ + rAssert( movieName != NULL ); + + FMVEvent* pEvent = NULL; + GetPresentationManager()->QueueFMV( &pEvent, this ); + + strcpy( pEvent->fileName, movieName ); + pEvent->SetRenderLayer( RenderEnums::PresentationSlot ); + pEvent->SetAutoPlay( false ); + pEvent->SetClearWhenDone( true ); + pEvent->SetSkippable(IsSkippable); + +#ifdef PAL + if( IsLocalized ) + { + switch( CGuiTextBible::GetCurrentLanguage() ) + { + case Scrooby::XL_FRENCH: + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_FRENCH ); + + break; + } + case Scrooby::XL_GERMAN: + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_GERMAN ); + + break; + } + case Scrooby::XL_SPANISH: + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_SPANISH ); + + break; + } + default: + { + rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH ); + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH ); + + break; + } + } + } + else +#endif // PAL + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH ); + } + + if( KillMusic ) + { + pEvent->KillMusic(); + } +} + + +//============================================================================= +// CGuiScreenPlayMovie::OnPresentationEventBegin +//============================================================================= +// Description: Comment +// +// Parameters: ( PresentationEvent* pEvent ) +// +// Return: void +// +//============================================================================= +void CGuiScreenPlayMovie::OnPresentationEventBegin( PresentationEvent* pEvent ) +{ + GetSoundManager()->StopForMovie(); +} + + +//============================================================================= +// CGuiScreenPlayMovie::OnPresentationEventLoadComplete +//============================================================================= +// Description: Comment +// +// Parameters: ( PresentationEvent* pEvent ) +// +// Return: void +// +//============================================================================= +void CGuiScreenPlayMovie::OnPresentationEventLoadComplete( PresentationEvent* pEvent ) +{ +} + + +//============================================================================= +// CGuiScreenPlayMovie::OnPresentationEventEnd +//============================================================================= +// Description: Comment +// +// Parameters: ( PresentationEvent* pEvent ) +// +// Return: void +// +//============================================================================= +void CGuiScreenPlayMovie::OnPresentationEventEnd( PresentationEvent* pEvent ) +{ + if( GetPresentationManager()->IsQueueEmpty() ) + { + GetSoundManager()->ResumeAfterMovie(); + + if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_INTRO ) + { + // finished playing intro movie, now go to main menu + // + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_INTRO_TRANSITION, + CLEAR_WINDOW_HISTORY ); + } + else if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME ) + { + // finished playing new game movie, now quit the FE + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player + } + else + { + rAssert( m_guiManager ); + eGuiWindowID previousScreen = m_guiManager->GetPreviousScreen(); + if( previousScreen == GUI_SCREEN_ID_VIEW_MOVIES ) + { + this->StartTransitionAnimation( 1005, 1035 ); + } + else if( previousScreen == GUI_SCREEN_ID_OPTIONS ) + { + this->StartTransitionAnimation( 630, 660 ); + } + + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); + } + } +} + + +//=========================================================================== +// CGuiScreenPlayMovie::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPlayMovie::InitIntro() +{ + rAssertMsg( !GetPresentationManager()->IsQueueEmpty(), + "ERROR: *** No movies were queued for playing!" ); + + if( m_demoText != NULL ) + { + m_demoText->SetVisible( false ); + m_elapsedTime = 0; + } + +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetInGameMode( true ); +#endif + +/* + // hide background TV frame so we can fade in/out the foreground one + // + if( m_tvFrame != NULL ) + { + m_tvFrame->SetVisible( false ); + } +*/ +} + + +//=========================================================================== +// CGuiScreenPlayMovie::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPlayMovie::InitRunning() +{ + if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_DEMO ) + { + // disable screen clearing for GUI render layer + // + GetRenderManager()->mpLayer( RenderEnums::GUI )->pView( 0 )->SetClearMask( PDDI_BUFFER_DEPTH | PDDI_BUFFER_STENCIL ); + } + else + { + GetRenderManager()->mpLayer( RenderEnums::GUI )->Chill(); + } + + GetPresentationManager()->GetFMVPlayer()->Play(); + +#ifdef FINAL + if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME ) + { + // disable skipping of new game movie + // + FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler(); + rAssert( userInputHandler != NULL ); + userInputHandler->SetEnabled( false ); + } +#endif +} + + +//=========================================================================== +// CGuiScreenPlayMovie::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPlayMovie::InitOutro() +{ + if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_DEMO ) + { + // enable screen clearing + // + GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearMask( PDDI_BUFFER_ALL ); + } + else + { + GetRenderManager()->mpLayer( RenderEnums::GUI )->Warm(); + } + +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetInGameMode( false ); +#endif + +#ifdef FINAL + if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME ) + { + // re-enable FMV user inputs + // + FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler(); + rAssert( userInputHandler != NULL ); + userInputHandler->SetEnabled( true ); + } +#endif +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/frontend/guiscreenplaymovie.h b/game/code/presentation/gui/frontend/guiscreenplaymovie.h new file mode 100644 index 0000000..40c8c3a --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenplaymovie.h @@ -0,0 +1,70 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPlayMovie +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPLAYMOVIE_H +#define GUISCREENPLAYMOVIE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/presevents/presentationevent.h> +#include <constants/movienames.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPlayMovie : public CGuiScreen, + public PresentationEvent::PresentationEventCallBack +{ +public: + CGuiScreenPlayMovie( Scrooby::Screen* pScreen, CGuiEntity* pParent, + eGuiWindowID windowID = GUI_SCREEN_ID_PLAY_MOVIE ); + virtual ~CGuiScreenPlayMovie(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void SetMovieToPlay( const char* movieName, bool IsSkippable = true, + bool KillMusic = false, + bool IsLocalized = true ); + + // Implements PresentationEvent::PresentationEventCallBack + // + virtual void OnPresentationEventBegin( PresentationEvent* pEvent ); + virtual void OnPresentationEventLoadComplete( PresentationEvent* pEvent ); + virtual void OnPresentationEventEnd( PresentationEvent* pEvent ); + + void SetSkippable(bool IsSkippable) {m_IsSkippable = IsSkippable;} + bool GetSkippable(void) const {return m_IsSkippable;} + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + Scrooby::Text* m_demoText; + unsigned int m_elapsedTime; + bool m_IsSkippable : 1; +}; + +#endif // GUISCREENPLAYMOVIE_H diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbook.cpp b/game/code/presentation/gui/frontend/guiscreenscrapbook.cpp new file mode 100644 index 0000000..c41b52d --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenscrapbook.cpp @@ -0,0 +1,266 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenScrapBook +// +// Description: Implementation of the CGuiScreenScrapBook class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenscrapbook.h> +#include <presentation/gui/guimenu.h> + +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> + +// Scrooby +// +#include <screen.h> +#include <page.h> +#include <group.h> +#include <text.h> + +// ATG +// +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenScrapBook::CGuiScreenScrapBook +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenScrapBook::CGuiScreenScrapBook +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SCRAP_BOOK ), + m_pMenu( NULL ), + m_krustySticker( NULL ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "ScrapBook" ); + rAssert( pPage != NULL ); + + // get krusty sticker overlay + // + m_krustySticker = pPage->GetGroup( "KrustySticker" ); + rAssert( m_krustySticker != NULL ); + m_krustySticker->SetVisible( false ); // hide by default + +#ifdef PAL + m_krustySticker->ScaleAboutPoint( 0.9f, 0, 0 ); +#endif + + // create menu + // + m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // add menu items + // + Scrooby::Group* pGroup = pPage->GetGroup( "Menu" ); + rAssert( pGroup != NULL ); + m_pMenu->AddMenuItem( pGroup->GetText( "OpenBook" ) ); + Scrooby::Text* gameStats = pGroup->GetText( "GameStats" ); + m_pMenu->AddMenuItem( gameStats ); + +#ifdef PAL + rAssert( gameStats != NULL ); + gameStats->SetTextMode( Scrooby::TEXT_WRAP ); +#endif +} + + +//=========================================================================== +// CGuiScreenScrapBook::~CGuiScreenScrapBook +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenScrapBook::~CGuiScreenScrapBook() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenScrapBook::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBook::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + this->OnMenuSelectionMade( static_cast<eMenuItem>( param1 ) ); + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 350, 380 ); + + break; + } + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenScrapBook::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBook::InitIntro() +{ + // update percent game complete + // + float percentComplete = GetCharacterSheetManager()->QueryPercentGameCompleted(); + + // show krusty sticker only if game percent complete is 100% + // + rAssert( m_krustySticker != NULL ); + m_krustySticker->SetVisible( percentComplete > 99.999f ); +} + + +//=========================================================================== +// CGuiScreenScrapBook::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBook::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenScrapBook::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBook::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenScrapBook::OnMenuSelectionMade( eMenuItem selection ) +{ + switch( selection ) + { + case MENU_OPEN_BOOK: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ); + + break; + } + case MENU_GAME_STATS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SCRAP_BOOK_STATS ); + + break; + } + default: + { + rAssertMsg( false, "Invalid menu selection!" ); + + break; + } + } + + this->StartTransitionAnimation( 810, 830 ); +} + diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbook.h b/game/code/presentation/gui/frontend/guiscreenscrapbook.h new file mode 100644 index 0000000..d18d988 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenscrapbook.h @@ -0,0 +1,64 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenScrapBook +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENSCRAPBOOK_H +#define GUISCREENSCRAPBOOK_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenScrapBook : public CGuiScreen +{ +public: + CGuiScreenScrapBook( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenScrapBook(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + enum eMenuItem + { + MENU_OPEN_BOOK, + MENU_GAME_STATS, + + NUM_MENU_ITEMS + }; + + void OnMenuSelectionMade( eMenuItem selection ); + + CGuiMenu* m_pMenu; + Scrooby::Group* m_krustySticker; + +}; + +#endif // GUISCREENSCRAPBOOK_H diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.cpp b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.cpp new file mode 100644 index 0000000..b1daa4d --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.cpp @@ -0,0 +1,674 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenScrapBookContents +// +// Description: Implementation of the CGuiScreenScrapBookContents class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenscrapbookcontents.h> +#include <presentation/gui/frontend/guiscreenplaymovie.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiuserinputhandler.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guitextbible.h> + +#include <cards/cardgallery.h> +#include <events/eventmanager.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <render/enums/renderenums.h> + +// Scrooby +// +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <text.h> +#include <sprite.h> + +// ATG +// +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* MOVIES_INGAME[] = +{ + MovieNames::MOVIE2, // level 1 + MovieNames::MOVIE3, // level 2 + MovieNames::MOVIE8, // level 3 - I & S movie! + MovieNames::MOVIE4, // level 4 + MovieNames::MOVIE5, // level 5 + MovieNames::MOVIE6, // level 6 + MovieNames::MOVIE7, // level 7 + + "" // dummy terminator +}; + +const float LEVEL_BAR_CORRECTION_SCALE = 2.0f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenScrapBookContents::CGuiScreenScrapBookContents +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenScrapBookContents::CGuiScreenScrapBookContents +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ), + m_pMenu( NULL ), + m_levelBarGroup( NULL ), + m_levelSelection( NULL ), + m_LTrigger( NULL ), + m_RTrigger( NULL ), + m_LTriggerBgd( NULL ), + m_RTriggerBgd( NULL ), + m_currentLevel( 0 ), + m_sparkles( NULL ) +{ + memset( m_menuImages, 0, sizeof( m_menuImages ) ); + + // Retrieve the Scrooby drawing elements (from LevelBar.pag) + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LevelBar" ); + rAssert( pPage != NULL ); + + m_levelBarGroup = pPage->GetGroup( "LevelBar" ); + rAssert( m_levelBarGroup != NULL ); + + // apply image correction scale + // + Scrooby::Sprite* levelBarBgd = m_levelBarGroup->GetSprite( "LevelBar" ); + if( levelBarBgd != NULL ) + { + levelBarBgd->ResetTransformation(); + levelBarBgd->ScaleAboutCenter( LEVEL_BAR_CORRECTION_SCALE ); + } + + // get level bar elements + // + m_levelSelection = m_levelBarGroup->GetText( "Level" ); + rAssert( m_levelSelection != NULL ); + m_levelSelection->ResetTransformation(); + m_levelSelection->ScaleAboutCenter( 0.75f ); + + m_LTrigger = m_levelBarGroup->GetGroup( "LTrigger" ); + rAssert( m_LTrigger != NULL ); + + m_RTrigger = m_levelBarGroup->GetGroup( "RTrigger" ); + rAssert( m_RTrigger != NULL ); + +#ifdef RAD_PS2 + // PS2 only, scale up L1 and R1 button images + // + m_LTrigger->ResetTransformation(); + m_LTrigger->ScaleAboutCenter( 1.25f, 1.15f, 1.0f ); + m_RTrigger->ResetTransformation(); + m_RTrigger->ScaleAboutCenter( 1.25f, 1.15f, 1.0f ); +#endif + +#ifdef RAD_XBOX + switch( CGuiTextBible::GetCurrentLanguage() ) + { + case Scrooby::XL_FRENCH: + { + m_LTrigger->GetSprite( "LTrigger" )->SetIndex( 2 ); + m_RTrigger->GetSprite( "RTrigger" )->SetIndex( 1 ); + + break; + } + case Scrooby::XL_SPANISH: + { + m_LTrigger->GetSprite( "LTrigger" )->SetIndex( 1 ); + m_RTrigger->GetSprite( "RTrigger" )->SetIndex( 1 ); + + break; + } + default: + { + break; + } + } +#endif // RAD_XBOX + + m_LTriggerBgd = m_LTrigger->GetSprite( "LTriggerBgd" ); + m_RTriggerBgd = m_RTrigger->GetSprite( "RTriggerBgd" ); + +#ifdef RAD_WIN32 + m_LTriggerBgd->ScaleAboutCenter( 0.5 ); + m_RTriggerBgd->ScaleAboutCenter( 0.5 ); +#endif + + // Retrieve the Scrooby drawing elements (from ScrapBookContents.pag) + // + pPage = m_pScroobyScreen->GetPage( "ScrapBookContents" ); + rAssert( pPage != NULL ); + + // create a 2D menu + // + m_pMenu = new CGuiMenu2D( this, NUM_MENU_ITEMS, 3 ); + rAssert( m_pMenu != NULL ); + + // add menu items + // + Scrooby::Group* pGroup = pPage->GetGroup( "Menu" ); + rAssert( pGroup != NULL ); + m_pMenu->AddMenuItem( pGroup->GetText( "StoryMissions" ), + pGroup->GetText( "StoryMissions_Unlocked" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "CharacterClothing" ), + pGroup->GetText( "CharacterClothing_Unlocked" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "Vehicles" ), + pGroup->GetText( "Vehicles_Unlocked" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "Dummy" ), + NULL, NULL, NULL, NULL, NULL, ALL_ATTRIBUTES_OFF ); + m_pMenu->AddMenuItem( pGroup->GetText( "CollectorCards" ), + pGroup->GetText( "CollectorCards_Unlocked" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "Dummy" ), + NULL, NULL, NULL, NULL, NULL, ALL_ATTRIBUTES_OFF ); +// m_pMenu->AddMenuItem( pGroup->GetText( "Movies" ), +// pGroup->GetText( "Movies_Unlocked" ) ); + + // get menu images + // + m_menuImages[ MENU_STORY_MISSIONS ] = pGroup->GetSprite( "StoryMissions" ); + m_menuImages[ MENU_CHARACTER_CLOTHING ] = pGroup->GetSprite( "CharacterClothing" ); + m_menuImages[ MENU_VEHICLES ] = pGroup->GetSprite( "Vehicles" ); + m_menuImages[ MENU_COLLECTOR_CARDS ] = pGroup->GetSprite( "CollectorCards" ); +// m_menuImages[ MENU_MOVIES ] = pGroup->GetSprite( "Movies" ); + + // shrink down bottom row images + // + const float MENU_IMAGE_SCALE = 0.75f; + rAssert( m_menuImages[ MENU_COLLECTOR_CARDS ] != NULL ); + m_menuImages[ MENU_COLLECTOR_CARDS ]->ResetTransformation(); + m_menuImages[ MENU_COLLECTOR_CARDS ]->ScaleAboutCenter( MENU_IMAGE_SCALE ); + + // get sparkles overlay + // + pPage = m_pScroobyScreen->GetPage( "3dFE" ); + rAssert( pPage != NULL ); + m_sparkles = pPage->GetLayer( "ScrapBookSparkles" ); +} + +//=========================================================================== +// CGuiScreenScrapBookContents::~CGuiScreenScrapBookContents +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenScrapBookContents::~CGuiScreenScrapBookContents() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiScreenScrapBookContents::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreenScrapBookContents::CheckCursorAgainstHotspots( float x, float y ) +{ + eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y ); + if( hotSpotType == HOTSPOT_NONE ) + { + if( m_LTriggerBgd ) + { + if( m_LTriggerBgd->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_LTRIGGER; + } + } + if( m_RTriggerBgd ) + { + if( m_RTriggerBgd->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_RTRIGGER; + } + } + + } + return hotSpotType; +} +#endif + +//=========================================================================== +// CGuiScreenScrapBookContents::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookContents::HandleMessage( eGuiMessage message, + unsigned int param1, + unsigned int param2 ) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + // toggle L/R trigger icon backgrounds + // + if( m_LTriggerBgd != NULL && m_RTriggerBgd != NULL ) + { + m_LTriggerBgd->SetIndex( 0 ); + m_RTriggerBgd->SetIndex( 0 ); + + if( !m_pMenu->HasSelectionBeenMade() ) + { + int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers(); + for( int i = 0; i < numUserInputHandlers; i++ ) + { + CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i ); + if( userInputHandler != NULL ) + { + if( userInputHandler->IsButtonDown( GuiInput::L1 ) +#ifdef RAD_WIN32 + || GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_LTRIGGER +#endif + ) + { + rAssert( m_LTriggerBgd->GetNumOfImages() > 1 ); + m_LTriggerBgd->SetIndex( 1 ); + } + + if( userInputHandler->IsButtonDown( GuiInput::R1 ) +#ifdef RAD_WIN32 + || GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_RTRIGGER +#endif + ) + { + rAssert( m_RTriggerBgd->GetNumOfImages() > 1 ); + m_RTriggerBgd->SetIndex( 1 ); + } + } + } + } + } + + break; + } + case GUI_MSG_CONTROLLER_L1: + { + if( !m_pMenu->HasSelectionBeenMade() ) + { + // decrement level selection + // + this->OnLevelSelectionChange( -1 ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + + break; + } + case GUI_MSG_CONTROLLER_R1: + { + if( !m_pMenu->HasSelectionBeenMade() ) + { + // increment level selection + // + this->OnLevelSelectionChange( +1 ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + this->OnMenuSelectionMade( static_cast<eMenuItem>( param1 ) ); + + break; + } +/* + case GUI_MSG_CONTROLLER_SELECT: + { + if( m_currentLevel == RenderEnums::L3 && + m_pMenu->GetSelection() == MENU_MOVIES ) + { + GetInputManager()->RegisterControllerID( 0, param1 ); + } + + break; + } +*/ + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 830, 850 ); + + // hide sparkles + // + if( m_sparkles != NULL ) + { + m_sparkles->SetVisible( false ); + } + + break; + } + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenScrapBookContents::SetLevelBarVisible +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookContents::SetLevelBarVisible( bool isVisible ) +{ + rAssert( m_levelBarGroup != NULL ); + m_levelBarGroup->SetVisible( isVisible ); +} + +//=========================================================================== +// CGuiScreenScrapBookContents::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookContents::InitIntro() +{ + // this is needed here to update all the unlocked n/N values + // + this->OnLevelSelectionChange( 0 ); + + // show L/R trigger buttons + // + rAssert( m_LTrigger != NULL && m_RTrigger != NULL ); + m_LTrigger->SetVisible( true ); + m_RTrigger->SetVisible( true ); +} + +//=========================================================================== +// CGuiScreenScrapBookContents::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookContents::InitRunning() +{ + // show sparkles only if game percent complete is 100% + // + float percentComplete = GetCharacterSheetManager()->QueryPercentGameCompleted(); + if( m_sparkles != NULL ) + { + // TC: [TODO] verify sparkles look OK + // +// m_sparkles->SetVisible( percentComplete == 100.0f ); + } +} + +//=========================================================================== +// CGuiScreenScrapBookContents::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookContents::InitOutro() +{ +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenScrapBookContents::OnLevelSelectionChange( int delta ) +{ + m_currentLevel = (m_currentLevel + RenderEnums::numLevels + delta) % RenderEnums::numLevels; + rAssert( m_levelSelection ); + + // update level selection bar + // + m_levelSelection->SetIndex( m_currentLevel ); + + // update menu images and unlocked values + // + for( int i = 0; i < NUM_MENU_ITEMS; i++ ) + { + if( m_menuImages[ i ] != NULL ) + { + m_menuImages[ i ]->SetIndex( m_currentLevel ); + } + } + + // update unlocked values + // + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + char buffer[ 8 ]; + Scrooby::Text* unlockedText = NULL; + rAssert( m_pMenu != NULL ); + + // missions + int numMissionsCompleted = GetCharacterSheetManager()->QueryNumMissionsCompleted( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ); + if( GetCharacterSheetManager()->QueryBonusMissionCompleted( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ) ) + { + numMissionsCompleted++; + } + + sprintf( buffer, "%d / %d", + numMissionsCompleted, + 8 ); // m_currentLevel == 6 ? 5 : 7 ); + unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_STORY_MISSIONS )->GetItemValue() ); + rAssert( unlockedText != NULL ); + unlockedText->SetString( 0, buffer ); + + // clothing + sprintf( buffer, "%d / %d", + GetCharacterSheetManager()->QueryNumSkinsUnlocked( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ), + 3 ); + unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_CHARACTER_CLOTHING )->GetItemValue() ); + rAssert( unlockedText != NULL ); + unlockedText->SetString( 0, buffer ); + + // vehicles + int numVehiclesUnlocked = GetCharacterSheetManager()->QueryNumCarUnlocked( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ); + if( GetRewardsManager()->GetReward( m_currentLevel, Reward::eDefaultCar )->RewardStatus() ) + { + numVehiclesUnlocked++; + } + sprintf( buffer, "%d / %d", + numVehiclesUnlocked, + 6 ); + unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_VEHICLES )->GetItemValue() ); + rAssert( unlockedText != NULL ); + unlockedText->SetString( 0, buffer ); + + // cards + sprintf( buffer, "%d / %d", + GetCharacterSheetManager()->QueryNumCardsCollected( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ), + NUM_CARDS_PER_LEVEL ); + unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_COLLECTOR_CARDS )->GetItemValue() ); + rAssert( unlockedText != NULL ); + unlockedText->SetString( 0, buffer ); + +/* + // movies + bool isMovieUnlocked = GetCharacterSheetManager()->QueryFMVUnlocked( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ); + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MOVIES ) ) + { + isMovieUnlocked = true; + } + + sprintf( buffer, "%d / %d", + isMovieUnlocked ? 1 : 0, + 1 ); + unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_MOVIES )->GetItemValue() ); + rAssert( unlockedText != NULL ); + unlockedText->SetString( 0, buffer ); + + m_pMenu->SetMenuItemEnabled( MENU_MOVIES, isMovieUnlocked ); +*/ + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); +} + +void +CGuiScreenScrapBookContents::OnMenuSelectionMade( eMenuItem selection ) +{ + switch( selection ) + { + case MENU_STORY_MISSIONS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MISSION_GALLERY ); + + break; + } + case MENU_CHARACTER_CLOTHING: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SKIN_GALLERY ); + + break; + } + case MENU_VEHICLES: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VEHICLE_GALLERY ); + + break; + } + case MENU_COLLECTOR_CARDS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_CARD_GALLERY ); + + break; + } +/* + case MENU_MOVIES: + { + if( m_currentLevel != RenderEnums::L3 ) + { + rAssert( m_guiManager ); + CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE ) ); + rAssert( playMovieScreen ); + + rAssert( MOVIES_INGAME[ m_currentLevel ] != "" ); + playMovieScreen->SetMovieToPlay( MOVIES_INGAME[ m_currentLevel ] ); + + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_PLAY_MOVIE ); + } + else // special case for level 3 + { + // TC: [TODO] Need to find out from D.Evenson which mission in L3 to start + // + GetCharacterSheetManager()->SetCurrentMission( static_cast<RenderEnums::LevelEnum>( m_currentLevel ), + static_cast<RenderEnums::MissionEnum>( RenderEnums::M1 ) ); + + // send message to front-end manager to quit front-end and + // start single player story mode + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player + } + + break; + } +*/ + default: + { + rAssertMsg( false, "Invalid menu selection!" ); + + break; + } + } + + // hide L/R trigger buttons + // + rAssert( m_LTrigger != NULL && m_RTrigger != NULL ); + m_LTrigger->SetVisible( false ); + m_RTrigger->SetVisible( false ); +} + diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.h b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.h new file mode 100644 index 0000000..d3a6d0f --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.h @@ -0,0 +1,97 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenScrapBookContents +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENSCRAPBOOKCONTENTS_H +#define GUISCREENSCRAPBOOKCONTENTS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu2D; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenScrapBookContents : public CGuiScreen +{ +public: + CGuiScreenScrapBookContents( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenScrapBookContents(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + unsigned int GetCurrentLevel() const; + void SetLevelBarVisible( bool isVisible ); +#ifdef RAD_WIN32 + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); +#endif + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + enum eMenuItem + { + MENU_STORY_MISSIONS, + MENU_CHARACTER_CLOTHING, + MENU_VEHICLES, + MENU_DUMMY_3, + MENU_COLLECTOR_CARDS, + MENU_DUMMY_5, +// MENU_MOVIES, + + NUM_MENU_ITEMS + }; + + void OnLevelSelectionChange( int delta ); + void OnMenuSelectionMade( eMenuItem selection ); + + CGuiMenu2D* m_pMenu; + + Scrooby::Sprite* m_menuImages[ NUM_MENU_ITEMS ]; + + Scrooby::Group* m_levelBarGroup; + Scrooby::Text* m_levelSelection; + Scrooby::Group* m_LTrigger; + Scrooby::Group* m_RTrigger; + Scrooby::Sprite* m_LTriggerBgd; + Scrooby::Sprite* m_RTriggerBgd; + unsigned int m_currentLevel; + + Scrooby::Layer* m_sparkles; + +}; + +//=========================================================================== +// Inlines +//=========================================================================== + +inline unsigned int CGuiScreenScrapBookContents::GetCurrentLevel() const +{ + return m_currentLevel; +} + +#endif // GUISCREENSCRAPBOOKCONTENTS_H diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookstats.cpp b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.cpp new file mode 100644 index 0000000..857dc2f --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.cpp @@ -0,0 +1,284 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenScrapBookStats +// +// Description: Implementation of the CGuiScreenScrapBookStats class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenscrapbookstats.h> + +#include <cards/cardgallery.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <render/enums/renderenums.h> + +// Scrooby +// +#include <screen.h> +#include <page.h> +#include <group.h> +#include <text.h> + +// ATG +// +#include <raddebug.hpp> + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenScrapBookStats::CGuiScreenScrapBookStats +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenScrapBookStats::CGuiScreenScrapBookStats +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SCRAP_BOOK_STATS ), + m_percentGameComplete( NULL ) +{ + memset( m_gameStats, 0, sizeof( m_gameStats ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "ScrapBookStats" ); + rAssert( pPage != NULL ); + + // scale down game stats text bit + // + Scrooby::Text* gameStats = pPage->GetText( "GameStats" ); + if( gameStats != NULL ) + { + gameStats->ResetTransformation(); + gameStats->ScaleAboutCenter( 0.75f ); + } + + Scrooby::Group* pGroup = pPage->GetGroup( "Stats" ); + rAssert( pGroup != NULL ); + + m_gameStats[ STAT_STORY_MISSIONS ] = pGroup->GetText( "StoryMissions_Unlocked" ); + m_gameStats[ STAT_BONUS_MISSIONS ] = pGroup->GetText( "BonusMissions_Unlocked" ); + m_gameStats[ STAT_STREET_RACES ] = pGroup->GetText( "StreetRaces_Unlocked" ); + m_gameStats[ STAT_CARDS ] = pGroup->GetText( "Cards_Unlocked" ); + m_gameStats[ STAT_CLOTHING ] = pGroup->GetText( "Clothing_Unlocked" ); + m_gameStats[ STAT_VEHICLES ] = pGroup->GetText( "Vehicles_Unlocked" ); + m_gameStats[ STAT_WASPS ] = pGroup->GetText( "Wasps_Unlocked" ); + m_gameStats[ STAT_GAGS ] = pGroup->GetText( "Gags_Unlocked" ); + m_gameStats[ STAT_MOVIES ] = pGroup->GetText( "Movies_Unlocked" ); + + // get game complete value + // + m_percentGameComplete = pGroup->GetText( "GameComplete_Value" ); + rAssert( m_percentGameComplete != NULL ); + +#ifdef RAD_DEBUG + for( int i = 0; i < NUM_GAME_STATS; i++ ) + { + rAssert( m_gameStats[ i ] != NULL ); + } +#endif +} + + +//=========================================================================== +// CGuiScreenScrapBookStats::~CGuiScreenScrapBookStats +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenScrapBookStats::~CGuiScreenScrapBookStats() +{ +} + + +//=========================================================================== +// CGuiScreenScrapBookStats::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookStats::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 830, 850 ); + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenScrapBookStats::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookStats::InitIntro() +{ + // sum game stats totals for all levels + // + int numUnlocked[ NUM_GAME_STATS ]; + memset( numUnlocked, 0, sizeof( numUnlocked ) ); + + int numTotalGagsInGame = 0; + int numTotalWaspsInGame = 0; + + for( int i = 0; i < RenderEnums::numLevels; i++ ) + { + numUnlocked[ STAT_STORY_MISSIONS ] += GetCharacterSheetManager()->QueryNumMissionsCompleted( static_cast<RenderEnums::LevelEnum>( i ) ); + numUnlocked[ STAT_BONUS_MISSIONS ] += GetCharacterSheetManager()->QueryBonusMissionCompleted( static_cast<RenderEnums::LevelEnum>( i ) ) ? 1 : 0; + numUnlocked[ STAT_STREET_RACES ] += GetCharacterSheetManager()->QueryNumStreetRacesCompleted( static_cast<RenderEnums::LevelEnum>( i ) ); + numUnlocked[ STAT_CARDS ] += GetCardGallery()->GetCollectedCards( i )->m_numCards; + numUnlocked[ STAT_CLOTHING ] += GetCharacterSheetManager()->QueryNumSkinsUnlocked( static_cast<RenderEnums::LevelEnum>( i ) ); + numUnlocked[ STAT_VEHICLES ] += GetCharacterSheetManager()->QueryNumCarUnlocked( static_cast<RenderEnums::LevelEnum>( i ) ); + numUnlocked[ STAT_WASPS ] += GetCharacterSheetManager()->QueryNumWaspsDestroyed( static_cast<RenderEnums::LevelEnum>( i ) ); + numUnlocked[ STAT_GAGS ] += GetCharacterSheetManager()->QueryNumGagsViewed( static_cast<RenderEnums::LevelEnum>( i ) ); + numUnlocked[ STAT_MOVIES ] += GetCharacterSheetManager()->QueryFMVUnlocked( static_cast<RenderEnums::LevelEnum>( i ) ) ? 1 : 0; + + numTotalGagsInGame += GetRewardsManager()->GetTotalGags( i ); + numTotalWaspsInGame += GetRewardsManager()->GetTotalWasps( i ); + } + + // update game stats + // + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + char buffer[ 32 ]; + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_STORY_MISSIONS ], 49 ); + m_gameStats[ STAT_STORY_MISSIONS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_BONUS_MISSIONS ], 7 ); + m_gameStats[ STAT_BONUS_MISSIONS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_STREET_RACES ], 21 ); + m_gameStats[ STAT_STREET_RACES ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_CARDS ], 49 ); + m_gameStats[ STAT_CARDS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_CLOTHING ], 21 ); + m_gameStats[ STAT_CLOTHING ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_VEHICLES ], 35 ); + m_gameStats[ STAT_VEHICLES ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_WASPS ], numTotalWaspsInGame ); + m_gameStats[ STAT_WASPS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_GAGS ], numTotalGagsInGame ); + m_gameStats[ STAT_GAGS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", numUnlocked[ STAT_MOVIES ], 7 ); + m_gameStats[ STAT_MOVIES ]->SetString( 0, buffer ); + + sprintf( buffer, "%.1f %%", GetCharacterSheetManager()->QueryPercentGameCompleted() ); + m_percentGameComplete->SetString( 0, buffer ); + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); +} + + +//=========================================================================== +// CGuiScreenScrapBookStats::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookStats::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenScrapBookStats::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenScrapBookStats::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookstats.h b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.h new file mode 100644 index 0000000..ce2f706 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.h @@ -0,0 +1,67 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenScrapBookStats +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENSCRAPBOOKSTATS_H +#define GUISCREENSCRAPBOOKSTATS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenScrapBookStats : public CGuiScreen +{ +public: + CGuiScreenScrapBookStats( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenScrapBookStats(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + enum eGameStats + { + STAT_STORY_MISSIONS, + STAT_BONUS_MISSIONS, + STAT_STREET_RACES, + STAT_CARDS, + STAT_CLOTHING, + STAT_VEHICLES, + STAT_WASPS, + STAT_GAGS, + STAT_MOVIES, + + NUM_GAME_STATS + }; + + Scrooby::Text* m_gameStats[ NUM_GAME_STATS ]; + Scrooby::Text* m_percentGameComplete; + +}; + +#endif // GUISCREENSCRAPBOOKSTATS_H diff --git a/game/code/presentation/gui/frontend/guiscreenskingallery.cpp b/game/code/presentation/gui/frontend/guiscreenskingallery.cpp new file mode 100644 index 0000000..3d79266 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenskingallery.cpp @@ -0,0 +1,785 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSkinGallery +// +// Description: Implementation of the CGuiScreenSkinGallery class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenskingallery.h> +#include <presentation/gui/frontend/guiscreenscrapbookcontents.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guimenu.h> + +#include <cheats/cheatinputsystem.h> +#include <memory/srrmemory.h> +#include <mission/rewards/rewardsmanager.h> +#include <mission/rewards/reward.h> +#include <events/eventmanager.h> + +#include <p3d/inventory.hpp> + +#include <raddebug.hpp> // Foundation + +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <text.h> + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* SKIN_GALLERY_INVENTORY_SECTION = "FE_SkinGallery"; +const char* SKIN_GALLERY_IMAGES_DIR = "art\\frontend\\dynaload\\images\\skins2d\\"; + +const float SKIN_VIEW_TRANSITION_TIME = 250.0f; // in msec +const float SKIN_VIEW_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms +const int SKIN_VIEW_POS_X = 250; +const int SKIN_VIEW_POS_Y = 130; + +#ifdef RAD_WIN32 +const float SKIN_BASE_SCALE = 1.0f / 2.5f; +const float SKIN_IMAGE_SCALE = 0.5f / 2.5f; +#else +const float SKIN_BASE_SCALE = 1.0f; +const float SKIN_IMAGE_SCALE = 1.5f - 1.0f; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenSkinGallery::CGuiScreenSkinGallery +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSkinGallery::CGuiScreenSkinGallery +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SKIN_GALLERY ), + m_pMenu( NULL ), + m_numSelections( 0 ), + m_isSkinsLoaded( false ), + m_screenState( SCREEN_STATE_NORMAL ), + m_elapsedTime( 0 ), + m_projectileVelocity( 0.0f, 0.0f, 0.0f ), + m_skinInfo( NULL ), +#ifdef RAD_WIN32 + m_selectedSkin(0), +#endif + m_skinName( NULL ) +{ + memset( m_rewardSelections, 0, sizeof( m_rewardSelections ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "SkinGallery" ); + rAssert( pPage != NULL ); + + // create a 2D sprite menu + // + m_pMenu = new CGuiMenu2D( this, MAX_NUM_SKINS_PER_LEVEL, 3, GUI_SPRITE_MENU, MENU_SFX_NONE ); + rAssert( m_pMenu != NULL ); + m_pMenu->SetGreyOutEnabled( false ); + + Scrooby::Group* pGroup = pPage->GetGroup( "Menu" ); + rAssert( pGroup != NULL ); + + // add sprites to menu + // + for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ ) + { + char name[ 16 ]; + sprintf( name, "Skin%d", i ); + + m_pMenu->AddMenuItem( pGroup->GetSprite( name ) ); + } + + // add menu cursor + // + m_pMenu->SetCursor( pGroup->GetSprite( "SkinCursor" ) ); + + // get skin info layer and name + // + m_skinInfo = pPage->GetLayer( "ViewSkin" ); + m_skinName = pPage->GetText( "SkinName" ); + + // hide skin info layer by default + // + rAssert( m_skinInfo != NULL ); + m_skinInfo->SetVisible( false ); + m_skinInfo->SetAlpha( 0.0f ); + + if( this->IsWideScreenDisplay() ) + { + m_skinInfo->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( m_skinInfo ); + } + + // wrap skin name + // +// rAssert( m_skinName != NULL ); +// m_skinName->SetTextMode( Scrooby::TEXT_WRAP ); + + // add outline to skin name + // + m_skinName->SetDisplayOutline( true ); + + // create inventory section for skin galllery resources + // + p3d::inventory->AddSection( SKIN_GALLERY_INVENTORY_SECTION ); +} + + +//=========================================================================== +// CGuiScreenSkinGallery::~CGuiScreenSkinGallery +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSkinGallery::~CGuiScreenSkinGallery() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } + + // destroy skin gallery inventory section + // + p3d::inventory->DeleteSection( SKIN_GALLERY_INVENTORY_SECTION ); +} + + +//=========================================================================== +// CGuiScreenSkinGallery::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSkinGallery::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_screenState == SCREEN_STATE_GOTO_VIEW || + m_screenState == SCREEN_STATE_BACK_VIEW ) + { + if( message == GUI_MSG_UPDATE ) + { + this->OnUpdate( param1 ); + } + + return; + } + + if( m_screenState == SCREEN_STATE_VIEWING ) + { + if( message == GUI_MSG_UPDATE ) + { + this->OnUpdate( param1 ); + } + else if( message == GUI_MSG_CONTROLLER_BACK ) + { + m_screenState = SCREEN_STATE_BACK_VIEW; + m_elapsedTime = 0; + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect + } + + return; + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->OnUpdate( param1 ); + + break; + } + case GUI_MSG_MENU_SELECTION_CHANGED: + { + this->OnMenuSelectionChange( static_cast<int>( param1 ) ); + + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + this->OnMenuSelectionMade( static_cast<int>( param1 ) ); +#ifdef RAD_WIN32 + m_selectedSkin = static_cast<int>( param1 ); + // Hide/disable all other menu items. + this->SetVisibilityForAllOtherMenuItems( false ); +#endif + + break; + } + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenSkinGallery::OnProcessRequestsComplete +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiScreenSkinGallery::OnProcessRequestsComplete( void* pUserData ) +{ + m_numTransitionsPending--; + + p3d::pddi->DrawSync(); + + // push and select inventory section for searching + // + p3d::inventory->PushSection(); + p3d::inventory->SelectSection( SKIN_GALLERY_INVENTORY_SECTION ); + bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly(); + p3d::inventory->SetCurrentSectionOnly( true ); + + // update all 3D models + // + CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( pScreen != NULL ); + + for( int i = 0; i < m_numSelections; i++ ) + { + if( (m_pMenu->GetMenuItem( i )->m_attributes & SELECTION_ENABLED) > 0 ) + { + char name[ 16 ]; + sprintf( name, "%s.png", m_rewardSelections[ i ]->GetName() ); + tSprite* pSprite = p3d::find<tSprite>( name ); + if( pSprite != NULL ) + { + Scrooby::Sprite* skinImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( skinImage != NULL ); + skinImage->SetRawSprite( pSprite, true ); + } + else + { + rAssertMsg( false, "Skin image not found!" ); + } + } + } + + // pop inventory section and restore states + // + p3d::inventory->SetCurrentSectionOnly( currentSectionOnly ); + p3d::inventory->PopSection(); + + m_isSkinsLoaded = true; +} + +//=========================================================================== +// CGuiScreenSkinGallery::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSkinGallery::InitIntro() +{ + if( !m_isSkinsLoaded ) + { + this->Load2DImages(); + } + + // set level-specific silhouettes + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ ) + { + Scrooby::Sprite* skinImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( skinImage != NULL ); + skinImage->SetIndex( scrapBookContents->GetCurrentLevel() ); + } + + this->OnMenuSelectionChange( m_pMenu->GetSelection() ); + + GetEventManager()->TriggerEvent( EVENT_PLAY_MUZAK ); +} + + +//=========================================================================== +// CGuiScreenSkinGallery::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSkinGallery::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenSkinGallery::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSkinGallery::InitOutro() +{ + if( m_isSkinsLoaded ) + { + this->Unload2DImages(); + } + + GetEventManager()->TriggerEvent( EVENT_PLAY_FE_MUSIC ); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenSkinGallery::OnUpdate( unsigned int elapsedTime ) +{ + switch( m_screenState ) + { + case SCREEN_STATE_NORMAL: + { + // pulse cursor alpha + // + Scrooby::Drawable* cursor = m_pMenu->GetCursor(); + if( cursor != NULL ) + { + const unsigned int PULSE_PERIOD = 1000; + + float alpha = GuiSFX::Pulse( (float)m_elapsedTime, + (float)PULSE_PERIOD, + 0.75f, + 0.25f, + -rmt::PI_BY2 ); + + cursor->SetAlpha( alpha ); + + m_elapsedTime += elapsedTime; + m_elapsedTime %= PULSE_PERIOD; + } + + break; + } + case SCREEN_STATE_GOTO_VIEW: + { + m_elapsedTime += elapsedTime; + + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem(); + rAssert( pDrawable != NULL ); + + pDrawable->ResetTransformation(); + + if( m_elapsedTime < (unsigned int)SKIN_VIEW_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / SKIN_VIEW_TRANSITION_TIME; + + pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE + percentageDone * SKIN_IMAGE_SCALE ); + + GuiSFX::Projectile( pDrawable, + (float)m_elapsedTime, + SKIN_VIEW_TRANSITION_TIME, + m_projectileVelocity, + false, + SKIN_VIEW_PROJECTILE_GRAVITY ); + + // fade out rest of the menu items + // + this->SetMenuAlpha( 1.0f - rmt::Sqrt( percentageDone ) ); + + // fade in skin info layer + // + rAssert( m_skinInfo != NULL ); + m_skinInfo->SetAlpha( percentageDone * percentageDone ); + } + else + { + pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE + SKIN_IMAGE_SCALE ); + + GuiSFX::Projectile( pDrawable, + SKIN_VIEW_TRANSITION_TIME, + SKIN_VIEW_TRANSITION_TIME, + m_projectileVelocity, + false, + SKIN_VIEW_PROJECTILE_GRAVITY ); + + this->SetMenuAlpha( 0.0f ); + + rAssert( m_skinInfo != NULL ); + m_skinInfo->SetAlpha( 1.0f ); + + m_screenState = SCREEN_STATE_VIEWING; + } + + break; + } + case SCREEN_STATE_VIEWING: + { + + break; + } + case SCREEN_STATE_BACK_VIEW: + { + m_elapsedTime += elapsedTime; + + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem(); + rAssert( pDrawable != NULL ); + + pDrawable->ResetTransformation(); + + if( m_elapsedTime < (unsigned int)SKIN_VIEW_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / SKIN_VIEW_TRANSITION_TIME; + + pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE + (1.0f - percentageDone) * SKIN_IMAGE_SCALE ); + + GuiSFX::Projectile( pDrawable, + (float)m_elapsedTime, + SKIN_VIEW_TRANSITION_TIME, + m_projectileVelocity, + true, + SKIN_VIEW_PROJECTILE_GRAVITY ); + + // fade back in rest of the menu items + // + this->SetMenuAlpha( percentageDone * percentageDone ); + + // fade in skin info layer + // + rAssert( m_skinInfo != NULL ); + m_skinInfo->SetAlpha( 1.0f - rmt::Sqrt( percentageDone ) ); + } + else + { + pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE ); + + GuiSFX::Projectile( pDrawable, + SKIN_VIEW_TRANSITION_TIME, + SKIN_VIEW_TRANSITION_TIME, + m_projectileVelocity, + true, + SKIN_VIEW_PROJECTILE_GRAVITY ); + + // show menu cursor + // + rAssert( m_pMenu != NULL ); + m_pMenu->GetCursor()->SetVisible( true ); + + // show level bar + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + scrapBookContents->SetLevelBarVisible( true ); + + this->SetMenuAlpha( 1.0f ); + + rAssert( m_skinInfo != NULL ); + m_skinInfo->SetAlpha( 0.0f ); + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + + // hide skin info layer + // + rAssert( m_skinInfo != NULL ); + m_skinInfo->SetVisible( false ); + + m_elapsedTime = 0; + m_screenState = SCREEN_STATE_NORMAL; +#ifdef RAD_WIN32 + // Show/enable all hidden menu items. + this->SetVisibilityForAllOtherMenuItems( true ); +#endif + } + + break; + } + default: + { + rAssertMsg( false, "Invalid screen state!" ); + + break; + } + } +} + +void +CGuiScreenSkinGallery::OnMenuSelectionChange( int selection ) +{ + // scale up new selection + // + for( int i = 0; i < m_numSelections; i++ ) + { + Scrooby::BoundedDrawable* drawable = m_pMenu->GetMenuItem( i )->GetItem(); + rAssert( drawable != NULL ); + drawable->ResetTransformation(); + drawable->ScaleAboutCenter( SKIN_BASE_SCALE ); + + if( i != selection ) + { + drawable->ScaleAboutCenter( 0.9f ); + } + } +} + +void +CGuiScreenSkinGallery::OnMenuSelectionMade( int selection ) +{ + if( m_numSelections > 0 ) + { + // hide level bar + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + scrapBookContents->SetLevelBarVisible( false ); + + // hide menu cursor + // + rAssert( m_pMenu != NULL ); + m_pMenu->GetCursor()->SetVisible( false ); + + // show skin info layer + // + rAssert( m_skinInfo != NULL ); + m_skinInfo->SetVisible( true ); + + // update skin name + // + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + char stringID[ 16 ]; + rAssert( m_rewardSelections[ m_pMenu->GetSelection() ] != NULL ); + strcpy( stringID, m_rewardSelections[ m_pMenu->GetSelection() ]->GetName() ); + + UnicodeString unicodeString; + unicodeString.ReadUnicode( GetTextBibleString( strupr( stringID ) ) ); + + rAssert( m_skinName != NULL ); + m_skinName->SetString( 0, unicodeString ); + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + + // calculate the initial projectile velocity + // + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( selection )->GetItem(); + rAssert( pDrawable != NULL ); + + int startPosX = 0; + int startPosY = 0; + pDrawable->GetOriginPosition( startPosX, startPosY ); + + m_projectileVelocity.x = (SKIN_VIEW_POS_X - startPosX) / SKIN_VIEW_TRANSITION_TIME; + m_projectileVelocity.y = (SKIN_VIEW_POS_Y - startPosY - 0.5f * SKIN_VIEW_PROJECTILE_GRAVITY * SKIN_VIEW_TRANSITION_TIME * SKIN_VIEW_TRANSITION_TIME) / SKIN_VIEW_TRANSITION_TIME; + + m_screenState = SCREEN_STATE_GOTO_VIEW; + m_elapsedTime = 0; + } +} + +void +CGuiScreenSkinGallery::SetMenuAlpha( float alpha ) +{ + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ ) + { + if( i != currentSelection ) + { + Scrooby::Drawable* skinImage = m_pMenu->GetMenuItem( i )->GetItem(); + rAssert( skinImage != NULL ); + skinImage->SetAlpha( alpha ); + } + } +} + +void +CGuiScreenSkinGallery::Load2DImages() +{ + // load 2D images for current level + // + CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( pScreen != NULL ); + + m_numSelections = 0; + + for( Reward* pReward = GetRewardsManager()->FindFirstMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_INTERIOR ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_INTERIOR ) ) + { + rAssert( m_numSelections < MAX_NUM_SKINS_PER_LEVEL ); + + // store reference to reward + // + m_rewardSelections[ m_numSelections ] = pReward; + + char filename[ 64 ]; + sprintf( filename, "%s%s.p3d", SKIN_GALLERY_IMAGES_DIR, pReward->GetName() ); + rAssert( strlen( filename) < sizeof( filename ) ); + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + filename, + GMA_LEVEL_FE, + SKIN_GALLERY_INVENTORY_SECTION, + SKIN_GALLERY_INVENTORY_SECTION ); + + m_numSelections++; + } + + rWarningMsg( m_numSelections > 0, "No model selections available!" ); + + if( m_numSelections > 0 ) + { + GetLoadingManager()->AddCallback( this ); + + m_numTransitionsPending++; + } + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); // hide by default + + for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ ) + { + if( i < m_numSelections ) + { + bool isUnlocked = m_rewardSelections[ i ]->RewardStatus(); + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_SKINS ) ) + { + isUnlocked = true; + } + + m_pMenu->SetMenuItemEnabled( i, isUnlocked ); + + if( isUnlocked ) + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + } + } + else + { + m_pMenu->SetMenuItemEnabled( i, false ); + } + } +} + +void +CGuiScreenSkinGallery::Unload2DImages() +{ + p3d::pddi->DrawSync(); + + // clear all drawables + // + for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ ) + { + Scrooby::Sprite* skinImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( skinImage != NULL ); + skinImage->SetRawSprite( NULL, true ); + + m_pMenu->SetMenuItemEnabled( i, false ); + } + + // unload 2D images + // + p3d::inventory->RemoveSectionElements( SKIN_GALLERY_INVENTORY_SECTION ); + + m_isSkinsLoaded = false; +} + +#ifdef RAD_WIN32 +void CGuiScreenSkinGallery::SetVisibilityForAllOtherMenuItems( bool bVisible ) +{ + for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ ) + { + if( i != m_selectedSkin ) + m_pMenu->GetMenuItem(i)->GetItem()->SetVisible( bVisible ); + } +} +#endif
\ No newline at end of file diff --git a/game/code/presentation/gui/frontend/guiscreenskingallery.h b/game/code/presentation/gui/frontend/guiscreenskingallery.h new file mode 100644 index 0000000..c082306 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenskingallery.h @@ -0,0 +1,100 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSkinGallery +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENSKINGALLERY_H +#define GUISCREENSKINGALLERY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <loading/loadingmanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu2D; +class Reward; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenSkinGallery : public CGuiScreen, + public LoadingManager::ProcessRequestsCallback +{ +public: + CGuiScreenSkinGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenSkinGallery(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + // Implements LoadingManager::ProcessRequestsCallback + // + virtual void OnProcessRequestsComplete( void* pUserData ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void OnUpdate( unsigned int elapsedTime ); + void OnMenuSelectionChange( int selection ); + void OnMenuSelectionMade( int selection ); + void SetMenuAlpha( float alpha ); +#ifdef RAD_WIN32 + void SetVisibilityForAllOtherMenuItems( bool bDisable ); +#endif + + void Load2DImages(); + void Unload2DImages(); + + static const int MAX_NUM_SKINS_PER_LEVEL = 3; + + CGuiMenu2D* m_pMenu; + + Reward* m_rewardSelections[ MAX_NUM_SKINS_PER_LEVEL ]; + int m_numSelections; + + bool m_isSkinsLoaded : 1; + + enum eScreenState + { + SCREEN_STATE_NORMAL, + SCREEN_STATE_GOTO_VIEW, + SCREEN_STATE_VIEWING, + SCREEN_STATE_BACK_VIEW, + + NUM_SCREEN_STATES + }; + + eScreenState m_screenState; + unsigned int m_elapsedTime; + rmt::Vector m_projectileVelocity; + + Scrooby::Layer* m_skinInfo; + Scrooby::Text* m_skinName; + +#ifdef RAD_WIN32 + int m_selectedSkin; +#endif +}; + +#endif // GUISCREENSKINGALLERY_H diff --git a/game/code/presentation/gui/frontend/guiscreensound.cpp b/game/code/presentation/gui/frontend/guiscreensound.cpp new file mode 100644 index 0000000..a8f4b81 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreensound.cpp @@ -0,0 +1,541 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSound +// +// Description: Implementation of the CGuiScreenSound class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreensound.h> +#include <presentation/gui/guimenu.h> + +#include <memory/srrmemory.h> +#include <sound/soundmanager.h> + +#include <raddebug.hpp> // Foundation +#include <page.h> +#include <screen.h> +#include <group.h> +#include <sprite.h> +#include <text.h> + +#include <string.h> + +#ifdef RAD_WIN32 +#include <data/config/gameconfigmanager.h> +#endif + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* SOUND_MENU_ITEMS[] = +{ + "Music", + "Effects", + "Engine", + "Voice", + +#ifdef INCLUDE_SOUND_MODE + "SurroundSound", +#endif + + "" // dummy terminator +}; + +const float SLIDER_CORRECTION_SCALE = 4.0f; // in x-direction only + +#ifdef RAD_WIN32 +const float SLIDER_ICON_SCALE = 0.5f; +#endif +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenSound::CGuiScreenSound +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSound::CGuiScreenSound +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SOUND ), + m_pMenu( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenSound" ); + memset( m_soundOffIcons, 0, sizeof( m_soundOffIcons ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "Sound" ); + rAssert( pPage ); + + // Create a menu. + // + m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + Scrooby::Text* pText = NULL; + Scrooby::Text* pTextValue = NULL; + Scrooby::Sprite* pArrowL = NULL; + Scrooby::Sprite* pArrowR = NULL; + + char itemName[ 32 ]; + + for( int i = 0; i < NUM_MENU_ITEMS; i++ ) + { + Scrooby::Group* group = pPage->GetGroup( SOUND_MENU_ITEMS[ i ] ); + rAssert( group != NULL ); + + pText = group->GetText( SOUND_MENU_ITEMS[ i ] ); + + // if text value exists + // + sprintf( itemName, "%s_Value", SOUND_MENU_ITEMS[ i ] ); + pTextValue = group->GetText( itemName ); + +#ifdef INCLUDE_SOUND_MODE + if( i == MENU_ITEM_SURROUND_SOUND ) + { +/* + // get "dolby prologic #" text and set: # = 1 for GC + // # = 2 for PS2 + // + P3D_UNICODE* unicodeString = static_cast<P3D_UNICODE*>( pTextValue->GetStringBuffer( SURROUND_SOUND ) ); + if( unicodeString != NULL ) + { + int stringLength = p3d::UnicodeStrLen( unicodeString ); + for( int j = 0; j < stringLength; j++ ) + { + if( unicodeString[ j ] == '#' ) + { +#ifdef RAD_GAMECUBE + unicodeString[ j ] = '1'; +#endif +#ifdef RAD_PS2 + unicodeString[ j ] = '2'; +#endif + } + } + } +*/ + + // add menu item for sound mode setting + // + pText = pTextValue; + + sprintf( itemName, "%s_LArrow", SOUND_MENU_ITEMS[ i ] ); + pArrowL = group->GetSprite( itemName ); + + sprintf( itemName, "%s_RArrow", SOUND_MENU_ITEMS[ i ] ); + pArrowR = group->GetSprite( itemName ); + + m_pMenu->AddMenuItem( pText, + pTextValue, + NULL, + NULL, + pArrowL, + pArrowR, + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + } +#endif + + // if slider exists + // + sprintf( itemName, "%s_Slider", SOUND_MENU_ITEMS[ i ] ); + Scrooby::Group* sliderGroup = group->GetGroup( itemName ); + if( sliderGroup != NULL ) + { + sliderGroup->ResetTransformation(); + sliderGroup->ScaleAboutCenter( SLIDER_CORRECTION_SCALE, 1.0f, 1.0f ); + + m_pMenu->AddMenuItem( pText, + pTextValue, + NULL, + sliderGroup->GetSprite( itemName ), + pArrowL, + pArrowR, + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + + m_pMenu->GetMenuItem( i )->m_slider.m_type = Slider::HORIZONTAL_SLIDER_ABOUT_CENTER; + + // get sound off icon + // + sprintf( itemName, "%s_Off", SOUND_MENU_ITEMS[ i ] ); + m_soundOffIcons[ i ] = group->GetSprite( itemName ); +#ifdef RAD_WIN32 + m_soundOffIcons[ i ]->ScaleAboutCenter( SLIDER_ICON_SCALE ); + + sprintf( itemName, "%s_Icon", SOUND_MENU_ITEMS[ i ] ); + Scrooby::Sprite* soundOnIcon = group->GetSprite( itemName ); + soundOnIcon->ScaleAboutCenter( SLIDER_ICON_SCALE ); +#endif + } + } + +#ifdef INCLUDE_SOUND_MODE + m_pMenu->SetSelectionValueCount( MENU_ITEM_SURROUND_SOUND, NUM_SOUND_SETTINGS ); +#else + // hide surround sound setting + // + Scrooby::Group* surroundSoundSetting = pPage->GetGroup( "SurroundSound" ); + if( surroundSoundSetting != NULL ) + { + surroundSoundSetting->SetVisible( false ); + } + + #ifndef RAD_WIN32 // for PC don't shift the pixels... essential for the mouse cursor. + // and move regular sound menu down a bit to re-center vertically + // + Scrooby::Group* soundMenu = pPage->GetGroup( "Menu" ); + rAssert( soundMenu != NULL ); + soundMenu->Translate( 0, -30 ); + #endif +#endif + +MEMTRACK_POP_GROUP("CGUIScreenSound"); +} + + +//=========================================================================== +// CGuiScreenSound::~CGuiScreenSound +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSound::~CGuiScreenSound() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenSound::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSound::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + rAssert( m_pMenu ); + GuiMenuItem* currentItem = m_pMenu->GetMenuItem( param1 ); + rAssert( currentItem ); + + switch( param1 ) + { + case MENU_ITEM_MUSIC: + { + GetSoundManager()->SetMusicVolume( currentItem->m_slider.m_value ); + + break; + } + case MENU_ITEM_EFFECTS: + { + GetSoundManager()->SetSfxVolume( currentItem->m_slider.m_value ); + + // + // HACK!! + // + // Oh boy, this is ugly. We've got four sliders and five sets of volumes. + // Sfx needs to adjust ambience as well. In a stroke of genius, I didn't + // provide a separate set of volumes for the designers. So, the sfx needs + // to adjust ambience without upsetting whatever ambience volume they choose + // in the scripts. I'm not proud of this. + // + // Esan + // + GetSoundManager()->SetAmbienceVolume( GetSoundManager()->GetCalculatedAmbienceVolume() ); + + break; + } + case MENU_ITEM_ENGINE: + { + GetSoundManager()->SetCarVolume( currentItem->m_slider.m_value ); + + break; + } + case MENU_ITEM_VOICE: + { + GetSoundManager()->SetDialogueVolume( currentItem->m_slider.m_value ); + + break; + } +#ifdef INCLUDE_SOUND_MODE + case MENU_ITEM_SURROUND_SOUND: + { + if( param2 == MONO_SOUND ) + { + GetSoundManager()->SetSoundMode( SOUND_MONO ); + } + else if( param2 == STEREO_SOUND ) + { + GetSoundManager()->SetSoundMode( SOUND_STEREO ); + } + else if( param2 == SURROUND_SOUND ) + { + GetSoundManager()->SetSoundMode( SOUND_SURROUND ); + } + else + { + rAssert( false ); + } + + break; + } +#endif + default: + { + break; + } + } + + // show 'sound off' icon if volume is completely turn off + // + if( m_soundOffIcons[ param1 ] != NULL ) + { + m_soundOffIcons[ param1 ]->SetVisible( currentItem->m_slider.m_value == 0 ); + } + + // set flag indicating slider value has changed + // + m_hasSliderValueChanged[ param1 ] = true; + + break; + } + case GUI_MSG_MENU_SLIDER_NOT_CHANGING: + { + // play stinger if music slider has recently changed + // + if( m_hasSliderValueChanged[ MENU_ITEM_MUSIC ] ) + { + m_hasSliderValueChanged[ MENU_ITEM_MUSIC ] = false; + + GetSoundManager()->PlayMusicOptionMenuStinger(); + } + + // play stinger if effects slider has recently changed + // + if( m_hasSliderValueChanged[ MENU_ITEM_EFFECTS ] ) + { + m_hasSliderValueChanged[ MENU_ITEM_EFFECTS ] = false; + + GetSoundManager()->PlaySfxOptionMenuStinger(); + } + + // play stinger if engine slider has recently changed + // + if( m_hasSliderValueChanged[ MENU_ITEM_ENGINE ] ) + { + m_hasSliderValueChanged[ MENU_ITEM_ENGINE ] = false; + + GetSoundManager()->PlayCarOptionMenuStinger(); + } + + // play stinger if voic slider has recently changed + // + if( m_hasSliderValueChanged[ MENU_ITEM_VOICE ] ) + { + m_hasSliderValueChanged[ MENU_ITEM_VOICE ] = false; + + GetSoundManager()->PlayDialogueOptionMenuStinger(); + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 690, 720 ); + + break; + } + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenSound::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSound::InitIntro() +{ + // Set slider values to current volume settings + // + GuiMenuItem* menuItem = NULL; + rAssert( m_pMenu ); + + // music + // + menuItem = m_pMenu->GetMenuItem( MENU_ITEM_MUSIC ); + rAssert( menuItem ); + menuItem->m_slider.SetValue( GetSoundManager()->GetMusicVolume() ); + + rAssert( m_soundOffIcons[ MENU_ITEM_MUSIC ] != NULL ); + m_soundOffIcons[ MENU_ITEM_MUSIC ]->SetVisible( menuItem->m_slider.m_value == 0 ); + + // effects + // + menuItem = m_pMenu->GetMenuItem( MENU_ITEM_EFFECTS ); + rAssert( menuItem ); + menuItem->m_slider.SetValue( GetSoundManager()->GetSfxVolume() ); + + rAssert( m_soundOffIcons[ MENU_ITEM_EFFECTS ] != NULL ); + m_soundOffIcons[ MENU_ITEM_EFFECTS ]->SetVisible( menuItem->m_slider.m_value == 0 ); + + // engine + // + menuItem = m_pMenu->GetMenuItem( MENU_ITEM_ENGINE ); + rAssert( menuItem ); + menuItem->m_slider.SetValue( GetSoundManager()->GetCarVolume() ); + + rAssert( m_soundOffIcons[ MENU_ITEM_ENGINE ] != NULL ); + m_soundOffIcons[ MENU_ITEM_ENGINE ]->SetVisible( menuItem->m_slider.m_value == 0 ); + + // voice + // + menuItem = m_pMenu->GetMenuItem( MENU_ITEM_VOICE ); + rAssert( menuItem ); + menuItem->m_slider.SetValue( GetSoundManager()->GetDialogueVolume() ); + + rAssert( m_soundOffIcons[ MENU_ITEM_VOICE ] != NULL ); + m_soundOffIcons[ MENU_ITEM_VOICE ]->SetVisible( menuItem->m_slider.m_value == 0 ); + + // surround sound + // +#ifdef INCLUDE_SOUND_MODE + if( GetSoundManager()->GetSoundMode() == SOUND_MONO ) + { + m_pMenu->SetSelectionValue( MENU_ITEM_SURROUND_SOUND, MONO_SOUND ); + } + else if( GetSoundManager()->GetSoundMode() == SOUND_STEREO ) + { + m_pMenu->SetSelectionValue( MENU_ITEM_SURROUND_SOUND, STEREO_SOUND ); + } + else if( GetSoundManager()->GetSoundMode() == SOUND_SURROUND ) + { + m_pMenu->SetSelectionValue( MENU_ITEM_SURROUND_SOUND, SURROUND_SOUND ); + } +#endif + + // reset slider value changed flags + // + for( int i = 0; i < NUM_MENU_ITEMS; i++ ) + { + m_hasSliderValueChanged[ i ] = false; + } +} + + +//=========================================================================== +// CGuiScreenSound::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSound::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenSound::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSound::InitOutro() +{ +#ifdef RAD_WIN32 + // Save the new controller mappings to the config file. + GetGameConfigManager()->SaveConfigFile(); +#endif +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/frontend/guiscreensound.h b/game/code/presentation/gui/frontend/guiscreensound.h new file mode 100644 index 0000000..a263ef7 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreensound.h @@ -0,0 +1,94 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSound +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENSOUND_H +#define GUISCREENSOUND_H + +#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 ) + #define INCLUDE_SOUND_MODE +#endif + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +namespace Scrooby +{ + class Screen; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenSound : public CGuiScreen +{ +public: + CGuiScreenSound( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenSound(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +#ifdef RAD_WIN32 + //virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); +#endif + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + enum eMenuItem + { + MENU_ITEM_MUSIC, + MENU_ITEM_EFFECTS, + MENU_ITEM_ENGINE, + MENU_ITEM_VOICE, + +#ifdef INCLUDE_SOUND_MODE + MENU_ITEM_SURROUND_SOUND, +#endif + + NUM_MENU_ITEMS + }; + +#ifdef INCLUDE_SOUND_MODE + enum eMenuItemSurroundSound + { + MONO_SOUND, + STEREO_SOUND, + SURROUND_SOUND, + + NUM_SOUND_SETTINGS + }; +#endif + + CGuiMenu* m_pMenu; + + Scrooby::Sprite* m_soundOffIcons[ NUM_MENU_ITEMS ]; + bool m_hasSliderValueChanged[ NUM_MENU_ITEMS ]; + +}; + +#endif // GUISCREENSOUND_H diff --git a/game/code/presentation/gui/frontend/guiscreensplash.cpp b/game/code/presentation/gui/frontend/guiscreensplash.cpp new file mode 100644 index 0000000..5b8cec7 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreensplash.cpp @@ -0,0 +1,344 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSplash +// +// Description: Implementation of the CGuiScreenSplash class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreensplash.h> +#include <presentation/gui/frontend/guiscreenplaymovie.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/frontend/guimanagerfrontend.h> + +#include <cheats/cheatinputsystem.h> +#include <loading/loadingmanager.h> +#include <main/commandlineoptions.h> + +#include <raddebug.hpp> // Foundation +#include <page.h> +#include <screen.h> +#include <sprite.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +short CGuiScreenSplash::s_demoPlaybackToggle = 0; + +const unsigned int SPLASH_SCREEN_DEMO_WAIT_TIME = 30000; // in msec + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenSplash::CGuiScreenSplash +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSplash::CGuiScreenSplash +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SPLASH ), + m_pMenu( NULL ), + m_pressStart( NULL ), + m_demoLoopTime( SPLASH_SCREEN_DEMO_WAIT_TIME ), + m_elapsedTime( 0 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Splash" ); + rAssert( pPage != NULL ); +/* + Scrooby::Sprite* splashImage = pPage->GetSprite( "GameLogo" ); + if( splashImage != NULL ) + { + const float SPLASH_SCREEN_IMAGE_CORRECTION_SCALE = 2.0f; + splashImage->ScaleAboutCenter( SPLASH_SCREEN_IMAGE_CORRECTION_SCALE ); + } +*/ + // Create a menu. + // + m_pMenu = new CGuiMenu( this ); + rAssert( m_pMenu != NULL ); + + m_pressStart = pPage->GetText( "PressStart" ); + rAssert( m_pressStart != NULL ); + + m_pMenu->AddMenuItem( m_pressStart, + NULL, + NULL, + NULL, + NULL, + NULL, + SELECTION_ENABLED | TEXT_OUTLINE_ENABLED ); + + // set "press start" text to "loading ...", by default + // + m_pressStart->SetIndex( TEXT_LOADING ); + m_pressStart->SetColour( tColour( 255, 255, 255 ) ); + + if( CommandLineOptions::Get( CLO_DEMO_TEST ) || + GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_DEMO_TEST ) ) + { + m_demoLoopTime = 1000; // in msec + } +} + + +//=========================================================================== +// CGuiScreenSplash::~CGuiScreenSplash +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSplash::~CGuiScreenSplash() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenSplash::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSplash::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( !m_pMenu->HasSelectionBeenMade() ) + { + m_elapsedTime += param1; + if( m_elapsedTime > m_demoLoopTime ) + { + if( s_demoPlaybackToggle != 0 ) + { + if ( CommandLineOptions::Get( CLO_DEMO_TEST ) || + GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_DEMO_TEST ) ) + { + this->StartDemoInRuntime(); + } + else + { + this->StartDemoAsMovie(); + } + } + else + { + if ( CommandLineOptions::Get( CLO_DEMO_TEST ) || + GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_DEMO_TEST ) ) + { + this->StartDemoInRuntime(); + } + else + { + this->StartDemoAsMovie(); + } + } + + // toggle demo playback format (btw. movie and runtime) + // + s_demoPlaybackToggle = 1 - s_demoPlaybackToggle; + + m_elapsedTime = 0; + } + } + + if( m_pressStart != NULL && !GetLoadingManager()->IsLoading() ) // sound loading is done + { + rAssert( m_pMenu != NULL ); + + m_pressStart->SetIndex( TEXT_PRESS_START_GC + PLATFORM_TEXT_INDEX); + m_pressStart->SetColour( m_pMenu->GetHighlightColour() ); + m_pMenu->GetMenuItem( 0 )->m_attributes |= SELECTABLE; + + // set this to NULL cuz we don't need to change it anymore + // + m_pressStart = NULL; + } + + break; + } + case GUI_MSG_CONTROLLER_SELECT: + { + // ignore controller select inputs + // + return; + + break; + } + case GUI_MSG_CONTROLLER_START: + { + + GetGuiSystem()->SetPrimaryController((int)param1); + + if( GetLoadingManager()->IsLoading() ) + { + // ignore start input until all loading is done + // + return; + } + + if( !m_pMenu->HasSelectionBeenMade() ) + { + m_pMenu->MakeSelection(); + } + + break; + } + + case GUI_MSG_MENU_SELECTION_MADE: + { + m_pParent->HandleMessage( GUI_MSG_SPLASH_SCREEN_DONE ); + + break; + } + + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenSplash::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSplash::InitIntro() +{ +} + + +//=========================================================================== +// CGuiScreenSplash::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSplash::InitRunning() +{ + m_elapsedTime = 0; +} + + +//=========================================================================== +// CGuiScreenSplash::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSplash::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenSplash::StartDemoInRuntime() +{ + // Quit FE and start the demo in runtime. + // + m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 0 ); // 0 = demo mode +} + +void +CGuiScreenSplash::StartDemoAsMovie() +{ +#ifndef RAD_WIN32 + // Play demo movie. + // + rAssert( m_guiManager ); + CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE_DEMO ) ); + rAssert( playMovieScreen ); + playMovieScreen->SetMovieToPlay( MovieNames::DEMO ); + + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_PLAY_MOVIE_DEMO ); +#endif +} + diff --git a/game/code/presentation/gui/frontend/guiscreensplash.h b/game/code/presentation/gui/frontend/guiscreensplash.h new file mode 100644 index 0000000..86568ce --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreensplash.h @@ -0,0 +1,73 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSplash +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENSPLASH_H +#define GUISCREENSPLASH_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenSplash : public CGuiScreen +{ +public: + CGuiScreenSplash( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenSplash(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void StartDemoAsMovie(); + void StartDemoInRuntime(); + + enum ePressStartText + { + TEXT_LOADING, + TEXT_PRESS_START_GC, + TEXT_PRESS_START_PS2, + TEXT_PRESS_START_XBOX, + + NUM_PRESS_START_TEXTS + }; + + CGuiMenu* m_pMenu; + Scrooby::Text* m_pressStart; + + unsigned int m_demoLoopTime; + unsigned int m_elapsedTime; + + static short s_demoPlaybackToggle; + +}; + +#endif // GUISCREENSPLASH_H diff --git a/game/code/presentation/gui/frontend/guiscreenvehiclegallery.cpp b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.cpp new file mode 100644 index 0000000..7619c94 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.cpp @@ -0,0 +1,837 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenVehicleGallery +// +// Description: Implementation of the CGuiScreenVehicleGallery class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenvehiclegallery.h> +#include <presentation/gui/frontend/guiscreenscrapbookcontents.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guimenu.h> + +#include <cheats/cheatinputsystem.h> +#include <memory/srrmemory.h> +#include <mission/rewards/rewardsmanager.h> +#include <mission/rewards/reward.h> +#include <events/eventmanager.h> + +#include <p3d/inventory.hpp> + +#include <raddebug.hpp> // Foundation + +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <text.h> + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* VEHICLE_GALLERY_INVENTORY_SECTION = "FE_VehicleGallery"; +const char* VEHICLE_GALLERY_IMAGES_DIR = "art\\frontend\\dynaload\\images\\cars2d\\"; + +const float VEHICLE_VIEW_TRANSITION_TIME = 250.0f; // in msec +const float VEHICLE_VIEW_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms +const int VEHICLE_VIEW_POS_X = 250; +const int VEHICLE_VIEW_POS_Y = 140; +#ifdef RAD_WIN32 +const float VEHICLE_BASE_SCALE = 0.66f; +const float VEHICLE_IMAGE_SCALE = 1.33f - 0.66f; +#else +const float VEHICLE_BASE_SCALE = 1.0f; +const float VEHICLE_IMAGE_SCALE = 2.0f - 1.0f; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenVehicleGallery::CGuiScreenVehicleGallery +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenVehicleGallery::CGuiScreenVehicleGallery +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_VEHICLE_GALLERY ), + m_pMenu( NULL ), + m_numSelections( 0 ), + m_isVehiclesLoaded( false ), + m_screenState( SCREEN_STATE_NORMAL ), + m_elapsedTime( 0 ), + m_projectileVelocity( 0.0f, 0.0f, 0.0f ), + m_vehicleInfo( NULL ), +#ifdef RAD_WIN32 + m_selectedVehicle(0), +#endif + m_vehicleName( NULL ) +{ + memset( m_rewardSelections, 0, sizeof( m_rewardSelections ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "VehicleGallery" ); + rAssert( pPage != NULL ); + + // create a 2D sprite menu + // + m_pMenu = new CGuiMenu2D( this, MAX_NUM_VEHICLES_PER_LEVEL, 3, GUI_SPRITE_MENU, MENU_SFX_NONE ); + rAssert( m_pMenu != NULL ); + m_pMenu->SetGreyOutEnabled( false ); + + Scrooby::Group* pGroup = pPage->GetGroup( "Menu" ); + rAssert( pGroup != NULL ); + + // add sprites to menu + // + for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ ) + { + char name[ 16 ]; + sprintf( name, "Vehicle%d", i ); + + m_pMenu->AddMenuItem( pGroup->GetSprite( name ) ); + } + + // add menu cursor + // + Scrooby::Sprite* pCursor = pGroup->GetSprite( "VehicleCursor" ); + if( pCursor != NULL ) + { + // scale up cursor a bit for vehicles + // + pCursor->ScaleAboutCenter( 2.0f ); + + m_pMenu->SetCursor( pCursor ); + } + + // get vehicle info layer and name + // + m_vehicleInfo = pPage->GetLayer( "ViewVehicle" ); + m_vehicleName = pPage->GetText( "VehicleName" ); + + // hide vehicle info layer by default + // + rAssert( m_vehicleInfo != NULL ); + m_vehicleInfo->SetVisible( false ); + m_vehicleInfo->SetAlpha( 0.0f ); + + if( this->IsWideScreenDisplay() ) + { + m_vehicleInfo->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( m_vehicleInfo ); + } + + // wrap vehicle name + // +// rAssert( m_vehicleName != NULL ); +// m_vehicleName->SetTextMode( Scrooby::TEXT_WRAP ); + + // add outline to vehicle name + // + m_vehicleName->SetDisplayOutline( true ); + + // create inventory section for vehicle galllery resources + // + p3d::inventory->AddSection( VEHICLE_GALLERY_INVENTORY_SECTION ); +} + + +//=========================================================================== +// CGuiScreenVehicleGallery::~CGuiScreenVehicleGallery +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenVehicleGallery::~CGuiScreenVehicleGallery() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } + + // destroy vehicle gallery inventory section + // + p3d::inventory->DeleteSection( VEHICLE_GALLERY_INVENTORY_SECTION ); +} + + +//=========================================================================== +// CGuiScreenVehicleGallery::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenVehicleGallery::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_screenState == SCREEN_STATE_GOTO_VIEW || + m_screenState == SCREEN_STATE_BACK_VIEW ) + { + if( message == GUI_MSG_UPDATE ) + { + this->OnUpdate( param1 ); + } + + return; + } + + if( m_screenState == SCREEN_STATE_VIEWING ) + { + if( message == GUI_MSG_UPDATE ) + { + this->OnUpdate( param1 ); + } + else if( message == GUI_MSG_CONTROLLER_BACK ) + { + m_screenState = SCREEN_STATE_BACK_VIEW; + m_elapsedTime = 0; + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect + } + + return; + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->OnUpdate( param1 ); + + break; + } + case GUI_MSG_MENU_SELECTION_CHANGED: + { + this->OnMenuSelectionChange( static_cast<int>( param1 ) ); + + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + this->OnMenuSelectionMade( static_cast<int>( param1 ) ); + +#ifdef RAD_WIN32 + m_selectedVehicle = static_cast<int>( param1 ); + // Hide/disable all other menu items. + this->SetVisibilityForAllOtherMenuItems( false ); +#endif + + break; + } + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenVehicleGallery::OnProcessRequestsComplete +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiScreenVehicleGallery::OnProcessRequestsComplete( void* pUserData ) +{ + m_numTransitionsPending--; + + p3d::pddi->DrawSync(); + + // push and select inventory section for searching + // + p3d::inventory->PushSection(); + p3d::inventory->SelectSection( VEHICLE_GALLERY_INVENTORY_SECTION ); + bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly(); + p3d::inventory->SetCurrentSectionOnly( true ); + + // update all 3D models + // + CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( pScreen != NULL ); + + for( int i = 0; i < m_numSelections; i++ ) + { + if( (m_pMenu->GetMenuItem( i )->m_attributes & SELECTION_ENABLED) > 0 ) + { + char name[ 16 ]; + sprintf( name, "%s.png", m_rewardSelections[ i ]->GetName() ); + tSprite* pSprite = p3d::find<tSprite>( name ); + if( pSprite != NULL ) + { + Scrooby::Sprite* vehicleImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( vehicleImage != NULL ); + vehicleImage->SetRawSprite( pSprite, true ); + } + else + { + rAssertMsg( false, "Vehicle image not found!" ); + } + } + } + + // pop inventory section and restore states + // + p3d::inventory->SetCurrentSectionOnly( currentSectionOnly ); + p3d::inventory->PopSection(); + + m_isVehiclesLoaded = true; +} + +//=========================================================================== +// CGuiScreenVehicleGallery::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenVehicleGallery::InitIntro() +{ + if( !m_isVehiclesLoaded ) + { + this->Load2DImages(); + } + + this->OnMenuSelectionChange( m_pMenu->GetSelection() ); + + GetEventManager()->TriggerEvent( EVENT_PLAY_MUZAK ); +} + + +//=========================================================================== +// CGuiScreenVehicleGallery::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenVehicleGallery::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenVehicleGallery::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenVehicleGallery::InitOutro() +{ + if( m_isVehiclesLoaded ) + { + this->Unload2DImages(); + } + + GetEventManager()->TriggerEvent( EVENT_PLAY_FE_MUSIC ); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenVehicleGallery::OnUpdate( unsigned int elapsedTime ) +{ + switch( m_screenState ) + { + case SCREEN_STATE_NORMAL: + { + // pulse cursor alpha + // + Scrooby::Drawable* cursor = m_pMenu->GetCursor(); + if( cursor != NULL ) + { + const unsigned int PULSE_PERIOD = 1000; + + float alpha = GuiSFX::Pulse( (float)m_elapsedTime, + (float)PULSE_PERIOD, + 0.75f, + 0.25f, + -rmt::PI_BY2 ); + + cursor->SetAlpha( alpha ); + + m_elapsedTime += elapsedTime; + m_elapsedTime %= PULSE_PERIOD; + } + + break; + } + case SCREEN_STATE_GOTO_VIEW: + { + m_elapsedTime += elapsedTime; + + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem(); + rAssert( pDrawable != NULL ); + + pDrawable->ResetTransformation(); + + if( m_elapsedTime < (unsigned int)VEHICLE_VIEW_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / VEHICLE_VIEW_TRANSITION_TIME; + + pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE + percentageDone * VEHICLE_IMAGE_SCALE ); + + GuiSFX::Projectile( pDrawable, + (float)m_elapsedTime, + VEHICLE_VIEW_TRANSITION_TIME, + m_projectileVelocity, + false, + VEHICLE_VIEW_PROJECTILE_GRAVITY ); + + // fade out rest of the menu items + // + this->SetMenuAlpha( 1.0f - rmt::Sqrt( percentageDone ) ); + + // fade in vehicle info layer + // + rAssert( m_vehicleInfo != NULL ); + m_vehicleInfo->SetAlpha( percentageDone * percentageDone ); + } + else + { + pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE + VEHICLE_IMAGE_SCALE ); + + GuiSFX::Projectile( pDrawable, + VEHICLE_VIEW_TRANSITION_TIME, + VEHICLE_VIEW_TRANSITION_TIME, + m_projectileVelocity, + false, + VEHICLE_VIEW_PROJECTILE_GRAVITY ); + + this->SetMenuAlpha( 0.0f ); + + rAssert( m_vehicleInfo != NULL ); + m_vehicleInfo->SetAlpha( 1.0f ); + + m_screenState = SCREEN_STATE_VIEWING; + } + + break; + } + case SCREEN_STATE_VIEWING: + { + + break; + } + case SCREEN_STATE_BACK_VIEW: + { + m_elapsedTime += elapsedTime; + + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem(); + rAssert( pDrawable != NULL ); + + pDrawable->ResetTransformation(); + + if( m_elapsedTime < (unsigned int)VEHICLE_VIEW_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / VEHICLE_VIEW_TRANSITION_TIME; + + pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE + (1.0f - percentageDone) * VEHICLE_IMAGE_SCALE ); + + GuiSFX::Projectile( pDrawable, + (float)m_elapsedTime, + VEHICLE_VIEW_TRANSITION_TIME, + m_projectileVelocity, + true, + VEHICLE_VIEW_PROJECTILE_GRAVITY ); + + // fade back in rest of the menu items + // + this->SetMenuAlpha( percentageDone * percentageDone ); + + // fade in vehicle info layer + // + rAssert( m_vehicleInfo != NULL ); + m_vehicleInfo->SetAlpha( 1.0f - rmt::Sqrt( percentageDone ) ); + } + else + { + pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE ); + + GuiSFX::Projectile( pDrawable, + VEHICLE_VIEW_TRANSITION_TIME, + VEHICLE_VIEW_TRANSITION_TIME, + m_projectileVelocity, + true, + VEHICLE_VIEW_PROJECTILE_GRAVITY ); + + // show menu cursor + // + rAssert( m_pMenu != NULL ); + m_pMenu->GetCursor()->SetVisible( true ); + + // show level bar + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + scrapBookContents->SetLevelBarVisible( true ); + + this->SetMenuAlpha( 1.0f ); + + rAssert( m_vehicleInfo != NULL ); + m_vehicleInfo->SetAlpha( 0.0f ); + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + + // hide vehicle info layer + // + rAssert( m_vehicleInfo != NULL ); + m_vehicleInfo->SetVisible( false ); + + m_elapsedTime = 0; + m_screenState = SCREEN_STATE_NORMAL; +#ifdef RAD_WIN32 + // Show/enable all hidden menu items. + this->SetVisibilityForAllOtherMenuItems( true ); +#endif + } + + break; + } + default: + { + rAssertMsg( false, "Invalid screen state!" ); + + break; + } + } +} + +void +CGuiScreenVehicleGallery::OnMenuSelectionChange( int selection ) +{ + // scale up new selection + // + for( int i = 0; i < m_numSelections; i++ ) + { + Scrooby::BoundedDrawable* drawable = m_pMenu->GetMenuItem( i )->GetItem(); + rAssert( drawable != NULL ); + drawable->ResetTransformation(); + drawable->ScaleAboutCenter( VEHICLE_BASE_SCALE ); + + if( i != selection ) + { + drawable->ScaleAboutCenter( 0.9f ); + } + } +} + +void +CGuiScreenVehicleGallery::OnMenuSelectionMade( int selection ) +{ + if( m_numSelections > 0 ) + { + // hide level bar + // + CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( scrapBookContents != NULL ); + scrapBookContents->SetLevelBarVisible( false ); + + // hide menu cursor + // + rAssert( m_pMenu != NULL ); + m_pMenu->GetCursor()->SetVisible( false ); + + // show vehicle info layer + // + rAssert( m_vehicleInfo != NULL ); + m_vehicleInfo->SetVisible( true ); + + // update vehicle name + // + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + char stringID[ 16 ]; + rAssert( m_rewardSelections[ m_pMenu->GetSelection() ] != NULL ); + strcpy( stringID, m_rewardSelections[ m_pMenu->GetSelection() ]->GetName() ); + + UnicodeString unicodeString; + unicodeString.ReadUnicode( GetTextBibleString( strupr( stringID ) ) ); + + rAssert( m_vehicleName != NULL ); + m_vehicleName->SetString( 0, unicodeString ); + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + + // calculate the initial projectile velocity + // + Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( selection )->GetItem(); + rAssert( pDrawable != NULL ); + + int startPosX = 0; + int startPosY = 0; + pDrawable->GetOriginPosition( startPosX, startPosY ); + + m_projectileVelocity.x = (VEHICLE_VIEW_POS_X - startPosX) / VEHICLE_VIEW_TRANSITION_TIME; + m_projectileVelocity.y = (VEHICLE_VIEW_POS_Y - startPosY - 0.5f * VEHICLE_VIEW_PROJECTILE_GRAVITY * VEHICLE_VIEW_TRANSITION_TIME * VEHICLE_VIEW_TRANSITION_TIME) / VEHICLE_VIEW_TRANSITION_TIME; + + m_screenState = SCREEN_STATE_GOTO_VIEW; + m_elapsedTime = 0; + } +} + +void +CGuiScreenVehicleGallery::SetMenuAlpha( float alpha ) +{ + rAssert( m_pMenu != NULL ); + int currentSelection = m_pMenu->GetSelection(); + + for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ ) + { + if( i != currentSelection ) + { + Scrooby::Drawable* vehicleImage = m_pMenu->GetMenuItem( i )->GetItem(); + rAssert( vehicleImage != NULL ); + vehicleImage->SetAlpha( alpha ); + } + } +} + +void +CGuiScreenVehicleGallery::Load2DImages() +{ + // load 2D images for current level + // + CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) ); + rAssert( pScreen != NULL ); + + Reward* pReward = NULL; + char filename[ 64 ]; + m_numSelections = 0; + + // load earnable reward and default vehicles + // + for( int i = Reward::eBlank + 1; i < Reward::NUM_QUESTS; i++ ) + { + pReward = GetRewardsManager()->GetReward( pScreen->GetCurrentLevel(), static_cast<Reward::eQuestType>( i ) ); + if( pReward != NULL ) + { + if( pReward->GetRewardType() == Reward::ALT_PLAYERCAR ) + { + rAssert( m_numSelections < MAX_NUM_VEHICLES_PER_LEVEL ); + + // store reference to reward + // + m_rewardSelections[ m_numSelections ] = pReward; + + sprintf( filename, "%s%s.p3d", VEHICLE_GALLERY_IMAGES_DIR, pReward->GetName() ); + rAssert( strlen( filename) < sizeof( filename ) ); + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + filename, + GMA_LEVEL_FE, + VEHICLE_GALLERY_INVENTORY_SECTION, + VEHICLE_GALLERY_INVENTORY_SECTION ); + + m_numSelections++; + } + } + } + + // load merchandise vehicles (from GIL) + // + for( pReward = GetRewardsManager()->FindFirstMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_GIL ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_GIL ) ) + { + rAssert( m_numSelections < MAX_NUM_VEHICLES_PER_LEVEL ); + + // store reference to reward + // + m_rewardSelections[ m_numSelections ] = pReward; + + sprintf( filename, "%s%s.p3d", VEHICLE_GALLERY_IMAGES_DIR, pReward->GetName() ); + rAssert( strlen( filename) < sizeof( filename ) ); + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + filename, + GMA_LEVEL_FE, + VEHICLE_GALLERY_INVENTORY_SECTION, + VEHICLE_GALLERY_INVENTORY_SECTION ); + + m_numSelections++; + } + + // load merchandise vehicles (from SIMPSON CHARACTER) + // + for( pReward = GetRewardsManager()->FindFirstMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_SIMPSON ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_SIMPSON ) ) + { + rAssert( m_numSelections < MAX_NUM_VEHICLES_PER_LEVEL ); + + // store reference to reward + // + m_rewardSelections[ m_numSelections ] = pReward; + + sprintf( filename, "%s%s.p3d", VEHICLE_GALLERY_IMAGES_DIR, pReward->GetName() ); + rAssert( strlen( filename) < sizeof( filename ) ); + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + filename, + GMA_LEVEL_FE, + VEHICLE_GALLERY_INVENTORY_SECTION, + VEHICLE_GALLERY_INVENTORY_SECTION ); + + m_numSelections++; + } + + rWarningMsg( m_numSelections > 0, "No model selections available!" ); + + if( m_numSelections > 0 ) + { + GetLoadingManager()->AddCallback( this ); + + m_numTransitionsPending++; + } + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); // hide by default + + for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ ) + { + if( i < m_numSelections ) + { + bool isUnlocked = m_rewardSelections[ i ]->RewardStatus(); + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) ) + { + isUnlocked = true; + } + + m_pMenu->SetMenuItemEnabled( i, isUnlocked ); + + if( isUnlocked ) + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + } + } + else + { + m_pMenu->SetMenuItemEnabled( i, false ); + } + } +} + +void +CGuiScreenVehicleGallery::Unload2DImages() +{ + p3d::pddi->DrawSync(); + + // clear all drawables + // + for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ ) + { + Scrooby::Sprite* vehicleImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( vehicleImage != NULL ); + vehicleImage->SetRawSprite( NULL, true ); + + m_pMenu->SetMenuItemEnabled( i, false ); + } + + // unload 2D images + // + p3d::inventory->RemoveSectionElements( VEHICLE_GALLERY_INVENTORY_SECTION ); + + m_isVehiclesLoaded = false; +} +#ifdef RAD_WIN32 +void CGuiScreenVehicleGallery::SetVisibilityForAllOtherMenuItems( bool bVisible ) +{ + for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ ) + { + if( i != m_selectedVehicle ) + m_pMenu->GetMenuItem(i)->GetItem()->SetVisible( bVisible ); + } +} +#endif diff --git a/game/code/presentation/gui/frontend/guiscreenvehiclegallery.h b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.h new file mode 100644 index 0000000..6ddc500 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.h @@ -0,0 +1,100 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenVehicleGallery +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENVEHICLEGALLERY_H +#define GUISCREENVEHICLEGALLERY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <loading/loadingmanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu2D; +class Reward; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenVehicleGallery : public CGuiScreen, + public LoadingManager::ProcessRequestsCallback +{ +public: + CGuiScreenVehicleGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenVehicleGallery(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + // Implements LoadingManager::ProcessRequestsCallback + // + virtual void OnProcessRequestsComplete( void* pUserData ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void OnUpdate( unsigned int elapsedTime ); + void OnMenuSelectionChange( int selection ); + void OnMenuSelectionMade( int selection ); + void SetMenuAlpha( float alpha ); +#ifdef RAD_WIN32 + void SetVisibilityForAllOtherMenuItems( bool bDisable ); +#endif + + void Load2DImages(); + void Unload2DImages(); + + static const int MAX_NUM_VEHICLES_PER_LEVEL = 6; + + CGuiMenu2D* m_pMenu; + + Reward* m_rewardSelections[ MAX_NUM_VEHICLES_PER_LEVEL ]; + int m_numSelections; + + bool m_isVehiclesLoaded : 1; + + enum eScreenState + { + SCREEN_STATE_NORMAL, + SCREEN_STATE_GOTO_VIEW, + SCREEN_STATE_VIEWING, + SCREEN_STATE_BACK_VIEW, + + NUM_SCREEN_STATES + }; + + eScreenState m_screenState; + unsigned int m_elapsedTime; + rmt::Vector m_projectileVelocity; + + Scrooby::Layer* m_vehicleInfo; + Scrooby::Text* m_vehicleName; + +#ifdef RAD_WIN32 + int m_selectedVehicle; +#endif +}; + +#endif // GUISCREENVEHICLEGALLERY_H diff --git a/game/code/presentation/gui/frontend/guiscreenviewcredits.cpp b/game/code/presentation/gui/frontend/guiscreenviewcredits.cpp new file mode 100644 index 0000000..ed3a614 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenviewcredits.cpp @@ -0,0 +1,503 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenViewCredits +// +// Description: Implementation of the CGuiScreenViewCredits class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/05/14 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenviewcredits.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guiuserinputhandler.h> + +#include <cheats/cheatinputsystem.h> +#include <events/eventmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> + +// Scrooby +#include <app.h> +#include <page.h> +#include <screen.h> +#include <group.h> +#include <text.h> +#include <sprite.h> + +// ATG +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float CREDITS_SCROLL_RATE = 20.0f; // in pixels per second +const float CREDITS_MANUAL_SCROLL_FACTOR = 5.0f; +const float CREDITS_FGD_CORRECTION_SCALE = 2.0f; + +const int CREDITS_PARTITION_FOR_LOCALIZATION = 13; +const int CREDITS_PARTITION_FOR_LOGITECH = 30; + +float CGuiScreenViewCredits::s_totalTranslateY = 0.0f; +float CGuiScreenViewCredits::s_numPixelsPerLine = 0.0f; +float CGuiScreenViewCredits::s_creditsOffsets[ CGuiScreenViewCredits::MAX_NUM_CREDITS_PARTITIONS ]; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenViewCredits::CGuiScreenViewCredits +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenViewCredits::CGuiScreenViewCredits +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_VIEW_CREDITS ), + m_playKKDialog( false ), + m_creditsGroup( NULL ), + m_currentTranslateY( 0.0f ), + m_lastLineDisplayed( 0 ), + m_elapsedIdleTime( 0 ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "ViewCredits" ); + rAssert( pPage != NULL ); + + // get credits group drawable + // + m_creditsGroup = pPage->GetGroup( "Credits" ); + rAssert( m_creditsGroup != NULL ); + + bool isFirstTime = ( s_totalTranslateY == 0.0f ); + float currentTranslateY = 0.0f; + + // get all credits (partitioned) text + // + for( int i = 0; i < MAX_NUM_CREDITS_PARTITIONS; i++ ) + { + char name[ 16 ]; + sprintf( name, "Credits%d", i ); + m_credits[ i ] = m_creditsGroup->GetText( name ); + + if( m_credits[ i ] != NULL ) + { +#ifndef PAL + // hide localization partition from credits for NTSC builds + // + if( i == CREDITS_PARTITION_FOR_LOCALIZATION ) + { + m_credits[ i ]->SetVisible( false ); + + continue; + } +#endif // !PAL + +#ifndef RAD_GAMECUBE + #ifndef RAD_PS2 + // hide logitech line from credits for non-GC and non-PS2 platforms + // + if( i == CREDITS_PARTITION_FOR_LOGITECH ) + { + m_credits[ i ]->SetVisible( false ); + + continue; + } + #endif // !RAD_PS2 +#endif // !RAD_GAMECUBE + + if( isFirstTime ) + { + currentTranslateY = this->FormatTextWithLineBreaks( m_credits[ i ] ); + + s_creditsOffsets[ i ] = -s_totalTranslateY; + s_totalTranslateY += currentTranslateY; + } + + // offset current credits partition by total translation so far + // + m_credits[ i ]->ResetTransformation(); + m_credits[ i ]->Translate( 0, (int)s_creditsOffsets[ i ] ); + + // disable any text outlining or drop shadow effects + // + m_credits[ i ]->SetDisplayOutline( false ); + m_credits[ i ]->SetDisplayShadow( false ); + } + else + { + // assuming there's no more partitions to follow + // + break; + } + } + + // increment total translation for the screen area + // + if( isFirstTime ) + { + s_totalTranslateY += Scrooby::App::GetInstance()->GetScreenHeight(); + } + +/* + // get skip label + // + m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "SkipLabel" ); + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); +*/ + + // apply correction scale to credits foreground overlay image (from CreditsFgd.pag) + // + pPage = m_pScroobyScreen->GetPage( "CreditsFgd" ); + if( pPage != NULL ) + { + Scrooby::Sprite* creditsFgd = pPage->GetSprite( "CreditsFgd" ); + if( creditsFgd != NULL ) + { + creditsFgd->ResetTransformation(); + creditsFgd->ScaleAboutCenter( CREDITS_FGD_CORRECTION_SCALE ); + } + } +} + + +//=========================================================================== +// CGuiScreenViewCredits::~CGuiScreenViewCredits +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenViewCredits::~CGuiScreenViewCredits() +{ +} + + +//=========================================================================== +// CGuiScreenViewCredits::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCredits::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_WINDOW_ENTER ) + { + this->SetFadingEnabled( !GetGuiSystem()->IsShowCreditsUponReturnToFE() ); + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + float currentScrollAmount = param1 / 1000.0f * CREDITS_SCROLL_RATE; + + // auto-scrolling + // + bool isScrollingDone = this->ScrollCredits( currentScrollAmount ); + + // check for up/down controller inputs for manual scroll control + // + const int NUM_USER_INPUT_HANDLERS = GetGuiSystem()->GetNumUserInputHandlers(); + + for( int i = 0; i < NUM_USER_INPUT_HANDLERS; i++ ) + { + CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i ); + if( userInputHandler != NULL ) + { +#ifdef RAD_WIN32 + if( userInputHandler->IsYAxisOnUp() ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Up ) || + userInputHandler->IsYAxisOnUp() ) +#endif + { + // scroll upwards at opposite rate + // + isScrollingDone = this->ScrollCredits( -(1.0f + CREDITS_MANUAL_SCROLL_FACTOR) * currentScrollAmount ); + } + + if( !m_playKKDialog ) // only allow speed-up if dialog is not playing + { +#ifdef RAD_WIN32 + if( userInputHandler->IsYAxisOnDown() ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Down ) || + userInputHandler->IsYAxisOnDown() ) +#endif + { + // double the scroll rate + // + isScrollingDone = this->ScrollCredits( (CREDITS_MANUAL_SCROLL_FACTOR - 1.0f) * currentScrollAmount ); + } + } + } + } + + // check if scroll idle time has expired + // + if( m_elapsedIdleTime > SCROLL_IDLE_TIME_BEFORE_RESET ) + { + this->OnScrollingDone(); + } + else if( isScrollingDone ) + { + m_elapsedIdleTime += param1; + } + + break; + } + case GUI_MSG_CONTROLLER_SELECT: + { + this->OnScrollingDone(); + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + // ignore back controller inputs + // + return; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenViewCredits::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCredits::InitIntro() +{ + // only play K&K credits dialog if either cheat is enabled or user has completed + // the last mission of the game + // + m_playKKDialog = GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_PLAY_CREDITS_DIALOG ) || + GetCharacterSheetManager()->QueryMissionStatus( RenderEnums::L7, RenderEnums::M7 )->mCompleted; + + this->ResetScrolling(); + + // hide back button label + // + this->SetButtonVisible( BUTTON_ICON_BACK, false ); + + GetEventManager()->TriggerEvent( EVENT_PLAY_CREDITS ); +} + + +//=========================================================================== +// CGuiScreenViewCredits::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCredits::InitRunning() +{ + if( GetGuiSystem()->IsShowCreditsUponReturnToFE() ) + { + this->RestoreDefaultFadeTime(); + } +} + + +//=========================================================================== +// CGuiScreenViewCredits::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCredits::InitOutro() +{ + if( GetGuiSystem()->IsShowCreditsUponReturnToFE() ) + { + GetGuiSystem()->ShowCreditsUponReturnToFE( false ); + } + + GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP ); + GetEventManager()->TriggerEvent( EVENT_PLAY_FE_MUSIC ); +} + + +void +CGuiScreenViewCredits::ResetScrolling() +{ + rAssert( m_creditsGroup != NULL ); + m_creditsGroup->ResetTransformation(); + + m_currentTranslateY = 0.0f; + + m_lastLineDisplayed = 0; +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +float +CGuiScreenViewCredits::FormatTextWithLineBreaks( Scrooby::Text* pText ) +{ + rAssert( pText != NULL ); + + float totalTranslateY = 0.0f; + + int width = 0; + int height = 0; + pText->GetBoundingBoxSize( width, height ); + +#ifdef RAD_WIN32 + const float SPACING_FUDGE_FACTOR = 1.20f; +#else + const float SPACING_FUDGE_FACTOR = 1.15f; +#endif + + s_numPixelsPerLine = height * SPACING_FUDGE_FACTOR; + + P3D_UNICODE* textBuffer = static_cast<P3D_UNICODE*>( pText->GetStringBuffer() ); + rAssert( textBuffer != NULL ); + + for( int i = 0; textBuffer[ i ] != '\0'; i++ ) + { + if( textBuffer[ i ] == '\\' ) // replace backslashes with line breaks + { + textBuffer[ i ] = '\n'; + + // increment total translation by number of pixels per line + // + totalTranslateY += s_numPixelsPerLine; + } + } + + return totalTranslateY; +} + +bool +CGuiScreenViewCredits::ScrollCredits( float pixels ) +{ + float newTranslateY = m_currentTranslateY + pixels; + + bool isScrollingDone = ( newTranslateY > s_totalTranslateY ); + + if( newTranslateY >= 0 && newTranslateY <= s_totalTranslateY ) + { + m_currentTranslateY = newTranslateY; + + rAssert( m_creditsGroup != NULL ); + m_creditsGroup->ResetTransformation(); + m_creditsGroup->Translate( 0, (int)m_currentTranslateY ); + + // check if new line is displayed + // + const float BOTTOM_OFFSET = 80.0f; // in pixels + if( (m_currentTranslateY - BOTTOM_OFFSET) >= (m_lastLineDisplayed * s_numPixelsPerLine) ) + { + m_lastLineDisplayed++; + + this->OnNewLineDisplayed( m_lastLineDisplayed ); + } + + m_elapsedIdleTime = 0; // reset idle time + } + else + { + rDebugPrintf( "Credits not scrolling.\n" ); + } + + return isScrollingDone; +} + +void +CGuiScreenViewCredits::OnScrollingDone() +{ + if( GetGuiSystem()->IsShowCreditsUponReturnToFE() ) + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_MAIN_MENU, + CLEAR_WINDOW_HISTORY ); + } + else if( m_guiManager->GetPreviousScreen() != GUI_WINDOW_ID_UNDEFINED ) + { + this->StartTransitionAnimation( 630, 660 ); + + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); + } +} + +void +CGuiScreenViewCredits::OnNewLineDisplayed( int lineNumber ) +{ + rTunePrintf( "Credits Line #%d\n", lineNumber ); + + if( m_playKKDialog ) + { + // trigger this event for the sound manager to play line-specific dialog + // + GetEventManager()->TriggerEvent( EVENT_FE_CREDITS_NEW_LINE, (void*)lineNumber ); + } +} + diff --git a/game/code/presentation/gui/frontend/guiscreenviewcredits.h b/game/code/presentation/gui/frontend/guiscreenviewcredits.h new file mode 100644 index 0000000..b1899bf --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenviewcredits.h @@ -0,0 +1,74 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenViewCredits +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/05/14 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENVIEWCREDITS_H +#define GUISCREENVIEWCREDITS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenViewCredits : public CGuiScreen +{ +public: + CGuiScreenViewCredits( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenViewCredits(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void ResetScrolling(); + bool m_playKKDialog : 1; + + Scrooby::Group* m_creditsGroup; + +private: + float FormatTextWithLineBreaks( Scrooby::Text* pText ); + + bool ScrollCredits( float pixels ); + virtual void OnScrollingDone(); + + void OnNewLineDisplayed( int lineNumber ); + + static const int MAX_NUM_CREDITS_PARTITIONS = 32; + + static float s_totalTranslateY; + static float s_numPixelsPerLine; + static float s_creditsOffsets[ MAX_NUM_CREDITS_PARTITIONS ]; + + Scrooby::Text* m_credits[ MAX_NUM_CREDITS_PARTITIONS ]; + float m_currentTranslateY; + int m_lastLineDisplayed; + + static const unsigned int SCROLL_IDLE_TIME_BEFORE_RESET = 0; // in msec + unsigned int m_elapsedIdleTime; + +}; + +#endif // GUISCREENVIEWCREDITS_H diff --git a/game/code/presentation/gui/frontend/guiscreenviewmovies.cpp b/game/code/presentation/gui/frontend/guiscreenviewmovies.cpp new file mode 100644 index 0000000..5573f98 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenviewmovies.cpp @@ -0,0 +1,287 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenViewMovies +// +// Description: Implementation of the CGuiScreenViewMovies class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenviewmovies.h> +#include <presentation/gui/frontend/guiscreenplaymovie.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guimanager.h> + +#include <cheats/cheatinputsystem.h> +#include <constants/movienames.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> + +#include <raddebug.hpp> // Foundation +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* MOVIES_MENU_ITEMS[] = +{ + "IntroMovie", + "Movie1", + "Movie2", + "Movie3", + "Movie4", + "Movie5", + "Movie6", + "Movie7", + "Movie8", + + "" // dummy terminator +}; + +const char* MOVIES_SELECTION[] = +{ + MovieNames::INTROFMV, + MovieNames::MOVIE1, + MovieNames::MOVIE2, + MovieNames::MOVIE3, + MovieNames::MOVIE4, + MovieNames::MOVIE5, + MovieNames::MOVIE6, + MovieNames::MOVIE7, + MovieNames::MOVIE8, + + "" // dummy terminator +}; + +const int NUM_MOVIE_SELECTIONS = sizeof( MOVIES_SELECTION ) / sizeof( MOVIES_SELECTION[ 0 ] ) - 1; + +const int MOVIE_INDEX_FOR_LEVEL[] = +{ + 2, // level 1 + 3, // level 2 + 8, // level 3 + 4, // level 4 + 5, // level 5 + 6, // level 6 + 7, // level 7 + + -1 +}; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenViewMovies::CGuiScreenViewMovies +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenViewMovies::CGuiScreenViewMovies +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_VIEW_MOVIES ), + m_pMenu( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGuiScreenViewMovies" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "ViewMovies" ); + rAssert( pPage ); + + // Create a menu. + // + m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MOVIE_SELECTIONS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + for( int i = 0; i < NUM_MOVIE_SELECTIONS; i++ ) + { + m_pMenu->AddMenuItem( pPage->GetText( MOVIES_MENU_ITEMS[ i ] ) ); + } + + this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) ); +MEMTRACK_POP_GROUP("CGuiScreenViewMovies"); +} + + +//=========================================================================== +// CGuiScreenViewMovies::~CGuiScreenViewMovies +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenViewMovies::~CGuiScreenViewMovies() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenViewMovies::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewMovies::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( m_guiManager ); + CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE ) ); + rAssert( playMovieScreen ); + + rAssert( static_cast<int>( param1 ) < NUM_MOVIE_SELECTIONS ); + if( param1 == 0 ) // 0 = Intro FMV + { + // Intro FMV does not have localized audio. + // + playMovieScreen->SetMovieToPlay( MOVIES_SELECTION[ param1 ], true, false, false ); + } + else + { + playMovieScreen->SetMovieToPlay( MOVIES_SELECTION[ param1 ] ); + } + + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_PLAY_MOVIE ); + this->StartTransitionAnimation( 975, 1005 ); + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + this->StartTransitionAnimation( 944, 974 ); + + break; + } + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenViewMovies::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewMovies::InitIntro() +{ + // update movies unlocked status + // + rAssert( m_pMenu != NULL ); + for( int i = 0; i < RenderEnums::numLevels; i++ ) + { + bool isUnlocked = GetCharacterSheetManager()->QueryFMVUnlocked( static_cast<RenderEnums::LevelEnum>( i ) ) || + GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MOVIES ); + + m_pMenu->SetMenuItemEnabled( MOVIE_INDEX_FOR_LEVEL[ i ], isUnlocked ); + } +} + + +//=========================================================================== +// CGuiScreenViewMovies::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewMovies::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenViewMovies::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewMovies::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/frontend/guiscreenviewmovies.h b/game/code/presentation/gui/frontend/guiscreenviewmovies.h new file mode 100644 index 0000000..5513f34 --- /dev/null +++ b/game/code/presentation/gui/frontend/guiscreenviewmovies.h @@ -0,0 +1,53 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenViewMovies +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENVIEWMOVIES_H +#define GUISCREENVIEWMOVIES_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenViewMovies : public CGuiScreen +{ +public: + CGuiScreenViewMovies( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenViewMovies(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + CGuiMenu* m_pMenu; + +}; + +#endif // GUISCREENVIEWMOVIES_H diff --git a/game/code/presentation/gui/guientity.cpp b/game/code/presentation/gui/guientity.cpp new file mode 100644 index 0000000..d2a1a6a --- /dev/null +++ b/game/code/presentation/gui/guientity.cpp @@ -0,0 +1,61 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiEntity +// +// Description: Implementation of the CGuiEntity class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/21 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guientity.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiEntity::CGuiEntity +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiEntity::CGuiEntity( CGuiEntity* pParent ) +: m_pParent( pParent ) +{ +} + +//=========================================================================== +// CGuiEntity::~CGuiEntity +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiEntity::~CGuiEntity() +{ +} diff --git a/game/code/presentation/gui/guientity.h b/game/code/presentation/gui/guientity.h new file mode 100644 index 0000000..8fc7afb --- /dev/null +++ b/game/code/presentation/gui/guientity.h @@ -0,0 +1,184 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiEntity +// +// Description: Interface for the CGuiEntity class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUIENTITY_H +#define GUIENTITY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +//=========================================================================== +// Forward References +//=========================================================================== + +#ifndef NULL + #define NULL 0 +#endif + +#ifdef RAD_GAMECUBE + const int PLATFORM_TEXT_INDEX = 0; +#endif +#ifdef RAD_PS2 + const int PLATFORM_TEXT_INDEX = 1; +#endif +#ifdef RAD_XBOX + const int PLATFORM_TEXT_INDEX = 2; +#endif +#ifdef RAD_WIN32 // parallel the xbox for now. + const int PLATFORM_TEXT_INDEX = 2; +#endif + +enum eGuiMessage +{ + GUI_MSG_UPDATE, // GUI system -> Manager -> current screen + GUI_MSG_CONTROLLER_ALPHA, // begin controller messages + GUI_MSG_CONTROLLER_UP, // + GUI_MSG_CONTROLLER_DOWN, + GUI_MSG_CONTROLLER_LEFT, + GUI_MSG_CONTROLLER_RIGHT, + GUI_MSG_CONTROLLER_AUX_UP, // on right analog stick + GUI_MSG_CONTROLLER_AUX_DOWN, // on right analog stick + GUI_MSG_CONTROLLER_AUX_LEFT, // on right analog stick + GUI_MSG_CONTROLLER_AUX_RIGHT, // on right analog stick + GUI_MSG_CONTROLLER_START, + GUI_MSG_CONTROLLER_SELECT, + GUI_MSG_CONTROLLER_BACK, + GUI_MSG_CONTROLLER_AUX_X, + GUI_MSG_CONTROLLER_AUX_Y, + GUI_MSG_CONTROLLER_L1, + GUI_MSG_CONTROLLER_R1, + GUI_MSG_CONTROLLER_CONNECT, + GUI_MSG_CONTROLLER_DISCONNECT, // + GUI_MSG_CONTROLLER_OMEGA, // end controller messages + GUI_MSG_PROJECT_LOAD_COMPLETE, // Scrooby File Handler -> GUI System + GUI_MSG_INIT_BOOTUP, // client -> System + GUI_MSG_RELEASE_BOOTUP, // client -> System + GUI_MSG_INIT_FRONTEND, // client -> System + GUI_MSG_RELEASE_FRONTEND, // client -> System + GUI_MSG_INIT_MINIGAME, // client -> System + GUI_MSG_RELEASE_MINIGAME, // client -> System + GUI_MSG_INIT_INGAME, // client -> System + GUI_MSG_RELEASE_INGAME, // client -> System + GUI_MSG_PRE_RUN_BACKEND, // ManagerInGame -> ManagerBackEnd + GUI_MSG_RUN_BACKEND, // client -> System + GUI_MSG_RUN_FRONTEND, // client -> System + GUI_MSG_RUN_MINIGAME, // client -> System + GUI_MSG_RUN_INGAME, // client -> System + GUI_MSG_RUN_DEMO, // client -> System + GUI_MSG_PAUSE_INGAME, // System -> ManagerInGame + GUI_MSG_UNPAUSE_INGAME, // Pause Menu Screen -> ManagerInGame + GUI_MSG_RESUME_INGAME, // System -> ManagerInGame + GUI_MSG_QUIT_BOOTUP, // client -> ManagerBootUp + GUI_MSG_QUIT_BACKEND, // client -> ManagerBackEnd + GUI_MSG_QUIT_FRONTEND, // Screen -> ManagerFrontEnd + GUI_MSG_QUIT_MINIGAME, // Screen -> ManagerMiniGame + GUI_MSG_QUIT_INGAME, // PauseMenu -> ManagerInGame + GUI_MSG_QUIT_INGAME_FOR_RELOAD, // MissionSelect -> ManagerInGame + GUI_MSG_QUIT_DEMO, // client/screen -> ManagerBackEnd + GUI_MSG_QUIT_GAME, // pc. Screen -> ManagerFrontEnd + GUI_MSG_BOOTUP_LOAD_COMPLETED, // screen -> ManagerBootUp + GUI_MSG_LANGUAGE_SELECTION_DONE, // screen -> ManagerBootUp + GUI_MSG_MEMCARD_CHECK_COMPLETED, // screen -> ManagerBootUp / ManagerFrontEnd + GUI_MSG_SPLASH_SCREEN_DONE, // screen -> ManagerFrontEnd + GUI_MSG_GOTO_SCREEN, // screen -> ManagerFrontEnd (param1 = screen id) + GUI_MSG_BACK_SCREEN, // screen -> Manager + GUI_MSG_SHOW_HUD_OVERLAY, // client -> In-game HUD (param1 = overlay id) + GUI_MSG_HIDE_HUD_OVERLAY, // client -> In-game HUD (param1 = overlay id) + GUI_MSG_INGAME_MISSION_COMPLETE, // client -> ManagerInGame + GUI_MSG_INGAME_MISSION_FAILED, // client -> ManagerInGame + GUI_MSG_INGAME_MISSION_LOAD_BEGIN, // client -> ManagerInGame + GUI_MSG_INGAME_MISSION_LOAD_END, // client -> ManagerInGame + GUI_MSG_INGAME_DISPLAY_PROMPT, // client -> ManagerInGame + GUI_MSG_WINDOW_ENTER, // Manager -> Window + GUI_MSG_WINDOW_EXIT, // Manager -> Window + GUI_MSG_WINDOW_FINISHED, // Window -> Manager + GUI_MSG_WINDOW_PAUSE, // client -> Window + GUI_MSG_WINDOW_RESUME, // client -> Window + GUI_MSG_DEMOLOOP_BEGIN, // ManagerFrontEnd->Screen + GUI_MSG_DEMOLOOP_END, // ManagerFrontEnd->Screen + GUI_MSG_RESTART_GAME, // Pause Menu -> ManagerInGame + GUI_MSG_MENU_SELECTION_CHANGED, // Menu -> Screen + GUI_MSG_MENU_SELECTION_VALUE_CHANGED, // Menu -> Screen + GUI_MSG_MENU_SELECTION_MADE, // Menu -> Screen + GUI_MSG_MENU_SLIDER_NOT_CHANGING, // Menu -> Screen + GUI_MSG_ON_DISPLAY_MESSAGE, // Message Screen -> Screen + GUI_MSG_MENU_PROMPT_RESPONSE, // Prompt Screen -> Screen + GUI_MSG_ERROR_PROMPT_RESPONSE, // Prompt Screen -> Screen + GUI_MSG_PROMPT_START_RESPONSE, // Prompt Screen -> Screen, only on ps2 + GUI_MSG_DEATH_VOLUME_START, // Play the death volume transition + GUI_MSG_MANUAL_RESET, // Play the death volume transition + GUI_MSG_START_IRIS_WIPE_CLOSE, // Do an iris wipe closing + GUI_MSG_START_IRIS_WIPE_OPEN, // Do an iris wipe opening + GUI_MSG_INGAME_FADE_OUT, // Fade from IN-GAME to BLACK + GUI_MSG_INGAME_FADE_IN, // Fade from BLACK to IN-GAME + GUI_MSG_INGAME_FADE_OUT_CANCEL, // Cancel fading from IN-GAME to BLACK + GUI_MSG_INGAME_FADE_IN_CANCEL, // Cancel fading from BLACK to IN-GAME + GUI_MSG_LOAD_RESOURCES, // GUI manager -> Screen + GUI_MSG_SET_GOTO_SCREEN_PARAMETERS, // GUI system -> GUI manager + GUI_MSG_ON_SAVE_GAME_COMPLETE, // save game screen -> GUI in-game manager + GUI_MSG_PROMPT_UPDATE, // Prompt Screen -> Screen called during CGuiScreenPrompt::HandleMessage GUI_MSG_UPDATE + GUI_MSG_MESSAGE_UPDATE, // Message Screen -> Screen called during CGuiScreenMessage::HandleMessage GUI_MSG_UPDATE +#ifdef RAD_WIN32 + GUI_MSG_MOUSE_OVER, // Called when a mouse cursor is on a hotspot. + GUI_MSG_MOUSE_LCLICK, // Called when a mouse clicks the left button and releases. + GUI_MSG_MOUSE_RCLICK, // Called when a mouse clicks the right button and releases. + GUI_MSG_MOUSE_LCLICKHOLD, // Called when a mouse clicks a hotspot and holds with the left button. + GUI_MSG_MOUSE_RCLICKHOLD, // Called when a mouse clicks a hotspot and holds with the right button. + GUI_MSG_MOUSE_LCLICKDRAG, // Called when a mouse left clicks on a hotspot and drags. + GUI_MSG_QUIT_TO_SYSTEM, +#endif + + GUI_MSG_TOTAL +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiEntity +{ +public: + CGuiEntity( CGuiEntity* pParent ); + virtual ~CGuiEntity(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ) = 0; + + static bool IsControllerMessage( eGuiMessage message ); + +protected: + CGuiEntity* m_pParent; + +private: + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignement. Declare but don't define. + // + CGuiEntity( const CGuiEntity& ); + CGuiEntity& operator= ( const CGuiEntity& ); + +}; + +inline bool +CGuiEntity::IsControllerMessage( eGuiMessage message ) +{ + return (message > GUI_MSG_CONTROLLER_ALPHA && message < GUI_MSG_CONTROLLER_OMEGA); +} + +#endif // GUIENTITY_H diff --git a/game/code/presentation/gui/guimanager.cpp b/game/code/presentation/gui/guimanager.cpp new file mode 100644 index 0000000..8a0ab88 --- /dev/null +++ b/game/code/presentation/gui/guimanager.cpp @@ -0,0 +1,650 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManager +// +// Description: Implementation of the CGuiManager class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/21 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guisystem.h> // for loading callback +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guiscreenprompt.h> +#include <input/inputmanager.h> + +#include <gameflow/gameflow.h> +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +CGuiManager::eMemoryCardCheckingState +CGuiManager::s_memcardCheckState = CGuiManager::MEM_CARD_CHECK_NOT_DONE; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManager::CGuiManager +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManager::CGuiManager +( + Scrooby::Project* pProject, + CGuiEntity* pParent +) +: CGuiEntity( pParent ), + m_numWindows( 0 ), + m_pScroobyProject( pProject ), + m_currentScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ), + m_nextScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ), + m_state( GUI_FE_UNINITIALIZED ), + m_windowHistoryCount( 0 ), + m_gotoScreenUserParam1( 0 ), + m_gotoScreenUserParam2( 0 ) +{ + for( unsigned int i = 0; i < sizeof( m_windows ) / + sizeof( m_windows[ 0 ] ); i++ ) + { + m_windows[ i ] = NULL; + } + + for( unsigned int j = 0; j < sizeof( m_windowHistory ) / + sizeof( m_windowHistory[ 0 ] ); j++ ) + { + m_windowHistory[ j ] = CGuiWindow::GUI_WINDOW_ID_UNDEFINED; + } + //Load the mouse cursor. +#ifdef RAD_WIN32 + tDrawable* pMouseCursor = p3d::find<tDrawable>("mouse_cursor.png"); + GetInputManager()->GetFEMouse()->InitMouseCursor( pMouseCursor ); +#endif +} + + +//=========================================================================== +// CGuiManager::~CGuiManager +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManager::~CGuiManager() +{ + // Remove all existing screens. + // + this->RemoveAllWindows(); +} + + +//=========================================================================== +// CGuiManager::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManager::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_SET_GOTO_SCREEN_PARAMETERS: + { + m_gotoScreenUserParam1 = param1; + m_gotoScreenUserParam2 = param2; + + break; + } + + case GUI_MSG_GOTO_SCREEN: + { + CGuiWindow::eGuiWindowID nextScreen = static_cast<CGuiWindow::eGuiWindowID>( param1 ); + + if( this->FindWindowByID( nextScreen ) == NULL ) + { + // ignore if screen not found + // + break; + } + + if( (nextScreen == m_currentScreen) && + (param2 & FORCE_WINDOW_RELOAD) == 0 ) + { + if( m_nextScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + m_nextScreen = nextScreen; + } + + // ignore if we are already on the requested screen, + // unless we're trying to force a screen reload + // + break; + } + + m_nextScreen = nextScreen; + + rDebugPrintf( "GUI GoTo Screen Request: (next screen ID = %d)\n", m_nextScreen ); + + // push current screen onto history stack, unless requested + // to keep existing history + // + if( (param2 & KEEP_WINDOW_HISTORY) == 0 ) + { + this->PushScreenHistory( m_currentScreen ); + } + + // clear screen history, if requested + // + if( (param2 & CLEAR_WINDOW_HISTORY) > 0 ) + { + this->ClearScreenHistory(); + } + + m_state = GUI_FE_CHANGING_SCREENS; + + // Tell the current screen to shut down. + // + if( m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + } + + if( (param2 & FORCE_WINDOW_CHANGE_IMMEDIATE) > 0 ) + { + m_currentScreen = m_nextScreen; + + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + } + + break; + } + + case GUI_MSG_BACK_SCREEN: + { + CGuiWindow::eGuiWindowID nextScreen = CGuiWindow::GUI_WINDOW_ID_UNDEFINED; + + // param1 = number of extra screens to go back + // + for( unsigned int numBackScreens = 0; numBackScreens < (param1 + 1); numBackScreens++ ) + { + nextScreen = this->PopScreenHistory(); + } + + if( nextScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + m_nextScreen = nextScreen; + + m_state = GUI_FE_CHANGING_SCREENS; + + // Tell the current screen to shut down. + // + rAssert( m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + } + + break; + } + + case GUI_MSG_MEMCARD_CHECK_COMPLETED: + { + s_memcardCheckState = MEM_CARD_CHECK_COMPLETED; + + break; + } + + default: + { + break; + } + } +} + + +//=========================================================================== +// CGuiManager::OnGotoScreenComplete +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManager::OnGotoScreenComplete() +{ + m_state = GUI_FE_SCREEN_RUNNING; + + rAssert( CGuiWindow::GUI_WINDOW_ID_UNDEFINED != m_nextScreen ); + + m_currentScreen = m_nextScreen; + + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_ENTER, + m_gotoScreenUserParam1, + m_gotoScreenUserParam2 ); + + // reset goto screen user parameters + // + m_gotoScreenUserParam1 = 0; + m_gotoScreenUserParam2 = 0; +} + + +//=========================================================================== +// CGuiManager::FindWindowByID +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +CGuiWindow* CGuiManager::FindWindowByID +( + CGuiWindow::eGuiWindowID id +) +{ +/* + for( int i = 0; i < m_windows.mSize; ++i ) + { + if( m_windows[i]->GetWindowID() == id ) + { + return( m_windows[i] ); + } + } +*/ + CGuiWindow* window = NULL; + + if( this->IsValidWindowID( id ) ) + { + window = m_windows[ id ]; + } + + return window; +} + +//=========================================================================== +// CGuiManager::GetCurrentWindow +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +CGuiWindow* CGuiManager::GetCurrentWindow() +{ + return FindWindowByID( m_currentScreen ); +} + + +//=========================================================================== +// CGuiManager::DisplayMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiManager::DisplayMessage +( + int messageIndex, + CGuiEntity* pCallback +) +{ + CGuiScreenMessage::Display( messageIndex, pCallback ); + + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE, + KEEP_WINDOW_HISTORY | FORCE_WINDOW_RELOAD ); +} + + +//=========================================================================== +// CGuiManager::DisplayPrompt +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiManager::DisplayPrompt +( + int messageIndex, + CGuiEntity* pCallback, + eGenericPromptType promptType, + bool enableDefaultToNo +) +{ + switch( promptType ) + { + case PROMPT_TYPE_YES_NO: + { + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_YES, + CGuiMenuPrompt::RESPONSE_NO + }; + + CGuiScreenPrompt::Display( messageIndex, pCallback, 2, responses ); + CGuiScreenPrompt::EnableDefaultToNo( enableDefaultToNo ); + + break; + } + case PROMPT_TYPE_CONTINUE: + { + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_CONTINUE + }; + + CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses ); + + break; + } + case PROMPT_TYPE_OK: + { + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_OK + }; + + CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses ); + + break; + } + case PROMPT_TYPE_DELETE: + { + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_DELETE + }; + + CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses ); + + break; + } + case PROMPT_TYPE_LOAD: + { + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_LOAD + }; + + CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses ); + + break; + } + case PROMPT_TYPE_SAVE: + { + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_SAVE + }; + + CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses ); + + break; + } + default: + { + rAssertMsg( 0, "*** ERROR: Invalid prompt type!" ); + + break; + } + } + + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, + KEEP_WINDOW_HISTORY | FORCE_WINDOW_RELOAD ); +} + + +//=========================================================================== +// CGuiManager::DisplayErrorPrompt +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiManager::DisplayErrorPrompt +( + int messageIndex, + CGuiEntity* pCallback, + int promptResponses +) +{ + int numResponses = 0; + CGuiMenuPrompt::ePromptResponse responses[ CGuiMenuPrompt::MAX_NUM_RESPONSES ]; + + + if( promptResponses & ERROR_RESPONSE_CONTINUE ) + { + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_CONTINUE; + } + + if( promptResponses & ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE ) + { + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_CONTINUE_WITHOUT_SAVE; + } + + if( promptResponses & ERROR_RESPONSE_RETRY ) + { + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_RETRY; + } + + if( promptResponses & ERROR_RESPONSE_DELETE ) + { + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_DELETE; + } + + if( promptResponses & ERROR_RESPONSE_YES ) + { + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_YES; + } + + if( promptResponses & ERROR_RESPONSE_NO ) + { + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_NO; + } + + if( promptResponses & ERROR_RESPONSE_FORMAT ) + { +#ifdef RAD_XBOX + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_XBOX; +#endif +#ifdef RAD_WIN32 + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_XBOX; +#endif +#ifdef RAD_GAMECUBE + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_GC; +#endif +#ifdef RAD_PS2 + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_PS2; +#endif + } + + if( promptResponses & ERROR_RESPONSE_MANAGE ) + { + responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_MANAGE_MEMCARDS; + } + + CGuiScreenPrompt::Display( messageIndex, pCallback, numResponses, responses ); + CGuiScreenPrompt::EnableDefaultToNo( false ); + + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT, + KEEP_WINDOW_HISTORY | FORCE_WINDOW_RELOAD ); +} + + +CGuiWindow::eGuiWindowID +CGuiManager::GetPreviousScreen( int fromCurrentScreen ) const +{ + CGuiWindow::eGuiWindowID previousScreenID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED; + + int windowHistoryCount = m_windowHistoryCount - fromCurrentScreen; + if( windowHistoryCount > 0 ) + { + previousScreenID = m_windowHistory[ windowHistoryCount - 1 ]; + } + + return previousScreenID; +} + +CGuiWindow::eGuiWindowID CGuiManager::GetCurrentScreen() const +{ + return m_currentScreen; +} + +//=========================================================================== +// Protected Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManager::AddWindow +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManager::AddWindow +( + CGuiWindow::eGuiWindowID windowID, + CGuiWindow* pWindow +) +{ + rAssert( this->IsValidWindowID( windowID ) && pWindow != NULL ); + + rAssert( m_windows[ windowID ] == NULL ); + m_windows[ windowID ] = pWindow; + + m_numWindows++; +} + +void +CGuiManager::RemoveWindow( CGuiWindow::eGuiWindowID windowID ) +{ + rAssert( this->IsValidWindowID( windowID ) ); + + if( m_windows[ windowID ] != NULL ) + { + delete m_windows[ windowID ]; + m_windows[ windowID ] = NULL; + + m_numWindows--; + } +} + +void +CGuiManager::RemoveAllWindows() +{ + for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ ) + { + if( m_windows[ i ] != NULL ) + { + delete m_windows[ i ]; + m_windows[ i ] = NULL; + } + } + + m_numWindows = 0; +} + +void +CGuiManager::PushScreenHistory( CGuiWindow::eGuiWindowID windowID ) +{ + if( this->IsValidWindowID( windowID ) ) + { + rAssert( m_windowHistoryCount < MAX_WINDOW_HISTORY ); + + m_windowHistory[ m_windowHistoryCount ] = windowID; + m_windowHistoryCount++; + } +} + +CGuiWindow::eGuiWindowID +CGuiManager::PopScreenHistory() +{ + CGuiWindow::eGuiWindowID windowID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED; + + if( m_windowHistoryCount > 0 ) + { + m_windowHistoryCount--; + + windowID = m_windowHistory[ m_windowHistoryCount ]; + } + + return windowID; +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + diff --git a/game/code/presentation/gui/guimanager.h b/game/code/presentation/gui/guimanager.h new file mode 100644 index 0000000..6e21afa --- /dev/null +++ b/game/code/presentation/gui/guimanager.h @@ -0,0 +1,207 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManager +// +// Description: Interface for the CGuiManager class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUIMANAGER_H +#define GUIMANAGER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guientity.h> +#include <presentation/gui/guiwindow.h> +#include <events/eventlistener.h> +#include <project.h> + +//=========================================================================== +// Forward References +//=========================================================================== +struct IGuiLoadingCallback; + +//=========================================================================== +// Constants +//=========================================================================== + +const int MAX_WINDOW_HISTORY = 8; + +enum eWindowCommand +{ + CLEAR_WINDOW_HISTORY = 1, + KEEP_WINDOW_HISTORY = 2, + FORCE_WINDOW_CHANGE_IMMEDIATE = 4, + FORCE_WINDOW_RELOAD = 8, + + NUM_WINDOW_COMMANDS +}; + +enum eGenericPromptType +{ + PROMPT_TYPE_YES_NO, + PROMPT_TYPE_CONTINUE, + PROMPT_TYPE_OK, + PROMPT_TYPE_DELETE, + PROMPT_TYPE_LOAD, + PROMPT_TYPE_SAVE, + + NUM_GENERIC_PROMPT_TYPES +}; + +enum eErrorPromptResponse +{ + ERROR_RESPONSE_NONE = 0, + + ERROR_RESPONSE_CONTINUE = 1, + ERROR_RESPONSE_RETRY = 2, + ERROR_RESPONSE_YES = 4, + ERROR_RESPONSE_NO = 8, + ERROR_RESPONSE_FORMAT = 16, + ERROR_RESPONSE_MANAGE = 32, + ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE = 64, + ERROR_RESPONSE_DELETE = 128, + ERROR_RESPONSE_ALL = ~0 +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiManager : public CGuiEntity, + public Scrooby::GotoScreenCallback, + public EventListener +{ + public: + + CGuiManager( Scrooby::Project* pProject, + CGuiEntity* pParent ); + + virtual ~CGuiManager(); + + virtual void Populate() = 0; + virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) = 0; + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + Scrooby::Project* GetScroobyProject() const { return m_pScroobyProject; } + + virtual void OnGotoScreenComplete(); + + CGuiWindow* FindWindowByID( CGuiWindow::eGuiWindowID id ); + + CGuiWindow* GetCurrentWindow(); + + void DisplayMessage( int messageIndex, + CGuiEntity* pCallback = NULL ); + + void DisplayPrompt( int messageIndex, + CGuiEntity* pCallback, + eGenericPromptType promptType = PROMPT_TYPE_YES_NO, + bool enableDefaultToNo = true ); + + void DisplayErrorPrompt( int messageIndex, + CGuiEntity* pCallback, + int promptResponses = ERROR_RESPONSE_NONE ); + + CGuiWindow::eGuiWindowID GetPreviousScreen( int fromCurrentScreen = 0 ) const; + CGuiWindow::eGuiWindowID GetCurrentScreen() const; + + // Implements EventListener + virtual void HandleEvent( EventEnum id, void* pEventData ) {}; + + enum eMemoryCardCheckingState + { + MEM_CARD_CHECK_NOT_DONE, + MEM_CARD_CHECK_IN_PROGRESS, + MEM_CARD_CHECK_COMPLETED, + + NUM_MEM_CARD_CHECK_STATES + }; + + static eMemoryCardCheckingState s_memcardCheckState; + + protected: + + //--------------------------------------------------------------------- + // Protected Functions + //--------------------------------------------------------------------- + + void AddWindow( CGuiWindow::eGuiWindowID windowID, CGuiWindow* pWindow ); + void RemoveWindow( CGuiWindow::eGuiWindowID windowID ); + void RemoveAllWindows(); + + void PushScreenHistory( CGuiWindow::eGuiWindowID windowID ); + CGuiWindow::eGuiWindowID PopScreenHistory(); + void ClearScreenHistory(); + + //--------------------------------------------------------------------- + // Protected Data + //--------------------------------------------------------------------- + + CGuiWindow* m_windows[ CGuiWindow::NUM_GUI_WINDOW_IDS ]; + int m_numWindows; + + Scrooby::Project* m_pScroobyProject; + + CGuiWindow::eGuiWindowID m_currentScreen; + CGuiWindow::eGuiWindowID m_nextScreen; + + enum eGuiFrontEndState + { + GUI_FE_UNINITIALIZED, + GUI_FE_SCREEN_RUNNING, + GUI_FE_CHANGING_SCREENS, + GUI_FE_DYNAMIC_LOADING, + GUI_FE_SHUTTING_DOWN, + GUI_FE_TERMINATED + }; + + eGuiFrontEndState m_state; + + private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignment. Declare but don't define. + // + CGuiManager( const CGuiManager& ); + CGuiManager& operator= ( const CGuiManager& ); + + bool IsValidWindowID( CGuiWindow::eGuiWindowID windowID ) const; + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + CGuiWindow::eGuiWindowID m_windowHistory[ MAX_WINDOW_HISTORY ]; + int m_windowHistoryCount; + + unsigned int m_gotoScreenUserParam1; + unsigned int m_gotoScreenUserParam2; +}; + +inline void +CGuiManager::ClearScreenHistory() +{ + m_windowHistoryCount = 0; +} + +inline bool +CGuiManager::IsValidWindowID( CGuiWindow::eGuiWindowID windowID ) const +{ + return (windowID >= 0 && windowID < CGuiWindow::NUM_GUI_WINDOW_IDS); +} + +#endif // GUIMANAGER_H diff --git a/game/code/presentation/gui/guimenu.cpp b/game/code/presentation/gui/guimenu.cpp new file mode 100644 index 0000000..5c52b35 --- /dev/null +++ b/game/code/presentation/gui/guimenu.cpp @@ -0,0 +1,1367 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiMenu +// +// Description: Implementation of the CGuiMenu class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/12/4 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiuserinputhandler.h> +#include <presentation/gui/utility/specialfx.h> + +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <events/eventmanager.h> + +#include <raddebug.hpp> // Foundation +#include <radmath/trig.hpp> // RadMath + +// Scrooby +// +#include <group.h> +#include <page.h> +#include <sprite.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +const tColour DEFAULT_SELECTED_ITEM_COLOUR( 255, 255, 0 ); +const tColour DEFAULT_DISABLED_ITEM_COLOUR( 128, 128, 128 ); // the same as in guiscreenmemorycard.cpp + +const tColour DEFAULT_OUTLINE_COLOUR( 0, 0, 0, 192 ); + +const float SLIDER_FULL_RANGE_TIME = 2000; // in milliseconds +const int SELECTION_MADE_DURATION = 250; // in milliseconds + +#ifdef RAD_WIN32 +const float ARROW_SCALE = 0.5f; +#endif + +//=========================================================================== +// Public Member Functions - CGuiMenu +//=========================================================================== + +//=========================================================================== +// CGuiMenu::CGuiMenu +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiMenu::CGuiMenu( CGuiEntity* pParent, int maxNumItems, + eMenuType menuType, + int specialEffects ) +: CGuiEntity( pParent ), + m_menuType( menuType ), + m_specialEffects( static_cast<short>( specialEffects ) ), + m_menuItems( NULL ), + m_numItems( 0 ), + m_selection( NO_SELECTION ), + m_pCursor( NULL ), + m_isSelectionMade( false ), + m_isHighlightEnabled( true ), + m_highlightColour( DEFAULT_SELECTED_ITEM_COLOUR ), + m_selectionMadeOutlineColour( tColour( 255, 0, 0, 192 ) ), + m_isGreyOutEnabled( true ), + m_elapsedTime( 0 ), + m_selectionMadeElapsedTime( 0 ), +#ifdef RAD_WIN32 + m_bIsSelectionOutlined( false ), + m_selectionOutlineColour( tColour( 0, 0, 255, 192 ) ), +#endif + m_controllerID( -1 ) +{ +MEMTRACK_PUSH_GROUP( "GUIMenu" ); + rAssertMsg( ( specialEffects & 0xFFFF0000 ) == 0, "Bitmask Overflow!" ); + + // create array of 'maxNumItems' menu items + // + rAssert( maxNumItems > 0 ); + m_menuItems = new GuiMenuItem*[ maxNumItems ]; + rAssert( m_menuItems != NULL ); + + for( int i = 0; i < maxNumItems; i++ ) + { + m_menuItems[ i ] = NULL; + } +MEMTRACK_POP_GROUP( "GUIMenu" ); +} + +//=========================================================================== +// CGuiMenu::~CGuiMenu +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiMenu::~CGuiMenu() +{ + if( m_menuItems != NULL ) + { + for( int i = 0; i < m_numItems; i++ ) + { + if( m_menuItems[ i ] != NULL ) + { + delete m_menuItems[ i ]; + m_menuItems[ i ] = NULL; + } + } + + delete [] m_menuItems; + m_menuItems = NULL; + } +} + +//=========================================================================== +// CGuiMenu::HandleMessage +//=========================================================================== +// Description: Message handler for this class. +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::HandleMessage( eGuiMessage message, unsigned int param1, + unsigned int param2 ) +{ + if( m_isSelectionMade && this->IsControllerMessage( message ) ) + { + // selection has already been made, ignore all controller messages + // + return; + } + + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( m_selection != NO_SELECTION ) + { + this->UpdateCurrentSelection( param1 ); + } + + break; + } + case GUI_MSG_CONTROLLER_UP: + { + this->ChangeSelection( -1 ); + + break; + } + case GUI_MSG_CONTROLLER_DOWN: + { + this->ChangeSelection( +1 ); + + break; + } + case GUI_MSG_CONTROLLER_LEFT: + { + this->DecrementSelectionValue(); + + break; + } + case GUI_MSG_CONTROLLER_RIGHT: + { + this->IncrementSelectionValue(); + + break; + } + case GUI_MSG_CONTROLLER_SELECT: + { + this->MakeSelection(); + + break; + } +#ifdef RAD_WIN32 + case GUI_MSG_MOUSE_OVER: + { + this->SetNewSelection(param1); + + break; + } + case GUI_MSG_MOUSE_LCLICKHOLD: + { + this->OutlineSelection( (param1!=0) ); + break; + } +#endif + default: + { + break; + } + } +} + +//=========================================================================== +// CGuiMenu::AddMenuItem +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +GuiMenuItem* CGuiMenu::AddMenuItem( Scrooby::BoundedDrawable* pItem, + Scrooby::BoundedDrawable* pItemValue, + Scrooby::Polygon* pSlider, + Scrooby::Sprite* pSliderImage, + Scrooby::Sprite* pItemValueArrowL, + Scrooby::Sprite* pItemValueArrowR, + int attributes ) +{ + rAssert( m_menuItems[ m_numItems ] == NULL ); + + // create a new menu item based on menu type + // + switch( m_menuType ) + { + case GUI_TEXT_MENU: + { + m_menuItems[ m_numItems ] = new GuiMenuItemText; + + break; + } + case GUI_SPRITE_MENU: + { + m_menuItems[ m_numItems ] = new GuiMenuItemSprite; + + break; + } + default: + { + rAssertMsg( false, "Invalid menu type!" ); + + break; + } + } + + rAssert( m_menuItems[ m_numItems ] != NULL ); + + GuiMenuItem* pMenuItem = m_menuItems[ m_numItems ]; + + m_menuItems[ m_numItems ]->SetItem( pItem ); + + // for items w/ value toggle + // + if( pItemValue != NULL ) + { + m_menuItems[ m_numItems ]->SetItemValue( pItemValue ); + + // hide arrows by default, if exists + // + if( pItemValueArrowL != NULL ) + { + pItemValueArrowL->SetVisible( false ); +#ifdef RAD_WIN32 + pItemValueArrowL->ScaleAboutCenter( ARROW_SCALE ); +#endif + m_menuItems[ m_numItems ]->m_itemValueArrowL = pItemValueArrowL; + } + if( pItemValueArrowR != NULL ) + { + pItemValueArrowR->SetVisible( false ); +#ifdef RAD_WIN32 + pItemValueArrowR->ScaleAboutCenter( ARROW_SCALE ); +#endif + m_menuItems[ m_numItems ]->m_itemValueArrowR = pItemValueArrowR; + } + } + + if( m_menuType == GUI_TEXT_MENU ) + { + if( (attributes & TEXT_OUTLINE_ENABLED) > 0 ) + { + // turn on text outlining + // + m_menuItems[ m_numItems ]->SetDisplayOutline( true ); + } +#ifdef RAD_WIN32 + pItem->SetVerticalJustification( Scrooby::Top ); +#endif + } + + // for items w/ sliders + // + if( pSliderImage != NULL ) + { + m_menuItems[ m_numItems ]->m_slider.SetScroobyImage( pSliderImage ); + } + + m_menuItems[ m_numItems ]->m_attributes = attributes; + m_menuItems[ m_numItems ]->m_defaultColour = pItem->GetColour(); + m_numItems++; + + // select first item by default + // + if( m_numItems == 1 ) + { + SelectItem( 0 ); + } + return pMenuItem; +} + +//=========================================================================== +// CGuiMenu::SetMenuItemEnabled +//=========================================================================== +// Description: Enable/disable menu item. +// +// Constraints: None. +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiMenu::SetMenuItemEnabled( int index, bool enabled, bool changeVisibility ) +{ + GuiMenuItem* currentMenuItem = this->GetMenuItem( index ); + rAssert( currentMenuItem != NULL ); + + Scrooby::BoundedDrawable* currentItem = currentMenuItem->GetItem(); + rAssert( currentItem != NULL ); + + Scrooby::BoundedDrawable* currentItemValue = currentMenuItem->GetItemValue(); + + if( enabled ) + { + currentMenuItem->m_attributes |= SELECTION_ENABLED; + + if( index != m_selection ) + { + if( m_isGreyOutEnabled ) + { + // restore default item colour + // + currentItem->SetColour( currentMenuItem->m_defaultColour ); + if( currentItemValue != NULL ) + { + currentItemValue->SetColour( currentMenuItem->m_defaultColour ); + } + } + + // show cursor + // + if( m_pCursor != NULL ) + { + m_pCursor->SetVisible( true ); + } + + if( m_selection == NO_SELECTION ) + { + m_selection = 0; + this->SelectItem( index ); + } + } + } + else // !enabled + { + currentMenuItem->m_attributes &= ~SELECTION_ENABLED; + + // if item disabled is current selection, select next enabled item + // + if( index == m_selection ) + { + this->ChangeSelection( +1, false ); + + if( index == m_selection ) + { + // reset cursor to first selection, and hide it + // + this->MoveCursor( m_selection, 0 ); + if( m_pCursor != NULL ) + { + m_pCursor->SetVisible( false ); + } + + // this means all selections have been disabled + // + m_selection = NO_SELECTION; + } + } + + if( m_isGreyOutEnabled ) + { + // grey out item colour + // + currentItem->SetColour( DEFAULT_DISABLED_ITEM_COLOUR ); + + if( currentItemValue != NULL ) + { + currentItemValue->SetColour( DEFAULT_DISABLED_ITEM_COLOUR ); + } + } + } + + if( changeVisibility ) + { + currentItem->SetVisible( enabled ); + + if( currentItemValue != NULL ) + { + currentItemValue->SetVisible( enabled ); + } + } +} + +bool CGuiMenu::IsMenuItemEnabled( int index ) +{ + GuiMenuItem* currentMenuItem = this->GetMenuItem( index ); + rAssert( currentMenuItem != NULL ); + return (currentMenuItem->m_attributes & SELECTION_ENABLED); +} + +//=========================================================================== +// CGuiMenu::Reset +//=========================================================================== +// Description: Unselect all menu items. +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::Reset( int defaultSelection ) +{ + // un-select current item + if( m_selection != NO_SELECTION ) + { + this->UnselectItem( m_selection ); + } + + // select first item + this->SelectItem( defaultSelection ); +} + +//=========================================================================== +// CGuiMenu::SetHighlightColour +//=========================================================================== +// Description: Sets the menu highlight colour. +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::SetHighlightColour( bool isEnabled, tColour colour ) +{ + m_isHighlightEnabled = isEnabled; + m_highlightColour = colour; +} + +//=========================================================================== +// CGuiMenu::SetSelectionValue +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::SetSelectionValue( int index, int value ) +{ + if( value >= 0 && value < m_menuItems[ index ]->m_itemValueCount ) + { + m_menuItems[ index ]->SetItemValueIndex( value ); + + // Notify screen that selection value has changed + m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, index, value ); + } +} + +//=========================================================================== +// CGuiMenu::SetSelectionValueCount +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::SetSelectionValueCount( int index, int count ) +{ + m_menuItems[ index ]->m_itemValueCount = count; + +// if( index == m_selection ) + { + // show arrows if more than one value to toggle; otherwise, hide them (partially) + // + bool showArrows = (m_menuItems[ index ]->m_itemValueCount > 1); + if( m_menuItems[ index ]->m_itemValueArrowL != NULL && + m_menuItems[ index ]->m_itemValueArrowR != NULL ) + { + m_menuItems[ index ]->m_itemValueArrowL->SetAlpha( showArrows ? 1.0f : 0.4f ); + m_menuItems[ index ]->m_itemValueArrowR->SetAlpha( showArrows ? 1.0f : 0.4f ); + } + } +} + +//=========================================================================== +// CGuiMenu::MakeSelection +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::MakeSelection( bool isSelectionMade ) +{ + if (m_selection == NO_SELECTION) return;//-------------> + + if( (m_menuItems[ m_selection ]->m_attributes & SELECTABLE) > 0 ) + { + if( isSelectionMade ) + { + if( m_selection != NO_SELECTION ) + { + if( m_menuType == GUI_TEXT_MENU ) + { + m_menuItems[ m_selection ]->SetOutlineColour( m_selectionMadeOutlineColour ); +#ifdef RAD_WIN32 + if( m_bIsSelectionOutlined ) + m_menuItems[ m_selection ]->GetItem()->SetColour( DEFAULT_SELECTED_ITEM_COLOUR ); +#endif + } + + m_selectionMadeElapsedTime = 0; + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); + + // tell parent screen to ignore all controller inputs until + // selection-made effect is completed + // + CGuiScreen* parentScreen = static_cast<CGuiScreen*>( m_pParent ); + rAssert( parentScreen ); + parentScreen->SetIngoreControllerInputs( true ); + + m_isSelectionMade = true; + } + } + else + { + CGuiScreen* parentScreen = static_cast<CGuiScreen*>( m_pParent ); + rAssert( parentScreen ); + parentScreen->SetIngoreControllerInputs( false ); + + if( m_menuType == GUI_TEXT_MENU ) + { + m_menuItems[ m_selection ]->SetOutlineColour( DEFAULT_OUTLINE_COLOUR ); + } + + // restore current item's regular L/R arrows, if exist + // + if( m_menuItems[ m_selection ]->m_itemValueArrowL != NULL && + m_menuItems[ m_selection ]->m_itemValueArrowR != NULL ) + { + m_menuItems[ m_selection ]->m_itemValueArrowL->SetIndex( 0 ); + m_menuItems[ m_selection ]->m_itemValueArrowR->SetIndex( 0 ); + } + + m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_MADE, m_selection ); + + m_isSelectionMade = false; + } + } +} + +//=========================================================================== +// Protected Member Functions - CGuiMenu +//=========================================================================== + +//=========================================================================== +// CGuiMenu::SelectItem +//=========================================================================== +// Description: Select specified item. +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::SelectItem( int index ) +{ + rAssert( index >= 0 && index < m_numItems ); + rAssert( m_menuItems[ index ] != NULL ); + + // move cursor + if( index != m_selection ) + { + this->MoveCursor( m_selection, index ); + } + + // reset elapsed time + m_elapsedTime = 0; + + if( m_isHighlightEnabled && m_menuType == GUI_TEXT_MENU ) + { + m_menuItems[ index ]->GetItem()->SetColour( m_highlightColour ); + } + + // apply to item value also, if exists + if( m_menuItems[ index ]->GetItemValue() != NULL ) + { + if( m_isHighlightEnabled && m_menuType == GUI_TEXT_MENU ) + { + m_menuItems[ index ]->GetItemValue()->SetColour( m_highlightColour ); + } + + // show arrows, if exists + // + if( m_menuItems[ index ]->m_itemValueArrowL != NULL && + m_menuItems[ index ]->m_itemValueArrowR != NULL ) + { + m_menuItems[ index ]->m_itemValueArrowL->SetVisible( true ); + m_menuItems[ index ]->m_itemValueArrowR->SetVisible( true ); + } + } +/* + if( m_specialEffects & MENU_SFX_DROP_SHADOW ) + { + // turn on drop shadow + m_menuItems[ index ]->m_item->SetDisplayShadow( true ); + + // apply to item value also, if exists + if( m_menuItems[ index ]->m_itemValue != NULL ) + { + m_menuItems[ index ]->m_itemValue->SetDisplayShadow( true ); + } + } +*/ + m_selection = index; +} + +//=========================================================================== +// CGuiMenu::UnselectItem +//=========================================================================== +// Description: Unselect specified item. +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::UnselectItem( int index ) +{ + rAssert( index >= 0 && index < m_numItems ); + rAssert( m_menuItems[ index ] != NULL ); + + if( m_menuType == GUI_TEXT_MENU ) + { + m_menuItems[ index ]->GetItem()->SetColour( m_menuItems[ index ]->m_defaultColour ); + } + + // apply to item value also, if exists + if( m_menuItems[ index ]->GetItemValue() != NULL ) + { + if( m_menuType == GUI_TEXT_MENU ) + { + m_menuItems[ index ]->GetItemValue()->SetColour( m_menuItems[ index ]->m_defaultColour ); + } + + // hide arrows until item is selected + // + if( m_menuItems[ index ]->m_itemValueArrowL != NULL && + m_menuItems[ index ]->m_itemValueArrowR != NULL ) + { + m_menuItems[ index ]->m_itemValueArrowL->SetVisible( false ); + m_menuItems[ index ]->m_itemValueArrowR->SetVisible( false ); + } + } + + if( m_specialEffects & MENU_SFX_SIZE_PULSE ) + { + // reset scale + m_menuItems[ index ]->GetItem()->ResetTransformation(); + + // apply to item value also, if exists + if( m_menuItems[ index ]->GetItemValue() != NULL ) + { + m_menuItems[ index ]->GetItemValue()->ResetTransformation(); + } + } +/* + if( m_specialEffects & MENU_SFX_DROP_SHADOW ) + { + // turn off drop shadow + m_menuItems[ index ]->m_item->SetDisplayShadow( false ); + + // apply to item value also, if exists + if( m_menuItems[ index ]->m_itemValue != NULL ) + { + m_menuItems[ index ]->m_itemValue->SetDisplayShadow( false ); + } + } +*/ +} + +//=========================================================================== +// CGuiMenu::ChangeSelection +//=========================================================================== +// Description: Select the next menu item. +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::ChangeSelection( int deltaItems, bool isUserInput ) +{ + if( m_selection != NO_SELECTION ) + { + rAssert( m_numItems > 0 ); + + // Increment and check for wrap around. + // + int newSelection = (m_selection + deltaItems + m_numItems) % m_numItems; + + // Skip to next enabled selection if new selection is disabled + while( newSelection != m_selection ) + { + if( m_menuItems[ newSelection ]->m_attributes & SELECTION_ENABLED ) + { + // Unselect the current item. + // + this->UnselectItem( m_selection ); + + // Notify screen that menu selection has changed + // (param1 = new selection, param2 = old selection) + // + m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_CHANGED, newSelection, m_selection ); + + // Make the new selection. + // + this->SelectItem( newSelection ); + + if( isUserInput ) + { + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + + break; + } + + newSelection = (newSelection + deltaItems + m_numItems) % m_numItems; + } + } +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiMenu::ChangeSelection +//=========================================================================== +// Description: Select a specific selection. +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::SetNewSelection( int newSelection, bool isUserInput ) +{ + if( m_selection != NO_SELECTION ) + { + rAssert( m_numItems > 0 ); + + if( newSelection != m_selection ) + { + if( m_menuItems[ newSelection ]->m_attributes & SELECTION_ENABLED ) + { + // Unselect the current item. + // + this->UnselectItem( m_selection ); + + // Notify screen that menu selection has changed + // (param1 = new selection, param2 = old selection) + // + m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_CHANGED, newSelection, m_selection ); + + // Make the new selection. + // + this->SelectItem( newSelection ); + + if( isUserInput ) + { + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + } + } + } +} +//=========================================================================== +// CGuiMenu::OutlineSelection +//=========================================================================== +// Description: Outlines a specific selection. +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::OutlineSelection( bool bOutline ) +{ + if (m_selection == NO_SELECTION) return;//-------------> + + if( (m_menuItems[ m_selection ]->m_attributes & SELECTABLE) > 0 ) + { + if( m_menuType == GUI_TEXT_MENU ) + { + if( bOutline ) + m_menuItems[ m_selection ]->GetItem()->SetColour( m_selectionOutlineColour ); + else + m_menuItems[ m_selection ]->GetItem()->SetColour( DEFAULT_SELECTED_ITEM_COLOUR ); + + m_bIsSelectionOutlined = bOutline; + } + } +} + +#endif + +//=========================================================================== +// CGuiMenu::IncrementSelectionValue +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::IncrementSelectionValue( bool isUserInput ) +{ + if( m_selection != NO_SELECTION && + m_menuItems[ m_selection ]->GetItemValue() != NULL ) + { + int currentIndex = m_menuItems[ m_selection ]->GetItemValueIndex(); + int newIndex = currentIndex; + + if( currentIndex < m_menuItems[ m_selection ]->m_itemValueCount - 1 ) + { + newIndex = currentIndex + 1; + } + else if( m_menuItems[ m_selection ]->m_attributes & VALUES_WRAPPED ) + { + // wrap around to beginning + newIndex = 0; + } + + if( newIndex != currentIndex ) + { + m_menuItems[ m_selection ]->SetItemValueIndex( newIndex ); + + // Notify screen that selection value has changed + m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, m_selection, newIndex ); + + if( isUserInput ) + { + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + } + } +} + +//=========================================================================== +// CGuiMenu::DecrementSelectionValue +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: N/A. +// +// Return: N/A. +// +//=========================================================================== +void CGuiMenu::DecrementSelectionValue( bool isUserInput ) +{ + if( m_selection != NO_SELECTION && + m_menuItems[ m_selection ]->GetItemValue() != NULL ) + { + int currentIndex = m_menuItems[ m_selection ]->GetItemValueIndex(); + int newIndex = currentIndex; + + if( currentIndex > 0 ) + { + newIndex = currentIndex - 1; + } + else if( m_menuItems[ m_selection ]->m_attributes & VALUES_WRAPPED ) + { + // wrap around to end + newIndex = m_menuItems[ m_selection ]->m_itemValueCount - 1; + } + + if( newIndex != currentIndex ) + { + rAssertMsg( newIndex != -1, "This means item value count is zero!" ); + + m_menuItems[ m_selection ]->SetItemValueIndex( newIndex ); + + // Notify screen that selection value has changed + m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, m_selection, newIndex ); + + if( isUserInput ) + { + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + } + } +} + +//=========================================================================== +// Private Member Functions - CGuiMenu +//=========================================================================== + +//=========================================================================== +// CGuiMenu::UpdateCurrentSelection +//=========================================================================== +// Description: Updates current selection. +// +// Constraints: None. +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiMenu::UpdateCurrentSelection( int elapsedTime ) +{ + rAssert( m_selection >= 0 && m_selection < m_numItems ); + + Scrooby::BoundedDrawable* currentItem = m_menuItems[ m_selection ]->GetItem(); + rAssert( currentItem != NULL ); + + if( m_isSelectionMade ) // update "selection made" effect + { + m_selectionMadeElapsedTime += elapsedTime; + + if( m_selectionMadeElapsedTime > SELECTION_MADE_DURATION ) + { + this->MakeSelection( false ); + } + } + else // update current selection + { + const unsigned int ITEM_PULSE_PERIOD = 600; // in milliseconds + + if( m_specialEffects & MENU_SFX_COLOUR_PULSE ) + { + // pulse text colour + // + tColour textColour; + GuiSFX::ModulateColour( &textColour, + (float)m_elapsedTime, + (float)ITEM_PULSE_PERIOD, + tColour( 255, 224, 32 ), // m_menuItems[ m_selection ]->m_defaultColour, + m_highlightColour ); + + currentItem->SetColour( textColour ); + } + + if( m_specialEffects & MENU_SFX_SIZE_PULSE ) + { + // pulse text size + // + const float ITEM_SCALE_FACTOR = 0.10f; + + currentItem->ResetTransformation(); + +// if( m_elapsedTime < ITEM_PULSE_PERIOD ) + { + // TC: [IMPROVE] Man, this looks ugly! + // + static const float THETA_OFFSET = -rmt::ASin( -0.5f ); // = -ASin( (1 - center) / amplitude ) + + float scale = GuiSFX::Pulse( (float)m_elapsedTime, + (float)ITEM_PULSE_PERIOD, + 1.0f + ITEM_SCALE_FACTOR / 2, + ITEM_SCALE_FACTOR, + THETA_OFFSET ); + + int width = 0; + int height = 0; + currentItem->GetBoundingBoxSize( width, height ); + + // scale text about (left center, right center, or middle center) + // + if( currentItem->GetHorizontalJustification() == Scrooby::Left ) + { + currentItem->ScaleAboutPoint( scale, 0, height / 2 ); + } + else if( currentItem->GetHorizontalJustification() == Scrooby::Right ) + { + currentItem->ScaleAboutPoint( scale, width, height / 2 ); + } + else + { + currentItem->ScaleAboutCenter( scale ); + } + } + } + + // update slider, if exists on current selection + // + ImageSlider* currentItemSlider = &(m_menuItems[ m_selection ]->m_slider); + if( currentItemSlider->m_pImage != NULL ) + { + bool hasSliderValueChanged = false; + + int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers(); + for( int i = 0; i < numUserInputHandlers; i++ ) + { + if( m_controllerID != -1 && m_controllerID != static_cast<short>( i ) ) + { + // ignore other controller inputs + // + continue; + } + + CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i ); + if( userInputHandler != NULL ) + { +#ifdef RAD_WIN32 + if( userInputHandler->IsXAxisOnLeft() || + GetInputManager()->GetFEMouse()->OnSliderHorizontalClickDrag() == MDIR_LEFT ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Left ) || + userInputHandler->IsXAxisOnLeft() ) +#endif + { + float newValue = currentItemSlider->m_value - elapsedTime / SLIDER_FULL_RANGE_TIME; + if( newValue < 0.0f ) + { + newValue = 0.0f; // clamp lower-end at 0.0 + } + + if( newValue != currentItemSlider->m_value ) + { + currentItemSlider->SetValue( newValue ); + hasSliderValueChanged = true; + } + } + +#ifdef RAD_WIN32 + if( userInputHandler->IsXAxisOnRight() || + GetInputManager()->GetFEMouse()->OnSliderHorizontalClickDrag() == MDIR_RIGHT ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Right ) || + userInputHandler->IsXAxisOnRight() ) +#endif + { + float newValue = currentItemSlider->m_value + elapsedTime / SLIDER_FULL_RANGE_TIME; + if( newValue > 1.0f ) + { + newValue = 1.0f; // clamp higher-end at 1.0 + } + + if( newValue != currentItemSlider->m_value ) + { + currentItemSlider->SetValue( newValue ); + hasSliderValueChanged = true; + } + } + } + } + + if( hasSliderValueChanged ) + { + // notify screen that slider value has changed + // + m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, m_selection ); + } + else + { + // otherwise, notify screen that slider value is currently not changing + // + m_pParent->HandleMessage( GUI_MSG_MENU_SLIDER_NOT_CHANGING, m_selection ); + } + } + + // update L/R arrows (if exists for current selection) + // + if( m_menuItems[ m_selection ]->m_itemValueArrowL != NULL && + m_menuItems[ m_selection ]->m_itemValueArrowR != NULL ) + { + m_menuItems[ m_selection ]->m_itemValueArrowL->SetIndex( 0 ); + m_menuItems[ m_selection ]->m_itemValueArrowR->SetIndex( 0 ); + + // if there are more than one item to choose from + // + if( m_menuItems[ m_selection ]->m_itemValueCount > 1 ) + { + int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers(); + for( int i = 0; i < numUserInputHandlers; i++ ) + { + if( m_controllerID != -1 && m_controllerID != static_cast<short>( i ) ) + { + // ignore other controller inputs + // + continue; + } + + CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i ); + if( userInputHandler != NULL ) + { +#ifdef RAD_WIN32 + if( userInputHandler->IsXAxisOnLeft() || + GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWLEFT ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Left ) || + userInputHandler->IsXAxisOnLeft() ) +#endif + { + rAssert( m_menuItems[ m_selection ]->m_itemValueArrowL->GetNumOfImages() > 1 ); + m_menuItems[ m_selection ]->m_itemValueArrowL->SetIndex( 1 ); + } + +#ifdef RAD_WIN32 + if( userInputHandler->IsXAxisOnRight() || + GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWRIGHT ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Right ) || + userInputHandler->IsXAxisOnRight() ) +#endif + { + rAssert( m_menuItems[ m_selection ]->m_itemValueArrowR->GetNumOfImages() > 1 ); + m_menuItems[ m_selection ]->m_itemValueArrowR->SetIndex( 1 ); + } + } + } + } + } + + // update elapsed time + // + m_elapsedTime = (m_elapsedTime + elapsedTime) % ITEM_PULSE_PERIOD; + } +} + +//=========================================================================== +// CGuiMenu::MoveCursor +//=========================================================================== +// Description: Move cursor from previous selection to next selection. +// +// Constraints: None. +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiMenu::MoveCursor( int previousIndex, int nextIndex ) +{ + // if cursor exists + // + if( m_pCursor != NULL && previousIndex != NO_SELECTION ) + { + Scrooby::BoundedDrawable* item = NULL; + int x1, y1, x2, y2; + + // get location of previous item + item = m_menuItems[ previousIndex ]->GetItem(); + rAssert( item != NULL ); + item->GetOriginPosition( x1, y1 ); + + // get location of next item + item = m_menuItems[ nextIndex ]->GetItem(); + rAssert( item != NULL ); + item->GetOriginPosition( x2, y2 ); + + // translate cursor + m_pCursor->Translate( x2 - x1, y2 - y1 ); + } +} + + +//=========================================================================== +// Public Member Functions - CGuiMenu2D +//=========================================================================== + +CGuiMenu2D::CGuiMenu2D( CGuiEntity* pParent, + int numItems, + int numColumns, + eMenuType menuType, + int specialEffects ) +: CGuiMenu( pParent, numItems, menuType, specialEffects ), + m_numColumns( static_cast<short>( numColumns ) ) +{ +} + +CGuiMenu2D::~CGuiMenu2D() +{ +} + +void +CGuiMenu2D::HandleMessage( eGuiMessage message, unsigned int param1, + unsigned int param2 ) +{ + if( m_isSelectionMade && this->IsControllerMessage( message ) ) + { + // selection has already been made, ignore all controller messages + // + return; + } + + switch( message ) + { + case GUI_MSG_CONTROLLER_LEFT: + { + this->ChangeSelection( -1 ); + + break; + } + case GUI_MSG_CONTROLLER_RIGHT: + { + this->ChangeSelection( +1 ); + + break; + } + case GUI_MSG_CONTROLLER_UP: + { + this->ChangeSelection( -m_numColumns ); + + break; + } + case GUI_MSG_CONTROLLER_DOWN: + { + this->ChangeSelection( +m_numColumns ); + + break; + } + default: + { + CGuiMenu::HandleMessage( message, param1, param2 ); + + break; + } + } +} + + +//=========================================================================== +// Public Member Functions - CGuiMenuPrompt +//=========================================================================== + +CGuiMenuPrompt::CGuiMenuPrompt( CGuiEntity* pParent, + Scrooby::Page* pPage, + int numResponses, + int specialEffects ) +: + CGuiMenu( pParent, numResponses, GUI_TEXT_MENU, specialEffects ), + m_numResponses( static_cast<short>( numResponses ) ) +{ + rAssert( pPage != NULL ); + + Scrooby::Group* menu = pPage->GetGroup( "Menu" ); + rAssert( menu != NULL ); + // add response menu items + // + for( short i = 0; i < m_numResponses; i++ ) + { + char textName[ 32 ]; + sprintf( textName, "Response%d", i ); + this->AddMenuItem( menu->GetText( textName ) ); + } +} + +CGuiMenuPrompt::~CGuiMenuPrompt() +{ +} + +void +CGuiMenuPrompt::SetNumResponses( int numResponses ) +{ + for( short i = 0; i < m_numResponses; i++ ) + { + this->SetMenuItemEnabled( i, (i < numResponses), true ); + } +} + +void +CGuiMenuPrompt::SetResponse( int index, ePromptResponse response ) +{ + rAssert( static_cast<short>( index ) >= 0 && static_cast<short>( index ) < m_numResponses ); + + GuiMenuItem* menuItem = this->GetMenuItem( index ); + rAssert( menuItem != NULL ); + + Scrooby::Text* textItem = dynamic_cast<Scrooby::Text*>( menuItem->GetItem() ); + rAssert( textItem != NULL ); + textItem->SetIndex( response ); +} + +CGuiMenuPrompt::ePromptResponse +CGuiMenuPrompt::GetResponse( int index ) const +{ + rAssert( static_cast<short>( index ) >= 0 && static_cast<short>( index ) < m_numResponses ); + + GuiMenuItem* menuItem = this->GetMenuItem( index ); + rAssert( menuItem != NULL ); + + Scrooby::Text* textItem = dynamic_cast<Scrooby::Text*>( menuItem->GetItem() ); + rAssert( textItem != NULL ); + + return static_cast<ePromptResponse>( textItem->GetIndex() ); +} + +CGuiMenuPrompt::ePromptResponse +CGuiMenuPrompt::GetCurrentResponse() const +{ + return this->GetResponse( m_selection ); +} + diff --git a/game/code/presentation/gui/guimenu.h b/game/code/presentation/gui/guimenu.h new file mode 100644 index 0000000..0361079 --- /dev/null +++ b/game/code/presentation/gui/guimenu.h @@ -0,0 +1,251 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiMenu +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/12/4 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUIMENU_H +#define GUIMENU_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guientity.h> +#include <presentation/gui/guimenuitem.h> + +namespace Scrooby +{ + class Page; + class Drawable; + class BoundedDrawable; + class Sprite; +} + +enum eMenuType +{ + GUI_TEXT_MENU, + GUI_SPRITE_MENU, + + NUM_MENU_TYPES +}; + +enum eMenuSpecialEffect +{ + MENU_SFX_NONE = 0, + + MENU_SFX_COLOUR_PULSE = 1, + MENU_SFX_SIZE_PULSE = 2, + + MENU_SFX_ALL = ~0 +}; + +//=========================================================================== +// Interface Definitions - CGuiMenu +//=========================================================================== +class CGuiMenu : public CGuiEntity +{ +public: + CGuiMenu( CGuiEntity* pParent, + int maxNumItems = 1, + eMenuType menuType = GUI_TEXT_MENU, + int specialEffects = MENU_SFX_SIZE_PULSE ); + + virtual ~CGuiMenu(); + + void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + GuiMenuItem* AddMenuItem( Scrooby::BoundedDrawable* pItem, + Scrooby::BoundedDrawable* pItemValue = NULL, + Scrooby::Polygon* pSlider = NULL, + Scrooby::Sprite* pSliderImage = NULL, + Scrooby::Sprite* pItemValueArrowL = NULL, + Scrooby::Sprite* pItemValueArrowR = NULL, + int attributes = ALL_ATTRIBUTES_ON ); + + void SetMenuItemEnabled( int index, bool enabled, + bool changeVisibility = false ); + + bool IsMenuItemEnabled( int index ); + + void SetCursor( Scrooby::Drawable* pCursor ) { m_pCursor = pCursor; } + Scrooby::Drawable* GetCursor() const { return m_pCursor; } + + // Reset Menu + // + void Reset( int defaultSelection = 0 ); + + // Menu Highlight Colour + // + void SetHighlightColour( bool isEnabled, tColour colour ); + tColour GetHighlightColour() const { return m_highlightColour; } + + void SetGreyOutEnabled( bool isEnabled ) { m_isGreyOutEnabled = isEnabled; } + + // Selection Made Outline Colour + // + void SetSelectionMadeOutlineColour( tColour colour ) { m_selectionMadeOutlineColour = colour; } + + // Set Selection Values and Value Counts + // + void SetSelectionValue( int index, int value ); + void SetSelectionValueCount( int index, int count ); + + // Make Menu Selection and Query Menu Selection Made + // + void MakeSelection( bool isSelectionMade = true ); + bool HasSelectionBeenMade() const { return m_isSelectionMade; } + + // Set Specific Controller ID + // + void SetControllerID( int controllerID ); + + // Menu Accessors + // + GuiMenuItem* GetMenuItem( int index ) const; + int GetNumItems() const { return m_numItems; } + int GetSelection() const { return m_selection; } + int GetSelectionValue( int index ) const; + +protected: + enum eSelection { NO_SELECTION = -1 }; + + void SelectItem( int index ); + void UnselectItem( int index ); + + void ChangeSelection( int deltaItems, bool isUserInput = true ); +#ifdef RAD_WIN32 + void SetNewSelection( int newSelection, bool isUserInput = false ); + void OutlineSelection( bool bOutline = true ); +#endif + void IncrementSelectionValue( bool isUserInput = true ); + void DecrementSelectionValue( bool isUserInput = true ); + + eMenuType m_menuType; + short m_specialEffects; // bitmask + + GuiMenuItem** m_menuItems; + int m_numItems; + + int m_selection; +#ifdef RAD_WIN32 + bool m_bIsSelectionOutlined; + tColour m_selectionOutlineColour; +#endif + Scrooby::Drawable* m_pCursor; + bool m_isSelectionMade : 1; + +private: + void UpdateCurrentSelection( int elapsedTime ); + void MoveCursor( int previousIndex, int nextIndex ); + + bool m_isHighlightEnabled : 1; + tColour m_highlightColour; + tColour m_selectionMadeOutlineColour; + + bool m_isGreyOutEnabled : 1; + + unsigned int m_elapsedTime; + int m_selectionMadeElapsedTime; + + short m_controllerID; +}; + +inline void CGuiMenu::SetControllerID( int controllerID ) +{ + m_controllerID = static_cast<short>( controllerID ); +} + +inline GuiMenuItem* CGuiMenu::GetMenuItem( int index ) const +{ + rAssert( index >= 0 && index < m_numItems ); + return m_menuItems[ index ]; +} + +inline int CGuiMenu::GetSelectionValue( int index ) const +{ + rAssert( index >= 0 && index < m_numItems ); + return m_menuItems[ index ]->GetItemValueIndex(); +} + +//=========================================================================== +// Interface Definitions - CGuiMenu2D +//=========================================================================== +class CGuiMenu2D : public CGuiMenu +{ +public: + CGuiMenu2D( CGuiEntity* pParent, + int numItems, + int numColumns, + eMenuType menuType = GUI_TEXT_MENU, + int specialEffects = MENU_SFX_SIZE_PULSE ); + + virtual ~CGuiMenu2D(); + + void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +private: + short m_numColumns; + +}; + +//=========================================================================== +// Interface Definitions - CGuiMenuPrompt +//=========================================================================== +class CGuiMenuPrompt : public CGuiMenu +{ +public: + enum ePromptResponse + { + RESPONSE_NO, + RESPONSE_YES, + RESPONSE_CONTINUE, + RESPONSE_CONTINUE_WITHOUT_SAVE, + RESPONSE_RETRY, + RESPONSE_MANAGE_MEMCARDS, + RESPONSE_FORMAT_GC, + RESPONSE_FORMAT_PS2, + RESPONSE_FORMAT_XBOX, + RESPONSE_CONTINUE_WITHOUT_FORMAT, + RESPONSE_DELETE, + RESPONSE_OK, + RESPONSE_LOAD, + RESPONSE_SAVE, + + NUM_PROMPT_RESPONSES + }; + + static const int MAX_NUM_RESPONSES = 3; + + CGuiMenuPrompt( CGuiEntity* pParent, + Scrooby::Page* pPage, + int numResponses = MAX_NUM_RESPONSES, + int specialEffects = MENU_SFX_SIZE_PULSE ); + + virtual ~CGuiMenuPrompt(); + + void SetNumResponses( int numResponses ); + void SetResponse( int index, ePromptResponse response ); + ePromptResponse GetResponse( int index ) const; + ePromptResponse GetCurrentResponse() const; + +private: + short m_numResponses; + +}; + +#endif // GUIMENU_H diff --git a/game/code/presentation/gui/guimenuitem.cpp b/game/code/presentation/gui/guimenuitem.cpp new file mode 100644 index 0000000..daf6490 --- /dev/null +++ b/game/code/presentation/gui/guimenuitem.cpp @@ -0,0 +1,318 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: GuiMenuItem +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/19 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guimenuitem.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions - GuiMenuItem +//=========================================================================== + +GuiMenuItem::GuiMenuItem() +: m_attributes( ALL_ATTRIBUTES_OFF ), + m_defaultColour( 0, 0, 0 ), + m_itemValueArrowL( NULL ), + m_itemValueArrowR( NULL ), + m_itemValueCount( 0 ) +{ +} + +GuiMenuItem::~GuiMenuItem() +{ +} + +//=========================================================================== +// Public Member Functions - GuiMenuItemText +//=========================================================================== + +GuiMenuItemText::GuiMenuItemText() +: GuiMenuItem(), + m_item( NULL ), + m_itemValue( NULL ) +{ +} + +//=========================================================================== +// GuiMenuItemText::SetItem +//=========================================================================== +// Description: Sets the text drawable menu item. +// +// Parameters: pointer to a Scrooby text drawable +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemText::SetItem( Scrooby::BoundedDrawable* item ) +{ + m_item = dynamic_cast<Scrooby::Text*>( item ); + rAssert( m_item != NULL ); +} + +//=========================================================================== +// GuiMenuItemText::SetItemValue +//=========================================================================== +// Description: Sets the text drawable menu item value. +// +// Parameters: pointer to a Scrooby text drawable +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemText::SetItemValue( Scrooby::BoundedDrawable* itemValue ) +{ + m_itemValue = dynamic_cast<Scrooby::Text*>( itemValue ); + rAssert( m_itemValue != NULL ); + + m_itemValueCount = m_itemValue->GetNumOfStrings(); +} + +//=========================================================================== +// GuiMenuItemText::SetItemValueIndex +//=========================================================================== +// Description: Sets the current item value index. +// +// Parameters: text index +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemText::SetItemValueIndex( int index ) +{ + rAssert( m_itemValue != NULL ); + m_itemValue->SetIndex( index ); +} + +//=========================================================================== +// GuiMenuItemText::GetItemValueIndex +//=========================================================================== +// Description: Gets the current item value index. +// +// Parameters: n/a +// +// Return: text index +// +//=========================================================================== +int +GuiMenuItemText::GetItemValueIndex() const +{ + rAssert( m_itemValue != NULL ); + return m_itemValue->GetIndex(); +} + +//=========================================================================== +// GuiMenuItemText::SetDisplayOutline +//=========================================================================== +// Description: Enables/Disables text outlining. +// +// Parameters: enable/disable flag +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemText::SetDisplayOutline( bool enable ) +{ + rAssert( m_item != NULL ); + m_item->SetDisplayOutline( enable ); + + if( m_itemValue != NULL ) + { + m_itemValue->SetDisplayOutline( enable ); + } +} + +//=========================================================================== +// GuiMenuItemText::SetOutlineColour +//=========================================================================== +// Description: Sets the current text outline colour. +// +// Parameters: colour +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemText::SetOutlineColour( tColour colour ) +{ + rAssert( m_item != NULL ); + m_item->SetOutlineColour( colour ); + + if( m_itemValue != NULL ) + { + m_itemValue->SetOutlineColour( colour ); + } +} + +//=========================================================================== +// GuiMenuItemText::GetOutlineColour +//=========================================================================== +// Description: Gets the current text outline colour. +// +// Parameters: n/a +// +// Return: colour +// +//=========================================================================== +tColour +GuiMenuItemText::GetOutlineColour() const +{ + rAssert( m_item != NULL ); + return m_item->GetOutlineColour(); +} + + +//=========================================================================== +// Public Member Functions - GuiMenuItemSprite +//=========================================================================== + +GuiMenuItemSprite::GuiMenuItemSprite() +: GuiMenuItem(), + m_item( NULL ), + m_itemValue( NULL ) +{ +} + +//=========================================================================== +// GuiMenuItemSprite::SetItem +//=========================================================================== +// Description: Sets the text drawable menu item. +// +// Parameters: pointer to a Scrooby sprite drawable +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemSprite::SetItem( Scrooby::BoundedDrawable* item ) +{ + m_item = dynamic_cast<Scrooby::Sprite*>( item ); + rAssert( m_item != NULL ); +} + +//=========================================================================== +// GuiMenuItemSprite::SetItemValue +//=========================================================================== +// Description: Sets the text drawable menu item value. +// +// Parameters: pointer to a Scrooby sprite drawable +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemSprite::SetItemValue( Scrooby::BoundedDrawable* itemValue ) +{ + m_itemValue = dynamic_cast<Scrooby::Sprite*>( itemValue ); + rAssert( m_itemValue != NULL ); + + m_itemValueCount = m_itemValue->GetNumOfImages(); +} + +//=========================================================================== +// GuiMenuItemSprite::SetItemValueIndex +//=========================================================================== +// Description: Sets the current item value index. +// +// Parameters: sprite index +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemSprite::SetItemValueIndex( int index ) +{ + rAssert( m_itemValue != NULL ); + m_itemValue->SetIndex( index ); +} + +//=========================================================================== +// GuiMenuItemSprite::GetItemValueIndex +//=========================================================================== +// Description: Gets the current item value index. +// +// Parameters: n/a +// +// Return: sprite index +// +//=========================================================================== +int +GuiMenuItemSprite::GetItemValueIndex() const +{ + rAssert( m_itemValue != NULL ); + return m_itemValue->GetIndex(); +} + +//=========================================================================== +// GuiMenuItemSprite::SetDisplayOutline +//=========================================================================== +// Description: Not applicable for GuiMenuItemSprite's and should never be +// invoked. +// +// Parameters: n/a +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemSprite::SetDisplayOutline( bool enable ) +{ + rAssertMsg( false, "No outlining on sprites!" ); +} + +//=========================================================================== +// GuiMenuItemSprite::SetOutlineColour +//=========================================================================== +// Description: Not applicable for GuiMenuItemSprite's and should never be +// invoked. +// +// Parameters: n/a +// +// Return: n/a +// +//=========================================================================== +void +GuiMenuItemSprite::SetOutlineColour( tColour colour ) +{ + rAssertMsg( false, "No outlining on sprites!" ); +} + +//=========================================================================== +// GuiMenuItemSprite::SetOutlineColour +//=========================================================================== +// Description: Not applicable for GuiMenuItemSprite's and should never be +// invoked. +// +// Parameters: n/a +// +// Return: n/a +// +//=========================================================================== +tColour +GuiMenuItemSprite::GetOutlineColour() const +{ + rAssertMsg( false, "No outlining on sprites!" ); + + return tColour( 0, 0, 0 ); +} + diff --git a/game/code/presentation/gui/guimenuitem.h b/game/code/presentation/gui/guimenuitem.h new file mode 100644 index 0000000..6d10730 --- /dev/null +++ b/game/code/presentation/gui/guimenuitem.h @@ -0,0 +1,164 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: GuiMenuItem +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/19 TChu Created +// +//=========================================================================== + +#ifndef GUIMENUITEM_H +#define GUIMENUITEM_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/utility/slider.h> + +#include <p3d/p3dtypes.hpp> + +// Scrooby +// +#include <text.h> +#include <sprite.h> + +//=========================================================================== +// Forward References +//=========================================================================== +namespace Scrooby +{ + class BoundedDrawable; + class Sprite; + class Text; +} + +enum eMenuAttribute +{ + ALL_ATTRIBUTES_OFF = 0, + + SELECTION_ENABLED = 1, + SELECTABLE = 2, + VALUES_WRAPPED = 4, + TEXT_OUTLINE_ENABLED = 8, + + ALL_ATTRIBUTES_ON = -1 +}; + +//=========================================================================== +// Interface Definitions - GuiMenuItem (Abstract Base Class) +//=========================================================================== +struct GuiMenuItem +{ + GuiMenuItem(); + virtual ~GuiMenuItem(); + + virtual void SetItem( Scrooby::BoundedDrawable* item ) = 0; + virtual Scrooby::BoundedDrawable* GetItem() const = 0; + + virtual void SetItemValue( Scrooby::BoundedDrawable* itemValue ) = 0; + virtual Scrooby::BoundedDrawable* GetItemValue() const = 0; + + virtual void SetItemValueIndex( int index ) = 0; + virtual int GetItemValueIndex() const = 0; + + virtual void SetDisplayOutline( bool enable ) = 0; + virtual void SetOutlineColour( tColour colour ) = 0; + virtual tColour GetOutlineColour() const = 0; + + int m_attributes; + tColour m_defaultColour; + + Scrooby::Sprite* m_itemValueArrowL; + Scrooby::Sprite* m_itemValueArrowR; + int m_itemValueCount; + + ImageSlider m_slider; + +}; + +//=========================================================================== +// Interface Definitions - GuiMenuItemText +//=========================================================================== +struct GuiMenuItemText : public GuiMenuItem +{ + GuiMenuItemText(); + + virtual void SetItem( Scrooby::BoundedDrawable* item ); + virtual Scrooby::BoundedDrawable* GetItem() const; + + virtual void SetItemValue( Scrooby::BoundedDrawable* itemValue ); + virtual Scrooby::BoundedDrawable* GetItemValue() const; + + virtual void SetItemValueIndex( int index ); + virtual int GetItemValueIndex() const; + + virtual void SetDisplayOutline( bool enable ); + virtual void SetOutlineColour( tColour colour ); + virtual tColour GetOutlineColour() const; + + Scrooby::Text* m_item; + Scrooby::Text* m_itemValue; + +}; + +//=========================================================================== +// Inlines - GuiMenuItemText +//=========================================================================== + +inline Scrooby::BoundedDrawable* GuiMenuItemText::GetItem() const +{ + return m_item; +} + +inline Scrooby::BoundedDrawable* GuiMenuItemText::GetItemValue() const +{ + return m_itemValue; +} + +//=========================================================================== +// Interface Definitions - GuiMenuItemSprite +//=========================================================================== +struct GuiMenuItemSprite : public GuiMenuItem +{ + GuiMenuItemSprite(); + + virtual void SetItem( Scrooby::BoundedDrawable* item ); + virtual Scrooby::BoundedDrawable* GetItem() const; + + virtual void SetItemValue( Scrooby::BoundedDrawable* itemValue ); + virtual Scrooby::BoundedDrawable* GetItemValue() const; + + virtual void SetItemValueIndex( int index ); + virtual int GetItemValueIndex() const; + + virtual void SetDisplayOutline( bool enable ); + virtual void SetOutlineColour( tColour colour ); + virtual tColour GetOutlineColour() const; + + Scrooby::Sprite* m_item; + Scrooby::Sprite* m_itemValue; + +}; + +//=========================================================================== +// Inlines - GuiMenuItemSprite +//=========================================================================== + +inline Scrooby::BoundedDrawable* GuiMenuItemSprite::GetItem() const +{ + return m_item; +} + +inline Scrooby::BoundedDrawable* GuiMenuItemSprite::GetItemValue() const +{ + return m_itemValue; +} + + +#endif // GUIMENUITEM_H diff --git a/game/code/presentation/gui/guiscreen.cpp b/game/code/presentation/gui/guiscreen.cpp new file mode 100644 index 0000000..aee9b0e --- /dev/null +++ b/game/code/presentation/gui/guiscreen.cpp @@ -0,0 +1,1314 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreen +// +// Description: Implementation of the CGuiScreen class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/21 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <memory/classsizetracker.h> +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/utility/specialfx.h> + +#include <events/eventmanager.h> + +#include <app.h> +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <pure3dobject.h> +#include <sprite.h> +#include <text.h> + +#include <p3d/anim/multicontroller.hpp> +#include <p3d/utility.hpp> +#include <pddi/pddi.hpp> + +#include <raddebug.hpp> + +#include <string.h> + +#ifdef RAD_WIN32 +#include <input/inputmanager.h> +#endif + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//#define PRINTSCREENUPDATES + +const char* FOREGROUND_LAYER = "Foreground"; +const char* BACKGROUND_LAYER = "Background"; +const char* FE_PURE3D_OBJECT = "CamAndSet"; + +const float DEFAULT_SCREEN_FADE_TIME = 250.0f; // in msec +const float DEFAULT_SCREEN_ZOOM_TIME = 250.0f; // in msec +const float DEFAULT_SCREEN_SLIDE_TIME = 250.0f; // in msec +const float DEFAULT_IRIS_WIPE_SPEED = 0.5f; + +const float WIDE_SCREEN_CORRECTION_SCALE = (4.0f / 3.0f) * (9.0f / 16.0f); + +const char* ACCEPT_PAGES[] = +{ + "Accept", + "Accept2", + "Accept3", + "Buy", + "Continue", + + "" // dummy terminator +}; + +const int NUM_ACCEPT_PAGES = sizeof( ACCEPT_PAGES ) / sizeof( ACCEPT_PAGES[ 0 ] ); + +const char* BACK_PAGES[] = +{ + "Back", + "Back2", + "Cancel", + + "" // dummy terminator +}; + +const int NUM_BACK_PAGES = sizeof( BACK_PAGES ) / sizeof( BACK_PAGES[ 0 ] ); + +tMultiController* CGuiScreen::s_p3dMultiController = NULL; +float CGuiScreen::s_numIrisFrames = 0.0f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreen::CGuiScreen +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreen::CGuiScreen +( + Scrooby::Screen* pScroobyScreen, + CGuiEntity* pParent, + eGuiWindowID id, + unsigned int screenFX +) +: CGuiWindow( id, pParent ), + m_pScroobyScreen( pScroobyScreen ), + m_screenCover( NULL ), + m_p3dObject( NULL ), + m_p3dIris( NULL ), + m_irisController( NULL ), + m_currentIrisState( IRIS_STATE_IDLE ), + m_autoOpenIris( false ), + m_numForegroundLayers( 0 ), + m_numBackgroundLayers( 0 ), + m_ignoreControllerInputs( false ), + m_inverseFading( false ), + m_screenFX( screenFX ), + m_fadeTime( DEFAULT_SCREEN_FADE_TIME ), + m_elapsedFadeTime( -1 ), + m_zoomTime( DEFAULT_SCREEN_ZOOM_TIME ), + m_elapsedZoomTime( -1 ), + m_slideTime( DEFAULT_SCREEN_SLIDE_TIME ), + m_elapsedSlideTime( -1 ), + m_playTransitionAnimationLast( false ) +{ + CLASSTRACKER_CREATE( CGuiScreen ); + memset( m_foregroundLayers, 0, sizeof( m_foregroundLayers ) ); + memset( m_backgroundLayers, 0, sizeof( m_backgroundLayers ) ); + memset( m_buttonIcons, 0, sizeof( m_buttonIcons ) ); + + m_guiManager = static_cast<CGuiManager*>( m_pParent ); + rAssert( m_guiManager ); + + rAssert( m_pScroobyScreen != NULL ); + + Scrooby::Page* pPage = NULL; + + // Get foreground and background layers of all pages in screen + // + int numPages = m_pScroobyScreen->GetNumberOfPages(); + for( int i = 0; i < numPages; i++ ) + { + pPage = m_pScroobyScreen->GetPageByIndex( i ); + rAssert( pPage ); + + Scrooby::Layer* pLayer = pPage->GetLayer( FOREGROUND_LAYER ); + if( pLayer != NULL ) + { + rAssert( m_numForegroundLayers < MAX_FOREGROUND_LAYERS ); + m_foregroundLayers[ m_numForegroundLayers ] = pLayer; + m_numForegroundLayers++; + + if( this->IsWideScreenDisplay() ) + { + pLayer->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( pLayer ); + } + } + + pLayer = pPage->GetLayer( BACKGROUND_LAYER ); + if( pLayer != NULL ) + { + rAssert( m_numBackgroundLayers < MAX_BACKGROUND_LAYERS ); + m_backgroundLayers[ m_numBackgroundLayers ] = pLayer; + m_numBackgroundLayers++; + } + } + + this->RestoreScreenCover(); + + // Get pure3d object from "3dFE" page, if included + // + pPage = m_pScroobyScreen->GetPage( "3dFE" ); + if( pPage != NULL ) + { + m_p3dObject = pPage->GetPure3dObject( FE_PURE3D_OBJECT ); + rAssert( m_p3dObject ); + } + + // Get iris pure3d object from "IrisCover" page, if included + // + pPage = m_pScroobyScreen->GetPage( "IrisCover" ); + if( pPage != NULL ) + { + // set iris layer visible + // + Scrooby::Layer* irisLayer = pPage->GetLayer( "IrisCover" ); + rAssert( irisLayer != NULL ); + irisLayer->SetVisible( true ); + + m_p3dIris = pPage->GetPure3dObject( "3dIris" ); + rAssert( m_p3dIris != NULL ); + m_p3dIris->SetZBufferEnabled( false ); + + m_irisController = p3d::find<tMultiController>( "IrisController" ); + rAssert( m_irisController != NULL ); + m_irisController->AddRef(); + + s_numIrisFrames = m_irisController->GetNumFrames(); + } + + // Get button icons + // + for( int j = 0; j < NUM_ACCEPT_PAGES; j++ ) + { + pPage = m_pScroobyScreen->GetPage( ACCEPT_PAGES[ j ] ); + if( pPage != NULL ) + { + m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "AcceptLabel" ); + rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL ); + +#ifndef RAD_WIN32 + // add text outline to accept text + // + Scrooby::Text* accept = m_buttonIcons[ BUTTON_ICON_ACCEPT ]->GetText( "Accept" ); + rAssert( accept != NULL ); + accept->SetDisplayOutline( true ); +#endif + + break; + } + } + + for( int k = 0; k < NUM_BACK_PAGES; k++ ) + { + pPage = m_pScroobyScreen->GetPage( BACK_PAGES[ k ] ); + if( pPage != NULL ) + { + m_buttonIcons[ BUTTON_ICON_BACK ] = pPage->GetGroup( "BackLabel" ); + rAssert( m_buttonIcons[ BUTTON_ICON_BACK ] != NULL ); + +#ifndef RAD_WIN32 + // add text outline to accept text + // + Scrooby::Text* back = m_buttonIcons[ BUTTON_ICON_BACK ]->GetText( "Back" ); + rAssert( back != NULL ); + back->SetDisplayOutline( true ); +#endif + + break; + } + } +} + +//=========================================================================== +// CGuiScreen::~CGuiScreen +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreen::~CGuiScreen() +{ + CLASSTRACKER_DESTROY( CGuiScreen ); + if( m_irisController != NULL ) + { + m_irisController->Release(); + m_irisController = NULL; + } +} + + +//=========================================================================== +// CGuiScreen::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiScreen::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_ignoreControllerInputs && + this->IsControllerMessage( message ) ) + { + // ignore controller messages + return; + } + + +#ifdef RAD_WIN32 + if( message == GUI_MSG_WINDOW_ENTER ) + { + // just entered screen, so re-enable mouse + GetInputManager()->GetFEMouse()->SetSelectable( true ); + } + else if( message == GUI_MSG_WINDOW_EXIT ) + { + // exiting screen, so disable mouse + GetInputManager()->GetFEMouse()->SetSelectable( false ); + } +#endif + + switch( message ) + { + case GUI_MSG_WINDOW_ENTER: + { + // reset any pending transitions + m_numTransitionsPending = 0; + + if( !m_inverseFading ) + { + if( m_screenFX & SCREEN_FX_FADE ) + { + this->SetAlphaForLayers( 0.0f, + m_foregroundLayers, + m_numForegroundLayers ); + } + } + + if( m_screenFX & SCREEN_FX_ZOOM ) + { + this->SetAlphaForLayers( 0.0f, + m_backgroundLayers, + m_numBackgroundLayers ); + } + + if( m_screenFX & SCREEN_FX_IRIS ) + { + this->SetAlphaForLayers( 0.0f, + m_foregroundLayers, + m_numForegroundLayers ); + + this->SetAlphaForLayers( 0.0f, + m_backgroundLayers, + m_numBackgroundLayers ); + } + + // restore all button icon visibilities + this->RestoreButtons(); + + // follow-through + // + } + case GUI_MSG_WINDOW_EXIT: + { + if( m_screenFX & SCREEN_FX_FADE ) + { + if( m_numForegroundLayers > 0 || m_screenCover != NULL ) + { + // reset fade elapsed time + m_elapsedFadeTime = 0; + + // increment number of pending transitions + m_numTransitionsPending++; + } + } + + if( m_screenFX & SCREEN_FX_ZOOM ) + { + // reset zoom elapsed time + m_elapsedZoomTime = 0; + + // increment number of pending transitions + m_numTransitionsPending++; + } + + if( m_screenFX & SCREEN_FX_SLIDE_X || + m_screenFX & SCREEN_FX_SLIDE_Y ) + { + m_elapsedSlideTime = 0; + m_numTransitionsPending++; + } + + if( m_screenFX & SCREEN_FX_IRIS ) + { + rAssert( m_irisController != NULL ); + m_irisController->Reset(); + m_irisController->SetRelativeSpeed( DEFAULT_IRIS_WIPE_SPEED ); + m_irisController->SetFrameRange( 0.0f, s_numIrisFrames ); + m_irisController->SetFrame( 0.0f ); + + m_currentIrisState = IRIS_STATE_CLOSING; + + m_numTransitionsPending++; + } + break; + } + + case GUI_MSG_UPDATE: + { + #ifdef PRINTSCREENUPDATES + const char* screenName = GetWatcherName(); + rDebugPrintf( "Screen - %s\n", screenName ); + #endif + + switch( m_state ) + { + case GUI_WINDOW_STATE_INTRO: + { + // update screen fade in + // + if( (m_screenFX & SCREEN_FX_FADE) && + m_elapsedFadeTime != -1 ) + { + if( m_inverseFading ) + { + this->FadeOut( static_cast<float>( param1 ) ); + } + else + { + this->FadeIn( static_cast<float>( param1 ) ); + } + } + + // update screen zoom in + // + if( (m_screenFX & SCREEN_FX_ZOOM) && + m_elapsedZoomTime != -1 ) + { + this->ZoomIn( static_cast<float>( param1 ) ); + } + + // update screen slide in + // + if( ((m_screenFX & SCREEN_FX_SLIDE_X) || (m_screenFX & SCREEN_FX_SLIDE_Y)) && + m_elapsedSlideTime != -1 ) + { + this->SlideIn( static_cast<float>( param1 ) ); + } + + // update transition in animation + // + if( m_p3dObject != NULL ) + { + tMultiController* controller = m_p3dObject->GetMultiController(); + if( controller != NULL ) + { + if( controller->GetFrame() >= controller->GetNumFrames() ) + { + // nullify multicontroller + m_p3dObject->SetMultiController( NULL ); + + // decrement number of pending transitions + m_numTransitionsPending--; + } + } + } + + // update iris wipe + // + if( m_screenFX & SCREEN_FX_IRIS ) + { + rAssert( m_irisController != NULL ); + if( m_currentIrisState == IRIS_STATE_CLOSING ) + { + if( m_irisController->GetFrame() > m_irisController->GetNumFrames() / 2 ) + { + this->OnIrisWipeClosed(); + + this->SetAlphaForLayers( 1.0f, + m_foregroundLayers, + m_numForegroundLayers ); + + this->SetAlphaForLayers( 1.0f, + m_backgroundLayers, + m_numBackgroundLayers ); + } + } + else if( m_currentIrisState == IRIS_STATE_OPENING ) + { + if( m_irisController->LastFrameReached() ) + { + m_numTransitionsPending--; + + m_currentIrisState = IRIS_STATE_IDLE; + } + } + } + + // get p3d multicontroller upon first time entering screen + // and store reference to it + // + if( m_firstTimeEntered ) + { + if( m_p3dObject != NULL && + s_p3dMultiController == NULL ) + { + s_p3dMultiController = m_p3dObject->GetMultiController(); + if( s_p3dMultiController != NULL ) + { + s_p3dMultiController->AddRef(); + + m_p3dObject->SetMultiController( NULL ); + } + } + } + + break; + } + case GUI_WINDOW_STATE_OUTRO: + { + // update screen fade out + // + if( (m_screenFX & SCREEN_FX_FADE) && + m_elapsedFadeTime != -1 ) + { + if( m_inverseFading ) + { + this->FadeIn( static_cast<float>( param1 ) ); + } + else + { + this->FadeOut( static_cast<float>( param1 ) ); + } + } + + // update screen zoom out + // + if( (m_screenFX & SCREEN_FX_ZOOM) && + m_elapsedZoomTime != -1 ) + { + this->ZoomOut( static_cast<float>( param1 ) ); + } + + // update screen slide out + // + if( ((m_screenFX & SCREEN_FX_SLIDE_X) || (m_screenFX & SCREEN_FX_SLIDE_Y)) && + m_elapsedSlideTime != -1 ) + { + this->SlideOut( static_cast<float>( param1 ) ); + } + + // update transition out animation + // + if( m_p3dObject != NULL ) + { + if( m_playTransitionAnimationLast ) + { + if( m_numTransitionsPending == 1 ) + { + s_p3dMultiController->Reset(); + m_p3dObject->SetMultiController( s_p3dMultiController ); + m_playTransitionAnimationLast = false; + } + } + else + { + tMultiController* controller = m_p3dObject->GetMultiController(); + if( controller != NULL ) + { + if( controller->GetFrame() >= controller->GetNumFrames() ) + { + // nullify multicontroller + m_p3dObject->SetMultiController( NULL ); + + // decrement number of pending transitions + m_numTransitionsPending--; + } + } + } + } + + // update iris wipe + // + if( m_screenFX & SCREEN_FX_IRIS ) + { + rAssert( m_irisController != NULL ); + if( m_currentIrisState == IRIS_STATE_CLOSING ) + { + if( m_irisController->GetFrame() > m_irisController->GetNumFrames() / 2 ) + { + this->OnIrisWipeClosed(); + + this->SetAlphaForLayers( 0.0f, + m_foregroundLayers, + m_numForegroundLayers ); + + this->SetAlphaForLayers( 0.0f, + m_backgroundLayers, + m_numBackgroundLayers ); + + m_currentIrisState = IRIS_STATE_CLOSED; + } + } + else if( m_currentIrisState == IRIS_STATE_OPENING ) + { + if( m_irisController->LastFrameReached() ) + { + m_numTransitionsPending--; + + m_currentIrisState = IRIS_STATE_IDLE; + } + } + } + + break; + } + + default: + { + break; + } + } + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( m_guiManager->GetPreviousScreen() != GUI_WINDOW_ID_UNDEFINED ) + { + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); + } + } + + break; + } + + default: + { + break; + } + }; + + // Pass the message up the heirarchy. + // + CGuiWindow::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreen::SetFadingEnabled( bool enable ) +{ + if( enable ) + { + m_screenFX |= SCREEN_FX_FADE; + } + else + { + m_screenFX &= ~SCREEN_FX_FADE; + + this->SetAlphaForLayers( 1.0f, + m_foregroundLayers, + m_numForegroundLayers ); + + if( m_screenCover != NULL ) + { + m_screenCover->SetVisible( false ); + } + } +} + +void +CGuiScreen::SetZoomingEnabled( bool enable ) +{ + if( enable ) + { + m_screenFX |= SCREEN_FX_ZOOM; + } + else + { + m_screenFX &= ~SCREEN_FX_ZOOM; + + m_pScroobyScreen->SetScale( 1.0f ); + + this->SetAlphaForLayers( 1.0f, + m_backgroundLayers, + m_numBackgroundLayers ); + } +} + +void +CGuiScreen::SetSlidingEnabled( eScreenEffect slideType, bool enable ) +{ + rAssert( slideType == SCREEN_FX_SLIDE_X || + slideType == SCREEN_FX_SLIDE_Y ); + + rAssertMsg( !this->IsWideScreenDisplay() || slideType != SCREEN_FX_SLIDE_X, + "Horizontal screen sliding currently not supported for widescreen display!" ); + + if( enable ) + { + m_screenFX |= slideType; + } + else + { + m_screenFX &= ~slideType; + } +} + +void +CGuiScreen::SetIrisWipeEnabled( bool enable, bool autoOpenIris ) +{ + if( enable ) + { + m_screenFX |= SCREEN_FX_IRIS; + + m_autoOpenIris = autoOpenIris; + } + else + { + m_screenFX &= ~SCREEN_FX_IRIS; + } +} + +bool +CGuiScreen::IsEffectEnabled( eScreenEffect effect ) const +{ + return ((m_screenFX & effect) > 0); +} + +void +CGuiScreen::Reset3dFEMultiController() +{ + if( s_p3dMultiController != NULL ) + { + s_p3dMultiController->Release(); + s_p3dMultiController = NULL; + } +} + +void +CGuiScreen::SetButtonVisible( eButtonIcon button, bool isVisible ) +{ + if( m_buttonIcons[ button ] != NULL ) + { + m_buttonIcons[ button ]->SetVisible( isVisible ); + } +} + +bool +CGuiScreen::IsButtonVisible( eButtonIcon button ) const +{ + if( m_buttonIcons[ button ] != NULL ) + { + return m_buttonIcons[ button ]->IsVisible(); + } + + return false; +} + +void +CGuiScreen::StartTransitionAnimation( int startFrame, + int endFrame, + bool lastTransition ) +{ + if( m_ignoreControllerInputs ) + { + return; + } + + if( m_p3dObject != NULL ) + { + rAssert( s_p3dMultiController != NULL ); + + // if start and end frames are specified, set them for multicontroller + if( startFrame > -1 && endFrame > -1 ) + { + s_p3dMultiController->SetFrameRange( (float)startFrame, (float)endFrame ); + } + + m_playTransitionAnimationLast = lastTransition; + if( !m_playTransitionAnimationLast ) + { + // set multicontroller for p3dobject + s_p3dMultiController->Reset(); + m_p3dObject->SetMultiController( s_p3dMultiController ); + } + + // increment number of pending transitions + m_numTransitionsPending++; + } +} + +void +CGuiScreen::ReloadScreen() +{ + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + this->m_ID, + KEEP_WINDOW_HISTORY ); +} + +void +CGuiScreen::RestoreScreenCover() +{ + // Get screen cover, if Cover page included + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "COVER" ); + if( pPage != NULL ) + { + m_screenCover = pPage->GetLayerByIndex( 0 ); + rAssert( m_screenCover != NULL ); + + m_screenCover->SetVisible( true ); + m_screenCover->SetAlpha( 1.0f ); + } +} + +void +CGuiScreen::RestoreButtons() +{ + for( int i = 0; i < NUM_BUTTON_ICONS; i++ ) + { + if( m_buttonIcons[ i ] != NULL ) + { + m_buttonIcons[ i ]->SetVisible( true ); + } + } +} + +bool +CGuiScreen::IsWideScreenDisplay() +{ +#ifdef RAD_XBOX + return p3d::display->IsWidescreen(); +#else + return false; +#endif +} + +void +CGuiScreen::ApplyWideScreenCorrectionScale( Scrooby::Drawable* drawable ) +{ + // Assumes drawable is currently screen-centered! + // + int screenWidthBy2 = static_cast<int>( Scrooby::App::GetInstance()->GetScreenWidth() ) / 2; + + rAssert( drawable != NULL ); + drawable->Translate( -screenWidthBy2, 0 ); + drawable->Scale( WIDE_SCREEN_CORRECTION_SCALE, 1.0f, 1.0f ); + drawable->Translate( screenWidthBy2, 0 ); +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiScreen::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreen::CheckCursorAgainstHotspots( float x, float y ) +{ + eFEHotspotType hotSpotType = HOTSPOT_NONE; + CGuiMenu* pCurrentMenu = HasMenu(); + int numMenuItems = 0; + GuiMenuItem* pMenuItem = NULL; + + + if( pCurrentMenu ) + { + numMenuItems = pCurrentMenu->GetNumItems(); + + for( int i = 0; i < numMenuItems; i++ ) + { + bool bIsMenuItemEnabled = pCurrentMenu->IsMenuItemEnabled(i); + pMenuItem = pCurrentMenu->GetMenuItem( i ); + + if( pMenuItem && bIsMenuItemEnabled ) + { + if( pMenuItem->GetItem()->IsVisible() ) + { + // Just tests if the point is in the bounding rect of the sprite. + if( pMenuItem->GetItem()->IsPointInBoundingRect( x, y ) ) + { + //rDebugPrintf( "Cursor is inside Sprite %d rectangle!\n", i ); + pCurrentMenu->HandleMessage( GUI_MSG_MOUSE_OVER, i ); + hotSpotType = HOTSPOT_BUTTON; + + //After taking care of all the events for this menu item, just bail out. + break; + } + else if( pCurrentMenu->GetSelection() == i ) + { + if( pMenuItem->m_itemValueArrowL ) + { + if( pMenuItem->m_itemValueArrowL->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWLEFT; + break; + } + } + + if( pMenuItem->m_itemValueArrowR ) + { + if( pMenuItem->m_itemValueArrowR->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWRIGHT; + break; + } + } + + if( pMenuItem->m_slider.m_pImage ) + { + if( pMenuItem->m_slider.m_pImage->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_SLIDER; + break; + } + } + } + } + } + } + } + + return hotSpotType; +} +#endif + +//=========================================================================== +// Protected Member Functions +//=========================================================================== + +void +CGuiScreen::RestoreDefaultFadeTime() +{ + m_fadeTime = DEFAULT_SCREEN_FADE_TIME; +} + +void +CGuiScreen::RestoreDefaultZoomTime() +{ + m_zoomTime = DEFAULT_SCREEN_ZOOM_TIME; +} + +void +CGuiScreen::IrisWipeOpen() +{ + rAssert( !m_autoOpenIris ); + + rAssert( m_irisController != NULL ); + m_irisController->SetRelativeSpeed( DEFAULT_IRIS_WIPE_SPEED ); + + m_currentIrisState = IRIS_STATE_OPENING; +} + +void CGuiScreen::SetAlphaForLayers( float alpha, Scrooby::Layer** layers, int numLayers ) +{ + rAssert( layers ); + rAssert( numLayers >= 0 ); + + for( int i = 0; i < numLayers; i++ ) + { + layers[ i ]->SetAlpha( alpha ); + } +} + +void +CGuiScreen::AutoScaleFrame( Scrooby::Page* pPage ) +{ + if( pPage != NULL ) + { + Scrooby::Group* pFrameGroup = pPage->GetGroup( "Frame" ); + if( pFrameGroup != NULL ) + { + const int SEGMENT_LENGTH = 40; // in pixels + + Scrooby::Sprite* pFrameTop = pFrameGroup->GetSprite( "Frame_Top" ); + rAssert( pFrameTop != NULL ); + Scrooby::Sprite* pFrameBottom = pFrameGroup->GetSprite( "Frame_Bottom" ); + rAssert( pFrameBottom != NULL ); + Scrooby::Sprite* pFrameLeft = pFrameGroup->GetSprite( "Frame_Left" ); + rAssert( pFrameLeft != NULL ); + Scrooby::Sprite* pFrameRight = pFrameGroup->GetSprite( "Frame_Right" ); + rAssert( pFrameRight != NULL ); + + int width = 0; + int height = 0; + + // scale top and bottom frames horizontally + // + pFrameTop->GetBoundingBoxSize( width, height ); + float scaleX = (width - SEGMENT_LENGTH) / (float)SEGMENT_LENGTH; + + pFrameTop->ResetTransformation(); + pFrameTop->ScaleAboutCenter( scaleX, 1.0f, 1.0f ); + pFrameTop->Translate( +5, 0 ); + + pFrameBottom->ResetTransformation(); + pFrameBottom->ScaleAboutCenter( scaleX, 1.0f, 1.0f ); + pFrameBottom->Translate( +5, 0 ); + + // scale left and right frames vertically + // + pFrameLeft->GetBoundingBoxSize( width, height ); + float scaleY = (height - SEGMENT_LENGTH) / (float)SEGMENT_LENGTH; + + pFrameLeft->ResetTransformation(); + pFrameLeft->ScaleAboutCenter( 1.0f, scaleY, 1.0f ); + + pFrameRight->ResetTransformation(); + pFrameRight->ScaleAboutCenter( 1.0f, scaleY, 1.0f ); + +#ifdef PAL + if( pPage == m_pScroobyScreen->GetPage( "BigBoard" ) ) + { + pFrameGroup->ResetTransformation(); + pFrameGroup->ScaleAboutCenter( 1.035f, 1.0f, 1.0f ); + } +#endif // PAL + } + } +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +void +CGuiScreen::FadeIn( float elapsedTime ) +{ + float alpha = (m_elapsedFadeTime + elapsedTime) / m_fadeTime; + + if( alpha < 1.0f ) + { + // for non-linear fading + // + alpha *= alpha; + + this->SetAlphaForLayers( alpha, + m_foregroundLayers, + m_numForegroundLayers ); + + if( m_screenCover != NULL ) + { + m_screenCover->SetVisible( true ); + m_screenCover->SetAlpha( 1.0f - alpha ); + } + } + else + { + this->SetAlphaForLayers( 1.0f, + m_foregroundLayers, + m_numForegroundLayers ); + + if( m_screenCover != NULL ) + { + m_screenCover->SetAlpha( 0.0f ); + } + } + + if( m_elapsedFadeTime < m_fadeTime ) + { + m_elapsedFadeTime += elapsedTime; + } + else + { + m_elapsedFadeTime = -1; + + // decrement number of pending transitions + m_numTransitionsPending--; + } +} + +void +CGuiScreen::FadeOut( float elapsedTime ) +{ + float alpha = 1.0f - (m_elapsedFadeTime + elapsedTime) / m_fadeTime; + + if( alpha > 0.0f ) + { + // for non-linear fading + // + alpha *= alpha; + + this->SetAlphaForLayers( alpha, + m_foregroundLayers, + m_numForegroundLayers ); + + if( m_screenCover != NULL ) + { + m_screenCover->SetVisible( true ); + m_screenCover->SetAlpha( 1.0f - alpha ); + } + } + else + { + this->SetAlphaForLayers( 0.0f, + m_foregroundLayers, + m_numForegroundLayers ); + + if( m_screenCover != NULL ) + { + m_screenCover->SetAlpha( 1.0f ); + } + } + + if( m_elapsedFadeTime < m_fadeTime ) + { + m_elapsedFadeTime += elapsedTime; + } + else + { + m_elapsedFadeTime = -1; + + // decrement number of pending transitions + m_numTransitionsPending--; + } +} + +void +CGuiScreen::ZoomIn( float elapsedTime ) +{ + rAssert( m_pScroobyScreen ); + + float zoomValue = (m_elapsedZoomTime + elapsedTime) / m_zoomTime; + rAssert( zoomValue >= 0.0f ); + + if( zoomValue < 1.0f ) + { + // scale screen + m_pScroobyScreen->SetScale( zoomValue ); + + // apply alpha to background layers + this->SetAlphaForLayers( zoomValue, + m_backgroundLayers, + m_numBackgroundLayers ); + } + else + { + m_pScroobyScreen->SetScale( 1.0f ); + + this->SetAlphaForLayers( 1.0f, + m_backgroundLayers, + m_numBackgroundLayers ); + } + + if( m_elapsedZoomTime < m_zoomTime ) + { + m_elapsedZoomTime += elapsedTime; + } + else + { + m_elapsedZoomTime = -1; + + // decrement number of pending transitions + m_numTransitionsPending--; + } +} + +void +CGuiScreen::ZoomOut( float elapsedTime ) +{ + rAssert( m_pScroobyScreen ); + + float zoomValue = 1.0f - (m_elapsedZoomTime + elapsedTime) / m_zoomTime; + rAssert( zoomValue <= 1.0f ); + + if( zoomValue > 0.0f ) + { + // scale screen + m_pScroobyScreen->SetScale( zoomValue ); + + // apply alpha to background layers + this->SetAlphaForLayers( zoomValue, + m_backgroundLayers, + m_numBackgroundLayers ); + } + else + { + m_pScroobyScreen->SetScale( 0.0f ); + + this->SetAlphaForLayers( 0.0f, + m_backgroundLayers, + m_numBackgroundLayers ); + } + + if( m_elapsedZoomTime < m_zoomTime ) + { + m_elapsedZoomTime += elapsedTime; + } + else + { + m_elapsedZoomTime = -1; + + // decrement number of pending transitions + m_numTransitionsPending--; + } +} + +void +CGuiScreen::SlideIn( float elapsedTime ) +{ + bool done = false; + + for( int i = 0; i < m_numForegroundLayers; i++ ) + { + rAssert( m_foregroundLayers[ i ] ); + + if( m_screenFX & SCREEN_FX_SLIDE_X ) + { + done = GuiSFX::SlideX( m_foregroundLayers[ i ], + m_elapsedSlideTime, + m_slideTime, + true, + GuiSFX::SLIDE_BORDER_RIGHT ); + } + + if( m_screenFX & SCREEN_FX_SLIDE_Y ) + { + done = GuiSFX::SlideY( m_foregroundLayers[ i ], + m_elapsedSlideTime, + m_slideTime, + true, + GuiSFX::SLIDE_BORDER_TOP ); + + if( this->IsWideScreenDisplay() ) + { + this->ApplyWideScreenCorrectionScale( m_foregroundLayers[ i ] ); + } + } + } + + if( done ) + { + m_elapsedSlideTime = -1; + m_numTransitionsPending--; + } + else + { + m_elapsedSlideTime += elapsedTime; + } +} + +void +CGuiScreen::SlideOut( float elapsedTime ) +{ + bool done = false; + + for( int i = 0; i < m_numForegroundLayers; i++ ) + { + rAssert( m_foregroundLayers[ i ] ); + + if( m_screenFX & SCREEN_FX_SLIDE_X ) + { + done = GuiSFX::SlideX( m_foregroundLayers[ i ], + m_elapsedSlideTime, + m_slideTime, + false, + GuiSFX::SLIDE_BORDER_LEFT ); + } + + if( m_screenFX & SCREEN_FX_SLIDE_Y ) + { + done = GuiSFX::SlideY( m_foregroundLayers[ i ], + m_elapsedSlideTime, + m_slideTime, + false, + GuiSFX::SLIDE_BORDER_TOP ); + + if( this->IsWideScreenDisplay() ) + { + this->ApplyWideScreenCorrectionScale( m_foregroundLayers[ i ] ); + } + } + } + + if( done ) + { + m_elapsedSlideTime = -1; + m_numTransitionsPending--; + } + else + { + m_elapsedSlideTime += elapsedTime; + } +} + +void +CGuiScreen::OnIrisWipeClosed() +{ + if( m_autoOpenIris ) + { + this->IrisWipeOpen(); + } + else + { + rAssert( m_irisController != NULL ); + m_irisController->SetRelativeSpeed( 0.0f ); + + m_currentIrisState = IRIS_STATE_CLOSED; + } +} + +#ifdef DEBUGWATCH +const char* CGuiScreen::GetWatcherName() const +{ + return "No Name"; +} +#endif
\ No newline at end of file diff --git a/game/code/presentation/gui/guiscreen.h b/game/code/presentation/gui/guiscreen.h new file mode 100644 index 0000000..3d82cd2 --- /dev/null +++ b/game/code/presentation/gui/guiscreen.h @@ -0,0 +1,234 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreen +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISCREEN_H +#define GUISCREEN_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiwindow.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiManager; +class tMultiController; + +namespace Scrooby +{ + class Screen; + class Page; + class Layer; + class Group; + class Drawable; + class Sprite; + class Text; + class Polygon; + class Pure3dObject; +} + +//class tCameraAnimationController; + +const int MAX_FOREGROUND_LAYERS = 8; +const int MAX_BACKGROUND_LAYERS = 2; + +enum eScreenEffect +{ + SCREEN_FX_ALL = ~0, + SCREEN_FX_NONE = 0, + + SCREEN_FX_FADE = 1, + SCREEN_FX_ZOOM = 2, + SCREEN_FX_SLIDE_X = 4, + SCREEN_FX_SLIDE_Y = 8, + SCREEN_FX_IRIS = 16, + + NUM_SCREEN_FX +}; + +enum eButtonIcon +{ + BUTTON_ICON_ACCEPT, + BUTTON_ICON_BACK, + + NUM_BUTTON_ICONS +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreen : public CGuiWindow +{ + public: + + CGuiScreen( Scrooby::Screen* pScroobyScreen, + CGuiEntity* pParent, + eGuiWindowID id, + unsigned int screenFX = SCREEN_FX_FADE ); + + virtual ~CGuiScreen(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void SetScroobyScreen( Scrooby::Screen* pScreen ) { m_pScroobyScreen = pScreen; } + Scrooby::Screen* GetScroobyScreen() const { return m_pScroobyScreen; } + + virtual CGuiMenu* HasMenu() { return NULL; } + + void SetFadingEnabled( bool enable ); + void SetZoomingEnabled( bool enable ); + void SetSlidingEnabled( eScreenEffect slideType, bool enable ); + void SetIrisWipeEnabled( bool enable, bool autoOpenIris = false ); + + bool IsEffectEnabled( eScreenEffect effect ) const; + + static void Reset3dFEMultiController(); + + void SetIngoreControllerInputs( bool ignore ) { m_ignoreControllerInputs = ignore; } + bool IsIgnoringControllerInputs() const { return m_ignoreControllerInputs; } + + void SetButtonVisible( eButtonIcon button, bool isVisible ); + bool IsButtonVisible( eButtonIcon button ) const; + + void StartTransitionAnimation( int startFrame = -1, + int endFrame = -1, + bool lastTransition = true ); + + void ReloadScreen(); + void RestoreScreenCover(); + void RestoreButtons(); + + static bool IsWideScreenDisplay(); + static void ApplyWideScreenCorrectionScale( Scrooby::Drawable* drawable ); + +#ifdef RAD_WIN32 + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); +#endif + + protected: + + //--------------------------------------------------------------------- + // Protected Functions + //--------------------------------------------------------------------- + + void SetFadeTime( float fadeTime ) { m_fadeTime = fadeTime; } + void RestoreDefaultFadeTime(); + + void SetZoomTime( float zoomTime ) { m_zoomTime = zoomTime; } + void RestoreDefaultZoomTime(); + + void IrisWipeOpen(); + + void SetAlphaForLayers( float alpha, + Scrooby::Layer** layers, + int numLayers ); + + void AutoScaleFrame( Scrooby::Page* pPage ); + #ifdef DEBUGWATCH + virtual const char* GetWatcherName() const; + #endif + + //--------------------------------------------------------------------- + // Protected Data + //--------------------------------------------------------------------- + + CGuiManager* m_guiManager; + + Scrooby::Screen* m_pScroobyScreen; + Scrooby::Layer* m_screenCover; + Scrooby::Pure3dObject* m_p3dObject; + + static tMultiController* s_p3dMultiController; + + enum eIrisState + { + IRIS_STATE_IDLE, + IRIS_STATE_CLOSING, + IRIS_STATE_CLOSED, + IRIS_STATE_OPENING, + + NUM_IRIS_STATES + }; + + Scrooby::Pure3dObject* m_p3dIris; + tMultiController* m_irisController; + eIrisState m_currentIrisState; + bool m_autoOpenIris : 1; + + Scrooby::Layer* m_foregroundLayers[ MAX_FOREGROUND_LAYERS ]; + int m_numForegroundLayers; + + Scrooby::Layer* m_backgroundLayers[ MAX_BACKGROUND_LAYERS ]; + int m_numBackgroundLayers; + + Scrooby::Group* m_buttonIcons[ NUM_BUTTON_ICONS ]; + + bool m_ignoreControllerInputs : 1; + bool m_inverseFading : 1; + + private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or asignment. Declare but don't define. + // + CGuiScreen( const CGuiScreen& ); + CGuiScreen& operator= ( const CGuiScreen& ); + + // Screen Fade In/Out Effects + void FadeIn( float elapsedTime ); + void FadeOut( float elapsedTime ); + + // Screen Zoom In/Out Effects + void ZoomIn( float elapsedTime ); + void ZoomOut( float elapsedTime ); + + // Screen Slide In/Out Effects + void SlideIn( float elapsedTime ); + void SlideOut( float elapsedTime ); + + // Iris Wipe Closed + // + void OnIrisWipeClosed(); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + static float s_numIrisFrames; + + unsigned int m_screenFX; // bit mask for screen effects + + float m_fadeTime; + float m_elapsedFadeTime; + + float m_zoomTime; + float m_elapsedZoomTime; + + float m_slideTime; + float m_elapsedSlideTime; + + bool m_playTransitionAnimationLast : 1; + +}; + +#endif // GUISCREEN_H diff --git a/game/code/presentation/gui/guiscreenmemcardcheck.cpp b/game/code/presentation/gui/guiscreenmemcardcheck.cpp new file mode 100644 index 0000000..71ccab6 --- /dev/null +++ b/game/code/presentation/gui/guiscreenmemcardcheck.cpp @@ -0,0 +1,518 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMemCardCheck +// +// Description: Implementation of the CGuiScreenMemCardCheck class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guiscreenmemcardcheck.h> +#include <presentation/gui/guiscreenmemorycard.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/frontend/guiscreenloadgame.h> +#include <presentation/gui/guiscreenprompt.h> + +#include <main/game.h> +#include <main/platform.h> +#include <memory/createheap.h> + +#include <raddebug.hpp> // Foundation +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +#ifdef RAD_GAMECUBE +#include <main/gamecube_extras/gcmanager.h> +#endif + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#ifndef RAD_E3 + // This will enable auto-loading the most recent saved game immediately + // after the memory card check. + // + #define ENABLE_AUTOLOAD_AFTER_MEMCHECK +#endif + +enum eMemCardCheckMessage +{ + CHECKING_MEMCARDS_GC, + CHECKING_MEMCARD_B_GC, + CHECKING_MEMCARDS_PS2, + CHECKING_MEMCARD_2_PS2, + CHECKING_HARDDISK_XBOX, + CHECKING_HARDDISK_PC, + + NUM_MEMCARD_CHECK_MESSAGES +}; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMemCardCheck::CGuiScreenMemCardCheck +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMemCardCheck::CGuiScreenMemCardCheck +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MEMORY_CARD_CHECK ), + m_messageText( NULL ), + m_minimumFormatTime(1000), + m_formatState(false), + m_StatusPromptShown(false), + m_isAutoLoadPending( false ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MemCardCheck" ); + rAssert( pPage ); + + Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" ); + + m_messageText = foreground->GetText( "CheckingMemoryCards" ); + rAssert( m_messageText ); + m_messageText->SetTextMode( Scrooby::TEXT_WRAP ); + +#ifdef RAD_GAMECUBE + m_messageText->SetIndex( CHECKING_MEMCARDS_GC ); +#endif + +#ifdef RAD_PS2 + m_messageText->SetIndex( CHECKING_MEMCARDS_PS2 ); + + #ifndef PAL + // no need to display checking message on PS2 + // + m_messageText->SetVisible( false ); + this->SetFadingEnabled( false ); + #endif +#endif + +#ifdef RAD_XBOX + m_messageText->SetIndex( CHECKING_HARDDISK_XBOX ); +#endif + +#ifdef RAD_WIN32 + m_messageText->SetIndex( CHECKING_HARDDISK_PC ); + // no need to display checking message on WIN32 + m_messageText->SetVisible( false ); + this->SetFadingEnabled( false ); +#endif +} + + +//=========================================================================== +// CGuiScreenMemCardCheck::~CGuiScreenMemCardCheck +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMemCardCheck::~CGuiScreenMemCardCheck() +{ +} + + +//=========================================================================== +// CGuiScreenMemCardCheck::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemCardCheck::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if (message == GUI_MSG_MESSAGE_UPDATE) + { + if (m_formatState) + { + m_elapsedFormatTime += param1; + + if (m_elapsedFormatTime > m_minimumFormatTime && m_formatDone) + { + m_StatusPromptShown = true; + if( m_formatResult == Success ) + { + m_guiManager->DisplayPrompt(PROMPT_FORMAT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format success + m_formatState = false; + } + else if (m_formatResult) + { + m_guiManager->DisplayPrompt(PROMPT_FORMAT_FAIL_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format fail + m_formatState = false; + } + } + } + } + else if (message == GUI_MSG_PROMPT_UPDATE) + { +#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 ) + // detect memcard unplugged in prompt + // update so status up to date + GetMemoryCardManager()->Update( param1 ); + if (m_StatusPromptShown==false) { // check for user unplugging memcard if not showing status + + if( !GetMemoryCardManager()->IsCurrentDrivePresent(CGuiScreenMemoryCard::s_currentMemoryCardSlot) ) + ReloadScreen(); + } +#endif + } + else if ( message == GUI_MSG_MENU_PROMPT_RESPONSE || message == GUI_MSG_ERROR_PROMPT_RESPONSE) + { + switch ( param1 ) + { + case PROMPT_FORMAT_SUCCESS_GC: + case PROMPT_FORMAT_SUCCESS_PS2: + case PROMPT_FORMAT_SUCCESS_XBOX: // format ok + this->OnContinue(); + break; + + case PROMPT_FORMAT_FAIL_GC: + case PROMPT_FORMAT_FAIL_PS2: + case PROMPT_FORMAT_FAIL_XBOX: // format fail + this->ReloadScreen(); // user has to retry + + GetMemoryCardManager()->ClearCurrentDrive(); + break; + case PROMPT_FORMAT_CONFIRM2_GC: + case PROMPT_FORMAT_CONFIRM2_PS2: + case PROMPT_FORMAT_CONFIRM2_XBOX: // really format + if (param2==CGuiMenuPrompt::RESPONSE_YES) + { + m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this); + m_formatState = true; + m_elapsedFormatTime = 0; + m_formatDone = false; + GetMemoryCardManager()->FormatDrive(CGuiScreenMemoryCard::s_currentMemoryCardSlot, this); + } + else + { + this->ReloadScreen(); // user has to retry + GetMemoryCardManager()->ClearCurrentDrive(); + } + break; + + default: + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + case (CGuiMenuPrompt::RESPONSE_CONTINUE): + case (CGuiMenuPrompt::RESPONSE_CONTINUE_WITHOUT_SAVE): + { + /* + if( GetMemoryCardManager()->GetMemcardCheckingState() != MemoryCardManager::MEMCARD_CHECKING_DONE ) + { + rAssert( m_messageText ); + #ifdef RAD_GAMECUBE + m_messageText->SetIndex( CHECKING_MEMCARD_B_GC ); + #endif + #ifdef RAD_PS2 + m_messageText->SetIndex( CHECKING_MEMCARD_2_PS2 ); + #endif + this->ReloadScreen(); + } + else + */ + this->OnContinue(); + + break; + } + case (CGuiMenuPrompt::RESPONSE_NO): + case (CGuiMenuPrompt::RESPONSE_RETRY): + { + /* + GetMemoryCardManager()->ResetMemoryCardCheck(); + + rAssert( m_messageText ); + #ifdef RAD_GAMECUBE + m_messageText->SetIndex( CHECKING_MEMCARDS_GC ); + #endif + #ifdef RAD_PS2 + m_messageText->SetIndex( CHECKING_MEMCARDS_PS2 ); + #endif + */ + this->ReloadScreen(); + + break; + } + case (CGuiMenuPrompt::RESPONSE_FORMAT_GC): + case (CGuiMenuPrompt::RESPONSE_FORMAT_XBOX): + case (CGuiMenuPrompt::RESPONSE_FORMAT_PS2): + { + m_StatusPromptShown = false; + m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this); + break; + } + case (CGuiMenuPrompt::RESPONSE_MANAGE_MEMCARDS): + { + #ifdef RAD_GAMECUBE + GCManager::GetInstance()->Reset(); + GCManager::GetInstance()->PerformReset( true, true ); + #else + IRadMemoryAllocator* allocator = GetAllocator( GMA_PERSISTENT ); + IRadMemoryHeap* staticHeap = dynamic_cast< IRadMemoryHeap* >( allocator ); + staticHeap->AllowFreeing( true ); + GetGame()->GetPlatform()->LaunchDashboard(); + #endif + + break; + } + default: + { + break; + } + } + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + GetMemoryCardManager()->UpdateMemoryCardCheck( param1 ); + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} +void +CGuiScreenMemCardCheck::OnFormatOperationComplete( radFileError errorCode ) +{ + if (m_formatDone != true) // check if we already received an error or not + m_formatResult = errorCode; + m_formatDone = true; +} + +void +CGuiScreenMemCardCheck::OnMemoryCardCheckDone( radFileError errorCode, + IRadDrive::MediaInfo::MediaState mediaState, + int driveIndex, + int mostRecentSaveGameDriveIndex, + int mostRecentSaveGameSlot ) +{ +#ifdef RAD_WIN32 + GetMemoryCardManager()->SetCurrentDrive( static_cast<unsigned int>( 0 ) ); +#endif + +#ifdef ENABLE_AUTOLOAD_AFTER_MEMCHECK + if( mostRecentSaveGameSlot != -1 ) + { + CGuiScreenMemoryCard::s_currentMemoryCardSlot = mostRecentSaveGameDriveIndex; + GetMemoryCardManager()->SetCurrentDrive( static_cast<unsigned int>( mostRecentSaveGameDriveIndex ) ); + + CGuiScreenAutoLoad::SetGameSlot( mostRecentSaveGameSlot ); + + m_isAutoLoadPending = true; + } +#endif + + if( errorCode == Success && mediaState == IRadDrive::MediaInfo::MediaPresent ) + { + this->OnContinue(); + } + else + { + CGuiScreenMemoryCard::s_currentMemoryCardSlot = driveIndex; + + m_StatusPromptShown = true; + + int errorMessage = -1; + if( mediaState != IRadDrive::MediaInfo::MediaPresent ) + { + errorMessage = GetErrorMessageIndex( mediaState ); + } + else if( errorCode != Success ) + { + errorMessage = GetErrorMessageIndex( errorCode, ERROR_DURING_CHECKING ); + } + + int format_response = 0; + + // TC: (PS2 TRC) formatting should NOT be offered to the user during the + // boot-up check, but only during save contexts + // +#ifndef RAD_PS2 + if (mediaState==IRadDrive::MediaInfo::MediaNotFormatted) + format_response = ERROR_RESPONSE_FORMAT; +#endif + +#ifdef RAD_GAMECUBE + if( mediaState == IRadDrive::MediaInfo::MediaEncodingErr ) + { + format_response = ERROR_RESPONSE_FORMAT; + } +#endif + + rAssert( errorMessage != -1 ); + +#ifdef RAD_GAMECUBE + int manage_response = ERROR_RESPONSE_MANAGE; + + if (mediaState == IRadDrive::MediaInfo::MediaNotPresent + || mediaState == IRadDrive::MediaInfo::MediaInvalid + || mediaState == IRadDrive::MediaInfo::MediaDamaged) + manage_response = 0; // no manage when no memory card + if (format_response) + manage_response = 0; // don't show both format and manage + m_guiManager->DisplayErrorPrompt( errorMessage, this, + format_response | manage_response | ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY ); +#endif // RAD_GAMECUBE + +#ifdef RAD_PS2 + // add retry if card full, or no card + if( errorCode == NoFreeSpace || mediaState == IRadDrive::MediaInfo::MediaNotPresent) + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY ); + } + else + { + if (format_response) + { // detect unplugged if we are asking for format + m_StatusPromptShown = false; + } + m_guiManager->DisplayErrorPrompt( errorMessage, this, format_response | ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY); + } +#endif // RAD_PS2 + +#ifdef RAD_XBOX + m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE ); +#endif // RAD_XBOX + +#ifdef RAD_WIN32 //parallel the xbox for now. + m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE ); +#endif // RAD_WIN32 + } +} + +//=========================================================================== +// CGuiScreenMemCardCheck::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemCardCheck::InitIntro() +{ + if( m_firstTimeEntered ) + { + GetMemoryCardManager()->LoadMemcardInfo(); + } + m_StatusPromptShown = false; +} + + +//=========================================================================== +// CGuiScreenMemCardCheck::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemCardCheck::InitRunning() +{ + GetMemoryCardManager()->StartMemoryCardCheck( this ); +} + + +//=========================================================================== +// CGuiScreenMemCardCheck::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemCardCheck::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMemCardCheck::OnContinue() +{ + GetMemoryCardManager()->UnloadMemcardInfo(); + +#ifdef RAD_PS2 + bool isCurrentDriveReady = true; +#else + bool isCurrentDriveReady = GetMemoryCardManager()->IsCurrentDriveReady( true ); +#endif + + if( m_isAutoLoadPending && isCurrentDriveReady ) + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_AUTO_LOAD, CLEAR_WINDOW_HISTORY ); + } + else + { + m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED ); + } + + m_isAutoLoadPending = false; +} + diff --git a/game/code/presentation/gui/guiscreenmemcardcheck.h b/game/code/presentation/gui/guiscreenmemcardcheck.h new file mode 100644 index 0000000..4183829 --- /dev/null +++ b/game/code/presentation/gui/guiscreenmemcardcheck.h @@ -0,0 +1,74 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMemCardCheck +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/23 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMEMCARDCHECK_H +#define GUISCREENMEMCARDCHECK_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <data/memcard/memorycardmanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMemCardCheck : public CGuiScreen, + public IMemoryCardCheckCallback, + public IMemoryCardFormatCallback +{ +public: + CGuiScreenMemCardCheck( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMemCardCheck(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual void OnMemoryCardCheckDone( radFileError errorCode, + IRadDrive::MediaInfo::MediaState mediaState, + int driveIndex, + int mostRecentSaveGameDriveIndex, + int mostRecentSaveGameSlot ); + + // Implements IMemoryCardFormatCallback + // + virtual void OnFormatOperationComplete(radFileError err); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void OnContinue(); + + Scrooby::Text* m_messageText; + + unsigned int m_minimumFormatTime; + unsigned int m_elapsedFormatTime; + radFileError m_formatResult; + bool m_formatState : 1; + bool m_formatDone : 1; + bool m_StatusPromptShown : 1; + bool m_isAutoLoadPending : 1; + +}; + +#endif // GUISCREENMEMCARDCHECK_H diff --git a/game/code/presentation/gui/guiscreenmemorycard.cpp b/game/code/presentation/gui/guiscreenmemorycard.cpp new file mode 100644 index 0000000..fe85922 --- /dev/null +++ b/game/code/presentation/gui/guiscreenmemorycard.cpp @@ -0,0 +1,920 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMemoryCard +// +// Description: Implementation of the CGuiScreenMemoryCard class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guiscreenmemorycard.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guimanager.h> + +#include <data/gamedatamanager.h> +#include <data/memcard/memorycardmanager.h> +#include <events/eventmanager.h> +#include <gameflow/gameflow.h> +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation +#include <layer.h> +#include <group.h> +#include <page.h> +#include <screen.h> +#include <strings/unicodestring.h> +#include <text.h> +#ifdef RAD_PS2 +#include <libmtap.h> +#endif + +const tColour DEFAULT_DISABLED_ITEM_COLOUR_GREY( 128, 128, 128 ); // the same as in guimenu.cpp + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +enum eMemoryCardMenuItem +{ + MENU_ITEM_MEMORY_DEVICE, + + NUM_MEMORY_CARD_MENU_ITEMS +}; + +bool CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = false; + +int CGuiScreenMemoryCard::s_currentMemoryCardSlot = 0; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +CGuiScreenLoadSave::CGuiScreenLoadSave( Scrooby::Screen* pScreen ) +: m_currentSlot( -1 ), + m_lastError( Success ), + m_currentMemoryDevice( NULL ), + m_currentDriveIndex( -1 ), + m_minimumFormatTime(1000), + m_formatState(false), + m_operation( SCREEN_OP_IDLE ) +{ + rAssert( pScreen != NULL ); +#ifdef RAD_WIN32 + Scrooby::Page* pPage = pScreen->GetPage( "GameSlots" ); + if( pPage != NULL ) + { + Scrooby::Text* pText = pPage->GetText( "LoadSaveMessage" ); + if( pText != NULL ) + { + pText->SetTextMode( Scrooby::TEXT_WRAP ); + } + } +#else + Scrooby::Page* pPage = pScreen->GetPage( "SelectMemoryDevice" ); + if( pPage != NULL ) + { + Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" ); + Scrooby::Text* pText = foreground->GetText( "LoadSave" ); + if( pText != NULL ) + { + pText->SetTextMode( Scrooby::TEXT_WRAP ); + } + + m_currentMemoryDevice = foreground->GetText( "CurrentMemoryDevice" ); + rAssert( m_currentMemoryDevice != NULL ); + m_currentMemoryDevice->SetTextMode( Scrooby::TEXT_WRAP ); + + // set platform-specific text + // + Scrooby::Group* selectMemoryDevice = foreground->GetGroup( "SelectMemoryDevice" ); + rAssert( selectMemoryDevice != NULL ); + +#ifdef RAD_XBOX + selectMemoryDevice->SetVisible( false ); +#endif + + pText = selectMemoryDevice->GetText( "SelectMemoryDevice" ); + if( pText != NULL ) + { + pText->SetIndex( PLATFORM_TEXT_INDEX ); + + // and apply wrapping + // + pText->SetTextMode( Scrooby::TEXT_WRAP ); + } + } +#endif +} + +CGuiScreenLoadSave::~CGuiScreenLoadSave() +{ +} + +void +CGuiScreenLoadSave::HandleMessage( eGuiMessage message, + unsigned int param1, + unsigned int param2 ) +{ + switch( message ) + { + case GUI_MSG_UPDATE: + { + GetMemoryCardManager()->Update( param1 ); + + if( !GetMemoryCardManager()->IsCurrentDriveReady() ) + { + this->GotoMemoryCardScreen(); + + return; + } + + break; + } + case GUI_MSG_CONTROLLER_AUX_X: + { +#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 ) + this->GotoMemoryCardScreen(); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); +#endif + + break; + } + default: + { + break; + } + } +} +void +CGuiScreenLoadSave::FormatCurrentDrive() +{ + m_formatState = true; + m_elapsedFormatTime = 0; + int currentDrive = GetMemoryCardManager()->GetCurrentDriveIndex(); + m_formatDone = false; + GetMemoryCardManager()->FormatDrive(currentDrive, this); +} + +void +CGuiScreenLoadSave::OnFormatOperationComplete( radFileError errorCode ) +{ + if (m_formatDone != true) // check if we already received an error or not + m_formatResult = errorCode; + m_formatDone = true; +} + +void +CGuiScreenLoadSave::UpdateCurrentMemoryDevice() +{ +#ifndef RAD_WIN32 + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + if( currentDrive != NULL ) + { + char textBibleEntry[ 32 ]; +#ifdef RAD_GAMECUBE + sprintf( textBibleEntry, "GC_%s", currentDrive->GetDriveName() ); +#endif +#ifdef RAD_PS2 + sprintf( textBibleEntry, "PS2_MEMCARD1A:" ); +#endif +#ifdef RAD_XBOX + sprintf( textBibleEntry, "XBOX_%s", currentDrive->GetDriveName() ); +#endif + + HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD ); + + UnicodeString deviceName; + deviceName.ReadUnicode( GetTextBibleString( textBibleEntry ) ); + +#ifdef RAD_PS2 + int port_number = CGuiScreenMemoryCard::s_currentMemoryCardSlot/4; + if (sceMtapGetConnection(port_number)==1) { // is multitap + deviceName.Append('1' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot/4)); + deviceName.Append('-' ); + deviceName.Append('A' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot%4)); + } + else { + deviceName.Append('1' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot/4)); + } +#endif +#ifdef RAD_XBOX + const char *volname = GetMemoryCardManager()->GetCurrentDriveVolumeName(); + UnicodeString muName; + if (volname[0]!=0) + { + if (p3d::UnicodeStrLen((P3D_UNICODE*)( volname ) ) < MAX_MEM_CARD_NAME) + muName.ReadUnicode((P3D_UNICODE*) volname ); + else + { + muName.ReadUnicode((P3D_UNICODE*) volname, MAX_MEM_CARD_NAME-1); + UnicodeString ellipsis; + ellipsis.ReadAscii("..."); + muName += ellipsis; + } + deviceName.Append(' '); + deviceName.Append('('); + deviceName += muName; + deviceName.Append(')'); + } +#endif + + rAssert( m_currentMemoryDevice != NULL ); + m_currentMemoryDevice->SetString( 0, deviceName ); + + HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD); + } +#endif + + // update current drive index + // + m_currentDriveIndex = GetMemoryCardManager()->GetCurrentDriveIndex(); +} + +void +CGuiScreenLoadSave::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ) +{ +} + + +//=========================================================================== +// CGuiScreenMemoryCard::CGuiScreenMemoryCard +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMemoryCard::CGuiScreenMemoryCard +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MEMORY_CARD, + SCREEN_FX_FADE | SCREEN_FX_SLIDE_Y ), + m_layerSelectMemoryDevice( NULL ), + m_layerNoMemoryDevice( NULL ), +#ifdef RAD_XBOX + m_numFreeBlocks( NULL ), +#endif + m_pMenu( NULL ), + m_numAttachedDevices( -1 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "MemoryCard" ); + rAssert( pPage ); + + m_layerSelectMemoryDevice = pPage->GetGroup( "SelectMemoryDevice" ); + rAssert( m_layerSelectMemoryDevice ); + m_layerSelectMemoryDevice->SetVisible( false ); + + m_layerNoMemoryDevice = pPage->GetGroup( "NoMemoryDevice" ); + rAssert( m_layerNoMemoryDevice ); + m_layerNoMemoryDevice->SetVisible( false ); + + m_memStatusText = pPage->GetText("Status"); + rAssert(m_memStatusText); + + m_memStatusText->SetTextMode( Scrooby::TEXT_WRAP ); + +#ifdef RAD_XBOX + Scrooby::Group* freeSpace = pPage->GetGroup( "FreeSpace" ); + rAssert( freeSpace != NULL ); + m_numFreeBlocks = freeSpace->GetText( "NumFreeBlocks" ); +#else + // hide free space display for non-Xbox platforms + // + Scrooby::Group* freeSpace = pPage->GetGroup( "FreeSpace" ); + rAssert( freeSpace != NULL ); + freeSpace->SetVisible( false ); +#endif + + // set platform-specific text + // + Scrooby::Text* pText = m_layerSelectMemoryDevice->GetText( "SelectMemoryDevice" ); + if( pText != NULL ) + { + pText->SetIndex( PLATFORM_TEXT_INDEX ); + + // and apply wrapping + // + pText->SetTextMode( Scrooby::TEXT_WRAP ); + } + + pText = m_layerNoMemoryDevice->GetText( "NoMemoryDevice" ); + if( pText != NULL ) + { + pText->SetIndex( PLATFORM_TEXT_INDEX ); + + // and apply wrapping + // + pText->SetTextMode( Scrooby::TEXT_WRAP ); + } + + pText = m_layerSelectMemoryDevice->GetText( "MemoryDevice" ); + if( pText != NULL ) + { + pText->SetTextMode( Scrooby::TEXT_WRAP ); + } + + // Create a menu. + // + m_pMenu = new CGuiMenu( this, NUM_MEMORY_CARD_MENU_ITEMS, GUI_TEXT_MENU, MENU_SFX_NONE ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + Scrooby::Group* selectMemoryDevice = pPage->GetGroup( "SelectMemoryDevice" ); + m_pMenu->AddMenuItem( selectMemoryDevice->GetText( "SelectMemoryDevice" ), + selectMemoryDevice->GetText( "MemoryDevice" ), + NULL, + NULL, + selectMemoryDevice->GetSprite( "LArrow" ), + selectMemoryDevice->GetSprite( "RArrow" ) ); + + Scrooby::Text * selectDeviceText = selectMemoryDevice->GetText( "SelectMemoryDevice" ); + selectDeviceText->SetTextMode( Scrooby::TEXT_WRAP ); + + this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) ); +#ifdef RAD_XBOX + for(int j = 0; j < radFileDriveMax; j++ ) + { + m_driveMountedFlag[j] = NULL; + } +#endif +} + + +//=========================================================================== +// CGuiScreenMemoryCard::~CGuiScreenMemoryCard +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMemoryCard::~CGuiScreenMemoryCard() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenMemoryCard::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemoryCard::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if ( message==GUI_MSG_PROMPT_START_RESPONSE ) + { + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + } + else if( m_state == GUI_WINDOW_STATE_RUNNING || message == GUI_MSG_MENU_PROMPT_RESPONSE) + { + switch( message ) + { + #ifdef RAD_PS2 + case GUI_MSG_CONTROLLER_START: + { + if ( GetGameFlow()->GetCurrentContext() == CONTEXT_PAUSE ) + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } + #endif + case GUI_MSG_UPDATE: + { + GetMemoryCardManager()->Update( param1 ); + + this->UpdateDeviceList(); + + break; + } + + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + rAssert( param1 == MENU_ITEM_MEMORY_DEVICE ); + + this->UpdateFreeSpace( param2 ); + + break; + } + + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( param1 == MENU_ITEM_MEMORY_DEVICE ); + + int selectedDevice = m_pMenu->GetSelectionValue( MENU_ITEM_MEMORY_DEVICE ); + +#ifdef RAD_XBOX + // check if user selected full xbox hd + if ( selectedDevice==0 + && !GetMemoryCardManager()->EnoughFreeSpace( 0 ) + && !GetGameDataManager()->DoesSaveGameExist(m_availableDrives[ 0 ], false) ) + { + m_guiManager->DisplayPrompt(PROMPT_HD_FULL_XBOX, this, PROMPT_TYPE_CONTINUE); + + break; + } +#endif + GetMemoryCardManager()->SetCurrentDrive( m_availableDrives[ selectedDevice ] ); + + s_currentMemoryCardSlot = GetMemoryCardManager()->GetCurrentDriveIndex(); + + CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = false; + + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + if( !GetMemoryCardManager()->IsCurrentDriveReady( true ) || + CGuiScreenLoadSave::s_forceGotoMemoryCardScreen ) + { + if( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ) + { + this->StartTransitionAnimation( 230, 260 ); + } + + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN, 1 ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); + } + + break; + } + case GUI_MSG_MENU_PROMPT_RESPONSE: + { + ReloadScreen(); + break; + } + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMemoryCard::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemoryCard::InitIntro() +{ + + + this->UpdateDeviceList( true ); + + // set selection to current device, if still attached + // + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + if( currentDrive != NULL ) + { + if( GetMemoryCardManager()->IsCurrentDriveReady( true ) ) + { + for( int i = 0; i < m_numAttachedDevices; i++ ) + { + if( m_availableDrives[ i ] == currentDrive ) + { + rAssert( m_pMenu ); + m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, i ); + + break; + } + } + } + } + this->UpdateFreeSpace( m_pMenu->GetSelectionValue( MENU_ITEM_MEMORY_DEVICE ) ); +} + + +//=========================================================================== +// CGuiScreenMemoryCard::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemoryCard::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenMemoryCard::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMemoryCard::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMemoryCard::UpdateDeviceList( bool forceUpdate ) +{ + IRadDrive* currentSelectedDrive = NULL; + +#ifdef RAD_XBOX + IRadDrive *driveMountedFlag[radFileDriveMax]; + int numAvailableDrives = GetMemoryCardManager()->GetAvailableDrives( m_availableDrives, + m_mediaInfos, + driveMountedFlag); +#else + if( m_numAttachedDevices > 0 ) + { + currentSelectedDrive = m_availableDrives[ m_pMenu->GetSelectionValue( MENU_ITEM_MEMORY_DEVICE ) ]; + } + + int numAvailableDrives = GetMemoryCardManager()->GetAvailableDrives( m_availableDrives, + m_mediaInfos); +#endif + + bool hasMoreDrive = false; + bool memoryDevicesAvailable = (numAvailableDrives > 0); + +// this->SetButtonVisible( BUTTON_ICON_BACK, !memoryDevicesAvailable ); + + if( numAvailableDrives == m_numAttachedDevices && + !forceUpdate ) + { + // since number of attached memory devices remain the same, + // assume no other changes occurred since last poll + // + return; + } + else + { + if (numAvailableDrives > m_numAttachedDevices) + hasMoreDrive = true; + // update number of attached memory devices + // + m_numAttachedDevices = numAvailableDrives; + } + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, memoryDevicesAvailable ); + + for( int i = 0; i < numAvailableDrives; i++ ) + { + rAssert( m_availableDrives[ i ] ); + rAssert( m_mediaInfos[ i ] ); + + char textBibleEntry[ 32 ]; +#ifdef RAD_GAMECUBE + sprintf( textBibleEntry, "GC_%s", m_availableDrives[ i ]->GetDriveName() ); +#endif +#ifdef RAD_PS2 + sprintf( textBibleEntry, "PS2_MEMCARD1A:" ); +#endif +#ifdef RAD_XBOX + sprintf( textBibleEntry, "XBOX_%s", m_availableDrives[ i ]->GetDriveName() ); +#endif +#ifdef RAD_WIN32 + sprintf( textBibleEntry, "XBOX_U:" ); // Temp. +#endif + + HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD ); + + UnicodeString deviceName; + deviceName.ReadUnicode( GetTextBibleString( textBibleEntry ) ); + +#ifdef RAD_PS2 + int drive_index = GetMemoryCardManager()->GetDriveIndex(m_availableDrives[ i ]); + int port_number = drive_index/4; + if (sceMtapGetConnection(port_number)==1) { // is multitap + deviceName.Append('1' + (drive_index/4)); + deviceName.Append('-' ); + deviceName.Append('A' + (drive_index%4)); + } + else { + deviceName.Append('1' + drive_index/4); + } +#endif + +#ifdef RAD_XBOX + if (i > 0 && m_mediaInfos[ i ]->m_VolumeName[0]!=0) // i==0 is the hard disk + { + UnicodeString muName; + if (p3d::UnicodeStrLen((P3D_UNICODE*)( m_mediaInfos[ i ]->m_VolumeName) ) < MAX_MEM_CARD_NAME) + muName.ReadUnicode((P3D_UNICODE*) m_mediaInfos[ i ]->m_VolumeName); + else + { + muName.ReadUnicode((P3D_UNICODE*) m_mediaInfos[ i ]->m_VolumeName, MAX_MEM_CARD_NAME-1); + UnicodeString ellipsis; + ellipsis.ReadAscii("..."); + muName += ellipsis; + } + deviceName.Append(' '); + deviceName.Append('('); + deviceName += muName; + deviceName.Append(')'); + + + } +#endif + + + + + Scrooby::Text* memoryDeviceText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->GetItemValue() ); + rAssert( memoryDeviceText != NULL ); + memoryDeviceText->SetString( i, deviceName ); + + HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD); + + } + + m_layerSelectMemoryDevice->SetVisible( memoryDevicesAvailable ); + m_layerNoMemoryDevice->SetVisible( !memoryDevicesAvailable ); + + rAssert( m_pMenu ); + if( memoryDevicesAvailable ) + { + m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes |= SELECTABLE; + } + else + { + m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes &= ~SELECTABLE; + m_pMenu->SetSelectionValueCount( MENU_ITEM_MEMORY_DEVICE, 1 ); // to disable left/right scrolling + } +// m_pMenu->SetMenuItemEnabled( MENU_ITEM_MEMORY_DEVICE, memoryDevicesAvailable ); + + if( memoryDevicesAvailable ) + { + m_pMenu->SetSelectionValueCount( MENU_ITEM_MEMORY_DEVICE, numAvailableDrives ); + + m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, 0 ); + +#ifndef RAD_XBOX + for( int i = 0; i < m_numAttachedDevices; i++ ) + { + if( m_availableDrives[ i ] == currentSelectedDrive ) + { + m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, i ); + + break; + } + } +#endif + } +#ifdef RAD_XBOX + int j; + if (hasMoreDrive) // find which drive is new and select it + { + for(j = 0; j < radFileDriveMax; j++ ) + { + if (driveMountedFlag[j] && m_driveMountedFlag[j]==NULL) + { + for (int x = 0; x < numAvailableDrives; x++) + { + if (m_availableDrives[x] == driveMountedFlag[j]) + { + m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, x ); + break; + } + } + break; + } + } + rAssert(j<radFileDriveMax); // we must find the different drive + } + + for(j = 0; j < radFileDriveMax; j++ ) + { + m_driveMountedFlag[j] = driveMountedFlag[j]; + } +#endif +} + +void +CGuiScreenMemoryCard::UpdateFreeSpace( unsigned int currentDriveIndex ) +{ + Scrooby::BoundedDrawable* menu_drawable + = m_pMenu->GetMenuItem(MENU_ITEM_MEMORY_DEVICE)->GetItemValue(); + + menu_drawable->SetColour(m_pMenu->GetHighlightColour()); + + m_memStatusText->SetVisible(false); + + // enable selection + // + if( m_numAttachedDevices > 0 ) + { + m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes |= SELECTABLE; + SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + } + + HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD ); + +#ifdef RAD_XBOX + if( static_cast<int>( currentDriveIndex ) < m_numAttachedDevices ) + { + const unsigned int MAX_NUM_FREE_BLOCKS = 50000; + unsigned int numFreeBlocks = m_mediaInfos[ currentDriveIndex ]->m_FreeSpace / + NUM_BYTES_PER_BLOCK; + + char buffer[ 16 ]; + if( numFreeBlocks > MAX_NUM_FREE_BLOCKS ) + { + sprintf( buffer, "50,000+" ); + } + else + { + if( numFreeBlocks < 1000 ) + { + sprintf( buffer, "%d", numFreeBlocks ); + } + else + { + sprintf( buffer, "%d,%03d", numFreeBlocks / 1000, numFreeBlocks % 1000 ); + } + } + + rAssert( m_numFreeBlocks != NULL ); + m_numFreeBlocks->SetString( 0, buffer ); + + m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes |= SELECTABLE; + SetButtonVisible(BUTTON_ICON_ACCEPT , true); + } +#endif // RAD_XBOX + + if (((int)currentDriveIndex < m_numAttachedDevices) && m_mediaInfos[ currentDriveIndex ]->m_MediaState != IRadDrive::MediaInfo::MediaPresent) + { + m_memStatusText->SetVisible(true); + m_memStatusText->SetIndex( + (m_mediaInfos[ currentDriveIndex ]->m_MediaState - IRadDrive::MediaInfo::MediaNotFormatted) * 3 + + PLATFORM_TEXT_INDEX); + bool disable = true; + +#ifdef RAD_GAMECUBE + // on GameCube, if memory card is unformatted or formatted for another market, allow it to be + // selected so that if can be formatted + // + if( m_mediaInfos[ currentDriveIndex ]->m_MediaState == IRadDrive::MediaInfo::MediaNotFormatted || + m_mediaInfos[ currentDriveIndex ]->m_MediaState == IRadDrive::MediaInfo::MediaEncodingErr ) + { + disable = false; + + m_memStatusText->SetVisible( false ); // no need to display status text + } +#endif // RAD_GAMECUBE + +#ifdef RAD_PS2 + // on PS2, if memory card is unformatted, allow it to be selected so that it can be formatted + // + if( m_mediaInfos[ currentDriveIndex ]->m_MediaState == IRadDrive::MediaInfo::MediaNotFormatted ) + { + disable = false; + + m_memStatusText->SetVisible( false ); // no need to display status text + } +#endif // RAD_PS2 + + if (disable) + { + // disable selection + m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes &= ~SELECTABLE; + SetButtonVisible(BUTTON_ICON_ACCEPT , false); + // change color + menu_drawable->SetColour( DEFAULT_DISABLED_ITEM_COLOUR_GREY ); + } + } + else // no error + { + if ( ((int)currentDriveIndex < m_numAttachedDevices) && GetMemoryCardManager()->IsMemcardInfoLoaded() ) + { + // this drive index is different than currentDriveIndex + int memcard_driveindex = GetMemoryCardManager()->GetDriveIndex(m_availableDrives[ currentDriveIndex ]); + rTuneAssert(memcard_driveindex >= 0); + if ( GetMemoryCardManager()->EnoughFreeSpace( memcard_driveindex )==false + && GetGameDataManager()->DoesSaveGameExist(m_availableDrives[ currentDriveIndex ], false)==false ) // check for full without save game + { + int message_index = 5 * 3 + PLATFORM_TEXT_INDEX; + #ifdef RAD_XBOX + if (currentDriveIndex==0) // hd + message_index ++; + #endif + m_memStatusText->SetVisible(true); + m_memStatusText->SetIndex( message_index ); + +#ifdef RAD_GAMECUBE + // append "Use Memory Card Screen" text to message; this is done in + // code because the text bible compiler can't handle strings with + // more than 255 characters + // + UnicodeString useMemCardScreen; + useMemCardScreen.ReadUnicode( GetTextBibleString( "USE_MEMORY_CARD_SCREEN" ) ); + + UnicodeString newString; + newString.ReadUnicode( GetTextBibleString( "MU_FULL_STATUS_(GC)" ) ); + newString.Append( ' ' ); + newString += useMemCardScreen; + + m_memStatusText->SetString( message_index, newString ); +#endif // RAD_GAMECUBE + + bool disable = true; +#ifdef RAD_XBOX + if (currentDriveIndex==0) // hd + disable = false; +#endif + + if (disable) + { + // change color + menu_drawable->SetColour( DEFAULT_DISABLED_ITEM_COLOUR_GREY ); + + // disable selection + m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes &= ~SELECTABLE; + SetButtonVisible(BUTTON_ICON_ACCEPT , false); + } + + } + } + } + + HeapMgr()->PopHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD ); + +} + diff --git a/game/code/presentation/gui/guiscreenmemorycard.h b/game/code/presentation/gui/guiscreenmemorycard.h new file mode 100644 index 0000000..29c5d1a --- /dev/null +++ b/game/code/presentation/gui/guiscreenmemorycard.h @@ -0,0 +1,206 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMemoryCard +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/30 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMEMORYCARD_H +#define GUISCREENMEMORYCARD_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guiscreenmessage.h> +#include <data/memcard/memorycardmanager.h> + +#include <radfile.hpp> + +//=========================================================================== +// Forward References +//=========================================================================== + +#ifdef RAD_XBOX + const unsigned int NUM_BYTES_PER_BLOCK = 16 * 1024; +#endif + +class CGuiMenu; +struct IRadDrive; + +namespace Scrooby +{ + class Group; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLoadSave : public IMemoryCardFormatCallback +{ +public: + CGuiScreenLoadSave( Scrooby::Screen* pScreen ); + virtual ~CGuiScreenLoadSave(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + static bool s_forceGotoMemoryCardScreen; + // Implements IMemoryCardFormatCallback + // + virtual void OnFormatOperationComplete(radFileError err); + +protected: + enum ScreenOperation + { + SCREEN_OP_IDLE, + LOAD, + SAVE, + FORMAT, + DELETE_GAME, + + NUM_SCREEN_OPS + }; + + void UpdateCurrentMemoryDevice(); + virtual void GotoMemoryCardScreen( bool isFromPrompt = false ) = 0; + virtual void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ); + + void FormatCurrentDrive(); + + int m_currentSlot; + radFileError m_lastError; + + Scrooby::Text* m_currentMemoryDevice; + int m_currentDriveIndex; + + unsigned int m_minimumFormatTime; + unsigned int m_elapsedFormatTime; + radFileError m_formatResult; + bool m_formatState; + bool m_formatDone; + + + ScreenOperation m_operation; + + +}; + +class CGuiScreenMemoryCard : public CGuiScreen +{ +public: + CGuiScreenMemoryCard( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMemoryCard(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + static int s_currentMemoryCardSlot; + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void UpdateDeviceList( bool forceUpdate = false ); + void UpdateFreeSpace( unsigned int currentDriveIndex ); + + Scrooby::Group* m_layerSelectMemoryDevice; + Scrooby::Group* m_layerNoMemoryDevice; + +#ifdef RAD_XBOX + Scrooby::Text* m_numFreeBlocks; + IRadDrive *m_driveMountedFlag[radFileDriveMax]; +#endif + Scrooby::Text* m_memStatusText; + + CGuiMenu* m_pMenu; + + IRadDrive* m_availableDrives[ radFileDriveMax ]; + IRadDrive::MediaInfo* m_mediaInfos[ radFileDriveMax ]; + int m_numAttachedDevices; + + +}; + +const int NUM_RADFILE_ERROR_MESSAGES = DataCorrupt; // should be last enum +const int NUM_MEDIA_INFO_STATES = IRadDrive::MediaInfo::MediaDamaged; // should be last enum + + +const int MAX_MEM_CARD_NAME = 16; // max display for memory card + +enum eErrorMessageMode +{ + ERROR_DURING_CHECKING, + ERROR_DURING_LOADING, + ERROR_DURING_SAVING, + + NUM_ERROR_MESSAGE_MODES +}; + +inline int GetErrorMessageIndex( radFileError errorCode, eErrorMessageMode mode ) +{ + const int NUM_PLATFORMS = 3; + + // radfile error messages are offset by media info states + // + int messageIndex = NUM_MEDIA_INFO_STATES; + + switch( mode ) + { + case ERROR_DURING_CHECKING: + { + messageIndex += (errorCode - 1); + + break; + } + case ERROR_DURING_LOADING: + { + messageIndex += (errorCode - 1) + NUM_RADFILE_ERROR_MESSAGES; + + break; + } + case ERROR_DURING_SAVING: + { + messageIndex += (errorCode - 1) + NUM_RADFILE_ERROR_MESSAGES * 2; + + break; + } + default: + { + rAssertMsg( false, "ERROR: *** Invalid error message mode!" ); + break; + } + } + + // return platform-specific message index + // + return( messageIndex * NUM_PLATFORMS + PLATFORM_TEXT_INDEX ); +}; + +inline int GetErrorMessageIndex( IRadDrive::MediaInfo::MediaState mediaState ) +{ + const int NUM_PLATFORMS = 3; + + int messageIndex = mediaState - 1; + + // return platform-specific message index + // + return( messageIndex * NUM_PLATFORMS + PLATFORM_TEXT_INDEX ); +}; + +#endif // GUISCREENMEMORYCARD_H diff --git a/game/code/presentation/gui/guiscreenmessage.cpp b/game/code/presentation/gui/guiscreenmessage.cpp new file mode 100644 index 0000000..4f47623 --- /dev/null +++ b/game/code/presentation/gui/guiscreenmessage.cpp @@ -0,0 +1,629 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMessage +// +// Description: Implementation of the CGuiScreenMessage class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guiscreenmemorycard.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/ingame/guimanageringame.h> + +#include <data/memcard/memorycardmanager.h> +#include <gameflow/gameflow.h> +#include <memory/srrmemory.h> + +#include <p3d/unicode.hpp> +#include <raddebug.hpp> // Foundation +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <sprite.h> +#include <text.h> + +#ifdef RAD_PS2 +#include <libmtap.h> +#endif +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +int CGuiScreenMessage::s_ControllerDisconnectedPort = 0; + +int CGuiScreenMessage::s_messageIndex = -1; +CGuiEntity* CGuiScreenMessage::s_pMessageCallback = NULL; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMessage::CGuiScreenMessage +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMessage::CGuiScreenMessage +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_GENERIC_MESSAGE ), + m_pMenu( NULL ), + m_messageText( NULL ), + m_messageIcon( NULL ), + m_elapsedTime( 0 ) +{ + m_originalStringBuffer[ 0 ] = '\0'; + +MEMTRACK_PUSH_GROUP( "GUIScreenMessage" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Message" ); + rAssert( pPage != NULL ); + + Scrooby::Layer* pLayer = pPage->GetLayer( "Foreground" ); + rAssert( pLayer != NULL ); + + m_messageText = pLayer->GetText( "Message" ); + rAssert( m_messageText ); + + // wrap text message + // + m_messageText->SetTextMode( Scrooby::TEXT_WRAP ); + m_messageText->ResetTransformation(); + m_messageText->ScaleAboutCenter(0.9f); + + // Retrieve the Scrooby drawing elements (from MessageBox page). + // + pPage = m_pScroobyScreen->GetPage( "MessageBox" ); + rAssert( pPage != NULL ); + + m_messageIcon = pPage->GetSprite( "ErrorIcon" ); + + this->AutoScaleFrame( pPage ); + + this->SetFadeTime( 0.0f ); +MEMTRACK_POP_GROUP( "GUIScreenMessage" ); +} + + +//=========================================================================== +// CGuiScreenMessage::~CGuiScreenMessage +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMessage::~CGuiScreenMessage() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenMessage::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMessage::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + m_elapsedTime += param1; + + // pulse message icon + // + float scale = GuiSFX::Pulse( (float)m_elapsedTime, + 500.0f, + 1.0f * MESSAGE_ICON_CORRECTION_SCALE, + 0.1f * MESSAGE_ICON_CORRECTION_SCALE ); + + rAssert( m_messageIcon ); + m_messageIcon->ResetTransformation(); + m_messageIcon->ScaleAboutCenter( scale ); + + if( s_pMessageCallback != NULL ) + { + s_pMessageCallback->HandleMessage( GUI_MSG_MESSAGE_UPDATE, param1 ); + } + + break; + } + + case GUI_MSG_CONTROLLER_BACK: + { + // ignore BACK inputs, thereby, not allowing users to back + // out of prompt + return; + + break; + } +/* + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( s_pMessageCallback ); + s_pMessageCallback->HandleMessage( GUI_MSG_MENU_MESSAGE_RESPONSE, + param1, param2 ); + + break; + } +*/ + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + if( m_numTransitionsPending < 0 ) + { + // restore original string buffer + // + if( m_originalStringBuffer[ 0 ] != '\0' ) + { + rAssert( m_messageText != NULL ); + UnicodeChar* stringBuffer = m_messageText->GetStringBuffer(); + rAssert( stringBuffer != NULL ); + + p3d::UnicodeStrCpy( static_cast<P3D_UNICODE*>( m_originalStringBuffer ), + static_cast<P3D_UNICODE*>( stringBuffer ), + sizeof( m_originalStringBuffer ) ); + + m_originalStringBuffer[ 0 ] = '\0'; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +void +CGuiScreenMessage::Display( int messageIndex, CGuiEntity* pCallback ) +{ + s_messageIndex = messageIndex; + s_pMessageCallback = pCallback; +} +void +CGuiScreenMessage::GetControllerDisconnectedMessage(int controller_id, char *str_buffer, int max_char) +{ + P3D_UNICODE* multitapString = NULL; + + s_ControllerDisconnectedPort = controller_id; + +#ifdef RAD_GAMECUBE + P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(GC)" ); +#endif + +#ifdef RAD_XBOX + P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(XBOX)" ); +#endif + +#ifdef RAD_PS2 + P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(PS2)" ); + if (s_ControllerDisconnectedPort > 7) + uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_WHEEL" ); // usb + int port = controller_id/4; + if ( controller_id < 8 && + GetInputManager()->GetLastMultitapStatus( port ) != 0 && + sceMtapGetConnection( port ) == 0 ) + { + uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_MULTITAP" ); // multitap + + // convert the first controller port wildcard character to either 1 or 2 + // + const UnicodeChar CONTROLLER_PORT_WILDCARD_CHARACTER = 0xa5; + + HeapMgr()->PushHeap( GMA_TEMP ); + + multitapString = new P3D_UNICODE[ max_char + 1 ]; + rAssert( multitapString != NULL ); + p3d::UnicodeStrCpy( uni_string, multitapString, max_char ); + for( int i = 0; multitapString[ i ] != '\0'; i++ ) + { + if( multitapString[ i ] == CONTROLLER_PORT_WILDCARD_CHARACTER ) + { + // found it! + // + multitapString[ i ] = '1' + port; + break; + } + } + + uni_string = multitapString; + + HeapMgr()->PopHeap( GMA_TEMP ); + } +#endif + +#ifdef RAD_WIN32 + P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(XBOX)" ); +#endif + + CGuiScreenMessage::ConvertUnicodeToChar(str_buffer, uni_string, max_char); + + if( multitapString != NULL ) + { + delete multitapString; + multitapString = NULL; + } +} +void +CGuiScreenMessage::ConvertUnicodeToChar(char *str, P3D_UNICODE* uni_str, int max_char) +{ + const UnicodeChar CONTROLLER_PORT_WILDCARD_CHARACTER = 0xa5;// since > 0x7f, '¥' wont work; + const UnicodeChar NEWLINE_CHARACTER = 0x5c; //'\'; + int i = 0; + while (*uni_str && i < max_char) + { + if (*uni_str==NEWLINE_CHARACTER) + *str = '\n'; + else if (*uni_str==CONTROLLER_PORT_WILDCARD_CHARACTER) + { +#ifdef RAD_PS2 + int port_number = s_ControllerDisconnectedPort/4; + if (sceMtapGetConnection(port_number)==1 + || GetInputManager()->GetLastMultitapStatus(port_number) == 1) { // is multitap + + UnicodeString unicodeString; // splice the mu name inside + UnicodeString restofString; + UnicodeString deviceName; + + *str++ = '1' + (s_ControllerDisconnectedPort/4); + i++; + if (i >= max_char) break; + *str++ = '-'; + i++; + if (i >= max_char) break; + *str = 'A' + (s_ControllerDisconnectedPort%4); + } + else // no multitap + { + *str = '1' + (s_ControllerDisconnectedPort/4); + if (s_ControllerDisconnectedPort==8) + *str = '1'; + else if (s_ControllerDisconnectedPort==9) + *str = '2'; + } + +#else + *str = '1' + s_ControllerDisconnectedPort; +#endif + } + else + *str = (char)*uni_str; + + + i++; + str++; + uni_str++; + } + *str++ = 0; +} +void +CGuiScreenMessage::FormatMessage( Scrooby::Text* pText, + UnicodeChar* originalStringBuffer, + int stringBufferLength ) +{ + const UnicodeChar SLOT_WILDCARD_CHARACTER = '$'; + const UnicodeChar BLOCKS_WILDCARD_CHARACTER = '#'; + const UnicodeChar CONTROLLER_PORT_WILDCARD_CHARACTER = 0xa5;// since > 0x7f, '¥' wont work; + + rAssert( pText != NULL ); + UnicodeChar* stringBuffer = pText->GetStringBuffer(); + rAssert( stringBuffer != NULL ); + + // save copy of original string buffer + // + if( originalStringBuffer != NULL ) + { + p3d::UnicodeStrCpy( static_cast<P3D_UNICODE*>( stringBuffer ), + static_cast<P3D_UNICODE*>( originalStringBuffer ), + stringBufferLength ); + } + + for( int i = 0; stringBuffer[ i ] != '\0'; i++ ) + { + // search for slot wildcard character + // + if( stringBuffer[ i ] == CONTROLLER_PORT_WILDCARD_CHARACTER ) + { +#ifdef RAD_PS2 + int port_number = s_ControllerDisconnectedPort/4; + if (sceMtapGetConnection(port_number)==1) { // is multitap + HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD ); + + UnicodeString unicodeString; // splice the mu name inside + UnicodeString restofString; + UnicodeString deviceName; + + deviceName.Append('1' + (s_ControllerDisconnectedPort/4)); + deviceName.Append('-' ); + deviceName.Append('A' + (s_ControllerDisconnectedPort%4)); + + unicodeString.ReadUnicode(stringBuffer, i); + restofString.ReadUnicode(&stringBuffer[i+1]); + unicodeString += deviceName; + unicodeString += restofString; + pText->SetString(pText->GetIndex(),unicodeString); + + HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD); + } + else // no multitap + stringBuffer[ i ] = '1' + (s_ControllerDisconnectedPort/4); + +#else + stringBuffer[ i ] = '1' + s_ControllerDisconnectedPort; +#endif + break; + } + } +// update slot wild card character--------------------- + +#ifdef RAD_GAMECUBE + for( int i = 0; stringBuffer[ i ] != '\0'; i++ ) + { + // search for slot wildcard character + // + if( stringBuffer[ i ] == SLOT_WILDCARD_CHARACTER ) + { + stringBuffer[ i ] = 'A' + CGuiScreenMemoryCard::s_currentMemoryCardSlot; + + break; + } + } +#endif // RAD_GAMECUBE + +#ifdef RAD_PS2 + for( int i = 0; stringBuffer[ i ] != '\0'; i++ ) + { + // search for slot wildcard character + // + if( stringBuffer[ i ] == SLOT_WILDCARD_CHARACTER ) + { + int port_number = CGuiScreenMemoryCard::s_currentMemoryCardSlot/4; + if (sceMtapGetConnection(port_number)==1) { // is multitap + + HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD ); + + UnicodeString unicodeString; // splice the mu name inside + UnicodeString restofString; + UnicodeString deviceName; + + deviceName.Append('1' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot/4)); + deviceName.Append('-' ); + deviceName.Append('A' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot%4)); + + unicodeString.ReadUnicode(stringBuffer, i); + restofString.ReadUnicode(&stringBuffer[i+1]); + unicodeString += deviceName; + unicodeString += restofString; + pText->SetString(pText->GetIndex(),unicodeString); + + HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD); + } + else + { + stringBuffer[ i ] = '1' + CGuiScreenMemoryCard::s_currentMemoryCardSlot/4; + } + break; + } + + } +#endif // RAD_PS2 + +#ifdef RAD_XBOX + for( int i = 0; stringBuffer[ i ] != '\0'; i++ ) + { + // search for num blocks wildcard character + // + if( stringBuffer[ i ] == BLOCKS_WILDCARD_CHARACTER ) + { + const IRadDrive::MediaInfo* mediaInfo = GetMemoryCardManager()->GetMediaInfo( static_cast<unsigned int>( CGuiScreenMemoryCard::s_currentMemoryCardSlot ) ); + rAssert( mediaInfo != NULL ); + + unsigned int savedGameSize = GetMemoryCardManager()->GetSavedGameCreationSize( static_cast<unsigned int>( CGuiScreenMemoryCard::s_currentMemoryCardSlot ) ); + + unsigned int numBlocksRequired = (savedGameSize - mediaInfo->m_FreeSpace) / NUM_BYTES_PER_BLOCK; + rAssert( numBlocksRequired > 0 ); + rWarningMsg( numBlocksRequired < 10, "WARNING: *** Number of free blocks required is more than one digit long!" ); + + stringBuffer[ i ] = '0' + numBlocksRequired; + + break; + } + } + for( int i = 0; stringBuffer[ i ] != '\0'; i++ ) + { + // search for slot wildcard character + // + if( stringBuffer[ i ] == SLOT_WILDCARD_CHARACTER ) + { + HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD ); + UnicodeString deviceName; + + const IRadDrive::MediaInfo* mediaInfo = + GetMemoryCardManager()->GetMediaInfo( static_cast<unsigned int>( + CGuiScreenMemoryCard::s_currentMemoryCardSlot ) ); + char textBibleEntry[ 32 ]; + sprintf( textBibleEntry, "XBOX_%s", + GetMemoryCardManager()->GetDriveName( static_cast<unsigned int>( + CGuiScreenMemoryCard::s_currentMemoryCardSlot ) ) ); + deviceName.ReadUnicode( GetTextBibleString( textBibleEntry ) ); + + if (mediaInfo->m_VolumeName[0]!=0) // append personalized name + { + UnicodeString muName; + if (p3d::UnicodeStrLen((P3D_UNICODE*)( mediaInfo->m_VolumeName) ) < MAX_MEM_CARD_NAME) + muName.ReadUnicode((P3D_UNICODE*) mediaInfo->m_VolumeName); + else + { + muName.ReadUnicode((P3D_UNICODE*) mediaInfo->m_VolumeName, MAX_MEM_CARD_NAME-1); + UnicodeString ellipsis; + ellipsis.ReadAscii("..."); + muName += ellipsis; + } + deviceName.Append(' '); + deviceName.Append('('); + deviceName += muName; + deviceName.Append(')'); + } + UnicodeString unicodeString; // splice the mu name inside + UnicodeString restofString; + unicodeString.ReadUnicode(stringBuffer, i); + restofString.ReadUnicode(&stringBuffer[i+1]); + unicodeString += deviceName; + unicodeString += restofString; + + pText->SetString(pText->GetIndex(),unicodeString); + + HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ? + GMA_LEVEL_FE : GMA_LEVEL_HUD); + } + } + + +#endif // RAD_XBOX +} + +//=========================================================================== +// CGuiScreenMessage::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMessage::InitIntro() +{ + rAssert( m_messageText ); + rAssert( s_messageIndex >= 0 && + s_messageIndex < m_messageText->GetNumOfStrings() ); + + // set message text + // + m_messageText->SetIndex( s_messageIndex ); + + CGuiScreenMessage::FormatMessage( m_messageText, + m_originalStringBuffer, + sizeof( m_originalStringBuffer ) ); + + rAssert( m_messageIcon ); + m_messageIcon->ResetTransformation(); + + m_elapsedTime = 0; + +/* + // show/hide accept button depending on whether menu is visible or not + // + rAssert( s_menuGroup ); + this->SetButtonVisible( BUTTON_ICON_ACCEPT, s_menuGroup->IsVisible() ); +*/ +} + + +//=========================================================================== +// CGuiScreenMessage::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMessage::InitRunning() +{ + if( s_pMessageCallback != NULL ) + { + s_pMessageCallback->HandleMessage( GUI_MSG_ON_DISPLAY_MESSAGE ); + } +} + + +//=========================================================================== +// CGuiScreenMessage::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMessage::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/guiscreenmessage.h b/game/code/presentation/gui/guiscreenmessage.h new file mode 100644 index 0000000..dec532d --- /dev/null +++ b/game/code/presentation/gui/guiscreenmessage.h @@ -0,0 +1,114 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMessage +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/10/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMESSAGE_H +#define GUISCREENMESSAGE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +#include <strings/unicodestring.h> + +#ifdef RAD_WIN32 +const float MESSAGE_ICON_CORRECTION_SCALE = 0.875f; +#else +const float MESSAGE_ICON_CORRECTION_SCALE = 1.75f; +#endif + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMessage : public CGuiScreen +{ +public: + enum eMessageID + { + MSG_ID_CONTROLLER_DISCONNECTED_GC, + MSG_ID_CONTROLLER_DISCONNECTED_PS2, + MSG_ID_CONTROLLER_DISCONNECTED_XBOX, + MSG_ID_AUTO_LOADING_GAME_GC, + MSG_ID_AUTO_LOADING_GAME_PS2, + MSG_ID_AUTO_LOADING_GAME_XBOX, + MSG_ID_AUTO_LOADING_GAME_XBOX_HD, + MSG_ID_LOADING_GAME_GC, + MSG_ID_LOADING_GAME_PS2, + MSG_ID_LOADING_GAME_XBOX, + MSG_ID_LOADING_GAME_XBOX_HD, + MSG_ID_SAVING_GAME_GC, + MSG_ID_SAVING_GAME_PS2, + MSG_ID_SAVING_GAME_XBOX, + MSG_ID_SAVING_GAME_XBOX_HD, + MSG_ID_FORMATTING_GC, + MSG_ID_FORMATTING_PS2, + MSG_ID_FORMATTING_XBOX, + MSG_ID_DELETING_GC, + MSG_ID_DELETING_PS2, + MSG_ID_DELETING_XBOX, + MSG_ID_LOADING_MISSION, + MSG_ID_PROGRESSIVE_SCAN_TEST, +#ifdef RAD_WIN32 + MSG_ID_LOADING_GAME_PC, + MSG_ID_SAVING_GAME_PC, + MSG_ID_AUTO_LOADING_GAME_PC, +#endif + + NUM_MESSAGE_ID + }; + + CGuiScreenMessage( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMessage(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + static void Display( int messageIndex, CGuiEntity* pCallback = NULL ); + + static void FormatMessage( Scrooby::Text* pText, + UnicodeChar* originalStringBuffer = NULL, + int stringBufferLength = -1 ); + static void GetControllerDisconnectedMessage(int controllerId, char *str, int max_char); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + CGuiMenu* m_pMenu; + + Scrooby::Text* m_messageText; + static int s_messageIndex; + static CGuiEntity* s_pMessageCallback; + static int s_ControllerDisconnectedPort; + + Scrooby::Sprite* m_messageIcon; + unsigned int m_elapsedTime; + + UnicodeChar m_originalStringBuffer[ 256 ]; + static void ConvertUnicodeToChar(char *str, P3D_UNICODE* uni_str, int max_char); + +}; + +#endif // GUISCREENMESSAGE_H diff --git a/game/code/presentation/gui/guiscreenprompt.cpp b/game/code/presentation/gui/guiscreenprompt.cpp new file mode 100644 index 0000000..a85329c --- /dev/null +++ b/game/code/presentation/gui/guiscreenprompt.cpp @@ -0,0 +1,498 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPrompt +// +// Description: Implementation of the CGuiScreenPrompt class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guiscreenmemorycard.h> +#include <presentation/gui/utility/specialfx.h> + +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/mission.h> +#include <gameflow/gameflow.h> + +#include <p3d/unicode.hpp> +#include <raddebug.hpp> // Foundation +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <text.h> +#include <sprite.h> +#include <group.h> +#include <pure3dobject.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +int CGuiScreenPrompt::s_messageIndex = 0; +int CGuiScreenPrompt::s_numResponses = 0; +CGuiMenuPrompt::ePromptResponse CGuiScreenPrompt::s_responses[ CGuiMenuPrompt::MAX_NUM_RESPONSES ]; +CGuiEntity* CGuiScreenPrompt::s_pPromptCallback = NULL; +bool CGuiScreenPrompt::s_defaultToNo = true; + +const float ERROR_PROMPT_FADE_TIME = 100.0f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPrompt::CGuiScreenPrompt +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPrompt::CGuiScreenPrompt +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID windowID +) +: CGuiScreen( pScreen, pParent, windowID ), + m_pMenu( NULL ), + m_messageIcon( NULL ), + m_elapsedTime( 0 ), + m_xboxDashboardLabel( NULL ), + m_promptMessage( NULL ), + m_tvFrame( NULL ) +{ +MEMTRACK_PUSH_GROUP( "GUIScreenPrompt" ); + if( m_screenCover != NULL ) + { + m_screenCover->SetAlpha( 0.0f ); + m_screenCover = NULL; + } + + m_originalStringBuffer[ 0 ] = '\0'; + + // Create a menu. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Prompt" ); + m_pMenu = new CGuiMenuPrompt( this, pPage ); + rAssert( m_pMenu != NULL ); + + // TC: quick & dirty hack, no time to make this pretty! + // + m_pMenu->GetMenuItem( 0 )->m_defaultColour = tColour( 255, 255, 255 ); + + if( windowID == GUI_SCREEN_ID_ERROR_PROMPT ) + { + pPage = m_pScroobyScreen->GetPage( "ErrorPrompt" ); + rAssert( pPage != NULL ); + +// m_messageIcon = pPage->GetSprite( "ErrorIcon" ); +// rAssert( m_messageIcon ); + + m_xboxDashboardLabel = pPage->GetGroup( "XboxDashboard" ); + rAssert( m_xboxDashboardLabel != NULL ); + m_xboxDashboardLabel->SetVisible( false ); + + this->SetFadeTime( ERROR_PROMPT_FADE_TIME ); + +#ifdef RAD_XBOX + // wrap "Go to Xbox Dashboard" text + // + Scrooby::Group* xboxDashboard = pPage->GetGroup( "XboxDashboard" ); + rAssert( xboxDashboard != NULL ); + + Scrooby::Text* pText = xboxDashboard->GetText( "GotoDashboard" ); + if( pText != NULL ) + { + pText->SetTextMode( Scrooby::TEXT_WRAP ); + } +#endif + } + else + { + this->SetSlidingEnabled( SCREEN_FX_SLIDE_Y, true ); + + pPage = m_pScroobyScreen->GetPage( "GenericPrompt" ); + rAssert( pPage != NULL ); + } + + Scrooby::Page* messageBoxPage = m_pScroobyScreen->GetPage( "MessageBox" ); + if( messageBoxPage != NULL ) + { + this->AutoScaleFrame( messageBoxPage ); + + Scrooby::Sprite* messageIcon = messageBoxPage->GetSprite( "ErrorIcon" ); + if( messageIcon != NULL ) + { + messageIcon->ResetTransformation(); + messageIcon->ScaleAboutCenter( MESSAGE_ICON_CORRECTION_SCALE ); + } + } + + m_promptMessage = pPage->GetText( "Message" ); + rAssert( m_promptMessage ); + m_promptMessage->SetTextMode( Scrooby::TEXT_WRAP ); + m_promptMessage->ResetTransformation(); + m_promptMessage->ScaleAboutCenter(0.9f); + + + pPage = m_pScroobyScreen->GetPage( "TVFrame" ); + if( pPage != NULL ) + { + m_tvFrame = pPage->GetLayer( "TVFrame" ); + } +MEMTRACK_POP_GROUP( "GUIScreenPrompt" ); +} + + +//=========================================================================== +// CGuiScreenPrompt::~CGuiScreenPrompt +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPrompt::~CGuiScreenPrompt() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenPrompt::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPrompt::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { +#ifdef RAD_PS2 + case GUI_MSG_CONTROLLER_START: + { + if ( GetGameFlow()->GetCurrentContext() == CONTEXT_PAUSE ) + if ( s_pPromptCallback ) + s_pPromptCallback->HandleMessage( GUI_MSG_PROMPT_START_RESPONSE ); + + break; + } +#endif + case GUI_MSG_UPDATE: + { + m_elapsedTime += param1; + + // pulse message icon + // + float scale = GuiSFX::Pulse( (float)m_elapsedTime, + 500.0f, + 1.0f, + 0.1f ); + + if( m_messageIcon != NULL ) + { + m_messageIcon->ResetTransformation(); + m_messageIcon->ScaleAboutCenter( scale ); + } + + if (!m_pMenu->HasSelectionBeenMade()) + { + rAssert( s_pPromptCallback ); + s_pPromptCallback->HandleMessage( GUI_MSG_PROMPT_UPDATE, param1, param2); + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { +#ifdef RAD_XBOX + if( m_ID == GUI_SCREEN_ID_ERROR_PROMPT ) + { + // special case for going to xbox dashboard on the + // "full xbox hard disk" error message + // + rAssert( s_pPromptCallback ); + rAssert( m_promptMessage ); + s_pPromptCallback->HandleMessage( GUI_MSG_MENU_PROMPT_RESPONSE, + m_promptMessage->GetIndex(), + CGuiMenuPrompt::RESPONSE_MANAGE_MEMCARDS ); + } +#endif + // ignore BACK inputs, thereby, not allowing users to back + // out of prompt + return; + + break; + } + + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( m_pMenu ); + CGuiMenuPrompt::ePromptResponse response = m_pMenu->GetResponse( param1 ); + + rAssert( s_pPromptCallback ); + rAssert( m_promptMessage ); + enum eGuiMessage message; + if (m_ID==GUI_SCREEN_ID_GENERIC_PROMPT) + message = GUI_MSG_MENU_PROMPT_RESPONSE; + else if (m_ID==GUI_SCREEN_ID_ERROR_PROMPT) + message = GUI_MSG_ERROR_PROMPT_RESPONSE; + else + { + message = GUI_MSG_MENU_PROMPT_RESPONSE; + rTuneAssert(!"not reached"); + } + s_pPromptCallback->HandleMessage( message, + m_promptMessage->GetIndex(), + response ); + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + // TC: This is a nasty hack! GOD, please forgive me, as this is the + // easiest thing for me to do w/ just a few days left before beta. + // + if( m_ID == GUI_SCREEN_ID_GENERIC_PROMPT && s_messageIndex == PROMPT_CONFIRM_NEW_GAME ) + { + rAssert( m_p3dObject != NULL ); + + tMultiController* multiController = m_p3dObject->GetMultiController(); + if( multiController != NULL ) + { + const float NUM_FADE_OUT_FRAMES = 15.0f; + float currentFrame = multiController->GetFrame(); + float numRemainingFrames = multiController->GetNumFrames() - currentFrame; + + if( numRemainingFrames < NUM_FADE_OUT_FRAMES ) + { + // fade out TV frame + // + if( m_tvFrame != NULL ) + { + float alpha = numRemainingFrames / NUM_FADE_OUT_FRAMES; + + // decrease fade rate for low alpha values + alpha *= alpha; + + if( alpha > 0.0f && alpha < 1.0f ) + { + m_tvFrame->SetAlpha( alpha ); + } + else + { + m_tvFrame->SetAlpha( 0.0f ); + } + } + + // TC [HACK]: To prevent any clipping in homer's mouth + // in the last few frames. + // + if( numRemainingFrames < 1.0f ) + { + this->RestoreScreenCover(); + } + } + } + } + + if( m_numTransitionsPending < 0 ) + { + // restore original string buffer + // + if( m_originalStringBuffer[ 0 ] != '\0' ) + { + rAssert( m_promptMessage != NULL ); + UnicodeChar* stringBuffer = m_promptMessage->GetStringBuffer(); + rAssert( stringBuffer != NULL ); + + p3d::UnicodeStrCpy( static_cast<P3D_UNICODE*>( m_originalStringBuffer ), + static_cast<P3D_UNICODE*>( stringBuffer ), + sizeof( m_originalStringBuffer ) ); + + m_originalStringBuffer[ 0 ] = '\0'; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPrompt::Display +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPrompt::Display( int messageIndex, + CGuiEntity* pCallback, + int numResponses, + CGuiMenuPrompt::ePromptResponse* responses ) +{ + s_messageIndex = messageIndex; + s_pPromptCallback = pCallback; + s_numResponses = numResponses; + + for( int i = 0; i < numResponses; i++ ) + { + s_responses[ i ] = responses[ i ]; + } +} + + +//=========================================================================== +// CGuiScreenPrompt::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPrompt::InitIntro() +{ + rAssert( m_promptMessage ); + rAssert( s_messageIndex >= 0 && + s_messageIndex < m_promptMessage->GetNumOfStrings() ); + +#ifdef RAD_XBOX + if( m_ID == GUI_SCREEN_ID_ERROR_PROMPT ) + { + // special case for "full xbox hard disk" error message + // + bool showLabel = (s_messageIndex == GetErrorMessageIndex( NoFreeSpace, ERROR_DURING_CHECKING )); + rAssert( m_xboxDashboardLabel != NULL ); + m_xboxDashboardLabel->SetVisible( showLabel ); + } +#endif + + m_promptMessage->SetIndex( s_messageIndex ); + + CGuiScreenMessage::FormatMessage( m_promptMessage, + m_originalStringBuffer, + sizeof( m_originalStringBuffer ) ); + +// rAssert( m_messageIcon ); +// m_messageIcon->ResetTransformation(); + + rAssert( m_pMenu ); + m_pMenu->SetNumResponses( s_numResponses ); + m_pMenu->Reset(); + + for( int i = 0; i < s_numResponses; i++ ) + { + m_pMenu->SetResponse( i, s_responses[ i ] ); + + if( s_defaultToNo && s_responses[ i ] == CGuiMenuPrompt::RESPONSE_NO ) + { + // set NO as default response + // + m_pMenu->Reset( i ); + } + } + + m_elapsedTime = 0; +} + + +//=========================================================================== +// CGuiScreenPrompt::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPrompt::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenPrompt::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPrompt::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/guiscreenprompt.h b/game/code/presentation/gui/guiscreenprompt.h new file mode 100644 index 0000000..b39e485 --- /dev/null +++ b/game/code/presentation/gui/guiscreenprompt.h @@ -0,0 +1,166 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPrompt +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPROMPT_H +#define GUISCREENPROMPT_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/guimenu.h> + +#include <strings/unicodestring.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Group; +} + +enum ePromptQuestion +{ + PROMPT_CONFIRM_QUIT, + PROMPT_CONFIRM_SAVE_BEFORE_QUIT, + PROMPT_CONFIRM_RESTART, + PROMPT_CONFIRM_ABORT, + PROMPT_CONFIRM_RACE_AGAIN, + PROMPT_CONFIRM_NEW_GAME, + PROMPT_CONFIRM_START_MISSION, + PROMPT_LOAD_CONFIRM_GC, + PROMPT_LOAD_CONFIRM_PS2, + PROMPT_LOAD_CONFIRM_XBOX, + + PROMPT_SAVE_CONFIRM_GC, + PROMPT_SAVE_CONFIRM_PS2, + PROMPT_SAVE_CONFIRM_XBOX, + PROMPT_SAVE_CONFIRM_OVERWRITE_GC, + PROMPT_SAVE_CONFIRM_OVERWRITE_PS2, + PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX, + + PROMPT_LOAD_SUCCESSFUL, + PROMPT_SAVE_SUCCESSFUL, + + PROMPT_FORMAT_CONFIRM_GC, + PROMPT_FORMAT_CONFIRM_PS2, + PROMPT_FORMAT_CONFIRM_XBOX, + + PROMPT_FORMAT_CONFIRM2_GC, + PROMPT_FORMAT_CONFIRM2_PS2, + PROMPT_FORMAT_CONFIRM2_XBOX, + + PROMPT_FORMAT_SUCCESS_GC, + PROMPT_FORMAT_SUCCESS_PS2, + PROMPT_FORMAT_SUCCESS_XBOX, + + PROMPT_FORMAT_FAIL_GC, + PROMPT_FORMAT_FAIL_PS2, + PROMPT_FORMAT_FAIL_XBOX, + + PROMPT_DELETE_CORRUPT_SUCCESS_GC, + PROMPT_DELETE_CORRUPT_SUCCESS_PS2, + PROMPT_DELETE_CORRUPT_SUCCESS_XBOX, + + PROMPT_DELETE_CORRUPT_FAIL_GC, + PROMPT_DELETE_CORRUPT_FAIL_PS2, + PROMPT_DELETE_CORRUPT_FAIL_XBOX, + + PROMPT_LOAD_CARD_EMPTY_GC, + PROMPT_LOAD_CARD_EMPTY_PS2, + PROMPT_LOAD_CARD_EMPTY_XBOX, + PROMPT_LOAD_CARD_EMPTY_XBOX_HD, +#ifdef RAD_WIN32 + PROMPT_LOAD_CARD_EMPTY_PC, +#endif + + PROMPT_DISPLAY_PROGRESSIVE_SCAN, + PROMPT_DISPLAY_PROGRESSIVE_SCAN_PS2, + PROMPT_DISPLAY_PROGRESSIVE_SCAN_CONFIRM, + PROMPT_DISPLAY_PROGRESSIVE_SCAN_TEST, + + PROMPT_LOAD_DELETE_CORRUPT_GC, + PROMPT_LOAD_DELETE_CORRUPT_PS2, + PROMPT_LOAD_DELETE_CORRUPT_XBOX, + PROMPT_LOAD_DELETE_CORRUPT_XBOX_HD, + + PROMPT_HD_FULL_XBOX, +#ifdef RAD_WIN32 + PROMPT_CONFIRM_RESTOREALLDEFAULTS, + PROMPT_CONFIRM_QUIT_TO_SYSTEM, + PROMPT_CONFIRM_SAVE_BEFORE_QUITTOSYSTEM, +#endif + NUM_PROMPT_QUESTIONS +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPrompt : public CGuiScreen +{ +public: + CGuiScreenPrompt( Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID windowID = GUI_SCREEN_ID_GENERIC_PROMPT ); + + virtual ~CGuiScreenPrompt(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + + static void Display( int messageIndex, + CGuiEntity* pCallback, + int numResponses, + CGuiMenuPrompt::ePromptResponse* responses ); + + static void EnableDefaultToNo( bool enable ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + CGuiMenuPrompt* m_pMenu; + + Scrooby::Sprite* m_messageIcon; + unsigned int m_elapsedTime; + + Scrooby::Group* m_xboxDashboardLabel; + + Scrooby::Text* m_promptMessage; + static int s_messageIndex; + static int s_numResponses; + static CGuiMenuPrompt::ePromptResponse s_responses[ CGuiMenuPrompt::MAX_NUM_RESPONSES ]; + static CGuiEntity* s_pPromptCallback; + static bool s_defaultToNo; + + UnicodeChar m_originalStringBuffer[ 256 ]; + + Scrooby::Layer* m_tvFrame; + +}; + +inline void CGuiScreenPrompt::EnableDefaultToNo( bool enable ) +{ + s_defaultToNo = enable; +} + +#endif // GUISCREENPROMPT_H diff --git a/game/code/presentation/gui/guisystem.cpp b/game/code/presentation/gui/guisystem.cpp new file mode 100644 index 0000000..f7523e6 --- /dev/null +++ b/game/code/presentation/gui/guisystem.cpp @@ -0,0 +1,1845 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiSystem +// +// Description: Implementation of the CGuiSystem class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/21 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/bootup/guimanagerlanguage.h> +#include <presentation/gui/bootup/guimanagerbootup.h> +#include <presentation/gui/bootup/guiscreenlanguage.h> +#include <presentation/gui/backend/guimanagerbackend.h> +#include <presentation/gui/frontend/guimanagerfrontend.h> +#include <presentation/gui/minigame/guimanagerminigame.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/guiuserinputhandler.h> +#include <presentation/tutorialmode.h> + +#include <data/gamedatamanager.h> +#include <main/game.h> +#include <main/platform.h> +#include <main/commandlineoptions.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/missionscriptloader.h> +#include <input/inputmanager.h> +#include <gameflow/gameflow.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> + +#include <p3d/view.hpp> +#include <raddebug.hpp> // Foundation +#include <raddebugwatch.hpp> +#include <page.h> +#include <polygon.h> +#include <resourcemanager.h> +#include <screen.h> +#include <sprite.h> +#include <text.h> +#include <feloaders.h> + +// Static pointer to instance of singleton. +CGuiSystem* CGuiSystem::spInstance = NULL; + +// Scrooby simulation time, needed for DrawFrame() render loop +// +unsigned int g_scroobySimulationTime = 0; + +//=========================================================================== +// Local Constants +//=========================================================================== + +#define LOAD_LEVEL_SPECIFIC_PROJECT + +/* +#ifdef RAD_GAMECUBE + float g_gcnScreenScaleX = 1.1f; + float g_gcnScreenScaleY = 1.0f; +#endif + +#ifdef RAD_PS2 + float g_ps2screenScale = 1.096f; +#endif +*/ + +#ifdef DEBUGWATCH + const char* GUI_WATCHER_NAMESPACE = "GUI System"; + float g_wGuiSimulationTimeFactor = 1.0f; + int g_wGuiMessage = 0; + int g_wGuiMessageParam1 = 0; + int g_wGuiMessageParam2 = 0; + + static void SendMsgToGuiSystem() + { + GetGuiSystem()->HandleMessage( static_cast<eGuiMessage>( g_wGuiMessage ), + g_wGuiMessageParam1, + g_wGuiMessageParam2 ); + } + + namespace Scrooby + { + extern float g_CameraNearPlane; + extern float g_CameraFarPlane; + } + +/* +#ifdef RAD_PS2 + static void UpdatePS2ScreenScale() + { + Scrooby::App::GetInstance()->EnableScreenScaling( true, + g_ps2screenScale, + g_ps2screenScale ); + } +#endif +*/ + + // for Formatting Scrooby Drawables in Run-time + // + static const char* WATCHER_NAMESPACE_SCROOBY = "GUI System - Scrooby"; + + static Scrooby::Page* g_wCurrentScroobyPage = NULL; + static char g_wScroobyPageName[ 32 ]; + static void SetCurrentScroobyPage() + { + Scrooby::Project* currentProject = Scrooby::App::GetInstance()->GetProject(); + rAssert( currentProject ); + + Scrooby::Screen* currentScreen = currentProject->GetCurrentScreen(); + rAssert( currentScreen ); + + g_wCurrentScroobyPage = currentScreen->GetPage( g_wScroobyPageName ); + rWarning( g_wCurrentScroobyPage ); + } + + static Scrooby::Drawable* g_wCurrentScroobyDrawable = NULL; + + static int g_wScroobyPosX = 0; + static int g_wScroobyPosY = 0; + static void SetScroobyDrawablePosition() + { + if( g_wCurrentScroobyDrawable != NULL ) + { + g_wCurrentScroobyDrawable->SetPosition( g_wScroobyPosX, g_wScroobyPosY ); + } + } + + static float g_wScroobyAlpha = 0.0f; + static void SetScroobyDrawableAlpha() + { + if( g_wCurrentScroobyDrawable != NULL ) + { + g_wCurrentScroobyDrawable->SetAlpha( g_wScroobyAlpha ); + } + } + + static void UpdateScroobyDrawableAttributes() + { + if( g_wCurrentScroobyDrawable != NULL ) + { + g_wCurrentScroobyDrawable->GetOriginPosition( g_wScroobyPosX, + g_wScroobyPosY ); + g_wScroobyAlpha = g_wCurrentScroobyDrawable->GetAlpha(); + } + } + + static char g_wScroobyTextName[ 32 ]; + static void SetCurrentScroobyDrawableAsText() + { + if( g_wCurrentScroobyPage != NULL ) + { + g_wCurrentScroobyDrawable = g_wCurrentScroobyPage->GetText( g_wScroobyTextName ); + UpdateScroobyDrawableAttributes(); + } + + rWarning( g_wCurrentScroobyDrawable ); + } + + static char g_wScroobySpriteName[ 32 ]; + static void SetCurrentScroobyDrawableAsSprite() + { + if( g_wCurrentScroobyPage != NULL ) + { + g_wCurrentScroobyDrawable = g_wCurrentScroobyPage->GetSprite( g_wScroobySpriteName ); + UpdateScroobyDrawableAttributes(); + } + + rWarning( g_wCurrentScroobyDrawable ); + } + + static char g_wScroobyPolygonName[ 32 ]; + static void SetCurrentScroobyDrawableAsPolygon() + { + if( g_wCurrentScroobyPage != NULL ) + { + g_wCurrentScroobyDrawable = g_wCurrentScroobyPage->GetPolygon( g_wScroobyPolygonName ); + UpdateScroobyDrawableAttributes(); + } + + rWarning( g_wCurrentScroobyDrawable ); + } + + int g_currentLanguage = 0; + + static void ToggleNextLanguage() + { + g_currentLanguage = (g_currentLanguage + 1) % NUM_SRR2_LANGUAGES; + CGuiTextBible::SetCurrentLanguage( SRR2_LANGUAGE[ g_currentLanguage ] ); + } + +#endif // DEBUGWATCH + +const char* PROJECT_FILE_LANGUAGE = "art\\frontend\\scrooby\\language.p3d"; +const char* PROJECT_FILE_BOOTUP = "art\\frontend\\scrooby\\bootup.p3d"; +const char* PROJECT_FILE_BACKEND = "art\\frontend\\scrooby\\backend.p3d"; +const char* PROJECT_FILE_FRONTEND = "art\\frontend\\scrooby\\frontend.p3d"; +const char* PROJECT_FILE_MINIGAME = "art\\frontend\\scrooby\\minigame.p3d"; +const char* PROJECT_FILE_INGAME = "art\\frontend\\scrooby\\ingame.p3d"; + +const char* LICENSE_SCREEN_IMAGE_DIR = "art\\frontend\\dynaload\\images\\license\\"; +#ifdef RAD_WIN32 +const char* MOUSE_CURSOR_DIR = "art\\frontend\\dynaload\\images\\"; +#endif + +const char* INGAME_LEVEL_PROJECT_FILES[] = +{ + "art\\frontend\\scrooby\\ingamel1.p3d", + "art\\frontend\\scrooby\\ingamel2.p3d", + "art\\frontend\\scrooby\\ingamel3.p3d", + "art\\frontend\\scrooby\\ingamel4.p3d", + "art\\frontend\\scrooby\\ingamel5.p3d", + "art\\frontend\\scrooby\\ingamel6.p3d", + "art\\frontend\\scrooby\\ingamel7.p3d" +}; + +const char* TEXT_BIBLE_NAME = "srr2"; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//============================================================================== +// CGuiSystem::CreateInstance +//============================================================================== +// +// Description: - Creates the CGuiSystem. +// +// Parameters: None. +// +// Return: Pointer to the CGuiSystem. +// +// Constraints: This is a singleton so only one instance is allowed. +// +//============================================================================== +CGuiSystem* CGuiSystem::CreateInstance() +{ +MEMTRACK_PUSH_GROUP( "CGUISystem" ); + spInstance = new CGuiSystem; + rAssert( spInstance != NULL ); +MEMTRACK_POP_GROUP( "CGUISystem" ); + + return spInstance; +} + +//============================================================================== +// CGuiSystem::DestroyInstance +//============================================================================== +// +// Description: Destroy the GUI system. +// +// Parameters: None. +// +// Return: None. +// +//============================================================================== +void CGuiSystem::DestroyInstance() +{ + rAssert( spInstance != NULL ); + + delete spInstance; + spInstance = NULL; +} + +//============================================================================== +// CGuiSystem::GetInstance +//============================================================================== +// +// Description: - Access point for the CGuiSystem singleton. +// - Creates the CGuiSystem if needed. +// +// Parameters: None. +// +// Return: Pointer to the CGuiSystem. +// +// Constraints: This is a singleton so only one instance is allowed. +// +//============================================================================== +CGuiSystem* CGuiSystem::GetInstance() +{ + rAssert( spInstance != NULL ); + + return spInstance; +} + +//=========================================================================== +// CGuiSystem::CGuiSystem +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +CGuiSystem::CGuiSystem() +: CGuiEntity( NULL ), + m_state( GUI_UNINITIALIZED ), + m_pTextBible( NULL ), + m_pManagerLanguage( NULL ), + m_pManagerBootUp( NULL ), + m_pManagerBackEnd( NULL ), + m_pManagerFrontEnd( NULL ), + m_pManagerMiniGame( NULL ), + m_pManagerInGame( NULL ), + m_pUserInputHandlers( NULL ), + m_numUserInputHandlers( 0 ), + m_registeredUserInputHandlers( 0 ), + m_primaryController(-1), + m_pApp( NULL ), + m_pProject( NULL ), + m_pLevelProject( NULL ), + m_pBackendProject( NULL ), + m_pLoadingCallback( NULL ), + m_isSplashScreenFinished( false ), + m_isRadarEnabled( true ), + m_isShowCreditsUponReturnToFE( false ) +{ + m_pTextBible = new CGuiTextBible; + rAssert( m_pTextBible != NULL ); +} + +//=========================================================================== +// CGuiSystem::~CGuiSystem +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +CGuiSystem::~CGuiSystem() +{ + // unload backend Scrooby project + // + if( m_pBackendProject != NULL ) + { + m_pApp->UnloadProject( m_pBackendProject ); + m_pBackendProject = NULL; + } + + // delete text bible + // + if( m_pTextBible != NULL ) + { + delete m_pTextBible; + m_pTextBible = NULL; + } + + // delete all GUI managers (if not already deleted) + // + if( m_pManagerFrontEnd != NULL ) + { + delete m_pManagerFrontEnd; + m_pManagerFrontEnd = NULL; + } + + if( m_pManagerMiniGame != NULL ) + { + delete m_pManagerMiniGame; + m_pManagerMiniGame = NULL; + } + + if( m_pManagerInGame != NULL ) + { + delete m_pManagerInGame; + m_pManagerInGame = NULL; + } + + if( m_pManagerBackEnd != NULL ) + { + delete m_pManagerBackEnd; + m_pManagerBackEnd = NULL; + } + + if( m_pManagerBootUp != NULL ) + { + delete m_pManagerBootUp; + m_pManagerBootUp = NULL; + } + + if( m_pManagerLanguage != NULL ) + { + delete m_pManagerLanguage; + m_pManagerLanguage = NULL; + } + + // delete all GUI user input handlers + // + if(m_pUserInputHandlers != NULL ) + { + for( int i = 0; i < m_numUserInputHandlers; i++ ) + { + if( m_pUserInputHandlers[ i ] != NULL ) + { + m_pUserInputHandlers[ i ]->Release(); + m_pUserInputHandlers[ i ] = NULL; + } + } + + delete [] m_pUserInputHandlers; + m_pUserInputHandlers = NULL; + } + + // delete Scrooby App singleton + // + if( m_pApp != NULL ) + { + Scrooby::App::DeleteInstance(); + m_pApp = NULL; + } +} + +//=========================================================================== +// CGuiSystem::Init +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::Init() +{ +MEMTRACK_PUSH_GROUP( "CGUISystem" ); + rAssert( m_state == GUI_UNINITIALIZED ); + + m_pApp = Scrooby::App::GetInstance(); + rAssert( m_pApp != NULL ); + + // set Scrooby to use full image names depending on whether or not + // resource files are joined together into single P3D project file + // + m_pApp->SetFullImageNames( CommandLineOptions::Get( CLO_FE_UNJOINED ) ); + + // set FE text bible loader to only load one string table for the + // current language + // + FeTextBibleLoader::SetOnlyLoadCurrentLanguage( true ); + +#if defined( PAL ) && defined( RAD_XBOX ) && !defined( RAD_RELEASE ) + // TC: disable this for Xbox non-release PAL builds so that I can + // change languages on-the-fly w/ the Watcher + // + FeTextBibleLoader::SetOnlyLoadCurrentLanguage( false ); +#endif + + // setup the GUI render layer + // + GetRenderManager()->mpLayer(RenderEnums::GUI)->AddGuts( m_pApp ); + GetRenderManager()->mpLayer(RenderEnums::GUI)->FreezeCorpse(); + GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) ); + + HeapMgr()->PushHeap( GMA_PERSISTENT ); + + // create array of user input handlers + // + m_numUserInputHandlers = GetInputManager()->GetMaxControllers(); + m_pUserInputHandlers = new CGuiUserInputHandler*[ m_numUserInputHandlers ]; + rAssert( m_pUserInputHandlers != NULL ); + + // create each user input handler + // + for( int i = 0; i < m_numUserInputHandlers; i++ ) + { + m_pUserInputHandlers[ i ] = new CGuiUserInputHandler; + rAssert( m_pUserInputHandlers[ i ] != NULL ); + m_pUserInputHandlers[ i ]->AddRef(); + } + + HeapMgr()->PopHeap( GMA_PERSISTENT ); + + // register GUI as game data handler + // + GetGameDataManager()->RegisterGameData( this, 1, "GUI System" ); + +#if defined( PAL ) && !defined( RAD_DEMO ) +/* + #ifdef RAD_GAMECUBE + // GC ONLY: load language configuration file + // + HeapMgr()->PushHeap( GMA_TEMP ); + GetMissionScriptLoader()->LoadScriptAsync( "language.ini" ); + HeapMgr()->PopHeap( GMA_TEMP ); + #endif +*/ + // load language Scrooby project (into FE heap) + // + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + PROJECT_FILE_LANGUAGE, + GMA_LEVEL_FE, + SCROOBY_INVENTORY_LANGUAGE, + SCROOBY_INVENTORY_LANGUAGE ); + + m_state = LANGUAGE_LOADING; +#else + this->OnInitBootUp(); +#endif // PAL + +#ifdef DEBUGWATCH + this->RegisterWatcherStuff(); +#endif + MEMTRACK_POP_GROUP( "CGUISystem" ); +} + +//=========================================================================== +// CGuiSystem::Update +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::Update( unsigned int elapsedTime ) +{ +#ifdef RAD_RELEASE + // TC [HACK]: To avoid any choppiness in FE animations + // + const unsigned int MAX_ELAPSED_TIME = 100; // in msec + if( elapsedTime > MAX_ELAPSED_TIME ) + { + rTunePrintf( "*** WARNING: GUI System elapsed time (%d ms) exceeded MAX_ELAPSED_TIME (%d ms)!\n", + elapsedTime, MAX_ELAPSED_TIME ); + + elapsedTime = 20; + } +#endif + +#ifdef DEBUGWATCH + elapsedTime = static_cast<unsigned int>( g_wGuiSimulationTimeFactor * + elapsedTime ); +#endif + + // check for repeated inputs + for( int i = 0; i < m_numUserInputHandlers; i++ ) + { + m_pUserInputHandlers[ i ]->Update( elapsedTime, i ); + } + + // set scrooby simulation time for use in the rendering loop + // + g_scroobySimulationTime = elapsedTime; + + // send update message to current GUI manager + // + CGuiManager* currentManager = this->GetCurrentManager(); + if( currentManager != NULL ) + { + currentManager->HandleMessage( GUI_MSG_UPDATE, elapsedTime ); + } + + if( m_state == DEMO_ACTIVE ) + { + if( m_pManagerInGame != NULL ) + { + m_pManagerInGame->HandleMessage( GUI_MSG_UPDATE, elapsedTime ); + } + } +} + +//=========================================================================== +// CGuiSystem::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiSystem::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_UPDATE: + { + rAssertMsg( 0, "*** Call GuiSystem::Update() instead! ***" ); + + break; + } + + case GUI_MSG_INIT_FRONTEND: + { + this->OnInitFrontEnd(); + + break; + } + case GUI_MSG_RELEASE_FRONTEND: + { + this->OnReleaseFrontEnd(); + + break; + } + case GUI_MSG_RUN_FRONTEND: + { + // thaw frontend render layer + GetRenderManager()->mpLayer(RenderEnums::GUI)->Thaw(); + + m_pApp->SetProject( m_pProject ); + + m_state = FRONTEND_ACTIVE; + + // start the frontend manager + rAssert( m_pManagerFrontEnd ); + if( param1 != 0 ) + { + m_pManagerFrontEnd->Start( static_cast<CGuiWindow::eGuiWindowID>( param1 ) ); + } + else + { + m_pManagerFrontEnd->Start(); + } + +/* +#ifdef RAD_GAMECUBE + // enable screen scaling (for GameCube) + m_pApp->EnableScreenScaling( true, g_gcnScreenScaleX, g_gcnScreenScaleY ); +#endif + +#ifdef RAD_PS2 + // enable screen scaling (for PS2) + m_pApp->EnableScreenScaling( true, g_ps2screenScale, g_ps2screenScale ); +#endif +*/ + + break; + } + + case GUI_MSG_INIT_MINIGAME: + { + this->OnInitMiniGame(); + + break; + } + case GUI_MSG_RELEASE_MINIGAME: + { + this->OnReleaseMiniGame(); + + break; + } + case GUI_MSG_RUN_MINIGAME: + { + m_pApp->SetProject( m_pProject ); + + m_state = MINIGAME_ACTIVE; + + // start the minigame manager + // + rAssert( m_pManagerMiniGame != NULL ); + if( param1 != 0 ) + { + m_pManagerMiniGame->Start( static_cast<CGuiWindow::eGuiWindowID>( param1 ) ); + } + else + { + m_pManagerMiniGame->Start(); + } + + break; + } + + case GUI_MSG_INIT_INGAME: + { + this->OnInitInGame(); + + break; + } + case GUI_MSG_RELEASE_INGAME: + { + this->OnReleaseInGame(); + + break; + } + case GUI_MSG_RUN_INGAME: + { + m_pApp->SetProject( m_pProject ); + + m_state = INGAME_ACTIVE; + + // start the in-game manager + rAssert( m_pManagerInGame ); + m_pManagerInGame->Start(); + + break; + } + + case GUI_MSG_INIT_BOOTUP: + { + this->OnInitBootUp(); + + break; + } + case GUI_MSG_RELEASE_BOOTUP: + { + this->OnReleaseBootUp(); + + break; + } + + case GUI_MSG_RUN_BACKEND: + { + m_pApp->SetProject( m_pBackendProject ); + + m_state = GUI_IDLE; + + rAssert( m_pManagerBackEnd ); + m_pManagerBackEnd->HandleMessage( message, param1, param2 ); + + break; + } + case GUI_MSG_RUN_DEMO: + { + m_state = DEMO_ACTIVE; + + rAssert( m_pManagerBackEnd ); + m_pManagerBackEnd->HandleMessage( message, param1, param2 ); + + break; + } + case GUI_MSG_PROJECT_LOAD_COMPLETE: + { + this->OnProjectLoadComplete( (Scrooby::Project*)param1 ); + + break; + } + default: + { + // relay message to current GUI manager + // + CGuiManager* currentManager = this->GetCurrentManager(); + if( currentManager != NULL ) + { + currentManager->HandleMessage( message, param1, param2 ); + } + + break; + } + } +} + +//=========================================================================== +// CGuiSystem::OnProjectLoadComplete +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnProjectLoadComplete( Scrooby::Project* pProject ) +{ +MEMTRACK_PUSH_GROUP( "CGUISystem" ); + rAssert( pProject != NULL ); + m_pProject = pProject; + + // update reference to text bible + // + rAssert( m_pTextBible != NULL ); + m_pTextBible->SetTextBible( TEXT_BIBLE_NAME ); + + switch( m_state ) + { + case LANGUAGE_LOADING: + { + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + m_pManagerLanguage = new CGuiManagerLanguage( m_pProject, this ); + rAssert( m_pManagerLanguage != NULL ); + + // Populate screens + // + m_pManagerLanguage->Populate(); + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); + + m_state = LANGUAGE_ACTIVE; + + // Start it up! + // + m_pManagerLanguage->Start(); + + break; + } + case BOOTUP_LOADING: + { + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + // Create bootup manager (for license screen, etc.) + // + m_pManagerBootUp = new CGuiManagerBootUp( m_pProject, this ); + rAssert( m_pManagerBootUp ); + + // Populate screens + // + m_pManagerBootUp->Populate(); + + // Start it up! + // + m_pManagerBootUp->Start(); + + m_pApp->SetProject( m_pProject ); + + // thaw frontend render layer + GetRenderManager()->mpLayer(RenderEnums::GUI)->Thaw(); + + m_state = BACKEND_LOADING; + + HeapMgr()->PopHeap( GMA_LEVEL_FE ); + + break; + } + case BACKEND_LOADING: + { + HeapMgr()->PushHeap( GMA_PERSISTENT ); + + // now that the text bible loaded from the backend project is residing + // in the persistend heap, there is no need to load any more instances + // of the text bible from subsequent scrooby project loads + // + FeTextBibleLoader::SetUseLastLoadedTextBible( true ); + + m_pBackendProject = pProject; + + // Create backend manager (for loading screens) + // + m_pManagerBackEnd = new CGuiManagerBackEnd( m_pProject, this ); + rAssert( m_pManagerBackEnd ); + + // Populate screens + // + m_pManagerBackEnd->Populate(); + + m_pManagerBackEnd->Start(); + + if( !CommandLineOptions::Get( CLO_SKIP_FE ) ) + { + m_state = FRONTEND_LOADING_DURING_BOOTUP; + } + else + { + m_state = BOOTUP_ACTIVE; + } + + HeapMgr()->PopHeap(GMA_PERSISTENT); + + break; + } + case FRONTEND_LOADING_DURING_BOOTUP: + { + m_state = BOOTUP_ACTIVE; + + // follow-through + } + case FRONTEND_LOADING: + { + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + // Create FE screen manager + // + m_pManagerFrontEnd = new CGuiManagerFrontEnd( m_pProject, this ); + rAssert( m_pManagerFrontEnd ); + + // Populate screens + // + m_pManagerFrontEnd->Populate(); + + // notify callback + // + if( m_pLoadingCallback != NULL ) + { + m_pLoadingCallback->OnGuiLoadComplete( IGuiLoadingCallback::GUI_LOADED_FRONT_END ); + } + + HeapMgr()->PopHeap(GMA_LEVEL_FE); + + break; + } + case MINIGAME_LOADING: + { + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + // create mini-game manager + // + m_pManagerMiniGame = new CGuiManagerMiniGame( m_pProject, this ); + rAssert( m_pManagerMiniGame != NULL ); + + // Populate screens + // + m_pManagerMiniGame->Populate(); + + // notify callback + // + if( m_pLoadingCallback != NULL ) + { + m_pLoadingCallback->OnGuiLoadComplete( IGuiLoadingCallback::GUI_LOADED_MINI_GAME ); + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + + break; + } + case INGAME_LOADING: + { + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + // Create InGame manager + // +#ifdef LOAD_LEVEL_SPECIFIC_PROJECT + if( m_pLevelProject == NULL ) + { + m_pLevelProject = m_pProject; + } + else +#endif // LOAD_LEVEL_SPECIFIC_PROJECT + { + m_pManagerInGame = new CGuiManagerInGame( m_pProject, this ); + rAssert( m_pManagerInGame ); + + // Populate screens + // + m_pManagerInGame->Populate(); + + // notify callback + // + if( m_pLoadingCallback != NULL ) + { + m_pLoadingCallback->OnGuiLoadComplete( IGuiLoadingCallback::GUI_LOADED_IN_GAME ); + } + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + + break; + } + default: + { + rAssertMsg( false, "Invalid state!" ); + + break; + } + } +MEMTRACK_POP_GROUP("CGUISystem"); +} + +//=========================================================================== +// CGuiSystem::GotoScreen +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::GotoScreen( unsigned int screenID, + unsigned int param1, + unsigned int param2, + unsigned int windowOptions ) +{ + CGuiManager* currentManager = this->GetCurrentManager(); + rAssert( currentManager != NULL ); + + if( param1 != 0 || param2 != 0 ) + { + currentManager->HandleMessage( GUI_MSG_SET_GOTO_SCREEN_PARAMETERS, + param1, param2 ); + } + + currentManager->HandleMessage( GUI_MSG_GOTO_SCREEN, screenID, windowOptions ); +} + +//=========================================================================== +// CGuiSystem::GetCurrentManager +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +CGuiManager* CGuiSystem::GetCurrentManager() const +{ + CGuiManager* currentManager = NULL; + + switch( m_state ) + { + case FRONTEND_ACTIVE: + { + currentManager = m_pManagerFrontEnd; + + break; + } + case MINIGAME_ACTIVE: + { + currentManager = m_pManagerMiniGame; + + break; + } + case INGAME_ACTIVE: + { + currentManager = m_pManagerInGame; + + break; + } + case BOOTUP_ACTIVE: + case BACKEND_LOADING: + case FRONTEND_LOADING_DURING_BOOTUP: + { + currentManager = m_pManagerBootUp; + + break; + } + case LANGUAGE_ACTIVE: + { + currentManager = m_pManagerLanguage; + + break; + } + case GUI_IDLE: + case DEMO_ACTIVE: + case FRONTEND_LOADING: + case MINIGAME_LOADING: + case INGAME_LOADING: + { + currentManager = m_pManagerBackEnd; + + break; + } + default: + { + break; + } + } + + return currentManager; +} + +//=========================================================================== +// CGuiSystem::RegisterUserInputHandlers +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::RegisterUserInputHandlers( int controllerIDs ) +{ + for( int i = 0; i < m_numUserInputHandlers; i++ ) + { + if( (controllerIDs & (1 << i)) > 0 ) + { + GetInputManager()->RegisterMappable( i, m_pUserInputHandlers[ i ] ); + + m_registeredUserInputHandlers |= (1 << i); + } + } +} + +//=========================================================================== +// CGuiSystem::UnregisterUserInputHandlers +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::UnregisterUserInputHandlers( int controllerIDs ) +{ + for( int i = 0; i < m_numUserInputHandlers; i++ ) + { + if( (controllerIDs & (1 << i)) > 0 ) + { + GetInputManager()->UnregisterMappable( i, m_pUserInputHandlers[ i ] ); + + m_registeredUserInputHandlers &= ~(1 << i); + } + } + + rAssertMsg( m_registeredUserInputHandlers == 0, + "*** WARNING: Not all GUI user input handlers were un-registered!" ); +} + +//=========================================================================== +// CGuiSystem::GetUserInputHandler +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +CGuiUserInputHandler* +CGuiSystem::GetUserInputHandler( int controllerId ) const +{ + rAssert( controllerId >= 0 && controllerId < m_numUserInputHandlers ); + rAssert( m_pUserInputHandlers != NULL ); + + if( (m_registeredUserInputHandlers & (1 << controllerId)) > 0 ) + { + return m_pUserInputHandlers[ controllerId ]; + } + else + { + return NULL; + } +} + +//=========================================================================== +// CGuiSystem::LoadData +//=========================================================================== +// Description: Load GUI data from memory card. +// +//=========================================================================== +void +CGuiSystem::LoadData( const GameDataByte* dataBuffer, unsigned int numBytes ) +{ + rAssert( dataBuffer != NULL && numBytes == 1 ); + m_isRadarEnabled = ( dataBuffer[ 0 ] != 0 ); +} + +//=========================================================================== +// CGuiSystem::SaveData +//=========================================================================== +// Description: Save GUI data to memory card. +// +//=========================================================================== +void +CGuiSystem::SaveData( GameDataByte* dataBuffer, unsigned int numBytes ) +{ + rAssert( dataBuffer != NULL && numBytes == 1 ); + dataBuffer[ 0 ] = m_isRadarEnabled ? 1 : 0; +} + +//=========================================================================== +// CGuiSystem::ResetData +//=========================================================================== +// Description: Reset GUI data to defaults. +// +//=========================================================================== +void +CGuiSystem::ResetData() +{ + m_isRadarEnabled = true; +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiSystem::OnInitBootUp +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnInitBootUp() +{ + char languageDir[ 16 ]; + languageDir[ 0 ] = '\0'; + +#ifdef PAL + switch( CGuiTextBible::GetCurrentLanguage() ) + { + case Scrooby::XL_FRENCH: + { + strcpy( languageDir, "french\\" ); + + break; + } + case Scrooby::XL_GERMAN: + { + strcpy( languageDir, "german\\" ); + + break; + } + case Scrooby::XL_SPANISH: + { + strcpy( languageDir, "spanish\\" ); + + break; + } + default: + { + rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH ); + + break; + } + } +#endif // PAL + + char licenseImageFile[ 256 ]; + sprintf( licenseImageFile, +#ifdef RAD_GAMECUBE + "%s%slicenseG.p3d", +#endif +#ifdef RAD_PS2 + "%s%slicenseP.p3d", +#endif +#ifdef RAD_XBOX + "%s%slicenseX.p3d", +#endif +#ifdef RAD_WIN32 + "%s%slicensePC.p3d", +#endif + LICENSE_SCREEN_IMAGE_DIR, + languageDir ); + + //Load the mouse cursor +#ifdef RAD_WIN32 + char cursorImageFile[256]; + sprintf( cursorImageFile, "%smouse_cursor.p3d", MOUSE_CURSOR_DIR ); + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + cursorImageFile, + GMA_PERSISTENT, + "Default", + "Default" ); +#endif + + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + licenseImageFile, + GMA_LEVEL_FE, + SCROOBY_INVENTORY_BOOTUP, + SCROOBY_INVENTORY_BOOTUP ); + + // load bootup Scrooby project (into FE heap) + // + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + PROJECT_FILE_BOOTUP, + GMA_LEVEL_FE, + SCROOBY_INVENTORY_BOOTUP, + SCROOBY_INVENTORY_BOOTUP ); + + // load backend Scrooby project (into PERSISTENT heap) + // + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + PROJECT_FILE_BACKEND, + GMA_PERSISTENT, // This is because the loading screen always stays around + SCROOBY_INVENTORY_BACKEND, + SCROOBY_INVENTORY_BACKEND ); + + if( !CommandLineOptions::Get( CLO_SKIP_FE ) ) + { + // load frontend Scrooby project (into FE heap) + // + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + PROJECT_FILE_FRONTEND, + GMA_LEVEL_FE, + SCROOBY_INVENTORY_FRONTEND, + SCROOBY_INVENTORY_FRONTEND ); + } + + m_state = BOOTUP_LOADING; +} + +//=========================================================================== +// CGuiSystem::OnReleaseBootUp +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnReleaseBootUp() +{ + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + Scrooby::Project* pScroobyProject = NULL; + + if( m_pManagerLanguage != NULL ) + { + pScroobyProject = m_pManagerLanguage->GetScroobyProject(); + + // destroy language manager + // + delete m_pManagerLanguage; + m_pManagerLanguage = NULL; + + if( pScroobyProject != NULL ) + { + m_pApp->UnloadProject( pScroobyProject ); + } + } + + if( m_pManagerBootUp != NULL ) + { + pScroobyProject = m_pManagerBootUp->GetScroobyProject(); + + // destroy bootup manager + delete m_pManagerBootUp; + m_pManagerBootUp = NULL; + + if( pScroobyProject != NULL ) + { + m_pApp->UnloadProject( pScroobyProject ); + } + } + + // update reference to text bible + // + rAssert( m_pTextBible != NULL ); + m_pTextBible->SetTextBible( TEXT_BIBLE_NAME ); + + HeapMgr()->PopHeap(GMA_LEVEL_FE); + +#ifdef PAL + this->FormatTutorialTextWithLineBreaks(); +#endif + + m_state = GUI_IDLE; +} + +//=========================================================================== +// CGuiSystem::OnInitFrontEnd +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnInitFrontEnd() +{ + // load frontend Scrooby project (into FE heap) + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + PROJECT_FILE_FRONTEND, + GMA_LEVEL_FE, + SCROOBY_INVENTORY_FRONTEND, + SCROOBY_INVENTORY_FRONTEND ); + + m_state = FRONTEND_LOADING; +} + +//=========================================================================== +// CGuiSystem::OnReleaseFrontEnd +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnReleaseFrontEnd() +{ + HeapMgr()->PushHeap( GMA_LEVEL_FE ); + + if( m_pManagerFrontEnd != NULL ) + { + // destroy frontend manager + delete m_pManagerFrontEnd; + m_pManagerFrontEnd = NULL; + } + + // unload frontend project resources + if( m_pProject != NULL ) + { + m_pApp->UnloadProject( m_pProject ); + m_pProject = NULL; + } + +/* +#ifdef RAD_GAMECUBE + // disable screen scaling (for GameCube) + m_pApp->EnableScreenScaling( false ); +#endif + +#ifdef RAD_PS2 + // disable screen scaling (for PS2) + m_pApp->EnableScreenScaling( false ); +#endif +*/ + + HeapMgr()->PopHeap(GMA_LEVEL_FE); + + m_state = GUI_IDLE; +} + +//=========================================================================== +// CGuiSystem::OnInitMiniGame +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnInitMiniGame() +{ + // load mini-game Scrooby project + // + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + PROJECT_FILE_MINIGAME, + GMA_LEVEL_HUD, + SCROOBY_INVENTORY_MINIGAME, + SCROOBY_INVENTORY_MINIGAME ); + + // load 3D characters + // +// CGuiManagerMiniGame::LoadCharacters(); + + m_state = MINIGAME_LOADING; +} + +//=========================================================================== +// CGuiSystem::OnReleaseMiniGame +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnReleaseMiniGame() +{ + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + // unload 3D characters + // +// CGuiManagerMiniGame::UnloadCharacters(); + + // destroy MiniGame manager + // + if( m_pManagerMiniGame != NULL ) + { + delete m_pManagerMiniGame; + m_pManagerMiniGame = NULL; + } + + // unload mini-game project resources + // + if( m_pProject != NULL ) + { + m_pApp->UnloadProject( m_pProject ); + m_pProject = NULL; + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + + m_state = GUI_IDLE; +} + +//=========================================================================== +// CGuiSystem::OnInitInGame +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnInitInGame() +{ + int currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + rAssert( currentLevel >= 0 ); + + // substitute levels > 7 with level 1 + // + if( static_cast<unsigned int>( currentLevel ) >= sizeof( INGAME_LEVEL_PROJECT_FILES ) / + sizeof( INGAME_LEVEL_PROJECT_FILES[ 0 ] ) ) + { + currentLevel = 0; + } + +#ifdef LOAD_LEVEL_SPECIFIC_PROJECT + // load level-specific ingame Scrooby project (into HUD heap) + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + INGAME_LEVEL_PROJECT_FILES[ currentLevel ], + GMA_LEVEL_HUD, + SCROOBY_INVENTORY_INGAME_LEVEL, + SCROOBY_INVENTORY_INGAME_LEVEL ); +#endif // LOAD_LEVEL_SPECIFIC_PROJECT + + // load ingame Scrooby project (into HUD heap) + GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY, + PROJECT_FILE_INGAME, + GMA_LEVEL_HUD, + SCROOBY_INVENTORY_INGAME, + SCROOBY_INVENTORY_INGAME ); + + rAssert( m_pApp ); + m_pApp->GetResourceManager().SetSecondaryInventorySection( SCROOBY_INVENTORY_INGAME_LEVEL ); + + m_state = INGAME_LOADING; +} + + +//=========================================================================== +// CGuiSystem::OnReleaseInGame +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::OnReleaseInGame() +{ + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + if( m_pManagerInGame != NULL ) + { + // destroy ingame manager + delete m_pManagerInGame; + m_pManagerInGame = NULL; + } + + // unload ingame project resources + if( m_pProject != NULL ) + { + m_pApp->UnloadProject( m_pProject ); + m_pProject = NULL; + } + + // as well as level-specific ingame resources + if( m_pLevelProject != NULL ) + { + m_pApp->UnloadProject( m_pLevelProject ); + m_pLevelProject = NULL; + } + + // update reference to text bible + // + rAssert( m_pTextBible != NULL ); + m_pTextBible->SetTextBible( TEXT_BIBLE_NAME ); + + rAssert( m_pApp ); + m_pApp->GetResourceManager().SetSecondaryInventorySection( NULL ); + + HeapMgr()->PopHeap(GMA_LEVEL_HUD); + + m_state = GUI_IDLE; +} + + +//=========================================================================== +// CGuiSystem::FormatTutorialTextWithLineBreaks +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiSystem::FormatTutorialTextWithLineBreaks() +{ +#ifdef PAL + const int MAX_NUM_CHARS_PER_LINE = 35; + const P3D_UNICODE TEXT_LINE_BREAK = '\\'; + + for( int tutorialID = 0; tutorialID < TUTORIAL_MAX; tutorialID++ ) + { + char textBibleID[ 32 ]; + sprintf( textBibleID, "TUTORIAL_%03d", tutorialID ); + P3D_UNICODE* tutorialText = GetTextBibleString( textBibleID ); + + // check for platform-specific text; if found, override default text + // + P3D_UNICODE* platformText = NULL; + +#ifdef RAD_GAMECUBE + strcat( textBibleID, "_(GC)" ); + platformText = GetTextBibleString( textBibleID ); +#endif +#ifdef RAD_PS2 + strcat( textBibleID, "_(PS2)" ); + platformText = GetTextBibleString( textBibleID ); +#endif +#ifdef RAD_XBOX + strcat( textBibleID, "_(XBOX)" ); + platformText = GetTextBibleString( textBibleID ); +#endif + if( platformText != NULL ) + { + tutorialText = platformText; + } + + // wrap tutorial text by inserting line breaks into text + // + int numCharsInCurrentLine = 0; + int lastSpaceCharIndex = -1; + +#ifdef RAD_DEBUG + const int MAX_NUM_LINES_PER_MESSAGE = 5; + int numLineBreaks = 0; +#endif + + int tutorialTextLength = p3d::UnicodeStrLen( tutorialText ); + for( int i = 0; i < tutorialTextLength; i++ ) + { + if( tutorialText[ i ] == TEXT_LINE_BREAK ) // line break character + { +#ifdef RAD_DEBUG + numLineBreaks++; + rAssert( numLineBreaks < MAX_NUM_LINES_PER_MESSAGE ); +#endif + numCharsInCurrentLine = 0; + + continue; + } + + if( tutorialText[ i ] == ' ' ) // space character + { + lastSpaceCharIndex = i; + } + + numCharsInCurrentLine++; + + if( numCharsInCurrentLine > MAX_NUM_CHARS_PER_LINE ) + { + rAssertMsg( lastSpaceCharIndex != -1, "We might encounter this w/ Japanese text!" ); + + // replace last space character w/ line break + // + tutorialText[ lastSpaceCharIndex ] = TEXT_LINE_BREAK; + numCharsInCurrentLine = i - lastSpaceCharIndex; + +#ifdef RAD_DEBUG + numLineBreaks++; + rAssertMsg( numLineBreaks < MAX_NUM_LINES_PER_MESSAGE, "Too many lines in tutorial message! Tell Tony." ); +#endif + + rAssertMsg( numCharsInCurrentLine <= MAX_NUM_CHARS_PER_LINE, "We might encounter this w/ Japanese text!" ); + } + } + } +#endif // PAL +} + + +int CGuiSystem::GetPrimaryController() const +{ + return m_primaryController; +} + +void CGuiSystem::SetPrimaryController(int id) +{ + m_primaryController = id; +} + + +#ifdef DEBUGWATCH + +void CGuiSystem::RegisterWatcherStuff() +{ + static bool s_watcherRegistered = false; + + if( s_watcherRegistered ) + { + // delete previously registered stuff + // + radDbgWatchDelete( &g_wGuiSimulationTimeFactor ); + radDbgWatchDelete( &g_wGuiMessage ); + radDbgWatchDelete( &g_wGuiMessageParam1 ); + radDbgWatchDelete( &g_wGuiMessageParam2 ); + radDbgWatchDelete( &(Scrooby::g_CameraNearPlane) ); + radDbgWatchDelete( &(Scrooby::g_CameraFarPlane) ); +/* +#ifdef RAD_PS2 + radDbgWatchDelete( &g_ps2screenScale ); +#endif +*/ + radDbgWatchDelete( &g_wScroobyPageName ); + radDbgWatchDelete( &g_wScroobyPosX ); + radDbgWatchDelete( &g_wScroobyPosY ); + radDbgWatchDelete( &g_wScroobyAlpha ); + radDbgWatchDelete( &g_wScroobyTextName ); + radDbgWatchDelete( &g_wScroobySpriteName ); + radDbgWatchDelete( &g_wScroobyPolygonName ); + } + + // and re-register again + // + radDbgWatchAddFloat( &g_wGuiSimulationTimeFactor, + "GUI Simulation Time Factor", + GUI_WATCHER_NAMESPACE, + NULL, + NULL, + 0.0f, + 2.0f ); + + radDbgWatchAddInt( &g_wGuiMessage, + "GUI Message", + GUI_WATCHER_NAMESPACE, + (RADDEBUGWATCH_CALLBACK)SendMsgToGuiSystem ); + + radDbgWatchAddInt( &g_wGuiMessageParam1, + "GUI Message Param1", + GUI_WATCHER_NAMESPACE ); + + radDbgWatchAddInt( &g_wGuiMessageParam2, + "GUI Message Param2", + GUI_WATCHER_NAMESPACE ); + + radDbgWatchAddFloat( &(Scrooby::g_CameraNearPlane), + "Override Camera Near Plane", + GUI_WATCHER_NAMESPACE, + NULL, NULL, 0.01f, 1.0f ); + + radDbgWatchAddFloat( &(Scrooby::g_CameraFarPlane), + "Override Camera Far Plane", + GUI_WATCHER_NAMESPACE, + NULL, NULL, 10.0f, 1000.0f ); + + radDbgWatchAddFunction( "Toggle Next Language", + (RADDEBUGWATCH_CALLBACK)ToggleNextLanguage, + NULL, + GUI_WATCHER_NAMESPACE ); +/* +#ifdef RAD_PS2 + radDbgWatchAddFloat( &g_ps2screenScale, + "PS2 Screen Scale", + GUI_WATCHER_NAMESPACE, + (RADDEBUGWATCH_CALLBACK)UpdatePS2ScreenScale, + NULL, 0.5f, 1.5f ); +#endif +*/ + radDbgWatchAddString( g_wScroobyPageName, + sizeof( g_wScroobyPageName ), + "Scrooby Page", + WATCHER_NAMESPACE_SCROOBY, + (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyPage ); + + radDbgWatchAddInt( &g_wScroobyPosX, + "X-Position", + WATCHER_NAMESPACE_SCROOBY, + (RADDEBUGWATCH_CALLBACK)SetScroobyDrawablePosition, + NULL, + 0, + (int)Scrooby::App::GetInstance()->GetScreenWidth() ); + + radDbgWatchAddInt( &g_wScroobyPosY, + "Y-Position", + WATCHER_NAMESPACE_SCROOBY, + (RADDEBUGWATCH_CALLBACK)SetScroobyDrawablePosition, + NULL, + 0, + (int)Scrooby::App::GetInstance()->GetScreenHeight() ); + + radDbgWatchAddFloat( &g_wScroobyAlpha, + "Alpha", + WATCHER_NAMESPACE_SCROOBY, + (RADDEBUGWATCH_CALLBACK)SetScroobyDrawableAlpha ); + + radDbgWatchAddString( g_wScroobyTextName, + sizeof( g_wScroobyTextName ), + "Scrooby Text", + WATCHER_NAMESPACE_SCROOBY, + (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyDrawableAsText ); + + radDbgWatchAddString( g_wScroobySpriteName, + sizeof( g_wScroobySpriteName ), + "Scrooby Sprite", + WATCHER_NAMESPACE_SCROOBY, + (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyDrawableAsSprite ); + + radDbgWatchAddString( g_wScroobyPolygonName, + sizeof( g_wScroobyPolygonName ), + "Scrooby Polygon", + WATCHER_NAMESPACE_SCROOBY, + (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyDrawableAsPolygon ); + + s_watcherRegistered = true; +} + +#endif // DEBUGWATCH diff --git a/game/code/presentation/gui/guisystem.h b/game/code/presentation/gui/guisystem.h new file mode 100644 index 0000000..c56e4bc --- /dev/null +++ b/game/code/presentation/gui/guisystem.h @@ -0,0 +1,320 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiSystem +// +// Description: Interface for the CGuiSystem class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISYSTEM_H +#define GUISYSTEM_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guientity.h> +#include <data/gamedata.h> +#include <app.h> + +//=========================================================================== +// External Constants +//=========================================================================== + +extern unsigned int g_scroobySimulationTime; + +static const char* SCROOBY_INVENTORY_LANGUAGE = "ScroobyLanguage"; +static const char* SCROOBY_INVENTORY_BOOTUP = "ScroobyBootup"; +static const char* SCROOBY_INVENTORY_BACKEND = "ScroobyBackend"; +static const char* SCROOBY_INVENTORY_FRONTEND = "ScroobyFrontend"; +static const char* SCROOBY_INVENTORY_MINIGAME = "ScroobyMiniGame"; +static const char* SCROOBY_INVENTORY_INGAME = "ScroobyIngame"; +static const char* SCROOBY_INVENTORY_INGAME_LEVEL = "ScroobyIngameLevel"; + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiTextBible; +class CGuiManager; +class CGuiManagerLanguage; +class CGuiManagerBootUp; +class CGuiManagerBackEnd; +class CGuiManagerFrontEnd; +class CGuiManagerMiniGame; +class CGuiManagerInGame; +class CGuiUserInputHandler; +class CGuiScreenMultiHud; + +// Implement this interface to be called back when the +// async loading of the GUI system is complete. +// +struct IGuiLoadingCallback +{ + enum eGameMode + { + GUI_LOADED_FRONT_END, + GUI_LOADED_IN_GAME, + GUI_LOADED_MINI_GAME, + + NUM_GAME_MODES + }; + + virtual void OnGuiLoadComplete( eGameMode mode ) = 0; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class CGuiSystem : public CGuiEntity, + public Scrooby::LoadProjectCallback, + public GameDataHandler +{ +public: + // Static Methods for accessing this singleton. + static CGuiSystem* CreateInstance(); + static void DestroyInstance(); + static CGuiSystem* GetInstance(); + + void Init(); + void Update( unsigned int elapsedTime ); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + // Implements Scrooby::LoadProjectCallback interface. + // + virtual void OnProjectLoadComplete( Scrooby::Project* pProject ); + + void GotoScreen( unsigned int screenID, + unsigned int param1 = 0, + unsigned int param2 = 0, + unsigned int windowOptions = 0 ); + + Scrooby::Project* GetCurrentScroobyProject() const { return m_pProject; } + void SetCurrentScroobyProject( Scrooby::Project* pProject ) { m_pProject = pProject; } + Scrooby::Project* GetScroobyLevelProject() const { return m_pLevelProject; } + + void SwitchToCurrentProject(); + void SwitchToLevelProject(); + void SwitchToBackendProject(); + + // Registration of Client Loading Callback Routine + // + void RegisterLoadingCallback( IGuiLoadingCallback* pCallback ); + void UnregisterLoadingCallback(); + + // Accessors to GUI System Managers + // + CGuiManager* GetCurrentManager() const; + + inline CGuiManagerBootUp* GetBootupManager() const { return m_pManagerBootUp; } + inline CGuiManagerBackEnd* GetBackendManager() const { return m_pManagerBackEnd; } + inline CGuiManagerFrontEnd* GetFrontEndManager() const { return m_pManagerFrontEnd; } + inline CGuiManagerInGame* GetInGameManager() const { return m_pManagerInGame; } + inline CGuiManagerMiniGame* GetMiniGameManager() const { return m_pManagerMiniGame; } + + // Registration of GUI User Input Handlers + // + void RegisterUserInputHandlers( int controllerIDs = ~0 ); + void UnregisterUserInputHandlers( int controllerIDs = ~0 ); + + // Accessor to GUI User Input Handlers + // + CGuiUserInputHandler* GetUserInputHandler( int controllerId ) const; + int GetNumUserInputHandlers() const { return m_numUserInputHandlers; } + + // Splash Screen + // + inline void SetSplashScreenFinished() { m_isSplashScreenFinished = true; } + inline bool IsSplashScreenFinished() const { return m_isSplashScreenFinished; } + + // Credits Screen + // + void ShowCreditsUponReturnToFE( bool enable ); + bool IsShowCreditsUponReturnToFE() const; + + // Enabling/Disabling HUD Radar + // + void SetRadarEnabled( bool isEnabled ); + bool IsRadarEnabled() const; + + // Implements GameDataHandler + // + virtual void LoadData( const GameDataByte* dataBuffer, unsigned int numBytes ); + virtual void SaveData( GameDataByte* dataBuffer, unsigned int numBytes ); + virtual void ResetData(); + + int GetPrimaryController() const; + void SetPrimaryController(int id); + + enum eGuiSystemState + { + GUI_UNINITIALIZED, + GUI_IDLE, + + LANGUAGE_LOADING, + LANGUAGE_ACTIVE, + + BOOTUP_LOADING, + BOOTUP_ACTIVE, + + BACKEND_LOADING, + FRONTEND_LOADING_DURING_BOOTUP, + + FRONTEND_LOADING, + FRONTEND_ACTIVE, + + MINIGAME_LOADING, + MINIGAME_ACTIVE, + + INGAME_LOADING, + INGAME_ACTIVE, + + DEMO_ACTIVE, + + NUM_GUI_STATES + }; + + eGuiSystemState GetCurrentState() const { return m_state; } + +private: + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No public access; use singleton interface. + // + CGuiSystem(); + virtual ~CGuiSystem(); + + // No copying or assignment. Declare but don't define. + // + CGuiSystem( const CGuiSystem& ); + CGuiSystem& operator= ( const CGuiSystem& ); + + void OnInitBootUp(); + void OnReleaseBootUp(); + + void OnInitFrontEnd(); + void OnReleaseFrontEnd(); + + void OnInitMiniGame(); + void OnReleaseMiniGame(); + + void OnInitInGame(); + void OnReleaseInGame(); + + void FormatTutorialTextWithLineBreaks(); + +#ifdef DEBUGWATCH + void RegisterWatcherStuff(); +#endif + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + // Pointer to the one and only instance of this singleton. + static CGuiSystem* spInstance; + + eGuiSystemState m_state; + + CGuiTextBible* m_pTextBible; + + CGuiManagerLanguage* m_pManagerLanguage; + CGuiManagerBootUp* m_pManagerBootUp; + CGuiManagerBackEnd* m_pManagerBackEnd; + CGuiManagerFrontEnd* m_pManagerFrontEnd; + CGuiManagerMiniGame* m_pManagerMiniGame; + CGuiManagerInGame* m_pManagerInGame; + + CGuiUserInputHandler** m_pUserInputHandlers; + int m_numUserInputHandlers; + int m_registeredUserInputHandlers; + int m_primaryController; + + Scrooby::App* m_pApp; + Scrooby::Project* m_pProject; + Scrooby::Project* m_pLevelProject; + Scrooby::Project* m_pBackendProject; + + IGuiLoadingCallback* m_pLoadingCallback; + + bool m_isSplashScreenFinished : 1; + bool m_isRadarEnabled : 1; + bool m_isShowCreditsUponReturnToFE : 1; + +}; + +//=========================================================================== +// Inline Methods +//=========================================================================== + +// A little syntactic sugar for getting at this singleton. +// +inline CGuiSystem* GetGuiSystem() { return( CGuiSystem::GetInstance() ); } + +inline void CGuiSystem::SwitchToCurrentProject() +{ + rAssert( m_pProject != NULL ); + rAssert( m_pApp != NULL ); + m_pApp->SetProject( m_pProject ); +} + +inline void CGuiSystem::SwitchToLevelProject() +{ + if( m_pLevelProject != NULL ) + { + rAssert( m_pApp != NULL ); + m_pApp->SetProject( m_pLevelProject ); + } +} + +inline void CGuiSystem::SwitchToBackendProject() +{ + rAssert( m_pBackendProject != NULL ); + rAssert( m_pApp != NULL ); + m_pApp->SetProject( m_pBackendProject ); +} + +inline void CGuiSystem::RegisterLoadingCallback( IGuiLoadingCallback* pCallback ) +{ + m_pLoadingCallback = pCallback; +} + +inline void CGuiSystem::UnregisterLoadingCallback() +{ + m_pLoadingCallback = NULL; +} + +inline void CGuiSystem::SetRadarEnabled( bool isEnabled ) +{ + m_isRadarEnabled = isEnabled; +} + +inline bool CGuiSystem::IsRadarEnabled() const +{ + return m_isRadarEnabled; +} + +inline void CGuiSystem::ShowCreditsUponReturnToFE( bool enable ) +{ + m_isShowCreditsUponReturnToFE = enable; +} + +inline bool CGuiSystem::IsShowCreditsUponReturnToFE() const +{ + return m_isShowCreditsUponReturnToFE; +} + +#endif // GUISYSTEM_H diff --git a/game/code/presentation/gui/guitextbible.cpp b/game/code/presentation/gui/guitextbible.cpp new file mode 100644 index 0000000..d060cb9 --- /dev/null +++ b/game/code/presentation/gui/guitextbible.cpp @@ -0,0 +1,89 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/26 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== + +#include <presentation/gui/guitextbible.h> + +#include <app.h> +#include <textbible.h> +#include <raddebug.hpp> + +#include <sound/soundmanager.h> + +Scrooby::TextBible* CGuiTextBible::s_textBible = NULL; +Scrooby::XLLanguage CGuiTextBible::s_currentLanguage = Scrooby::XL_ENGLISH; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +CGuiTextBible::CGuiTextBible() +{ +} + +CGuiTextBible::~CGuiTextBible() +{ + s_textBible = NULL; +} + +void +CGuiTextBible::SetTextBible( const char* textBible ) +{ + rAssert( textBible != NULL ); + s_textBible = Scrooby::App::GetInstance()->GetTextBible( textBible ); +} + +P3D_UNICODE* +CGuiTextBible::GetLocalizedText( const char* stringID ) +{ + rAssert( stringID != NULL ); + rAssert( s_textBible != NULL ); + + P3D_UNICODE* localizedText = static_cast<P3D_UNICODE*>( s_textBible->GetWChar( stringID ) ); + +/* +#ifndef RAD_RELEASE + if( localizedText == NULL ) + { + char msg[ 256 ]; + sprintf( msg, "Can't find text bible string for entry: %s!", stringID ); + rTuneWarningMsg( false, msg ); + } +#endif +*/ + + return localizedText; +} + +void +CGuiTextBible::SetCurrentLanguage( const Scrooby::XLLanguage language ) +{ + Scrooby::App::GetInstance()->SetLocalizationLanguage( language ); + + s_currentLanguage = language; + + GetSoundManager()->SetDialogueLanguage( language ); +} + +Scrooby::XLLanguage +CGuiTextBible::GetCurrentLanguage() +{ + return s_currentLanguage; +} + +bool CGuiTextBible::IsTextBibleLoaded() +{ + return s_textBible != NULL; +} + + diff --git a/game/code/presentation/gui/guitextbible.h b/game/code/presentation/gui/guitextbible.h new file mode 100644 index 0000000..87a8388 --- /dev/null +++ b/game/code/presentation/gui/guitextbible.h @@ -0,0 +1,86 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/26 TChu Created +// +//=========================================================================== + +#ifndef GUITEXTBIBLE_H +#define GUITEXTBIBLE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +#include <p3d/plat_types.hpp> + +// Scrooby +// +#include <enums.h> + +//=========================================================================== +// External Constants +//=========================================================================== + +const Scrooby::XLLanguage SRR2_LANGUAGE[] = +{ + Scrooby::XL_ENGLISH, + Scrooby::XL_FRENCH, + Scrooby::XL_GERMAN, +// Scrooby::XL_ITALIAN, + Scrooby::XL_SPANISH, + + Scrooby::XL_LAST_LANGUAGE +}; + +const int NUM_SRR2_LANGUAGES = + sizeof( SRR2_LANGUAGE ) / sizeof( SRR2_LANGUAGE[ 0 ] ) - 1; + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class TextBible; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class CGuiTextBible +{ +public: + CGuiTextBible(); + virtual ~CGuiTextBible(); + + // update reference to Scrooby text bible + // + void SetTextBible( const char* textBible ); + + // get localized text for string ID + // + static P3D_UNICODE* GetLocalizedText( const char* stringID ); + + // get/set current locale language + // + static void SetCurrentLanguage( const Scrooby::XLLanguage language ); + static Scrooby::XLLanguage GetCurrentLanguage(); + static bool IsTextBibleLoaded(); + +private: + static Scrooby::TextBible* s_textBible; + static Scrooby::XLLanguage s_currentLanguage; + +}; + +inline P3D_UNICODE* GetTextBibleString( const char* stringID ) +{ + return CGuiTextBible::GetLocalizedText( stringID ); +} + +#endif // GUITEXTBIBLE_H diff --git a/game/code/presentation/gui/guiuserinputhandler.cpp b/game/code/presentation/gui/guiuserinputhandler.cpp new file mode 100644 index 0000000..f53b3b6 --- /dev/null +++ b/game/code/presentation/gui/guiuserinputhandler.cpp @@ -0,0 +1,938 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiUserInputHandler +// +// Description: Implementation of the CGuiUserInputHandler class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/10/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/guiuserinputhandler.h> +#include <presentation/gui/guisystem.h> + +#include <gameflow/gameflow.h> + +#include <raddebug.hpp> + +#include <contexts/context.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +struct ControlMap +{ + char* inputName; + GuiInput::eGuiInput inputID; +}; + +const ControlMap GUI_CONTROL_MAP[] = +{ +#ifdef RAD_GAMECUBE + { "LeftStickX", GuiInput::XAxis }, + { "LeftStickY", GuiInput::YAxis }, + { "RightStickX", GuiInput::XAxisRight }, + { "RightStickY", GuiInput::YAxisRight }, + { "DPadLeft", GuiInput::Left }, + { "DPadRight", GuiInput::Right }, + { "DPadUp", GuiInput::Up }, + { "DPadDown", GuiInput::Down }, + { "Menu", GuiInput::Start }, + { "A", GuiInput::Select }, + { "B", GuiInput::Back }, + { "X", GuiInput::AuxX }, + { "Y", GuiInput::AuxY }, + { "TriggerL", GuiInput::L1 }, + { "TriggerR", GuiInput::R1 }, +#endif + +#ifdef RAD_PS2 + { "LeftStickX", GuiInput::XAxis }, + { "LeftStickY", GuiInput::YAxis }, + { "RightStickX", GuiInput::XAxisRight }, + { "RightStickY", GuiInput::YAxisRight }, + { "DPadLeft", GuiInput::Left }, + { "DPadRight", GuiInput::Right }, + { "DPadUp", GuiInput::Up }, + { "DPadDown", GuiInput::Down }, + { "Start", GuiInput::Start }, + { "X", GuiInput::Select }, + { "Triangle", GuiInput::Back }, + { "Square", GuiInput::AuxX }, + { "Circle", GuiInput::AuxY }, + { "L1", GuiInput::L1 }, + { "R1", GuiInput::R1 }, + { "LGA", GuiInput::AuxStart }, //Only on the GT Wheel + { "LGX", GuiInput::AuxSelect }, //Only on the GT Wheel + { "LGY", GuiInput::AuxBack }, //Only on the GT Wheel + { "Wheel", GuiInput::AuxXAxis }, //Only on the GT Wheel + { "LGR1", GuiInput::AuxUp }, //Only on the GT Wheel + { "LGL1", GuiInput::AuxDown }, //Only on the GT Wheel + +#endif + +#ifdef RAD_XBOX + { "LeftStickX", GuiInput::XAxis }, + { "LeftStickY", GuiInput::YAxis }, + { "RightStickX", GuiInput::XAxisRight }, + { "RightStickY", GuiInput::YAxisRight }, + { "DPadLeft", GuiInput::Left }, + { "DPadRight", GuiInput::Right }, + { "DPadUp", GuiInput::Up }, + { "DPadDown", GuiInput::Down }, + { "Start", GuiInput::Start }, + { "Back", GuiInput::Back }, + { "A", GuiInput::Select }, + { "B", GuiInput::Back }, + { "X", GuiInput::AuxX }, + { "Y", GuiInput::AuxY }, + { "LeftTrigger", GuiInput::L1 }, + { "RightTrigger", GuiInput::R1 }, +#endif + +#ifdef RAD_WIN32 + { "feMoveLeft", GuiInput::Left }, + { "feMoveRight", GuiInput::Right }, + { "feMoveUp", GuiInput::Up }, + { "feMoveDown", GuiInput::Down }, + { "feStart", GuiInput::Start }, + { "feBack", GuiInput::Back }, + { "feSelect", GuiInput::Select }, + { "feFunction1", GuiInput::AuxX }, + { "feFunction2", GuiInput::L1 }, + + { "P1_KBD_Start", GuiInput::P1_KBD_Start }, + { "P1_KBD_Gas", GuiInput::P1_KBD_Select }, + { "P1_KBD_Brake", GuiInput::P1_KBD_Back }, + { "P1_KBD_Left", GuiInput::P1_KBD_Left }, + { "P1_KBD_Right", GuiInput::P1_KBD_Right }, +#endif + + { "", GuiInput::UNKNOWN } +}; + +const int NUM_GUI_CONTROL_MAPPINGS = sizeof( GUI_CONTROL_MAP ) / + sizeof( GUI_CONTROL_MAP[ 0 ] ); + +// time between repeated inputs +const int INPUT_REPEAT_PERIOD = 166; // in milliseconds + +// time before first repeated input +const int INPUT_REPEAT_WAIT = INPUT_REPEAT_PERIOD; // in milliseconds + +const float ANALOG_BUTTON_THRESHOLD = 0.5f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiUserInputHandler::CGuiUserInputHandler +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiUserInputHandler::CGuiUserInputHandler( void ) +: Mappable( Input::ACTIVE_ALL ), + m_XAxisValue( 0.0f ), + m_YAxisValue( 0.0f ), + m_XAxisDuration( 0 ), + m_YAxisDuration( 0 ), +#ifdef RAD_WIN32 + m_RightValue( 0 ), + m_LeftValue( 0 ), + m_UpValue( 0 ), + m_DownValue( 0 ), + m_RightDuration( 0 ), + m_LeftDuration( 0 ), + m_UpDuration( 0 ), + m_DownDuration( 0 ), +#endif + m_isStartToSelectMappingEnabled( true ) +{ + this->ResetRepeatableButtons(); +} + + +//=========================================================================== +// CGuiUserInputHandler::~CGuiUserInputHandler +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiUserInputHandler::~CGuiUserInputHandler( void ) +{ +} + + +//=========================================================================== +// CGuiUserInputHandler::Left +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::Left( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_LEFT, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::Right +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::Right( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_RIGHT, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::Up +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::Up( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_UP, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::Down +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::Down( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_DOWN, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::Start +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::Start( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_START, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::Select +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::Select( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_SELECT, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::Back +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::Back( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_BACK, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::AuxX +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::AuxX( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_AUX_X, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::AuxY +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::AuxY( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_AUX_Y, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::L1 +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::L1( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_L1, controllerId ); +} + + +//=========================================================================== +// CGuiUserInputHandler::R1 +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== +void CGuiUserInputHandler::R1( int controllerId ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_R1, controllerId ); +} + + +void CGuiUserInputHandler::OnControllerDisconnect( int id ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_DISCONNECT, id ); + + this->ResetRepeatableButtons(); + + Mappable::OnControllerDisconnect( id ); +} + + +void CGuiUserInputHandler::OnControllerConnect( int id ) +{ + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_CONNECT, id ); + + Mappable::OnControllerConnect( id ); +} + +//=========================================================================== +// CGuiUserInputHandler::OnButton +//=========================================================================== +// Description: +// +// Constraints: +// +// Parameters: +// +// Return: +// +//=========================================================================== + +////////////////////////////////////////////////////////////////////////////// +// IButtonedObject declarations +// +void CGuiUserInputHandler::OnButton( int controllerId, int buttonId, const IButton* pButton ) +{ + rAssert( pButton != NULL ); + + switch ( buttonId ) + { + case GuiInput::AuxXAxis: + case GuiInput::XAxis: + { + if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_XAxisValue > ANALOG_BUTTON_THRESHOLD ) ) + { + Right( controllerId ); + + m_XAxisDuration = -INPUT_REPEAT_WAIT; + } + + if ( pButton->GetValue() < -ANALOG_BUTTON_THRESHOLD && !( m_XAxisValue < -ANALOG_BUTTON_THRESHOLD ) ) + { + Left( controllerId ); + + m_XAxisDuration = -INPUT_REPEAT_WAIT; + } + + m_XAxisValue = pButton->GetValue(); + + break; + } + case GuiInput::YAxis: + { + if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_YAxisValue > ANALOG_BUTTON_THRESHOLD ) ) + { + Up( controllerId ); + + m_YAxisDuration = -INPUT_REPEAT_WAIT; + } + + if ( pButton->GetValue() < -ANALOG_BUTTON_THRESHOLD && !( m_YAxisValue < -ANALOG_BUTTON_THRESHOLD ) ) + { + Down( controllerId ); + + m_YAxisDuration = -INPUT_REPEAT_WAIT; + } + + m_YAxisValue = pButton->GetValue(); + + break; + } + case GuiInput::XAxisRight: + case GuiInput::YAxisRight: + { + // TC: *** temporary for now *** + // + GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_AUX_LEFT, controllerId ); + + break; + } +#ifdef RAD_WIN32 + case GuiInput::Left: + { + if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_LeftValue > ANALOG_BUTTON_THRESHOLD ) ) + { + Left( controllerId ); + + m_LeftDuration = -INPUT_REPEAT_WAIT; + } + m_LeftValue = pButton->GetValue(); + break; + } + case GuiInput::Right: + { + if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_RightValue > ANALOG_BUTTON_THRESHOLD ) ) + { + Right( controllerId ); + + m_RightDuration = -INPUT_REPEAT_WAIT; + } + m_RightValue = pButton->GetValue(); + break; + } + case GuiInput::Up: + { + if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_UpValue > ANALOG_BUTTON_THRESHOLD ) ) + { + Up( controllerId ); + + m_UpDuration = -INPUT_REPEAT_WAIT; + } + m_UpValue = pButton->GetValue(); + break; + } + case GuiInput::Down: + { + if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_DownValue > ANALOG_BUTTON_THRESHOLD ) ) + { + Down( controllerId ); + + m_DownDuration = -INPUT_REPEAT_WAIT; + } + m_DownValue = pButton->GetValue(); + break; + } +#endif + default: + { + break; + } + } +} + +void CGuiUserInputHandler::OnButtonUp( int controllerId, int buttonId, const IButton* pButton ) +{ + rAssert( buttonId >= 0 && buttonId < GuiInput::NUM_GUI_INPUTS ); + + if ( static_cast<unsigned int>( buttonId ) < sizeof( m_buttonDownDuration ) / + sizeof( m_buttonDownDuration[ 0 ] ) ) + { + // reset button down duration time + m_buttonDownDuration[ buttonId ] = -INPUT_REPEAT_WAIT; + } +} + +void CGuiUserInputHandler::OnButtonDown( int controllerId, int buttonId, const IButton* pButton ) +{ + ContextEnum context = GetGameFlow()->GetCurrentContext(); + + switch( buttonId ) + { +#ifndef RAD_WIN32 // for windows we handle them in onbutton() + case GuiInput::Left: + { + this->Left( controllerId ); + + break; + } + case GuiInput::Right: + { + this->Right( controllerId ); + + break; + } + case GuiInput::AuxUp: + { + if ( context != CONTEXT_SUPERSPRINT_FE && + context != CONTEXT_SUPERSPRINT ) + { + break; + } + + //Fall through + } + case GuiInput::Up: + { + this->Up( controllerId ); + + break; + } + case GuiInput::AuxDown: + { + if ( context != CONTEXT_SUPERSPRINT_FE && + context != CONTEXT_SUPERSPRINT ) + { + break; + } + + //Fall through + } + case GuiInput::Down: + { + this->Down( controllerId ); + + break; + } +#endif + case GuiInput::AuxStart: + { + if ( context != CONTEXT_SUPERSPRINT_FE && + context != CONTEXT_SUPERSPRINT ) + { + break; + } + + //Fall through + } + case GuiInput::Start: + { + this->Start( controllerId ); + +#ifdef RAD_XBOX + if( m_isStartToSelectMappingEnabled ) + { + // for Xbox only, START is mapped to same functionality as SELECT + this->Select( controllerId ); + } +#endif + + break; + } + case GuiInput::AuxSelect: + { + if ( context != CONTEXT_SUPERSPRINT_FE && + context != CONTEXT_SUPERSPRINT ) + { + break; + } + + //Fall through + } + case GuiInput::Select: + { + this->Select( controllerId ); + + break; + } + case GuiInput::AuxBack: + { + if ( context != CONTEXT_SUPERSPRINT_FE && + context != CONTEXT_SUPERSPRINT ) + { + break; + } + + //Fall through + } + case GuiInput::Back: + { + this->Back( controllerId ); + + break; + } + case GuiInput::AuxX: + { + this->AuxX( controllerId ); + + break; + } + case GuiInput::AuxY: + { + this->AuxY( controllerId ); + + break; + } + case GuiInput::L1: + { + this->L1( controllerId ); + + break; + } + case GuiInput::R1: + { + this->R1( controllerId ); + + break; + } + default: + { +#ifdef RAD_WIN32 + if ( buttonId >= GuiInput::P1_KBD_Start && buttonId <= GuiInput::P1_KBD_Right ) + { + //This is a super sprint Key. + if ( context == CONTEXT_SUPERSPRINT_FE || context == CONTEXT_SUPERSPRINT ) + { + unsigned int button = (buttonId - GuiInput::P1_KBD_Start); + int player = 3; + + enum + { + Start, + Select, + Back, + Left, + Right + }; + + switch( button ) + { + case Start: + this->Start( player ); + break; + case Select: + this->Select( player ); + break; + case Back: + this->Back( player ); + break; + case Left: + this->Left( player ); + break; + case Right: + this->Right( player ); + break; + default: + break; + } + } + } +#endif + break; + } + } +} + +void CGuiUserInputHandler::LoadControllerMappings( unsigned int controllerId ) +{ + // now set controller mappings + for( int i = 0; i < NUM_GUI_CONTROL_MAPPINGS; i++ ) + { + this->Map( GUI_CONTROL_MAP[ i ].inputName, + GUI_CONTROL_MAP[ i ].inputID, + 0, + controllerId ); + } +} + +void CGuiUserInputHandler::Update( unsigned int elapsedTime, unsigned int controllerId ) +{ + if( !this->IsActive() ) + { + this->ResetRepeatableButtons(); + } + +#ifndef RAD_WIN32 + // check for repeated DPad inputs + // + for( unsigned int i = 0; i < sizeof( m_buttonDownDuration ) / + sizeof( m_buttonDownDuration[ 0 ] ); i++ ) + { + // check if button is still down + if( this->IsButtonDown( i ) ) + { + m_buttonDownDuration[ i ] += elapsedTime; + + if( m_buttonDownDuration[ i ] > INPUT_REPEAT_PERIOD ) + { + // repeat button down event + this->OnButtonDown( controllerId, i, NULL ); + + m_buttonDownDuration[ i ] = (m_buttonDownDuration[ i ] + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + } +#endif + + // check for repeated Thumbstick inputs + // + if( m_XAxisValue > ANALOG_BUTTON_THRESHOLD ) + { + m_XAxisDuration += elapsedTime; + + if( m_XAxisDuration > INPUT_REPEAT_PERIOD ) + { + // repeat right input + this->Right( controllerId ); + + m_XAxisDuration = (m_XAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + + if( m_XAxisValue < -ANALOG_BUTTON_THRESHOLD ) + { + m_XAxisDuration += elapsedTime; + + if( m_XAxisDuration > INPUT_REPEAT_PERIOD ) + { + // repeat left input + this->Left( controllerId ); + + m_XAxisDuration = (m_XAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + + if( m_YAxisValue > ANALOG_BUTTON_THRESHOLD ) + { + m_YAxisDuration += elapsedTime; + + if( m_YAxisDuration > INPUT_REPEAT_PERIOD ) + { + // repeat up input + this->Up( controllerId ); + + m_YAxisDuration = (m_YAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + + if( m_YAxisValue < -ANALOG_BUTTON_THRESHOLD ) + { + m_YAxisDuration += elapsedTime; + + if( m_YAxisDuration > INPUT_REPEAT_PERIOD ) + { + // repeat down input + this->Down( controllerId ); + + m_YAxisDuration = (m_YAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + +#ifdef RAD_WIN32 + if( m_LeftValue > ANALOG_BUTTON_THRESHOLD ) + { + m_LeftDuration += elapsedTime; + + if( m_LeftDuration > INPUT_REPEAT_PERIOD ) + { + // repeat down input + Left( controllerId ); + + m_LeftDuration = (m_LeftDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + if( m_RightValue > ANALOG_BUTTON_THRESHOLD ) + { + m_RightDuration += elapsedTime; + + if( m_RightDuration > INPUT_REPEAT_PERIOD ) + { + // repeat down input + Right( controllerId ); + + m_RightDuration = (m_RightDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + if( m_UpValue > ANALOG_BUTTON_THRESHOLD ) + { + m_UpDuration += elapsedTime; + + if( m_UpDuration > INPUT_REPEAT_PERIOD ) + { + // repeat down input + Up( controllerId ); + + m_UpDuration = (m_UpDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } + if( m_DownValue > ANALOG_BUTTON_THRESHOLD ) + { + m_DownDuration += elapsedTime; + + if( m_DownDuration > INPUT_REPEAT_PERIOD ) + { + // repeat down input + Down( controllerId ); + + m_DownDuration = (m_DownDuration + elapsedTime ) % INPUT_REPEAT_PERIOD; + } + } +#endif +} + +bool +CGuiUserInputHandler::IsXAxisOnLeft() const +{ +#ifdef RAD_WIN32 + return( m_LeftValue > ANALOG_BUTTON_THRESHOLD ); +#else + return( m_XAxisValue < -ANALOG_BUTTON_THRESHOLD ); +#endif +} + +bool +CGuiUserInputHandler::IsXAxisOnRight() const +{ +#ifdef RAD_WIN32 + return( m_RightValue > ANALOG_BUTTON_THRESHOLD ); +#else + return( m_XAxisValue > ANALOG_BUTTON_THRESHOLD ); +#endif +} + +bool +CGuiUserInputHandler::IsYAxisOnUp() const +{ +#ifdef RAD_WIN32 + return( m_UpValue > ANALOG_BUTTON_THRESHOLD ); +#else + return( m_YAxisValue > ANALOG_BUTTON_THRESHOLD ); +#endif +} + +bool +CGuiUserInputHandler::IsYAxisOnDown() const +{ +#ifdef RAD_WIN32 + return( m_DownValue > ANALOG_BUTTON_THRESHOLD ); +#else + return( m_YAxisValue < -ANALOG_BUTTON_THRESHOLD ); +#endif +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +void +CGuiUserInputHandler::ResetRepeatableButtons() +{ + for( unsigned int i = 0; i < sizeof( m_buttonDownDuration ) / + sizeof( m_buttonDownDuration[ 0 ] ); i++ ) + { + m_buttonDownDuration[ i ] = -INPUT_REPEAT_WAIT; + } + + m_XAxisValue = 0.0f; + m_YAxisValue = 0.0f; + m_XAxisDuration = -INPUT_REPEAT_WAIT; + m_YAxisDuration = -INPUT_REPEAT_WAIT; + +#ifdef RAD_WIN32 + m_RightValue = 0; + m_LeftValue = 0; + m_UpValue = 0; + m_DownValue = 0; + m_RightDuration = 0; + m_LeftDuration = 0; + m_UpDuration = 0; + m_DownDuration = 0; +#endif +} + diff --git a/game/code/presentation/gui/guiuserinputhandler.h b/game/code/presentation/gui/guiuserinputhandler.h new file mode 100644 index 0000000..af55835 --- /dev/null +++ b/game/code/presentation/gui/guiuserinputhandler.h @@ -0,0 +1,162 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiUserInputHandler +// +// Description: This class feeds the inputs received by the controller +// system into the GUI system. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/10/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUIUSERINPUTHANDLER_H +#define GUIUSERINPUTHANDLER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <input/mappable.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiSystem; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +namespace GuiInput +{ + // Definition of control points for an abstracted player controller + // + enum eGuiInput + { + UNKNOWN = -1, + + Left, + Right, + Up, + Down, + + NUM_DPAD_INPUTS, + + L1, + R1, + XAxis, + YAxis, + XAxisRight, + YAxisRight, + Start, + Select, + Back, + AuxX, + AuxY, + + //These are just for the PS2 GT Wheel. + AuxStart, + AuxSelect, + AuxBack, + AuxUp, + AuxDown, + AuxXAxis, + +#ifdef RAD_WIN32 + P1_KBD_Start, + P1_KBD_Select, + P1_KBD_Back, + P1_KBD_Left, + P1_KBD_Right, +#endif + + NUM_GUI_INPUTS + }; +}; + +class CGuiUserInputHandler : public Mappable +{ +public: + + CGuiUserInputHandler( void ); + virtual ~CGuiUserInputHandler( void ); + + void Left( int controllerId = 0 ); + void Right( int controllerId = 0 ); + void Up( int controllerId = 0 ); + void Down( int controllerId = 0 ); + void Start( int controllerId = 0 ); + void Select( int controllerId = 0 ); + void Back( int controllerId = 0 ); + void AuxX( int controllerId = 0 ); + void AuxY( int controllerId = 0 ); + void L1( int controllerId = 0 ); + void R1( int controllerId = 0 ); + + // Mappable interface declarations + // + virtual void OnButton( int controllerId, int buttonId, const IButton* pButton ); + virtual void OnButtonUp( int controllerId, int buttonId, const IButton* pButton ); + virtual void OnButtonDown( int controllerId, int buttonId, const IButton* pButton ); + + // Mappable interface declarations. + // Dispatch a message when controller is disconnected. + // + virtual void OnControllerDisconnect( int id ); + + // Mappable interface declarations. + // Dispatch a message when controller is connected. + // + virtual void OnControllerConnect( int id ); + + // Mappable interface declarations + // + virtual void LoadControllerMappings( unsigned int controllerId ); + + // Update repeated input states + void Update( unsigned int elapsedTime, unsigned int controllerId ); + + bool IsXAxisOnLeft() const; + bool IsXAxisOnRight() const; + bool IsYAxisOnUp() const; + bool IsYAxisOnDown() const; + + void EnableStartToSelectMapping( bool isEnabled ) { m_isStartToSelectMappingEnabled = isEnabled; } + +private: + // Disallow object copying or assigning until we know we need it + // + CGuiUserInputHandler( const CGuiUserInputHandler& original ); + CGuiUserInputHandler& operator=( const CGuiUserInputHandler& rhs ); + + void ResetRepeatableButtons(); + + int m_buttonDownDuration[ GuiInput::NUM_DPAD_INPUTS ]; + + float m_XAxisValue; + float m_YAxisValue; + + int m_XAxisDuration; + int m_YAxisDuration; + +#ifdef RAD_WIN32 + float m_RightValue; + float m_LeftValue; + float m_UpValue; + float m_DownValue; + + int m_RightDuration; + int m_LeftDuration; + int m_UpDuration; + int m_DownDuration; +#endif + + bool m_isStartToSelectMappingEnabled : 1; + +}; + +#endif // GUIUSERINPUTHANDLER_H diff --git a/game/code/presentation/gui/guiwindow.cpp b/game/code/presentation/gui/guiwindow.cpp new file mode 100644 index 0000000..19c2193 --- /dev/null +++ b/game/code/presentation/gui/guiwindow.cpp @@ -0,0 +1,241 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiWindow +// +// Description: Implementation of the CGuiWindow class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/21 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <memory/classsizetracker.h> +#include <presentation/gui/guiwindow.h> +#include <presentation/gui/guimanager.h> +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiWindow::CGuiWindow +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiWindow::CGuiWindow +( + eGuiWindowID id, + CGuiEntity* pParent +) +: + CGuiEntity( pParent ), + m_state( GUI_WINDOW_STATE_UNITIALIZED ), + m_ID( id ), + m_numTransitionsPending( 0 ), + m_firstTimeEntered( true ) +{ + CLASSTRACKER_CREATE( CGuiWindow ); +} + + +//=========================================================================== +// CGuiWindow::~CGuiWindow +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiWindow::~CGuiWindow() +{ + CLASSTRACKER_CREATE( CGuiWindow ); +} + + +//=========================================================================== +// CGuiWindow::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiWindow::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_WINDOW_ENTER: + { +/* + // Ignore multiple enter requests. + // + if( GUI_WINDOW_STATE_UNITIALIZED != m_state ) + { + break; + } +*/ + m_state = GUI_WINDOW_STATE_INTRO; + this->InitIntro(); + + break; + } + + case GUI_MSG_WINDOW_EXIT: + { +/* + if( GUI_WINDOW_STATE_OUTRO == m_state || + GUI_WINDOW_STATE_UNITIALIZED == m_state ) + { + // Ignore multiple exit requests. + // + break; + } +*/ + m_state = GUI_WINDOW_STATE_OUTRO; + this->InitOutro(); + + break; + } + + case GUI_MSG_WINDOW_PAUSE: + { + m_prevState = m_state; + m_state = GUI_WINDOW_STATE_PAUSED; + break; + } + + case GUI_MSG_WINDOW_RESUME: + { + m_state = m_prevState; + break; + } + + case GUI_MSG_UPDATE: + { + if( GUI_WINDOW_STATE_UNITIALIZED == m_state + || GUI_WINDOW_STATE_PAUSED == m_state ) + { + return; + } + + switch( m_state ) + { + case GUI_WINDOW_STATE_INTRO: + { + // The intro transition is complete if there are no more + // non-persistent sequencers running. + // + if( m_numTransitionsPending == 0 ) + { + m_state = GUI_WINDOW_STATE_RUNNING; + this->InitRunning(); + } + + break; + } + + case GUI_WINDOW_STATE_OUTRO: + { + // The outro transition is complete if there are no more + // non-persistent sequencers running. + // + if( m_numTransitionsPending == 0 ) + { + // wait one more frame for last transition update to get rendered + // + m_numTransitionsPending--; + CleanUp(); + } + else if( m_numTransitionsPending < 0 ) + { + m_state = GUI_WINDOW_STATE_UNITIALIZED; + m_firstTimeEntered = false; + + m_pParent->HandleMessage( GUI_MSG_WINDOW_FINISHED ); + } + + break; + } + + default: + { + break; + } + } + + break; + } + + default: + { + break; + } + } +} + +//=========================================================================== +// CGuiWindow::CleanUp +//=========================================================================== +// Description: Called after the last outro transition is done +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiWindow::CleanUp() +{ + //do nothing +} + +//=========================================================================== +// CGuiWindow::ForceClearTransitions +//=========================================================================== +// Description: Forces all transitions to think they are done +// +// Constraints: None. +// +// Parameters: +// +// Return: N/A. +// +//=========================================================================== +void CGuiWindow::ForceClearTransitions() +{ + m_numTransitionsPending = 0; +}
\ No newline at end of file diff --git a/game/code/presentation/gui/guiwindow.h b/game/code/presentation/gui/guiwindow.h new file mode 100644 index 0000000..c7d3aa1 --- /dev/null +++ b/game/code/presentation/gui/guiwindow.h @@ -0,0 +1,188 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiWindow +// +// Description: Interface for the CGuiWindow class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUIWINDOW_H +#define GUIWINDOW_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guientity.h> +#include <presentation/gui/guimenu.h> +#ifdef RAD_WIN32 +#include <input/FEMouse.h> +#endif + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiManager; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiWindow : public CGuiEntity +{ + public: + enum eGuiWindowID + { + GUI_WINDOW_ID_UNDEFINED = -1, + + // generic screens + // + GUI_SCREEN_ID_GENERIC_MESSAGE, + GUI_SCREEN_ID_GENERIC_PROMPT, + GUI_SCREEN_ID_ERROR_PROMPT, + + // bootup and backend screens + // + GUI_SCREEN_ID_BOOTUP_LOAD, + GUI_SCREEN_ID_LICENSE, + GUI_SCREEN_ID_LANGUAGE, + GUI_SCREEN_ID_LOADING, + GUI_SCREEN_ID_LOADING_FE, + GUI_SCREEN_ID_DEMO, + + GUI_SCREEN_ID_MEMORY_CARD, + GUI_SCREEN_ID_MEMORY_CARD_CHECK, + GUI_SCREEN_ID_AUTO_LOAD, + + // front-end screens + // + GUI_SCREEN_ID_SPLASH, + GUI_SCREEN_ID_INTRO_TRANSITION, + GUI_SCREEN_ID_MAIN_MENU, + GUI_SCREEN_ID_LOAD_GAME, + GUI_SCREEN_ID_SCRAP_BOOK, + GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS, + GUI_SCREEN_ID_SCRAP_BOOK_STATS, + GUI_SCREEN_ID_CARD_GALLERY, + GUI_SCREEN_ID_MISSION_GALLERY, + GUI_SCREEN_ID_SKIN_GALLERY, + GUI_SCREEN_ID_VEHICLE_GALLERY, +// GUI_SCREEN_ID_MULTIPLAYER_SETUP, +// GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER, + GUI_SCREEN_ID_OPTIONS, + GUI_SCREEN_ID_CONTROLLER, + GUI_SCREEN_ID_SOUND, + GUI_SCREEN_ID_VIEW_MOVIES, + GUI_SCREEN_ID_VIEW_CREDITS, +#ifdef RAD_WIN32 + GUI_SCREEN_ID_DISPLAY, +#endif + GUI_SCREEN_ID_PLAY_MOVIE, + GUI_SCREEN_ID_PLAY_MOVIE_DEMO, + GUI_SCREEN_ID_PLAY_MOVIE_INTRO, + GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME, + + // in-game screens + // + GUI_SCREEN_ID_HUD, + GUI_SCREEN_ID_MULTI_HUD, + GUI_SCREEN_ID_PAUSE_SUNDAY, + GUI_SCREEN_ID_PAUSE_MISSION, + GUI_SCREEN_ID_MISSION_SELECT, + GUI_SCREEN_ID_SETTINGS, + GUI_SCREEN_ID_LEVEL_STATS, + GUI_SCREEN_ID_VIEW_CARDS, + GUI_SCREEN_ID_SAVE_GAME, + GUI_SCREEN_ID_MISSION_LOAD, + GUI_SCREEN_ID_MISSION_OVER, + GUI_SCREEN_ID_MISSION_SUCCESS, + GUI_SCREEN_ID_LETTER_BOX, + GUI_SCREEN_ID_PHONE_BOOTH, + GUI_SCREEN_ID_PURCHASE_REWARDS, + GUI_SCREEN_ID_IRIS_WIPE, + GUI_SCREEN_ID_LEVEL_END, + GUI_SCREEN_ID_TUTORIAL, + + // mini-game screens + // + GUI_SCREEN_ID_MINI_MENU, + GUI_SCREEN_ID_MINI_HUD, + GUI_SCREEN_ID_MINI_PAUSE, + GUI_SCREEN_ID_MINI_SUMMARY, + + NUM_GUI_WINDOW_IDS + }; + + CGuiWindow( eGuiWindowID id, CGuiEntity* pParent ); + virtual ~CGuiWindow(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return NULL; } + eGuiWindowID GetWindowID( void ) const { return( m_ID ); }; + void ForceClearTransitions(); + + bool IsRunning(void) {return m_state == GUI_WINDOW_STATE_RUNNING;} + +#ifdef RAD_WIN32 + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ) + { + return HOTSPOT_NONE; + } +#endif + protected: + + //--------------------------------------------------------------------- + // Protected Functions + //--------------------------------------------------------------------- + + virtual void InitIntro() = 0; + virtual void InitRunning() = 0; + virtual void InitOutro() = 0; + virtual void CleanUp(); + + enum eGuiWindowState + { + GUI_WINDOW_STATE_UNITIALIZED, + GUI_WINDOW_STATE_INTRO, + GUI_WINDOW_STATE_RUNNING, + GUI_WINDOW_STATE_PAUSED, + GUI_WINDOW_STATE_IDLE, + GUI_WINDOW_STATE_OUTRO, + + GUI_WINDOW_STATE_DISABLED, + + GUI_WINDOW_STATE_COUNT + }; + + eGuiWindowState m_state; + eGuiWindowState m_prevState; + + eGuiWindowID m_ID; + + int m_numTransitionsPending; + + bool m_firstTimeEntered; + + private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignement. Declare but don't define. + // + CGuiWindow( const CGuiWindow& ); + CGuiWindow& operator= ( const CGuiWindow& ); + +}; + +#endif // GUIWINDOW_H diff --git a/game/code/presentation/gui/ingame/allingame.cpp b/game/code/presentation/gui/ingame/allingame.cpp new file mode 100644 index 0000000..ee04a6f --- /dev/null +++ b/game/code/presentation/gui/ingame/allingame.cpp @@ -0,0 +1,27 @@ +#include <presentation/gui/ingame/guimanageringame.cpp> +#include <presentation/gui/ingame/guiscreenhastransitions.cpp> +#include <presentation/gui/ingame/guiscreenhud.cpp> +#include <presentation/gui/ingame/guiscreeniriswipe.cpp> +#include <presentation/gui/ingame/guiscreenlevelstats.cpp> +#include <presentation/gui/ingame/guiscreenlevelend.cpp> +#include <presentation/gui/ingame/guiscreenletterbox.cpp> +#include <presentation/gui/ingame/guiscreenmissionbase.cpp> +#include <presentation/gui/ingame/guiscreenmissionload.cpp> +#include <presentation/gui/ingame/guiscreenmissionover.cpp> +#include <presentation/gui/ingame/guiscreenmissionsuccess.cpp> +#include <presentation/gui/ingame/guiscreenmultihud.cpp> +#include <presentation/gui/ingame/guiscreenpause.cpp> +#include <presentation/gui/ingame/guiscreenpausemission.cpp> +#include <presentation/gui/ingame/guiscreenpauseoptions.cpp> +#include <presentation/gui/ingame/guiscreenpausecontroller.cpp> +#include <presentation/gui/ingame/guiscreenpausesound.cpp> +#include <presentation/gui/ingame/guiscreenpausesettings.cpp> +#include <presentation/gui/ingame/guiscreenpausesunday.cpp> +#include <presentation/gui/ingame/guiscreenrewards.cpp> +#include <presentation/gui/ingame/guiscreenphonebooth.cpp> +#include <presentation/gui/ingame/guiscreenpurchaserewards.cpp> +#include <presentation/gui/ingame/guiscreenmissionselect.cpp> +#include <presentation/gui/ingame/guiscreensavegame.cpp> +#include <presentation/gui/ingame/guiscreenviewcards.cpp> +#include <presentation/gui/ingame/guiscreentutorial.cpp> +#include <presentation/gui/ingame/guiscreencreditspostfmv.cpp> diff --git a/game/code/presentation/gui/ingame/guihudtextbox.h b/game/code/presentation/gui/ingame/guihudtextbox.h new file mode 100644 index 0000000..4645818 --- /dev/null +++ b/game/code/presentation/gui/ingame/guihudtextbox.h @@ -0,0 +1,41 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/07/27 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUIHUDTEXTBOX_H +#define GUIHUDTEXTBOX_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +//=========================================================================== +// External Constants +//=========================================================================== + +const float MESSAGE_TEXT_SCALE = 0.8f; +const float MESSGAE_TEXT_HORIZONTAL_STRETCH = 1.1f; + +#ifdef RAD_WIN32 +const float MESSAGE_BOX_CORRECTION_SCALE = 1.0f; +const float MESSAGE_BOX_HORIZONTAL_STRETCH = 1.1f; +#else +const float MESSAGE_BOX_CORRECTION_SCALE = 2.0f; +const float MESSAGE_BOX_HORIZONTAL_STRETCH = 1.1f; +#endif + +#ifdef PAL + const int MESSAGE_TEXT_VERTICAL_TRANSLATION = +10; + const float MESSAGE_BOX_VERTICAL_STRETCH = 1.2f; +#else + const int MESSAGE_TEXT_VERTICAL_TRANSLATION = 0; + const float MESSAGE_BOX_VERTICAL_STRETCH = 1.0f; +#endif // PAL + +#endif // GUIHUDTEXTBOX_H diff --git a/game/code/presentation/gui/ingame/guimanageringame.cpp b/game/code/presentation/gui/ingame/guimanageringame.cpp new file mode 100644 index 0000000..0a32ae3 --- /dev/null +++ b/game/code/presentation/gui/ingame/guimanageringame.cpp @@ -0,0 +1,1646 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerInGame +// +// Description: Implementation of the CGuiManagerInGame class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/21 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/guiwindow.h> // for window IDs +#include <presentation/gui/guisystem.h> + +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guiscreenmemorycard.h> + +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/ingame/guiscreenmultihud.h> +#include <presentation/gui/ingame/guiscreenpausesunday.h> +#include <presentation/gui/ingame/guiscreenpausemission.h> +#include <presentation/gui/ingame/guiscreenmissionselect.h> +#include <presentation/gui/ingame/guiscreenhudmap.h> +#include <presentation/gui/ingame/guiscreenpauseoptions.h> +#ifdef RAD_WIN32 +#include <presentation/gui/ingame/guiscreenpausedisplay.h> +#endif +#include <presentation/gui/ingame/guiscreenpausecontroller.h> +#include <presentation/gui/ingame/guiscreenpausesound.h> +#include <presentation/gui/ingame/guiscreenpausesettings.h> +#include <presentation/gui/ingame/guiscreenmissionload.h> +#include <presentation/gui/ingame/guiscreenmissionover.h> +#include <presentation/gui/ingame/guiscreenmissionsuccess.h> +#include <presentation/gui/ingame/guiscreenlevelstats.h> +#include <presentation/gui/ingame/guiscreenlevelend.h> +#include <presentation/gui/ingame/guiscreenviewcards.h> +#include <presentation/gui/ingame/guiscreenletterbox.h> +#include <presentation/gui/ingame/guiscreeniriswipe.h> +#include <presentation/gui/ingame/guiscreenphonebooth.h> +#include <presentation/gui/ingame/guiscreenpurchaserewards.h> +#include <presentation/gui/ingame/guiscreensavegame.h> +#include <presentation/gui/ingame/guiscreentutorial.h> +#include <presentation/gui/ingame/guiscreencreditspostfmv.h> +#include <presentation/gui/backend/guimanagerbackend.h> +#include <presentation/gui/backend/guiscreenloadingfe.h> +#include <presentation/gui/utility/hudmap.h> + +#include <contexts/context.h> +#include <contexts/pausecontext.h> +#include <contexts/gameplay/gameplaycontext.h> +#include <data/memcard/memorycardmanager.h> +#include <events/eventmanager.h> +#include <gameflow/gameflow.h> +#include <input/inputmanager.h> +#include <interiors/interiormanager.h> +#include <main/commandlineoptions.h> +#include <memory/srrmemory.h> +#include <mission/missionmanager.h> +#include <mission/objectives/missionobjective.h> +#include <mission/gameplaymanager.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <presentation/presentation.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> +#include <sound/soundmanager.h> +#include <meta/eventlocator.h> + +#include <p3d/fileftt.hpp> +#include <p3d/utility.hpp> +#include <p3d/view.hpp> + +#include <main/platform.h> +#include <main/game.h> + +#include <raddebug.hpp> +#include <raddebugwatch.hpp> + +#include <layer.h> +#include <page.h> +#include <screen.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const unsigned int MINIMUM_DYNA_LOAD_TIME = 250; // in msec + +#ifdef DEBUGWATCH + static const char* WATCHER_NAMESPACE = "GUI System - Ingame"; + bool g_wReversePauseMenus; +#endif + +const char* INGAME_PROJECT_FILES[] = +{ + "art\\frontend\\scrooby\\ingame.p3d", + "art\\frontend\\scrooby\\pause.p3d", + "art\\frontend\\scrooby\\rewards.p3d", + + "" // dummy terminator +}; + +CGuiScreenHud* CGuiManagerInGame::s_currentHUD = NULL; +bool cGuiManagerInGameActive = false; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManagerInGame::CGuiManagerInGame +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerInGame::CGuiManagerInGame +( + Scrooby::Project* pProject, + CGuiEntity* pParent +) +: CGuiManager( pProject, pParent ), + m_nextLevelIndex( -1 ), + m_nextMissionIndex( -1 ), + m_isLoadingNewMission( false ), + m_quitAndReload( false ), + m_controllerPromptShown( false ), + m_enteringPauseMenu( false ), + m_exitingPauseMenu( false ), + m_onHudEnterCommand( ON_HUD_ENTER_NO_COMMAND ), + m_levelScreen( NULL ), + m_levelLayer( NULL ), + m_elapsedDynaLoadTime( 0 ), + m_pRewardsProject( NULL ), + m_unloadMemcardInfoWhenLoaded( false ), + m_promptSaveBeforeQuit( true ), + m_quitAfterSave( false ), +#ifdef RAD_WIN32 + m_quitToSystemAfterSave(false), +#endif + m_isControllerReconnected( false ), + m_RecieveIrisClosed( "Recieve Iris Closed" ), + m_resumeGameScreenID( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) +{ + // + // Set Up Transitions + // + m_RecieveIrisClosed.SetEvent( EVENT_GUI_IRIS_WIPE_CLOSED ); + + m_RestartMissionTransition.SetNextTransition( m_RecieveIrisClosed ); + m_RecieveIrisClosed. SetNextTransition( m_RestartMission ); + m_RestartMission. SetNextTransition( NULL ); + + m_AbortMissionTransition. SetNextTransition( m_AbortMission ); + m_AbortMission. SetNextTransition( NULL ); + + cGuiManagerInGameActive = true; + GetEventManager()->AddListener( this, EVENT_CONVERSATION_INIT ); + GetEventManager()->AddListener( this, EVENT_CONVERSATION_DONE_AND_FINISHED ); + GetEventManager()->AddListener( this, EVENT_ENTER_INTERIOR_TRANSITION_START ); + GetEventManager()->AddListener( this, EVENT_ENTER_INTERIOR_TRANSITION_END ); + GetEventManager()->AddListener( this, EVENT_EXIT_INTERIOR_START ); + GetEventManager()->AddListener( this, EVENT_EXIT_INTERIOR_END ); + GetEventManager()->AddListener( this, (EventEnum)(EVENT_LOCATOR + LocatorEvent::DEATH) ); + + Scrooby::Project* pLevelProject = GetGuiSystem()->GetScroobyLevelProject(); + if( pLevelProject != NULL ) + { + m_levelScreen = pLevelProject->GetCurrentScreen(); + rAssert( m_levelScreen ); + + // get layer + // + Scrooby::Page* pPage = m_levelScreen->GetPage( "PauseBgd" ); + rAssert( pPage ); + m_levelLayer = pPage->GetLayerByIndex( 0 ); + rAssert( m_levelLayer ); + m_levelLayer->SetAlpha( 0.0f ); + } + +#ifdef DEBUGWATCH + radDbgWatchAddBoolean( &g_wReversePauseMenus, + "Reverse Pause Menus", + WATCHER_NAMESPACE ); +#endif +} + + +//=========================================================================== +// CGuiManagerInGame::~CGuiManagerInGame +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerInGame::~CGuiManagerInGame() +{ + cGuiManagerInGameActive = false; + GetEventManager()->RemoveAll( this ); + +#ifdef DEBUGWATCH + radDbgWatchDelete( &g_wReversePauseMenus ); +#endif + s_currentHUD = NULL; +} + + +//=========================================================================== +// CGuiManagerInGame::Popluate +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerInGame::Populate() +{ +MEMTRACK_PUSH_GROUP( "CGUIManagerInGame" ); + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + Scrooby::Screen* pScroobyScreen = NULL; + CGuiScreen* pScreen = NULL; + + pScroobyScreen = m_pScroobyProject->GetScreen( "Message" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMessage( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPrompt( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "ErrorPrompt" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPrompt( pScroobyScreen, this, + CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT ); + + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Hud" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenHud( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_HUD, pScreen ); + + // store current HUD reference + // + s_currentHUD = dynamic_cast<CGuiScreenHud*>( pScreen ); + rAssert( s_currentHUD != NULL ); + } +/* + pScroobyScreen = m_pScroobyProject->GetScreen( "MultiHud" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMultiHud( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MULTI_HUD, pScreen ); + } +*/ + pScroobyScreen = m_pScroobyProject->GetScreen( "MissionLoad" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMissionLoad( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_LOAD, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MissionOver" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMissionOver( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_OVER, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MissionLoad" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMissionSuccess( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_SUCCESS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "LevelStats" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLevelStats( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LEVEL_STATS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "LevelEnd" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLevelEnd( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LEVEL_END, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseViewCards" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenViewCards( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_CARDS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "LetterBox" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenLetterBox( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LETTER_BOX, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "IrisWipe" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenIrisWipe( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PhoneBooth" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPhoneBooth( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PHONE_BOOTH, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PurchaseRewards" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPurchaseRewards( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PURCHASE_REWARDS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseSunday" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPauseSunday( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseMission" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPauseMission( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseOptions" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPauseOptions( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_OPTIONS, pScreen ); + } +#ifdef RAD_WIN32 + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseDisplay" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPauseDisplay( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_DISPLAY, pScreen ); + } +#endif + + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseController" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPauseController( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_CONTROLLER, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseSound" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPauseSound( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SOUND, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "PauseSettings" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenPauseSettings( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SETTINGS, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MissionSelect" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMissionSelect( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_SELECT, pScreen ); + } +/* + pScroobyScreen = m_pScroobyProject->GetScreen( "ViewMap" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenHudMap( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_HUD_MAP, pScreen ); + } +*/ + pScroobyScreen = m_pScroobyProject->GetScreen( "MemoryCard" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenMemoryCard( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "SaveGame" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenSaveGame( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SAVE_GAME, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "Tutorial" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenTutorial( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_TUTORIAL, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "CreditsPostFMV" ); + if( pScroobyScreen != NULL ) + { + pScreen = new CGuiScreenCreditsPostFMV( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_CREDITS, pScreen ); + } + + // hide HUD if specified in commandline options + // + if( CommandLineOptions::Get( CLO_NO_HUD ) ) + { + if( s_currentHUD != NULL ) + { + s_currentHUD->SetVisible( false ); + } + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); +MEMTRACK_POP_GROUP("CGUIManagerInGame"); +} + +void +CGuiManagerInGame::Start( CGuiWindow::eGuiWindowID initialWindow ) +{ + rAssert( GUI_FE_UNINITIALIZED == m_state || m_isLoadingNewMission ); + + m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ? + initialWindow : + CGuiWindow::GUI_SCREEN_ID_HUD; + + m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen() + + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); +} + +//=========================================================================== +// CGuiManagerInGame::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerInGame::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_FE_DYNAMIC_LOADING ) + { + rAssertMsg( false, "Dynamic loading of pause menu and HUD is no longer implemented!" ); + + return; + } + + if( m_isLoadingNewMission ) + { + if( message == GUI_MSG_UPDATE ) + { + this->UpdateDuringMissionLoading( param1 ); + } + else if( message == GUI_MSG_RESUME_INGAME ) + { + this->OnNewMissionLoadEnd(); + } + + CGuiManager::HandleMessage( message, param1, param2 ); + + // and ignore all other messages + // + return; + } + + if( m_state == GUI_FE_TERMINATED ) + { + if( message == GUI_MSG_UPDATE ) + { + this->UpdateWhileLoadingNotDone( param1 ); + } + + // and ignore all other messages + // + return; + } + +#ifdef RAD_DEMO + if( this->IsControllerMessage( message ) ) + { + GetGameplayManager()->ResetIdleTime(); + } +#endif + + switch( message ) + { + case GUI_MSG_PROMPT_START_RESPONSE: + { + HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + break; + } + case GUI_MSG_QUIT_INGAME_FOR_RELOAD: + { + m_quitAndReload = true; + m_nextLevelIndex = static_cast<int>( param1 ); + m_nextMissionIndex = static_cast<int>( param2 ); + + if( GetGameplayManager()->GetLevelComplete() ) + { + if( GetGameplayManager()->GetGameComplete() ) + { + // wrap back to level 1, mission 1 (not the tutorial mission) + // + GetCharacterSheetManager()->SetCurrentMission( RenderEnums::L1, RenderEnums::M2 ); // M2 = mission 1 + + // tell GUI system to show credits upon returning to FE + // +// GetGuiSystem()->ShowCreditsUponReturnToFE( true ); + + m_quitAndReload = false; + } + else + { + GetCharacterSheetManager()->SetCurrentMission( static_cast<RenderEnums::LevelEnum>( m_nextLevelIndex ), + static_cast<RenderEnums::MissionEnum>( m_nextMissionIndex ) ); + } + +#ifdef RAD_DEMO + m_promptSaveBeforeQuit = false; + m_quitAndReload = false; +#else + this->DisplayPrompt( PROMPT_CONFIRM_SAVE_BEFORE_QUIT, + this, + PROMPT_TYPE_YES_NO, + false ); + + break; +#endif // RAD_DEMO + } + else + { + // don't prompt to save unless we're advancing to a new level + // + m_promptSaveBeforeQuit = false; + } + + // follow-thru ... + // + } + + case GUI_MSG_QUIT_INGAME: + { + if( GUI_FE_SCREEN_RUNNING == m_state ) + { +#ifndef RAD_DEMO + if( m_promptSaveBeforeQuit && GetGameplayManager()->IsSundayDrive() ) + { + this->DisplayPrompt( PROMPT_CONFIRM_SAVE_BEFORE_QUIT, + this, + PROMPT_TYPE_YES_NO, + false ); + } + else +#endif + { + m_state = GUI_FE_SHUTTING_DOWN; + + // if paused in sunday drive mode, unload memory card info + // + if( GetGameplayManager()->IsSundayDrive() ) + { + if( GetMemoryCardManager()->IsMemcardInfoLoaded() ) + { + // unload it now + // + GetMemoryCardManager()->UnloadMemcardInfo(); + } + else + { + // wait until loading is complete, then unload it + // + m_unloadMemcardInfoWhenLoaded = true; + } + } +/* + CGuiScreenPrompt* promptScreen = static_cast<CGuiScreenPrompt*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) ); + rAssert( promptScreen != NULL ); + promptScreen->RestoreScreenCover(); +*/ + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + } + } + + break; + } +#ifdef RAD_WIN32 + case GUI_MSG_QUIT_TO_SYSTEM: + { + if( GUI_FE_SCREEN_RUNNING == m_state ) + { + if( m_promptSaveBeforeQuit && GetGameplayManager()->IsSundayDrive() ) + { + this->DisplayPrompt( PROMPT_CONFIRM_SAVE_BEFORE_QUITTOSYSTEM, + this, + PROMPT_TYPE_YES_NO, + false ); + } + else + { + m_state = GUI_FE_SHUTTING_DOWN; + + // if paused in sunday drive mode, unload memory card info + // + if( GetGameplayManager()->IsSundayDrive() ) + { + if( GetMemoryCardManager()->IsMemcardInfoLoaded() ) + { + // unload it now + // + GetMemoryCardManager()->UnloadMemcardInfo(); + } + else + { + // wait until loading is complete, then unload it + // + m_unloadMemcardInfoWhenLoaded = true; + } + } + /* + CGuiScreenPrompt* promptScreen = static_cast<CGuiScreenPrompt*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) ); + rAssert( promptScreen != NULL ); + promptScreen->RestoreScreenCover(); + */ + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + + // let's begin the quit procedure + // + GetGameFlow()->SetContext( CONTEXT_EXIT ); + } + } + + break; + } +#endif + case GUI_MSG_MENU_PROMPT_RESPONSE: + { +#ifdef RAD_WIN32 + if( param1 == PROMPT_CONFIRM_SAVE_BEFORE_QUITTOSYSTEM ) + { + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_SAVE_GAME ); + + m_quitToSystemAfterSave = true; + } + else + { + rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO ); + + m_promptSaveBeforeQuit = false; + + this->HandleMessage( GUI_MSG_QUIT_TO_SYSTEM ); + } + + } +#endif + if( param1 == PROMPT_CONFIRM_SAVE_BEFORE_QUIT ) + { + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { +#ifdef RAD_XBOX + // Xbox TCR Requirement: always prompt user to select memory + // device before loading/saving + // + CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = true; +#endif +// this->PushScreenHistory( GetGameplayManager()->IsSundayDrive() ? +// CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY : +// CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION ); + + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_SAVE_GAME ); + + m_quitAfterSave = true; + } + else + { + rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO ); + + m_promptSaveBeforeQuit = false; + + this->HandleMessage( GUI_MSG_QUIT_INGAME ); + } + } + + break; + } + case GUI_MSG_PAUSE_INGAME: + { + if( !this->IsPausingAllowed() ) + { + rTuneWarningMsg( false, "*** Pause request ingored! ***" ); + break; + } + + // switch to pause context + // + GetGameFlow()->SetContext( CONTEXT_PAUSE ); + + bool inSundayDriveMode = GetGameplayManager()->IsSundayDrive(); +#ifdef DEBUGWATCH + if( g_wReversePauseMenus ) + { + inSundayDriveMode = !inSundayDriveMode; + } +#endif + CGuiWindow::eGuiWindowID pauseWindow = inSundayDriveMode ? + CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY : + CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION; + + // remember current screen before going to pause menu + // + m_resumeGameScreenID = m_currentScreen; + + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + pauseWindow, + CLEAR_WINDOW_HISTORY ); + + // if pausing in sunday drive mode, load memory card info + // for saving games + // + if( GetGameplayManager()->IsSundayDrive() ) + { + m_unloadMemcardInfoWhenLoaded = false; + GetMemoryCardManager()->LoadMemcardInfo( this ); + } + + GetSoundManager()->OnPauseStart(); + + m_enteringPauseMenu = true; + GetGameplayContext()->PauseAllButPresentation( true ); + + m_promptSaveBeforeQuit = true; + + break; + } + case GUI_MSG_UNPAUSE_INGAME: + { + if( GetGameplayManager()->GetLevelComplete() || GetGameplayManager()->GetGameComplete() ) + { + // can't un-pause the game if either level or game is just completed (i.e. just + // finished the last mission of the level) + // + break; + } + + GetSoundManager()->OnPauseEnd(); + + // if paused in sunday drive mode, unload memory card info + // + if( GetGameplayManager()->IsSundayDrive() ) + { + if( GetMemoryCardManager()->IsMemcardInfoLoaded() ) + { + // unload it now + // + GetMemoryCardManager()->UnloadMemcardInfo(); + } + else + { + // wait until loading is complete, then unload it + // + m_unloadMemcardInfoWhenLoaded = true; + } + } + + m_exitingPauseMenu = true; + + // follow-thru ... + // + } + case GUI_MSG_RESUME_INGAME: + { + if( GetInteriorManager()->IsEntering() || GetInteriorManager()->IsExiting() ) + { + // ignore this message, cuz if we're either entering or exiting an interior, + // we're waiting for either the EVENT_ENTER_INTERIOR_TRANSITION_END or + // EVENT_EXIT_INTERIOR_END event from the InteriorManager to resume the game + // screen + // + break; + } + + this->ResumeGame( param1, param2 ); + + break; + } + case GUI_MSG_ON_SAVE_GAME_COMPLETE: + { + m_promptSaveBeforeQuit = false; + + if( m_quitAfterSave ) + { + this->HandleMessage( GUI_MSG_QUIT_INGAME ); + } +#ifdef RAD_WIN32 + else if( m_quitToSystemAfterSave ) + { + this->HandleMessage( GUI_MSG_QUIT_TO_SYSTEM ); + } +#endif + else + { + this->HandleMessage( GUI_MSG_BACK_SCREEN ); + } + + break; + } + case GUI_MSG_BACK_SCREEN: + { + if( this->GetPreviousScreen( param1 ) == CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) + { + m_quitAfterSave = false; + + CGuiMenuPrompt::ePromptResponse responses[] = + { + CGuiMenuPrompt::RESPONSE_YES, + CGuiMenuPrompt::RESPONSE_NO + }; + + CGuiScreenPrompt::Display( PROMPT_CONFIRM_SAVE_BEFORE_QUIT, this, 2, responses ); + CGuiScreenPrompt::EnableDefaultToNo( false ); + } + + break; + } + case GUI_MSG_WINDOW_FINISHED: + { + if( GUI_FE_CHANGING_SCREENS == m_state ) + { + m_currentScreen = m_nextScreen; + + if( m_exitingPauseMenu ) + { + this->GotoHUDScreen(); + } + else if( m_enteringPauseMenu ) + { + this->GotoPauseScreen(); + } + else + { + if( this->IsHudScreen( m_nextScreen ) ) + { + this->GotoHUDScreen(); + } + else + { + CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + } + } + } + else if( GUI_FE_SHUTTING_DOWN == m_state ) + { + m_state = GUI_FE_TERMINATED; + + // set backend scrooby project as active project + // + GetGuiSystem()->SwitchToBackendProject(); + + // pre-run backend loading screen + // + CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager(); + rAssert( backendManager != NULL ); + backendManager->HandleMessage( GUI_MSG_PRE_RUN_BACKEND, + m_quitAndReload ? IS_LOADING_GAMEPLAY : 0 ); + + // enable screen clearing + // + GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearMask( PDDI_BUFFER_ALL ); + } + + break; + } + case GUI_MSG_INGAME_MISSION_COMPLETE: + { + // param1 = 1 --> New Best Time! + // + if( s_currentHUD != NULL ) + { + s_currentHUD->HandleMessage( GUI_MSG_SHOW_HUD_OVERLAY, + HUD_MISSION_COMPLETE, param1 ); + } + + break; + } + case GUI_MSG_INGAME_MISSION_FAILED: + { + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_MISSION_OVER, + CLEAR_WINDOW_HISTORY ); + + // switch to pause context + GetGameFlow()->SetContext( CONTEXT_PAUSE ); + break; + } + case GUI_MSG_INGAME_MISSION_LOAD_BEGIN: + { + // + // if we're on the iris screen, then we don't want to open the iris + // + CGuiWindow::eGuiWindowID current = CGuiManager::GetCurrentScreen(); + if( current == CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE ) + { + CGuiScreenIrisWipe::DoNotOpenOnNextOutro(); + } + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_MISSION_LOAD, + CLEAR_WINDOW_HISTORY ); + + // switch to pause context + GetGameFlow()->SetContext( CONTEXT_PAUSE ); + + break; + } + case GUI_MSG_INGAME_MISSION_LOAD_END: + { + // notify MissionLoad screen that mission load has completed + // + if( !GetGameplayManager()->GetCurrentMission()->IsSundayDrive() ) + { + GetEventManager()->TriggerEvent( EVENT_GUI_MISSION_LOAD_COMPLETE ); + } + + break; + } + case GUI_MSG_SHOW_HUD_OVERLAY: + case GUI_MSG_HIDE_HUD_OVERLAY: + { + // send HUD overlay messages to current HUD + // + if( s_currentHUD != NULL ) + { + s_currentHUD->HandleMessage( message, param1, param2 ); + } + + break; + } + case GUI_MSG_CONTROLLER_CONNECT: + { +#ifndef RAD_GAMECUBE + if( m_oldControllerState == Input::ACTIVE_ANIM_CAM ) + { + // deactivate anim cam state first, since the input manager + // won't let us set the game state to anything else prior + // to that + // + GetInputManager()->SetGameState( Input::DEACTIVE_ANIM_CAM ); + } + GetInputManager()->SetGameState( Input::ACTIVE_FRONTEND ); +#endif // !RAD_GAMECUBE + + break; + } + case GUI_MSG_START_IRIS_WIPE_OPEN: + { + this->HandleMessage( GUI_MSG_RESUME_INGAME ); + + break; + } + case GUI_MSG_START_IRIS_WIPE_CLOSE: + { + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE, + CLEAR_WINDOW_HISTORY ); + + break; + } + case GUI_MSG_INGAME_DISPLAY_PROMPT: + { + int ingameMessageIndex = NUM_PROMPT_QUESTIONS + static_cast<int>( param1 ); + this->DisplayPrompt( ingameMessageIndex, s_currentHUD, PROMPT_TYPE_CONTINUE ); + + rAssert( GetGameFlow()->GetCurrentContext() == CONTEXT_GAMEPLAY ); + GetGameFlow()->SetContext( CONTEXT_PAUSE ); + + break; + } + default: + { + if( message == GUI_MSG_UPDATE && m_isControllerReconnected ) + { + m_isControllerReconnected = false; + m_controllerPromptShown = false; + + } + + if (m_controllerPromptShown) // don't pass event if controller error + { + if (message==GUI_MSG_CONTROLLER_START) // start trigger reconnection + { + this->OnControllerConnected( static_cast<int>( param1 ) ); + } + + break; + } + + if( m_state != GUI_FE_UNINITIALIZED && + m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + // Send the messages down to the current screen. + // + CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen ); + rAssert( pScreen ); + + pScreen->HandleMessage( message, param1, param2 ); + } + +#ifndef RAD_GAMECUBE + // poll controller connection status + // + if( message == GUI_MSG_UPDATE ) + { + int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 ); + if( !GetInputManager()->GetController( controllerID )->IsConnected() ) + { + bool setState = !m_controllerPromptShown; + this->OnControllerDisconnected( controllerID ); + + if ( setState ) + { + m_oldControllerState = InputManager::GetInstance()->GetGameState(); + } + } + } +#endif // !RAD_GAMECUBE + + break; + } + } + + // propogate message up the hierarchy + CGuiManager::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiManagerInGame::HandleEvent +//=========================================================================== +// Description: This function translates events from to GUI messages +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiManagerInGame::HandleEvent( EventEnum id, void* pEventData ) +{ + switch( id ) + { + case EVENT_CONVERSATION_INIT: + { + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_LETTER_BOX, + CLEAR_WINDOW_HISTORY ); + + GetInputManager()->SetGameState(Input::ACTIVE_FRONTEND); + + break; + } + case EVENT_CONVERSATION_DONE_AND_FINISHED: + { + // + // Was this mission a patty and selma conversation + // + GameplayManager* gpm = GetGameplayManager(); + Mission* mission = gpm->GetCurrentMission(); + bool pattyAndSelma = mission->GetCurrentStage()->GetObjective()->IsPattyAndSelmaDialog(); + if( pattyAndSelma ) + { + + GetInputManager()->SetGameState(Input::ACTIVE_GAMEPLAY); + this->HandleMessage( GUI_MSG_RESUME_INGAME ); + GetEventManager()->TriggerEvent( EVENT_GUI_TRIGGER_PATTY_AND_SELMA_SCREEN ); + + /* + GetGuiSystem()->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_MISSION_SUCCESS, + CLEAR_WINDOW_HISTORY ); + GetEventManager()->TriggerEvent( EVENT_GUI_ENTERING_MISSION_SUCCESS_SCREEN ); + GetGameFlow()->SetContext( CONTEXT_PAUSE ); + */ + } + else + { + GetInputManager()->SetGameState(Input::ACTIVE_GAMEPLAY); + this->HandleMessage( GUI_MSG_RESUME_INGAME ); + } + + break; + } + case EVENT_ENTER_INTERIOR_TRANSITION_START: + case EVENT_EXIT_INTERIOR_START: + { +/* + if( m_currentScreen == CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE ) + { + // ignore, if we're already on the iris wipe screen + // + break; + } +*/ + if( id == EVENT_ENTER_INTERIOR_TRANSITION_START ) + { + rReleasePrintf( "CGuiManagerInGame <= EVENT_ENTER_INTERIOR_TRANSITION_START.\n" ); + } + else + { + rReleasePrintf( "CGuiManagerInGame <= EVENT_EXIT_INTERIOR_START.\n" ); + } + + this->HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE, + CLEAR_WINDOW_HISTORY ); + + break; + } + case EVENT_ENTER_INTERIOR_TRANSITION_END: + case EVENT_EXIT_INTERIOR_END: + { + if( id == EVENT_ENTER_INTERIOR_TRANSITION_END ) + { + rReleasePrintf( "CGuiManagerInGame <= EVENT_ENTER_INTERIOR_TRANSITION_END.\n" ); + } + else + { + rReleasePrintf( "CGuiManagerInGame <= EVENT_EXIT_INTERIOR_END.\n" ); + } + + this->ResumeGame(); + + break; + } + case (EventEnum)(EVENT_LOCATOR + LocatorEvent::DEATH): + { + EventLocator* evtLoc = static_cast<EventLocator*>(pEventData); + if ( evtLoc->GetPlayerID() < static_cast<unsigned int>(MAX_PLAYERS) ) + { + //chuck: check if the current hud is active, if it's not then it may not generate the + //EVENT_DEATH_VOLUME_SCREEN_BLANK, so we should artifically trigger it + if( s_currentHUD != NULL && s_currentHUD->IsActive() ) + { + //This is a player who triggered this. + s_currentHUD->HandleMessage( GUI_MSG_DEATH_VOLUME_START, reinterpret_cast< unsigned int >( pEventData ) ); + } + else + { + // current HUD is not active, so letz just fire this event back to whoever is + // waiting for it and ditch the presentation + // + GetEventManager()->TriggerEvent(EVENT_DEATH_VOLUME_SCREEN_BLANK,pEventData); + } + } + + break; + } + default: + { + rWarningMsg( false, "Why are we receiving messages we care nothing about?" ); + + break; + } + } +} + + +//=========================================================================== +// CGuiManagerInGame::OnProjectLoadComplete +//=========================================================================== +void +CGuiManagerInGame::OnProjectLoadComplete( Scrooby::Project* pProject ) +{ + m_pScroobyProject = pProject; + GetGuiSystem()->SetCurrentScroobyProject( m_pScroobyProject ); + + rReleasePrintf( "Scrooby dynamic loading completed. (%d msec)\n", m_elapsedDynaLoadTime ); +} + +void +CGuiManagerInGame::OnMemcardInfoLoadComplete() +{ + if( m_unloadMemcardInfoWhenLoaded ) + { + GetMemoryCardManager()->UnloadMemcardInfo(); + } +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +void +CGuiManagerInGame::UpdateDuringMissionLoading( unsigned int elapsedTime ) +{ + // update backend loading screen + // + CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager(); + rAssert( backendManager != NULL ); + backendManager->HandleMessage( GUI_MSG_UPDATE, elapsedTime ); +} + +void +CGuiManagerInGame::UpdateWhileLoadingNotDone( unsigned int elapsedTime ) +{ + // update backend loading screen + // + CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager(); + rAssert( backendManager != NULL ); + backendManager->HandleMessage( GUI_MSG_UPDATE, elapsedTime ); + + // waiting for loading manger queue to empty before quitting + // + if( GetLoadingManager()->IsLoading() ) + { + rTunePrintf( ">> Waiting for loading manager to finish loading ... ...\n" ); + } + else + { + // ok, let's quit outa here! + // + this->QuitGame(); + } +} + +void +CGuiManagerInGame::GotoPauseScreen() +{ + m_enteringPauseMenu = false; + GetGameplayContext()->PauseAllButPresentation( false ); + + rAssert( m_nextScreen == CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY || + m_nextScreen == CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION ); + + CGuiScreen* pauseScreen = (CGuiScreen*)CGuiManager::FindWindowByID( m_nextScreen ); + rAssert( pauseScreen ); + pauseScreen->SetZoomingEnabled( true ); + + m_pScroobyProject->GotoScreen( pauseScreen->GetScroobyScreen(), this ); +} + +void +CGuiManagerInGame::GotoHUDScreen() +{ + m_exitingPauseMenu = false; + + GetEventManager()->TriggerEvent( EVENT_GUI_LEAVING_PAUSE_MENU ); + + CGuiScreen* hudScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) ); + rAssert( hudScreen != NULL ); + m_pScroobyProject->GotoScreen( hudScreen->GetScroobyScreen(), this ); + + // handle any commands specified for upon entering HUD + // + switch( m_onHudEnterCommand ) + { + case ON_HUD_ENTER_RESTART_MISSION: + { + GetGuiSystem()->HandleMessage( GUI_MSG_START_IRIS_WIPE_CLOSE, 0x00 ); + m_RestartMissionTransition.Activate(); + + // stop any dialog that may still be in progress + // + GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP ); + + break; + } + case ON_HUD_ENTER_ABORT_MISSION: + { + m_AbortMissionTransition.Activate(); + + // stop any dialog that may still be in progress + // + GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP ); + + break; + } + case ON_HUD_ENTER_SKIP_MISSION: + { + GetGameFlow()->SetContext( CONTEXT_GAMEPLAY ); + GetGameplayManager()->AbortCurrentMission(); + GetGameplayManager()->NextMission(); + + RenderEnums::LevelEnum currentLevel = GetCharacterSheetManager()->QueryCurrentMission().mLevel; + RenderEnums::MissionEnum currentMission = GetCharacterSheetManager()->QueryCurrentMission().mMissionNumber; + GetCharacterSheetManager()->SetMissionSkipped( currentLevel, currentMission ); + + break; + } + default: + { + // don't switch to gameplay context if returning to tutorial screen + // + if(m_nextScreen == CGuiWindow::GUI_SCREEN_ID_HUD) + { + GetGameFlow()->SetContext( CONTEXT_GAMEPLAY ); + } + + break; + } + } + + m_onHudEnterCommand = ON_HUD_ENTER_NO_COMMAND; +} + +void +CGuiManagerInGame::ResumeGame( unsigned int param1, unsigned int param2 ) +{ + if( m_resumeGameScreenID != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + m_resumeGameScreenID, + CLEAR_WINDOW_HISTORY ); + } + else + { + CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN, + CGuiWindow::GUI_SCREEN_ID_HUD, + CLEAR_WINDOW_HISTORY ); + } + + m_resumeGameScreenID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED; + + m_onHudEnterCommand = param1; + m_nextMissionIndex = param2; +} + +void +CGuiManagerInGame::QuitGame() +{ + if( m_quitAndReload ) + { + rAssert( m_nextLevelIndex != -1 && m_nextMissionIndex != -1 ); + + // switch to loading context + // + if( m_nextLevelIndex != GetGameplayManager()->GetCurrentLevelIndex() ) + { + if( GetGameplayManager()->GetGameComplete() ) // game finished + { + GetGameFlow()->SetContext( CONTEXT_FRONTEND ); + } + else + { + GetGameFlow()->SetContext( CONTEXT_LOADING_GAMEPLAY ); + } + } + else + { + this->OnNewMissionLoadBegin(); + } + + m_quitAndReload = false; + } + else + { + // switch to frontend context + GetGameFlow()->SetContext( CONTEXT_FRONTEND ); + } +} + +void +CGuiManagerInGame::OnControllerDisconnected( int controllerID ) +{ +/* + if( s_currentHUD != NULL ) + { + s_currentHUD->SetFadingEnabled( false ); + } +*/ + + m_controllerPromptShown = true; + char str_buffer[256]; + CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255); + GetGame()->GetPlatform()->OnControllerError(str_buffer); + +} + +void +CGuiManagerInGame::OnControllerConnected( int controllerID ) +{ + if( m_controllerPromptShown + && GetInputManager()->GetControllerIDforPlayer( 0 ) == controllerID ) + { + +#ifdef RAD_XBOX +// go to pause screen after disconnection + rAssert(s_currentHUD); + if( s_currentHUD && s_currentHUD->IsActive() ) + this->HandleMessage( GUI_MSG_PAUSE_INGAME ); +#endif + GetGame()->GetPlatform()->ClearControllerError(); + + InputManager::GetInstance()->SetGameState(m_oldControllerState); + + m_isControllerReconnected = true; + + } +} + +//=========================================================================== +// CGuiManagerInGame::OnNewMissionLoadBegin +//=========================================================================== +// Description: Starting point for loading a new mission (within the same +// level) from the Mission Select screen. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiManagerInGame::OnNewMissionLoadBegin() +{ + GetGameplayManager()->RestartToMission( static_cast<RenderEnums::MissionEnum>( m_nextMissionIndex ) ); + + GetPauseContext()->SetWaitingForContextSwitch( true ); + + m_resumeGameScreenID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED; + + // run backend loading screen + // + CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager(); + rAssert( backendManager != NULL ); + backendManager->HandleMessage( GUI_MSG_RUN_BACKEND, IS_LOADING_GAMEPLAY ); + + m_state = GUI_FE_UNINITIALIZED; + + m_isLoadingNewMission = true; +} + +//=========================================================================== +// CGuiManagerInGame::OnNewMissionLoadEnd +//=========================================================================== +// Description: Finishing point for loading a new mission (within the same +// level) from the Mission Select screen. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiManagerInGame::OnNewMissionLoadEnd() +{ + this->Start(); + this->ClearScreenHistory(); + + // quit backend loading screen + // + CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager(); + rAssert( backendManager != NULL ); + backendManager->HandleMessage( GUI_MSG_QUIT_BACKEND ); + + GetGuiSystem()->SwitchToCurrentProject(); + + m_isLoadingNewMission = false; +} + +//=========================================================================== +// CGuiManagerInGame::IsPausingAllowed +//=========================================================================== +// Description: returns FALSE if in-game pausing is not allowed due to +// at least one condition; otherwise, returns TRUE +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +bool +CGuiManagerInGame::IsPausingAllowed() const +{ + if( m_state == GUI_FE_CHANGING_SCREENS ) + { + // don't allow pausing if we're currently in the middle of changing screens + // + return false; + } + + if( GameplayContext::GetInstance()->IsPaused() || GetPresentationManager()->IsBusy() ) + { + return false; + } + + if( GetGameplayManager()->GetCurrentMessage() != GameplayManager::NONE ) + { + // don't allow pausing if the gameplay manager is in the middle of changing missions + // + rAssert( GetGameplayManager()->GetCurrentMessage() == GameplayManager::PREV_MISSION || + GetGameplayManager()->GetCurrentMessage() == GameplayManager::NEXT_MISSION ); + + return false; + } + + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + if( currentMission->IsChangingStages() ) + { + // don't allow pausing if the current mission is in the middle of changing stages + // + return false; + } + + if( GetGameplayManager()->GetLevelComplete() || GetGameplayManager()->GetGameComplete() ) + { + // don't allow pausing if level/game has just been completed + // + return false; + } + + return true; +} + + +//=========================================================================== +// AbortCurrentMission::Activate +//=========================================================================== +// Description: cancels a mission +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void GuiSFX::AbortCurrentMission::Activate() +{ + GetGameFlow()->SetContext( CONTEXT_GAMEPLAY ); + GetGameplayManager()->AbortCurrentMission(); + ContinueChain(); +}; + +//=========================================================================== +// RestartCurrentMission::OpenIris +//=========================================================================== +// Description: reactivates a paused mission +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void GuiSFX::OpenIris::Activate() +{ + bool irisClosed = CGuiScreenIrisWipe::IsIrisClosed(); + if( irisClosed ) + { + GetGuiSystem()->HandleMessage( GUI_MSG_START_IRIS_WIPE_OPEN, 0x00 ); + } + ContinueChain(); +}; + +//=========================================================================== +// RestartCurrentMission::Activate +//=========================================================================== +// Description: reactivates a paused mission +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void GuiSFX::RestartCurrentMission::Activate() +{ + GetGameplayManager()->RestartCurrentMission(); + ContinueChain(); +}; diff --git a/game/code/presentation/gui/ingame/guimanageringame.h b/game/code/presentation/gui/ingame/guimanageringame.h new file mode 100644 index 0000000..7356585 --- /dev/null +++ b/game/code/presentation/gui/ingame/guimanageringame.h @@ -0,0 +1,231 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerInGame +// +// Description: Interface for the CGuiManagerInGame class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/09/20 DChau Created +// 2002/05/29 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUIMANAGERINGAME_H +#define GUIMANAGERINGAME_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guimanager.h> +#include <presentation/gui/utility/transitions.h> +#include <data/memcard/memorycardmanager.h> +#include <input/inputmanager.h> + +#include <app.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiScreenHud; +namespace GuiSFX +{ + class RecieveEvent; + + class AbortCurrentMission : public GuiSFX::Chainable1 + { + public: + virtual void Activate(); + }; //class AbortCurrentMission; + + class OpenIris : public GuiSFX::Chainable1 + { + public: + virtual void Activate(); + }; //class RestartCurrentMission; + + class RestartCurrentMission : public GuiSFX::Chainable1 + { + public: + virtual void Activate(); + }; //class RestartCurrentMission; +}; //namespace GuiSFX + +namespace Scrooby +{ + class Layer; +} + +enum eOnHudEnterCommand +{ + ON_HUD_ENTER_NO_COMMAND = 0, + + ON_HUD_ENTER_RESTART_MISSION, + ON_HUD_ENTER_ABORT_MISSION, + ON_HUD_ENTER_SKIP_MISSION, + + NUM_ON_HUD_ENTER_COMMANDS +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class CGuiManagerInGame : public CGuiManager, + public Scrooby::LoadProjectCallback, + public IMemoryCardInfoLoadCallback +{ +public: + CGuiManagerInGame( Scrooby::Project* pProject, CGuiEntity* pParent ); + virtual ~CGuiManagerInGame(); + + virtual void Populate(); + virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual void HandleEvent( EventEnum id, void* pEventData ); + + int GetNextLevelToLoad() const { return m_nextLevelIndex; } + int GetNextMissionToLoad() const { return m_nextMissionIndex; } + + bool IsEnteringPauseMenu() const { return m_enteringPauseMenu; } + bool isExitingPauseMenu() const { return m_exitingPauseMenu; } + + bool IsLoadingNewMissionInSundayDrive() const; // newspaper loading screen displayed + bool IsLoadingNewMission() const; // mission briefing screen displayed + + CGuiWindow::eGuiWindowID GetResumeGameScreenID() const { return m_resumeGameScreenID; } + + // + // Implements Scrooby::LoadProjectCallback interface. + // + virtual void OnProjectLoadComplete( Scrooby::Project* pProject ); + + // Implements IMemoryCardInfoLoadCallback interface. + // + virtual void OnMemcardInfoLoadComplete(); + + // Pointer to current HUD. + // + static CGuiScreenHud* s_currentHUD; + +private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignment. Declare but don't define. + // + CGuiManagerInGame( const CGuiManagerInGame& ); + CGuiManagerInGame& operator= ( const CGuiManagerInGame& ); + + bool IsHudScreen( CGuiWindow::eGuiWindowID windowID ) const; + bool IsRewardsScreen( CGuiWindow::eGuiWindowID windowID ) const; + + enum eInGameProject + { + PROJECT_INGAME, + PROJECT_PAUSE, + PROJECT_REWARDS, + + NUM_INGAME_PROJECTS + }; + + void PopulateInGame( eInGameProject project = PROJECT_INGAME ); + + void UpdateDuringDynamicLoading( unsigned int elapsedTime ); + void UpdateDuringMissionLoading( unsigned int elapsedTime ); + void UpdateWhileLoadingNotDone( unsigned int elapsedTime ); + + void GotoPauseScreen(); + void GotoHUDScreen(); + + void ResumeGame( unsigned int param1 = 0, unsigned int param2 = 0 ); + void QuitGame(); + + void OnControllerDisconnected( int controllerID ); + void OnControllerConnected( int controllerID ); + + void OnNewMissionLoadBegin(); + void OnNewMissionLoadEnd(); + + bool IsPausingAllowed() const; + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + int m_nextLevelIndex; + int m_nextMissionIndex; + + bool m_isLoadingNewMission : 1; + bool m_quitAndReload : 1; + bool m_controllerPromptShown : 1; + bool m_enteringPauseMenu : 1; + bool m_exitingPauseMenu : 1; + + unsigned int m_onHudEnterCommand; + + Scrooby::Screen* m_levelScreen; + Scrooby::Layer* m_levelLayer; + unsigned int m_elapsedDynaLoadTime; + + Scrooby::Project* m_pRewardsProject; + + bool m_unloadMemcardInfoWhenLoaded : 1; + bool m_promptSaveBeforeQuit : 1; + bool m_quitAfterSave : 1; +#ifdef RAD_WIN32 + bool m_quitToSystemAfterSave : 1; +#endif + bool m_isControllerReconnected : 1; + + GuiSFX::Dummy m_RestartMissionTransition; + GuiSFX::RecieveEvent m_RecieveIrisClosed; + GuiSFX::RestartCurrentMission m_RestartMission; + + GuiSFX::Dummy m_AbortMissionTransition; + GuiSFX::AbortCurrentMission m_AbortMission; + + Input::ActiveState m_oldControllerState; + + CGuiWindow::eGuiWindowID m_resumeGameScreenID; + +}; + +inline CGuiScreenHud* GetCurrentHud() +{ + // return reference to current in-game HUD + // + return CGuiManagerInGame::s_currentHUD; +} + +inline bool CGuiManagerInGame::IsLoadingNewMissionInSundayDrive() const +{ + return m_isLoadingNewMission; +} + +inline bool CGuiManagerInGame::IsLoadingNewMission() const +{ + return ( m_currentScreen == CGuiWindow::GUI_SCREEN_ID_MISSION_LOAD ); +} + +inline bool CGuiManagerInGame::IsHudScreen( CGuiWindow::eGuiWindowID windowID ) const +{ + return( windowID == CGuiWindow::GUI_SCREEN_ID_HUD || + windowID == CGuiWindow::GUI_SCREEN_ID_MULTI_HUD ); +} + +inline bool CGuiManagerInGame::IsRewardsScreen( CGuiWindow::eGuiWindowID windowID ) const +{ + return( windowID == CGuiWindow::GUI_SCREEN_ID_PURCHASE_REWARDS ); +} + +#endif // GUIMANAGERINGAME_H diff --git a/game/code/presentation/gui/ingame/guiscreencreditspostfmv.cpp b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.cpp new file mode 100644 index 0000000..1d8e0e8 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.cpp @@ -0,0 +1,267 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenCreditsPostFMV +// +// Description: Implementation of the CGuiScreenCreditsPostFMV class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/06/02 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreencreditspostfmv.h> +#include <presentation/gui/guimanager.h> + +#include <events/eventmanager.h> +#include <sound/soundmanager.h> + +// Scrooby +#include <screen.h> +#include <page.h> +#include <group.h> +#include <sprite.h> + +// ATG +#include <p3d/utility.hpp> +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float KANG_KODOS_IMAGE_CORRECTION_SCALE = 1.5f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenCreditsPostFMV::CGuiScreenCreditsPostFMV +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenCreditsPostFMV::CGuiScreenCreditsPostFMV +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreenViewCredits( pScreen, pParent ), + m_kang( NULL ), + m_kodos( NULL ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "CreditsKK" ); + rAssert( pPage != NULL ); + + m_kang = pPage->GetSprite( "Kang" ); + rAssert( m_kang != NULL ); + m_kang->SetVisible( false ); // hide by default + + m_kodos = pPage->GetSprite( "Kodos" ); + rAssert( m_kodos != NULL ); + m_kodos->SetVisible( false ); // hide by default +} + + +//=========================================================================== +// CGuiScreenCreditsPostFMV::~CGuiScreenCreditsPostFMV +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenCreditsPostFMV::~CGuiScreenCreditsPostFMV() +{ + if( m_kang != NULL ) + { + m_kang->SetRawSprite( NULL ); + } + + if( m_kodos != NULL ) + { + m_kodos->SetRawSprite( NULL ); + } +} + + +//=========================================================================== +// CGuiScreenCreditsPostFMV::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCreditsPostFMV::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + this->OnScrollingDone(); + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + // ignore back controller inputs + // + return; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenViewCredits::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenCreditsPostFMV::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCreditsPostFMV::InitIntro() +{ + GetEventManager()->TriggerEvent( EVENT_PLAY_CREDITS ); + + m_playKKDialog = true; + + this->ResetScrolling(); + + GetSoundManager()->DuckForInGameCredits(); + + rAssert( m_creditsGroup != NULL ); + m_creditsGroup->SetVisible( false ); + + // + // TC: [TODO] remove the loading of these images from the mission script + // for level 7 - mission 8 - sunday drive + // +/* + // search for kang and kodos images + // + tSprite* pSprite = NULL; + + pSprite = p3d::find<tSprite>( "kang.png" ); + if( pSprite != NULL ) + { + rAssert( m_kang != NULL ); + m_kang->SetRawSprite( pSprite ); + m_kang->SetVisible( true ); + + m_kang->ResetTransformation(); + m_kang->ScaleAboutCenter( KANG_KODOS_IMAGE_CORRECTION_SCALE ); + } + else + { + rAssertMsg( false, "Can't find kang image!" ); + } + + pSprite = p3d::find<tSprite>( "kodos.png" ); + if( pSprite != NULL ) + { + rAssert( m_kodos != NULL ); + m_kodos->SetRawSprite( pSprite ); + m_kodos->SetVisible( true ); + + m_kodos->ResetTransformation(); + m_kodos->ScaleAboutCenter( KANG_KODOS_IMAGE_CORRECTION_SCALE ); + } + else + { + rAssertMsg( false, "Can't find kodos image!" ); + } +*/ +} + + +//=========================================================================== +// CGuiScreenCreditsPostFMV::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCreditsPostFMV::InitRunning() +{ + rAssert( m_creditsGroup != NULL ); + m_creditsGroup->SetVisible( true ); +} + + +//=========================================================================== +// CGuiScreenCreditsPostFMV::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenCreditsPostFMV::InitOutro() +{ + GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP ); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenCreditsPostFMV::OnScrollingDone() +{ + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_LEVEL_END, + CLEAR_WINDOW_HISTORY ); +} + diff --git a/game/code/presentation/gui/ingame/guiscreencreditspostfmv.h b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.h new file mode 100644 index 0000000..5a2d523 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.h @@ -0,0 +1,54 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenCreditsPostFMV +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/06/02 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENCREDITSPOSTFMV_H +#define GUISCREENCREDITSPOSTFMV_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreenviewcredits.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenCreditsPostFMV : public CGuiScreenViewCredits +{ +public: + CGuiScreenCreditsPostFMV( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenCreditsPostFMV(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + virtual void OnScrollingDone(); + + Scrooby::Sprite* m_kang; + Scrooby::Sprite* m_kodos; + +}; + +#endif // GUISCREENCREDITSPOSTFMV_H diff --git a/game/code/presentation/gui/ingame/guiscreenhastransitions.cpp b/game/code/presentation/gui/ingame/guiscreenhastransitions.cpp new file mode 100644 index 0000000..95eaeba --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenhastransitions.cpp @@ -0,0 +1,213 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLetterBox +// +// Description: Implementation of the CGuiScreenLetterBox class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenhastransitions.h> +#include <presentation/gui/utility/transitions.h> +#include <drawable.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenHasTransitions::CGuiScreenHasTransitions +//=========================================================================== +// Description: Constructor +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenHasTransitions::CGuiScreenHasTransitions(): + mDoneAddingTransitions( false ) +{ + // zero out the array of transitions (use a memset instead)? + int i; + for( i = 0; i < MAX_TRANSITIONS; ++i ) + { + m_Transitions[ i ] = NULL; + } +} + +//=========================================================================== +// CGuiScreenHasTransitions::AddTransition +//=========================================================================== +// Description: Adds the transition to the array of transitions +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHasTransitions::AddTransition( GuiSFX::Transition* transition ) +{ + int i; + for( i = 0; i < MAX_TRANSITIONS; ++i ) + { + if( m_Transitions[ i ] == NULL ) + { + m_Transitions[ i ] = transition; + return; + } + } + rAssertMsg( false, "Need to bump up the size of the array of transitions" ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::AddTransition +//=========================================================================== +// Description: Adds the transition to the array of transitions +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHasTransitions::AddTransition( GuiSFX::Transition& transition ) +{ + int i; + for( i = 0; i < MAX_TRANSITIONS; ++i ) + { + if( m_Transitions[ i ] == NULL ) + { + m_Transitions[ i ] = &transition; + return; + } + } + rAssertMsg( false, "Need to bump up the size of the array of transitions" ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::DoneAddingTransitions +//=========================================================================== +// Description: tells the class that we're done adding transitions to it. Used +// for debugging the size of the array +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHasTransitions::DoneAddingTransitions() +{ + mDoneAddingTransitions = true; +} + +//=========================================================================== +// CGuiScreenHasTransitions::ResetMovableObjects +//=========================================================================== +// Description: resets transformations for all movable objects +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHasTransitions::ResetMovableObjects() +{ + int i; + for( i = 0; i < MAX_TRANSITIONS; ++i ) + { + GuiSFX::Transition* t = m_Transitions[ i ]; + if( t != NULL ) + { + bool active = t->IsActive(); + if( active ) + { + bool movable = t->MovesDrawable(); + if( movable ) + { + Scrooby::Drawable* drawable = t->GetDrawable(); + if( drawable != NULL ) + { + drawable->ResetTransformation(); + } + } + } + } + } +} + +//=========================================================================== +// CGuiScreenHasTransitions::ResetTransitions +//=========================================================================== +// Description: resets all of the transitions on the screen +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHasTransitions::ResetTransitions() +{ + rAssert( mDoneAddingTransitions ); + int i; + for( i = 0; i < MAX_TRANSITIONS; ++i ) + { + if( m_Transitions[ i ] == NULL ) + { + return; + } + m_Transitions[ i ]->Reset(); + } +} + +//=========================================================================== +// CGuiScreenMissionLoad::UpdateTransitions +//=========================================================================== +// Description: updates all the transitions +// +// Constraints: None. +// +// Parameters: deltaT - how much time has elapsed +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHasTransitions::UpdateTransitions( const float deltaT ) +{ + rAssert( mDoneAddingTransitions ); + int i; + for( i = 0; i < MAX_TRANSITIONS; ++i ) + { + if( m_Transitions[ i ] == NULL ) + { + return; + } + if( m_Transitions[ i ]->IsActive() ) + { + m_Transitions[ i ]->Update( deltaT ); + } + } +}
\ No newline at end of file diff --git a/game/code/presentation/gui/ingame/guiscreenhastransitions.h b/game/code/presentation/gui/ingame/guiscreenhastransitions.h new file mode 100644 index 0000000..d175896 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenhastransitions.h @@ -0,0 +1,54 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenHasTransitions +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/19 Ian Gipson Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENHASTRANSITIONS_H +#define GUISCREENHASTRANSITIONS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +#define MAX_TRANSITIONS 64 + +namespace GuiSFX +{ + class Transition; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class CGuiScreenHasTransitions +{ +public: + CGuiScreenHasTransitions(); +protected: + void AddTransition( GuiSFX::Transition* transition ); + void AddTransition( GuiSFX::Transition& transition ); + void DoneAddingTransitions(); + void ResetMovableObjects(); + void ResetTransitions(); + void UpdateTransitions( const float deltaT ); +private: + GuiSFX::Transition* m_Transitions[ MAX_TRANSITIONS ]; + bool mDoneAddingTransitions; +}; + +#endif // GUISCREENHASTRANSITIONS_H diff --git a/game/code/presentation/gui/ingame/guiscreenhud.cpp b/game/code/presentation/gui/ingame/guiscreenhud.cpp new file mode 100644 index 0000000..b138d75 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenhud.cpp @@ -0,0 +1,2106 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenHud +// +// Description: Implementation of the CGuiScreenHud class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/ingame/guihudtextbox.h> +#include <presentation/gui/ingame/hudevents/hudcardcollected.h> +#include <presentation/gui/ingame/hudevents/hudcoincollected.h> +#include <presentation/gui/ingame/hudevents/hudmissionprogress.h> +#include <presentation/gui/ingame/hudevents/hudmissionobjective.h> +#include <presentation/gui/ingame/hudevents/hudcountdown.h> +#include <presentation/gui/ingame/hudevents/hudhitnrun.h> +#include <presentation/gui/ingame/hudevents/hudwaspdestroyed.h> +#include <presentation/gui/ingame/hudevents/huditemdropped.h> +#include <presentation/gui/utility/hudmap.h> +#include <presentation/gui/utility/scrollingtext.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guisystem.h> + +#ifdef SRR2_MOVABLE_HUD_MAP + #include <presentation/gui/guisystem.h> + #include <presentation/gui/guiuserinputhandler.h> +#endif + +#include <cards/card.h> +#include <contexts/context.h> +#include <contexts/gameplay/gameplaycontext.h> +#include <events/eventmanager.h> +#include <gameflow/gameflow.h> +#include <interiors/interiormanager.h> +#include <mission/gameplaymanager.h> +#include <mission/mission.h> +#include <mission/missionmanager.h> +#include <mission/conditions/getoutofcarcondition.h> +#include <memory/srrmemory.h> +#include <worldsim/hitnrunmanager.h> +#include <worldsim/coins/coinmanager.h> + +#include <p3d/unicode.hpp> + +// FTech +// +#include <raddebug.hpp> + +// Scrooby +// +#include <app.h> +#include <group.h> +#include <layer.h> +#include <page.h> +#include <pure3dobject.h> +#include <screen.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +// radar fade in/out transition time +// +const unsigned int RADAR_FADE_TIME = 250; // in msec + +const float RADAR_SCALE = 0.9f; + +//const tColour HNR_METER_EMPTY_COLOUR( 0x02, 0x45, 0x39 ); +const short NUMERIC_TEXT_SPACING = -12; + +const float HNR_METER_BLINKING_THRESHOLD = 0.78f; +const tColour HNR_METER_DEFAULT_COLOUR( 255, 234, 2 ); +const tColour HNR_METER_WARNING_COLOUR( 215, 16, 12 ); + +const tColour PROXIMITY_METER_RED( 255, 0, 0 ); +const tColour PROXIMITY_METER_GREEN( 0, 255, 0 ); + +// minimum time required for avatar to be off road before updating +// race position to a ?/N display +// +const unsigned int MIN_AVATAR_OFF_ROAD_TIME = 0; // in msec + +const unsigned int MESSAGE_DISPLAY_TIME = 3000; // in msec +const unsigned int MESSAGE_TRANSITION_TIME = 200; // in msec + +Scrooby::Sprite* CGuiScreenHud::s_numCoinsDisplay = NULL; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +MessageQueue::MessageQueue() +: m_front( 0 ), + m_back( 0 ), + m_isEmpty( true ), + m_isFull( false ) +{ +} + +MessageQueue::~MessageQueue() +{ +} + +void +MessageQueue::Enqueue( unsigned int messageID ) +{ + rAssertMsg( !m_isFull, "Queue is full!" ); + + m_messages[ m_back ] = messageID; + m_back = (m_back + 1) % MESSAGE_QUEUE_CAPACITY; + + m_isEmpty = false; + m_isFull = (m_front == m_back); +} + +unsigned int +MessageQueue::Dequeue() +{ + // assumes queue is not empty + // + rAssertMsg( !m_isEmpty, "Queue is empty!" ); + + unsigned int messageID = m_messages[ m_front ]; + m_front = (m_front + 1) % MESSAGE_QUEUE_CAPACITY; + + m_isEmpty = (m_front == m_back); + m_isFull = false; + + return messageID; +} + +void +MessageQueue::Clear() +{ + m_front = 0; + m_back = 0; + m_isEmpty = true; + m_isFull= false; +} + +//=========================================================================== +// CGuiScreenHud::CGuiScreenHud +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenHud::CGuiScreenHud +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreenMultiHud( pScreen, pParent, GUI_SCREEN_ID_HUD, 1 ), + m_missionOverlays( NULL ), + m_helpMessage( NULL ), + m_messageBox( NULL ), + m_actionButton( NULL ), + m_missionComplete( NULL ), + m_timer( NULL ), + m_defaultTimerColour( 255, 255, 255 ), + m_timerBlinkingStartTime( 10000 ), + m_timerBlinkingEndTime( 0 ), + m_parTime( NULL ), + m_collectibles( NULL ), + m_collectiblesUpdated( 0 ), + m_position( NULL ), + m_positionOrdinal( NULL ), + m_lap( NULL ), + m_lapUpdated( 0 ), + m_isSlidingDamageMeter( false ), + m_isFadingInRadar( false ), + m_isFadingOutRadar( false ), + m_hnrLights( NULL ), + m_hnrMeter( NULL ), + m_hnrMeterBgd( NULL ), + m_hnrElapsedTime( 0 ), + m_isFadingIn( false ), + m_isFadingOut( false ), + m_elapsedFadeTime( 0.0f ), + m_isBonusMissionJustCompleted( false ), + m_isAvatarOffRoad( false ), + m_avatarOffRoadDurationTime( 0 ), + m_pGetOutOfCarCondition( NULL ), + m_elapsedFgdFadeInTime( -1.0f ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenHud" ); + memset( m_overlays, 0, sizeof( m_overlays ) ); + memset( m_hudEventHandlers, 0, sizeof( m_hudEventHandlers ) ); + memset( m_hnrSectors, 0, sizeof( m_hnrSectors ) ); + + int i = 0; +/* + bool enableFadeIn = (GetGameFlow()->GetCurrentContext() == CONTEXT_LOADING_GAMEPLAY ); + this->SetFadingEnabled( enableFadeIn ); +*/ + this->SetFadingEnabled( false ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Hud" ); + rAssert( pPage != NULL ); + + // Get dynamic elements + this->RetrieveElements( pPage ); + + m_missionOverlays = pPage->GetGroup( "MissionOverlays" ); + rAssert( m_missionOverlays != NULL ); + + Scrooby::Group* pGroup = NULL; + + // Retrieve HUD overlays + // + pGroup = m_missionOverlays->GetGroup( "Timer" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_TIMER ] = pGroup; + m_overlays[ HUD_TIMER_TEMP ] = pGroup; + m_timer = pGroup->GetSprite( "Timer" ); + rAssert( m_timer != NULL ); + m_timer->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_timer->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE ); + m_timer->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING ); + m_defaultTimerColour = m_timer->GetColour(); +#ifdef RAD_WIN32 + m_timer->Translate( -25, 0 ); + m_timer->ScaleAboutCenter( 0.5f ); +#endif + + pGroup = m_missionOverlays->GetGroup( "ParTime" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_PAR_TIME ] = pGroup; + m_parTime = pGroup->GetSprite( "ParTime" ); + rAssert( m_parTime != NULL ); + m_parTime->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_parTime->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE ); + m_parTime->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING ); +#ifdef RAD_WIN32 + m_parTime->Translate( -25, 0 ); + m_parTime->ScaleAboutCenter( 0.5f ); +#endif + + pGroup = m_missionOverlays->GetGroup( "Collectibles" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_COLLECTIBLES ] = pGroup; + m_collectibles = pGroup->GetSprite( "Collectibles" ); + rAssert( m_collectibles != NULL ); + m_collectibles->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_collectibles->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE ); + m_collectibles->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING ); +#ifdef RAD_WIN32 + m_collectibles->Translate( -25, 0 ); + m_collectibles->ScaleAboutCenter( 0.5f ); +#endif + + pGroup = m_missionOverlays->GetGroup( "Position" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_RACE_POSITION ] = pGroup; + m_positionOrdinal = pGroup->GetText( "PositionOrdinal" ); + m_position = pGroup->GetSprite( "Position" ); + rAssert( m_position != NULL ); + m_position->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_position->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE ); + m_position->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING ); +#ifdef RAD_WIN32 + m_position->Translate( -25, 0 ); + m_position->ScaleAboutCenter( 0.5f ); +#endif + + pGroup = m_missionOverlays->GetGroup( "Lap" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_LAP_COUNTER ] = pGroup; + m_lap = pGroup->GetSprite( "Lap" ); + rAssert( m_lap != NULL ); + m_lap->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_lap->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE ); + m_lap->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING ); +#ifdef RAD_WIN32 + m_lap->Translate( -25, 0 ); + m_lap->ScaleAboutCenter( 0.5f ); +#endif + + pGroup = m_missionOverlays->GetGroup( "DamageMeter" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_DAMAGE_METER ] = pGroup; + m_damageMeter.SetScroobyImage( pGroup->GetSprite( "DamageBar" ) ); + + pGroup = m_missionOverlays->GetGroup( "ProximityMeter" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_PROXIMITY_METER ] = pGroup; + m_proximityMeter.SetScroobyImage( pGroup->GetSprite( "ProximityBar" ) ); + + pGroup = m_missionOverlays->GetGroup( "MissionComplete" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_MISSION_COMPLETE ] = pGroup; + + // get 'mission complete' text + // + m_missionComplete = pGroup->GetSprite( "MissionComplete" ); + rAssert( m_missionComplete != NULL ); + m_missionComplete->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_missionComplete->CreateBitmapTextBuffer( 256 ); + m_missionComplete->SetBitmapText( GetTextBibleString( "MISSION_COMPLETE" ) ); + m_missionComplete->SetBitmapTextLineSpacing( 10 ); + + // get 'mission failed' text + // + m_missionFailedSprite = pGroup->GetSprite( "MissionFailed" ); + rAssert( m_missionFailedSprite != NULL ); + m_missionFailedSprite->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_missionFailedSprite->CreateBitmapTextBuffer( 256 ); + m_missionFailedSprite->SetBitmapText( GetTextBibleString( "MISSION_FAILED" ) ); + m_missionFailedSprite->SetBitmapTextLineSpacing( 10 ); +#ifdef RAD_WIN32 + m_missionFailedSprite->ScaleAboutCenter( 0.5f ); +#endif + + pGroup = pPage->GetGroup( "HudMap0" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_MAP ] = pGroup; + + // scale entire HUD map (or RADAR, if you'd prefer to call it that) + // + m_overlays[ HUD_MAP ]->ResetTransformation(); + m_overlays[ HUD_MAP ]->ScaleAboutCenter( RADAR_SCALE ); + + Scrooby::Group* pGroupHNR = pGroup->GetGroup( "HitNRunMeter" ); + if( pGroupHNR != NULL ) + { + for( i = 0; i < NUM_HIT_N_RUN_SECTORS; i++ ) + { + char name[ 16 ]; + sprintf( name, "HnRSector%d", i ); + m_hnrSectors[ i ] = pGroupHNR->GetSprite( name ); + +// rAssert( m_hnrSectors[ i ] != NULL ); +// m_hnrSectors[ i ]->SetColour( HNR_METER_EMPTY_COLOUR ); + + } + + m_hnrLights = pGroupHNR->GetSprite( "HitNRun" ); + m_hnrMeter = pGroupHNR->GetSprite( "HnRMeter" ); + m_hnrMeterBgd = pGroupHNR->GetSprite( "HnRMeterBgd" ); + } + + pGroup = pPage->GetGroup( "Message" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_MESSAGE ] = pGroup; + m_helpMessage = pGroup->GetText( "Message" ); + rAssert( m_helpMessage != NULL ); + m_helpMessage->SetTextMode( Scrooby::TEXT_WRAP ); + m_helpMessage->ResetTransformation(); + m_helpMessage->Translate( 0, MESSAGE_TEXT_VERTICAL_TRANSLATION ); + m_helpMessage->ScaleAboutPoint( MESSAGE_TEXT_SCALE * MESSGAE_TEXT_HORIZONTAL_STRETCH, + MESSAGE_TEXT_SCALE, + 1.0f, 0, 0 ); + + m_messageBox = pGroup->GetSprite( "MessageBox" ); + rAssert( m_messageBox != NULL ); + m_messageBox->ResetTransformation(); + m_messageBox->ScaleAboutCenter( MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_HORIZONTAL_STRETCH, + MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_VERTICAL_STRETCH, + 1.0f ); + + pGroup = pPage->GetGroup( "ActionButton" ); + rAssert( pGroup != NULL ); + m_overlays[ HUD_ACTION_BUTTON ] = pGroup; +#ifdef RAD_WIN32 + m_actionButton = pGroup->GetText( "ActionTextButton" ); + m_actionLabel = pGroup->GetText( "ActionTextLabel" ); +#else + m_actionButton = pGroup->GetSprite( "ActionButton" ); +#endif + + // hide all HUD overlays by default + // + for( i = 0; i < NUM_HUD_OVERLAYS; i++ ) + { + if( i == NUM_HUD_MISSION_OVERLAYS ) + { + continue; + } + + rAssert( m_overlays[ i ] ); + m_overlays[ i ]->SetVisible( false ); + + m_elapsedTime[ i ] = 0; + } + + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + if( currentMission != NULL ) + { + this->SetVisible( currentMission->IsHUDVisible() ); + } + + // create HUD event handlers + // + m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] = new HudCardCollected( pPage ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] = new HudCoinCollected( pPage ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_PROGRESS ] = new HudMissionProgress( pPage ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ] = new HudMissionObjective( pPage ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_COUNTDOWN ] = new HudCountDown( pPage ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN ] = new HudHitNRun( pPage ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED ] = new HudWaspDestroyed( pPage ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ] = new HudItemDropped( pPage ); + + // register event listeners + // + GetEventManager()->AddListener( this, EVENT_CARD_COLLECTED ); + GetEventManager()->AddListener( this, EVENT_COLLECTED_COINS ); + GetEventManager()->AddListener( this, EVENT_LOST_COINS ); + GetEventManager()->AddListener( this, EVENT_STAGE_COMPLETE ); + GetEventManager()->AddListener( this, EVENT_SHOW_MISSION_OBJECTIVE ); + GetEventManager()->AddListener( this, EVENT_GUI_COUNTDOWN_START ); + GetEventManager()->AddListener( this, EVENT_HIT_AND_RUN_START ); + GetEventManager()->AddListener( this, EVENT_HIT_AND_RUN_CAUGHT ); + GetEventManager()->AddListener( this, EVENT_GAMBLERACE_SUCCESS ); + GetEventManager()->AddListener( this, EVENT_GAMBLERACE_FAILURE ); + GetEventManager()->AddListener( this, EVENT_WASP_BLOWED_UP ); + GetEventManager()->AddListener( this, EVENT_GAG_FOUND ); + GetEventManager()->AddListener( this, EVENT_DUMP_STATUS ); + GetEventManager()->AddListener( this, EVENT_AVATAR_ON_ROAD ); + GetEventManager()->AddListener( this, EVENT_AVATAR_OFF_ROAD ); + GetEventManager()->AddListener( this, EVENT_OUTOFCAR_CONDITION_ACTIVE ); + GetEventManager()->AddListener( this, EVENT_OUTOFCAR_CONDITION_INACTIVE ); + +MEMTRACK_POP_GROUP("CGUIScreenHud"); +} + + +//=========================================================================== +// CGuiScreenHud::~CGuiScreenHud +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenHud::~CGuiScreenHud() +{ + // destroy hud event handlers + // + for( int i = 0; i < NUM_HUD_EVENT_HANDLERS; i++ ) + { + if( m_hudEventHandlers[ i ] != NULL ) + { + // stop them first in case they're still in progress + // + m_hudEventHandlers[ i ]->Stop(); + + delete m_hudEventHandlers[ i ]; + m_hudEventHandlers[ i ] = NULL; + } + } + + // unregister event listeners + // + GetEventManager()->RemoveAll( this ); + + s_numCoinsDisplay = NULL; +} + + +//=========================================================================== +// CGuiScreenHud::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); + } + + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->Update( param1 ); + + break; + } + case GUI_MSG_SHOW_HUD_OVERLAY: + { + if( param1 == HUD_TIMER_TEMP && m_overlays[ HUD_TIMER ]->IsVisible() ) + { + // ignore, cuz these are both the same overlay + // + break; + } + + // follow-through + // + } + case GUI_MSG_HIDE_HUD_OVERLAY: + { + rAssert( param1 < NUM_HUD_OVERLAYS ); + rAssert( m_overlays[ param1 ] != NULL ); + + // show/hide HUD overlay + // + m_overlays[ param1 ]->SetVisible( message == GUI_MSG_SHOW_HUD_OVERLAY ); + m_elapsedTime[ param1 ] = 0; + + rAssertMsg( param1 != HUD_MESSAGE, "Call CGuiScreenHud::DisplayMessage() instead!" ); + + // for mission-related overlays + // + if( message == GUI_MSG_SHOW_HUD_OVERLAY && + this->IsMissionOverlay( param1 ) ) + { + const float SECONDARY_MISSION_OVERLAY_SCALE = 0.75f; + const int SECONDARY_MISSION_OVERLAY_OFFSET_Y = -45; + + m_overlays[ param1 ]->ResetTransformation(); + + unsigned int otherOverlayIndex = 0; + int numOverlaysEnabled = 0; + + for( unsigned int i = 0; this->IsMissionOverlay( i ); i++ ) + { + if( m_overlays[ i ]->IsVisible() && m_overlays[ i ] != m_overlays[ param1 ] ) + { + otherOverlayIndex = i; + numOverlaysEnabled++; + } + } + + if( numOverlaysEnabled >= 2 ) + { + rAssertMsg( numOverlaysEnabled == 2, "More than two is not handled properly yet!" ); + + // if already two overlays enabled, just push this new one down as the third one + // w/out re-ordering anything + // + m_overlays[ param1 ]->ScaleAboutPoint( SECONDARY_MISSION_OVERLAY_SCALE, 0, 0 ); + m_overlays[ param1 ]->Translate( 0, SECONDARY_MISSION_OVERLAY_OFFSET_Y * 2 ); + } + else if( numOverlaysEnabled == 1 ) + { + // already another mission overlay enabled, need to + // scale and translate the secondary one + // + unsigned int secondaryOverlay = rmt::Max( otherOverlayIndex, param1 ); + + m_overlays[ secondaryOverlay ]->ResetTransformation(); + m_overlays[ secondaryOverlay ]->ScaleAboutPoint( SECONDARY_MISSION_OVERLAY_SCALE, 0, 0 ); + m_overlays[ secondaryOverlay ]->Translate( 0, SECONDARY_MISSION_OVERLAY_OFFSET_Y ); + } + } + + // special cases + // + if( param1 == HUD_PROXIMITY_METER ) + { + rAssert( m_proximityMeter.m_pImage != NULL ); + if( param2 == 0 ) // 0 = red bar + { + m_proximityMeter.m_pImage->SetColour( PROXIMITY_METER_RED ); + } + else // 1 = green bar + { + m_proximityMeter.m_pImage->SetColour( PROXIMITY_METER_GREEN ); + } + } + else if( param1 == HUD_MISSION_COMPLETE ) + { + m_isBonusMissionJustCompleted = false; + + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + if( !currentMission->IsWagerMission() ) // not a wager race + { + if( currentMission->IsBonusMission() ) + { + rAssert( m_missionComplete != NULL ); + m_missionComplete->SetBitmapText( GetTextBibleString( "BONUS_MISSION_COMPLETE" ) ); + + m_isBonusMissionJustCompleted = true; + } + else + { + rAssert( m_missionComplete != NULL ); + m_missionComplete->SetBitmapText( GetTextBibleString( "MISSION_COMPLETE" ) ); + } + } + } + else if( param1 == HUD_LAP_COUNTER ) + { + m_lapUpdated = 0; + } +/* + else if( param1 == HUD_MAP ) + { + if( param2 != 0 ) // != 0 means w/ fading + { + if( message == GUI_MSG_SHOW_HUD_OVERLAY ) + { + m_isFadingInRadar = true; + m_isFadingOutRadar = false; + } + else + { + m_isFadingOutRadar = true; + m_isFadingInRadar = false; + + // wait for fade out transition to finish + // before turning off radar + // + m_overlays[ HUD_MAP ]->SetVisible( true ); + } + } + } + else if( param1 == HUD_DAMAGE_METER ) + { + m_isSlidingDamageMeter = (message == GUI_MSG_SHOW_HUD_OVERLAY); + } +*/ + + break; + } + case GUI_MSG_INGAME_FADE_OUT: + { + if( !m_isFadingOut ) + { + rAssertMsg( !m_isFadingIn, "Fade in currently in progress!" ); + + m_isFadingOut = true; + m_elapsedFadeTime = 0.0f; + ++m_numTransitionsPending; + } + else + { + rWarningMsg( false, "Fade out currently in progress! Ignoring redundant request." ); + } + + break; + } + case GUI_MSG_INGAME_FADE_IN: + { + if( !m_isFadingIn ) + { + rAssertMsg( !m_isFadingOut, "Fade out currently in progress!" ); + ++m_numTransitionsPending; + m_isFadingIn = true; + m_elapsedFadeTime = 0.0f; + } + else + { + rWarningMsg( false, "Fade in currently in progress! Ignoring redundant request." ); + } + + break; + } + case GUI_MSG_INGAME_FADE_OUT_CANCEL: + { + if( m_isFadingOut ) + { + rAssert( m_screenCover != NULL ); + m_screenCover->SetAlpha( 1.0f ); + + m_isFadingOut = false; + --m_numTransitionsPending; + + GetEventManager()->TriggerEvent( EVENT_GUI_FADE_OUT_DONE ); + } + + break; + } + case GUI_MSG_INGAME_FADE_IN_CANCEL: + { + if( m_isFadingIn ) + { + rAssert( m_screenCover != NULL ); + m_screenCover->SetAlpha( 0.0f ); + + m_isFadingIn = false; + --m_numTransitionsPending; + + GetEventManager()->TriggerEvent( EVENT_GUI_FADE_IN_DONE ); + } + + break; + } + case GUI_MSG_CONTROLLER_START: + { + if( m_screenCover != NULL && m_screenCover->GetAlpha() > 0.0f ) + { + // don't allow pausing during fade in/out + // + return; + } + + break; + } + default: + { + break; + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenMultiHud::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenHud::Update +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: elapsed time +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::Update( unsigned int elapsedTime ) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( m_elapsedFgdFadeInTime != -1.0f ) + { + // fade in entire HUD foreground layer(s) to prevent sudden flashes + // on screen during situations where the HUD gets displayed very + // briefly before transitioning out to another screen + // + const float HUD_FGD_FADE_IN_TIME = 100.0f; + + m_elapsedFgdFadeInTime += elapsedTime; + if( m_elapsedFgdFadeInTime < HUD_FGD_FADE_IN_TIME ) + { +// float alpha = m_elapsedFgdFadeInTime / HUD_FGD_FADE_IN_TIME; + this->SetAlphaForLayers( 0.0f, m_foregroundLayers, m_numForegroundLayers ); + } + else + { + this->SetAlphaForLayers( 1.0f, m_foregroundLayers, m_numForegroundLayers ); + + rAssert( m_overlays[ HUD_MAP ] != NULL ); + m_overlays[ HUD_MAP ]->SetAlpha( 1.0f ); + + rAssert( m_hudMap[ 0 ] != NULL ); + m_hudMap[ 0 ]->SetVisible( GetGuiSystem()->IsRadarEnabled() ); + + m_elapsedFgdFadeInTime = -1.0f; // fade in is done + } + } + else + { + rAssert( m_hudMap[ 0 ] != NULL ); + m_hudMap[ 0 ]->SetVisible( GetGuiSystem()->IsRadarEnabled() ); + } + } + + static float INGAME_FADE_TIME = 250.0f; // in msec + + if( m_isFadingOut ) + { + rAssert( m_screenCover != NULL ); + + m_elapsedFadeTime += (float)elapsedTime; + if( m_elapsedFadeTime < INGAME_FADE_TIME ) + { + m_screenCover->SetAlpha( m_elapsedFadeTime / INGAME_FADE_TIME ); + } + else + { + m_screenCover->SetAlpha( 1.0f ); + + --m_numTransitionsPending; + m_isFadingOut = false; + + GetEventManager()->TriggerEvent( EVENT_GUI_FADE_OUT_DONE ); + } + } + + if( m_isFadingIn ) + { + rAssert( m_screenCover != NULL ); + + m_elapsedFadeTime += (float)elapsedTime; + if( m_elapsedFadeTime < INGAME_FADE_TIME ) + { + m_screenCover->SetAlpha( 1.0f - m_elapsedFadeTime / INGAME_FADE_TIME ); + } + else + { + m_screenCover->SetAlpha( 0.0f ); + + --m_numTransitionsPending; + m_isFadingIn = false; + + GetEventManager()->TriggerEvent( EVENT_GUI_FADE_IN_DONE ); + } + } + + this->UpdateOverlays( elapsedTime ); + this->UpdateEventHandlers( elapsedTime ); + this->UpdateTutorialMode( static_cast<float>( elapsedTime ) ); + +#ifdef SRR2_MOVABLE_HUD_MAP + this->UpdateHudMapPosition( elapsedTime ); +#endif + +/* + // TC: *** testing only *** + // + static float s_elapsedTime = 0.0f; + s_elapsedTime += static_cast<float>( elapsedTime ); + float value = 0.5f * rmt::Sin( rmt::PI_2 * s_elapsedTime / 2000.0f ) + 0.5f; + this->SetHitAndRunMeter( value ); +*/ + HitnRunManager* hnrManager = GetHitnRunManager(); + rAssert( hnrManager != NULL ); + + // blink H&R Meter lights + // + const unsigned int HNR_BLINK_PERIOD = 500; + + rAssert( m_hnrLights != NULL ); + rAssert( m_hnrMeterBgd != NULL ); + if( hnrManager->IsHitnRunActive() ) + { + m_hnrMeterBgd->SetColour( tColour( 17, 31, 161 ) ); + } + else + { + m_hnrMeterBgd->SetColour( tColour( 0, 0, 0 ) ); + + m_hnrLights->SetIndex( 2 ); // 2 = lights off + } + + m_hnrElapsedTime += elapsedTime; + if( m_hnrElapsedTime > HNR_BLINK_PERIOD / 2 ) + { + if( hnrManager->IsHitnRunActive() ) + { + int currentIndex = m_hnrLights->GetIndex(); + m_hnrLights->SetIndex( currentIndex > 1 ? 0 : 1 - currentIndex ); + + rAssert( m_hnrMeter != NULL ); + m_hnrMeter->SetVisible( !m_hnrMeter->IsVisible() ); + } + else if( (hnrManager->GetHitnRunValue() / 100.0f) > HNR_METER_BLINKING_THRESHOLD ) + { + rAssert( m_hnrMeter != NULL ); + m_hnrMeter->SetVisible( !m_hnrMeter->IsVisible() ); + + // TC: [TODO] throw a sound event to go w/ this + // + } + + m_hnrElapsedTime %= HNR_BLINK_PERIOD / 2; + } + + if( m_isAvatarOffRoad ) + { + // update avatar off-road duration time + // + m_avatarOffRoadDurationTime += elapsedTime; + } +} + +//=========================================================================== +// CGuiScreenHud::SetVisible +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetVisible( bool isVisible ) +{ + rAssert( m_pScroobyScreen != NULL ); + + // for each page in screen + // + int numPages = m_pScroobyScreen->GetNumberOfPages(); + for( int i = 0; i < numPages; i++ ) + { + Scrooby::Page* pPage = m_pScroobyScreen->GetPageByIndex( i ); + rAssert( pPage != NULL ); + + // for each layer in page + // + int numLayers = pPage->GetNumberOfLayers(); + for( int j = 0; j < numLayers; j++ ) + { + Scrooby::Layer* pLayer = pPage->GetLayerByIndex( j ); + rAssert( pLayer ); + + pLayer->SetVisible( isVisible ); + } + } +} + + +//=========================================================================== +// CGuiScreenHud::SetTimerBlinkingInterval +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetTimerBlinkingInterval( int startTime, int endTime ) +{ + m_timerBlinkingStartTime = startTime; + m_timerBlinkingEndTime = endTime; +} + + +//=========================================================================== +// CGuiScreenHud::SetParTime +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetParTime( int parTime ) // in seconds +{ + char buffer[ BITMAP_TEXT_BUFFER_SIZE ]; + + sprintf( buffer, "%d:%02d", parTime / 60, parTime % 60 ); + + rAssert( m_parTime != NULL ); + m_parTime->SetBitmapText( buffer ); +} + + +//=========================================================================== +// CGuiScreenHud::SetCollectibles +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetCollectibles( int numCollected, int numToCollect ) +{ +// rAssert( m_collectibles != NULL ); +// m_collectibles->SetVisible( numToCollect > 1 ); // only show collectibles if more than 1 to collect + + char buffer[ BITMAP_TEXT_BUFFER_SIZE ]; + sprintf( buffer, "%d/%d", numCollected, numToCollect ); + + m_collectibles->SetBitmapText( buffer ); +/* + m_playerCollected.SetValue( numCollected ); + m_numToCollect.SetValue( numToCollect ); +*/ + if( numCollected > 0 ) + { + m_collectiblesUpdated = 1; + + m_elapsedTime[ HUD_COLLECTIBLES ] = 0; + + // TC [TODO]: play sound effect + // + } +} + + +//=========================================================================== +// CGuiScreenHud::SetRacePosition +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetRacePosition( int currentPosition, int numPositions ) +{ + char buffer[ BITMAP_TEXT_BUFFER_SIZE ]; + + // extra spaces are needed to make more room for the ordinal text + // + char extraSpaces[ 4 ]; + strcpy( extraSpaces, " " ); + +#ifdef PAL + if( CGuiTextBible::GetCurrentLanguage() != Scrooby::XL_ENGLISH ) + { + extraSpaces[ 0 ] = '\0'; + } +#endif // PAL + + if( m_isAvatarOffRoad && m_avatarOffRoadDurationTime > MIN_AVATAR_OFF_ROAD_TIME ) + { + sprintf( buffer, "?%s/%d", extraSpaces, numPositions ); + m_positionOrdinal->SetVisible( false ); + } + else + { + sprintf( buffer, "%d%s/%d", currentPosition, extraSpaces, numPositions ); + m_positionOrdinal->SetVisible( true ); + } + + rAssert( m_position != NULL ); + m_position->SetBitmapText( buffer ); +/* + m_currentPosition.SetValue( currentPosition ); + m_numPositions.SetValue( numPositions ); +*/ + m_positionOrdinal->SetIndex( currentPosition > 3 ? 3 : currentPosition - 1 ); +} + + +//=========================================================================== +// CGuiScreenHud::SetLap +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetLap( int currentLap, int numLaps ) +{ + char buffer[ BITMAP_TEXT_BUFFER_SIZE ]; + sprintf( buffer, "%d/%d", currentLap, numLaps ); + + rAssert( m_lap != NULL ); + m_lap->SetBitmapText( buffer ); +/* + m_currentLap.SetValue( currentLap ); + m_numLaps.SetValue( numLaps ); +*/ + if( currentLap > 1 ) + { + m_lapUpdated = 8; + + m_elapsedTime[ HUD_LAP_COUNTER ] = 0; + + // play sound effect + // + GetEventManager()->TriggerEvent( EVENT_HUD_LAP_UPDATED ); + } + else + { + m_lapUpdated = 0; + } +} + + +//=========================================================================== +// CGuiScreenHud::SetDamageMeter +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetDamageMeter( float value ) +{ + m_damageMeter.SetValue( value ); +} + + +//=========================================================================== +// CGuiScreenHud::SetProximityMeter +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetProximityMeter( float value ) +{ + m_proximityMeter.SetValue( value ); +} + + +//=========================================================================== +// CGuiScreenHud::SetHitAndRunMeter +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::SetHitAndRunMeter( float value ) +{ + rAssert( value >= 0.0f && value <= 1.0f ); + + rAssert( m_hnrMeter != NULL ); + if( value > HNR_METER_BLINKING_THRESHOLD || GetHitnRunManager()->IsHitnRunActive() ) + { + m_hnrMeter->SetColour( HNR_METER_WARNING_COLOUR ); + } + else + { + m_hnrMeter->SetColour( HNR_METER_DEFAULT_COLOUR ); // restore default colour + m_hnrMeter->SetVisible( true ); + } + + const float TOTAL_AMOUNT_COVERED = 1.0f - value; + const float SECTOR_AMOUNT = 1.0f / NUM_HIT_N_RUN_SECTORS; + const float TOTAL_ANGLE = (1.0f - 1 / (float)NUM_HIT_N_RUN_SECTORS) * 360.0f; + + float amountCovered = 0.0f; + + for( int i = 0; i < NUM_HIT_N_RUN_SECTORS; i++ ) + { + rAssert( m_hnrSectors[ i ] != NULL ); + m_hnrSectors[ i ]->ResetTransformation(); + + if( amountCovered < TOTAL_AMOUNT_COVERED ) + { + float currentCovered = TOTAL_AMOUNT_COVERED - amountCovered; + if( currentCovered > SECTOR_AMOUNT ) + { + currentCovered = SECTOR_AMOUNT; + } + + amountCovered += currentCovered; + + m_hnrSectors[ i ]->RotateAboutCenter( -amountCovered * TOTAL_ANGLE ); + + static float correctionScale = 1.02f; + m_hnrSectors[ i ]->ScaleAboutCenter( correctionScale ); +/* +#ifdef RAD_DEBUG + static tColour sectorColour( HNR_METER_EMPTY_COLOUR ); + m_hnrSectors[ i ]->SetColour( sectorColour ); +#endif +*/ + } + } +} + + +//=========================================================================== +// CGuiScreenHud::DisplayMessage +//=========================================================================== +// Description: adds some scrolling text to the queue of text to show +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::DisplayMessage( bool show, const int index ) +{ + rAssert( m_overlays[ HUD_MESSAGE ] != NULL ); + + if( show ) + { + if( !m_helpMessageQueue.IsEmpty() ) + { + m_helpMessageQueue.Enqueue( index ); + } + else + { + if( m_overlays[ HUD_MESSAGE ]->IsVisible() ) + { + if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_DISPLAY_TIME - MESSAGE_TRANSITION_TIME ) + { + m_elapsedTime[ HUD_MESSAGE ] = MESSAGE_DISPLAY_TIME - m_elapsedTime[ HUD_MESSAGE ]; + } + else if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_TRANSITION_TIME ) + { + m_elapsedTime[ HUD_MESSAGE ] = MESSAGE_TRANSITION_TIME; + } + } + else + { + m_overlays[ HUD_MESSAGE ]->SetVisible( true ); + m_overlays[ HUD_MESSAGE ]->ScaleAboutCenter( 0.0f ); + m_elapsedTime[ HUD_MESSAGE ] = 0; + } + + rAssert( index >= 0 ); + m_helpMessage->SetIndex( index ); + } + } + else + { + m_overlays[ HUD_MESSAGE ]->SetVisible( false ); + } +} + + +void +CGuiScreenHud::DisplayMissionOverlays( bool show ) +{ + rAssert( m_missionOverlays != NULL ); + m_missionOverlays->SetVisible( show ); +} + + +void +CGuiScreenHud::HandleEvent( EventEnum id, void* pEventData ) +{ + switch( id ) + { + case EVENT_CARD_COLLECTED: + { + // stop coin presentation in case it's currently active + // + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ]->Stop(); + + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ]->Start(); + + Card* collectedCard = reinterpret_cast<Card*>( pEventData ); + rAssert( collectedCard != NULL ); + HudCardCollected* hudCardCollected = static_cast<HudCardCollected*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] ); + hudCardCollected->SetCurrentCard( collectedCard->GetID() ); + + break; + } + case EVENT_COLLECTED_COINS: + case EVENT_LOST_COINS: + { + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] != NULL ); + if( !m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ]->IsActive() ) + { + // only show coin presentation if card presentation is not active + // + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ]->Start(); + } + + break; + } + case EVENT_STAGE_COMPLETE: + { + unsigned int showStageComplete = reinterpret_cast<unsigned int>( pEventData ); + if( showStageComplete > 0 ) + { + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_PROGRESS ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_PROGRESS ]->Start(); + } + + break; + } + case EVENT_SHOW_MISSION_OBJECTIVE: + { + int messageID = reinterpret_cast<unsigned int>( pEventData ); + + HudMissionObjective* hudMissionObjective = static_cast<HudMissionObjective*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ] ); + if( messageID != -1 ) + { + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ]->Start(); + +// this->DisplayMessage( true, messageID ); + + hudMissionObjective->SetMessageID( messageID ); + } + else + { + hudMissionObjective->UpdateIcon(); + } + + break; + } + case EVENT_GUI_COUNTDOWN_START: + { + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COUNTDOWN ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_COUNTDOWN ]->Start(); + + break; + } + case EVENT_HIT_AND_RUN_START: + case EVENT_HIT_AND_RUN_CAUGHT: + { + HudHitNRun* hudHitNRun = static_cast<HudHitNRun*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN] ); + rAssert( hudHitNRun != NULL ); + if( id == EVENT_HIT_AND_RUN_START ) + { + hudHitNRun->SetMessage( HudHitNRun::MSG_HIT_N_RUN ); + } + else + { + rAssert( id == EVENT_HIT_AND_RUN_CAUGHT ); + hudHitNRun->SetMessage( HudHitNRun::MSG_BUSTED ); + } + + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN ]->Start(); + + break; + } + case EVENT_GAMBLERACE_SUCCESS: // (pEventData != 0) means new best time been set + { + if( pEventData != 0 ) + { + // display "Congratulations! New Best Time!" + // + rAssert( m_missionComplete != NULL ); + m_missionComplete->SetBitmapText( GetTextBibleString( "GAMBLING_RACE_SUCCESS_NBT" ) ); + } + else + { + // display "Congratulations!" + // + rAssert( m_missionComplete != NULL ); + m_missionComplete->SetBitmapText( GetTextBibleString( "GAMBLING_RACE_SUCCESS" ) ); + } + + break; + } + case EVENT_GAMBLERACE_FAILURE: + { + rAssert( m_missionComplete != NULL ); + m_missionComplete->SetBitmapText( GetTextBibleString( "GAMBLING_RACE_FAILURE" ) ); + + break; + } + case EVENT_GAG_FOUND: + case EVENT_WASP_BLOWED_UP: + { + HudWaspDestroyed* hudWaspDestroyed = static_cast<HudWaspDestroyed*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED] ); + rAssert( hudWaspDestroyed != NULL ); + hudWaspDestroyed->SetGagInsteadOfWasp( id == EVENT_GAG_FOUND ); + + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED ]->Start(); + + break; + } + case EVENT_DUMP_STATUS: + { + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ] != NULL ); + + int numActiveItems = reinterpret_cast<int>( pEventData ); + if( numActiveItems > 0 ) + { + m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ]->Start(); + } + else + { + m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ]->Stop(); + } + + break; + } + case EVENT_AVATAR_ON_ROAD: + { + m_isAvatarOffRoad = false; + + break; + } + case EVENT_AVATAR_OFF_ROAD: + { + if( !m_isAvatarOffRoad ) // if previously on-road + { + m_avatarOffRoadDurationTime = 0; // reset off-road duration time + } + + m_isAvatarOffRoad = true; + + break; + } + case EVENT_OUTOFCAR_CONDITION_ACTIVE: + { + m_pGetOutOfCarCondition = static_cast<GetOutOfCarCondition*> (pEventData); + rAssert(m_pGetOutOfCarCondition != NULL); + + break; + } + + case EVENT_OUTOFCAR_CONDITION_INACTIVE: + { + m_pGetOutOfCarCondition = NULL; + + break; + } + + + default: + { + rWarningMsg( false, "Unhandled event caught by GUI HUD!" ); + + break; + } + } +} + +void +CGuiScreenHud::SetNumCoinsDisplay( Scrooby::Sprite* pSprite ) +{ + if( s_numCoinsDisplay == NULL ) + { + rAssert( pSprite != NULL ); + pSprite->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + pSprite->CreateBitmapTextBuffer( MAX_NUM_COIN_DIGITS ); + pSprite->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING ); + pSprite->SetVisible( false ); // hide by default + +#ifdef RAD_WIN32 + pSprite->ResetTransformation(); + pSprite->Translate( 70, 0 ); + pSprite->ScaleAboutCenter( 0.5f ); +#endif + + s_numCoinsDisplay = pSprite; + } +} + +void +CGuiScreenHud::UpdateNumCoinsDisplay( int numCoins, bool show ) +{ + rAssert( s_numCoinsDisplay != NULL ); + s_numCoinsDisplay->SetVisible( show ); + + static int coinPosX = CGuiScreen::IsWideScreenDisplay() ? 540 : 605; + static int coinPosY = 432; + GetCoinManager()->SetHUDCoin( coinPosX, coinPosY, show ); + + if( show ) + { + char buffer[ MAX_NUM_COIN_DIGITS ]; + sprintf( buffer, "%d", numCoins ); + s_numCoinsDisplay->SetBitmapText( buffer ); + } +} + +//=========================================================================== +// CGuiScreenHud::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::InitIntro() +{ + Scrooby::Screen* screen = GetScroobyScreen(); + screen->SetAlpha( 1.0f ); + + m_missionFailedSprite->SetVisible( false ); + +/* + if( GetInteriorManager()->IsInside() ) + { + this->HandleMessage( GUI_MSG_HIDE_HUD_OVERLAY, HUD_MAP ); + } + else +*/ + { + this->HandleMessage( GUI_MSG_SHOW_HUD_OVERLAY, HUD_MAP ); + } + + // hide hud map, by default + // + m_overlays[ HUD_MAP ]->SetAlpha( 0.0f ); + rAssert( m_hudMap[ 0 ] != NULL ); + m_hudMap[ 0 ]->SetVisible( false ); + + this->SetAlphaForLayers( 0.0f, m_foregroundLayers, m_numForegroundLayers ); + + // force update on hit & run meter + // + HitnRunManager* hnrManager = GetHitnRunManager(); + rAssert( hnrManager != NULL ); + this->SetHitAndRunMeter( hnrManager->GetHitnRunValue() / 100.0f ); + + CGuiScreenMultiHud::InitIntro(); +} + + +//=========================================================================== +// CGuiScreenHud::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::InitRunning() +{ +// this->SetFadingEnabled( false ); + + // for fading in/out ingame + // + rAssert( m_screenCover != NULL ); + m_screenCover->SetVisible( true ); + m_screenCover->SetAlpha( 0.0f ); + + // reset HUD foreground fade in time + // + m_elapsedFgdFadeInTime = 0.0f; + + CGuiScreenMultiHud::InitRunning(); +} + + +//=========================================================================== +// CGuiScreenHud::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::InitOutro() +{ +/* + this->HideMissionObjective(); + + rAssert( m_overlays[ HUD_MESSAGE ] ); + m_overlays[ HUD_MESSAGE ]->SetVisible( false ); + + m_helpMessageQueue.Clear(); +*/ + // stop coin collected presentation + // + rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] != NULL ); + m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ]->Stop(); + + if( m_isFadingIn ) // if we're in the middle of fading back in from blackness, just stop it right here + { + this->HandleMessage( GUI_MSG_INGAME_FADE_IN_CANCEL ); + } + + CGuiScreenMultiHud::InitOutro(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +/* +//=========================================================================== +// CGuiScreenHud::DisplayMissionObjective +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::DisplayMissionObjective( unsigned int messageID ) +{ + rAssert( m_helpMessage ); + + // display mission objective message + // + m_helpMessage->SetTextIndex( messageID ); + m_helpMessage->Start(); +} + + +//=========================================================================== +// CGuiScreenHud::HideMissionObjective +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHud::HideMissionObjective() +{ + // hide mission objective message + // + rAssert( m_helpMessage ); + if( m_helpMessage->GetCurrentState() != ScrollingText::STATE_IDLE ) + { + m_helpMessage->Stop(); + } +} +*/ + +void +CGuiScreenHud::UpdateOverlays( unsigned int elapsedTime ) +{ + // update 'timer' overlay + // + if( m_overlays[ HUD_TIMER ]->IsVisible() ) + { + this->UpdateTimer( elapsedTime ); + } + else + { + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + { + // TC: Temporary work-around until I get Cary's help to fix + // this properly + // + if( currentMission->GetMissionTimeLeftInMilliSeconds() > 1000 ) + { + this->HandleMessage( GUI_MSG_SHOW_HUD_OVERLAY, HUD_TIMER ); + + this->UpdateTimer( elapsedTime ); + } + + rWarningMsg( currentMission->GetMissionTimeLeftInMilliSeconds() <= 0, + "Why is there mission time left and the HUD timer is not enabled??" ); + } + } + + // update 'message' overlay + // + if( m_overlays[ HUD_MESSAGE ]->IsVisible() ) + { + m_elapsedTime[ HUD_MESSAGE ] += elapsedTime; + + if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_DISPLAY_TIME ) + { + if( !m_helpMessageQueue.IsEmpty() ) + { + unsigned int messageIndex = m_helpMessageQueue.Dequeue(); + m_helpMessage->SetIndex( static_cast<int>( messageIndex ) ); + + // reset elapsed message display time + // + m_elapsedTime[ HUD_MESSAGE ] = 0; + } + else + { + m_overlays[ HUD_MESSAGE ]->SetVisible( false ); + } + } + else + { + m_overlays[ HUD_MESSAGE ]->ResetTransformation(); + + if( m_elapsedTime[ HUD_MESSAGE ] < MESSAGE_TRANSITION_TIME ) + { + // transition in + // + float scaleY = m_elapsedTime[ HUD_MESSAGE ] / (float)MESSAGE_TRANSITION_TIME; + m_overlays[ HUD_MESSAGE ]->ScaleAboutCenter( 1.0f, scaleY, 1.0f ); + } + else if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_DISPLAY_TIME - MESSAGE_TRANSITION_TIME ) + { + // transition out + // + float scaleY = (MESSAGE_DISPLAY_TIME - m_elapsedTime[ HUD_MESSAGE ]) / (float)MESSAGE_TRANSITION_TIME; + m_overlays[ HUD_MESSAGE ]->ScaleAboutCenter( 1.0f, scaleY, 1.0f ); + } + } + } + + // update 'action button' overlay + // + if( m_overlays[ HUD_ACTION_BUTTON ]->IsVisible() ) + { +#ifdef RAD_WIN32 + const float PULSE_AMPLITUDE = 0.10f; + const float PULSE_PERIOD = 600.0f; // in milliseconds +#else + const float PULSE_AMPLITUDE = 0.25f; + const float PULSE_PERIOD = 500.0f; // in milliseconds +#endif + + float scale = GuiSFX::Pulse( (float)m_elapsedTime[ HUD_ACTION_BUTTON ], + PULSE_PERIOD, + 1.0f, + PULSE_AMPLITUDE ); + + m_actionButton->ResetTransformation(); + m_actionButton->ScaleAboutCenter( scale, scale, 1.0f ); + +#ifdef RAD_WIN32 + m_actionLabel->ResetTransformation(); + m_actionLabel->ScaleAboutCenter( 0.85f, 0.85f, 1.0f ); +#endif + + m_elapsedTime[ HUD_ACTION_BUTTON ] += elapsedTime; + } + + // update 'mission complete' overlay + // + if( m_overlays[ HUD_MISSION_COMPLETE ]->IsVisible() ) + { + static float MISSION_COMPLETE_DISPLAY_TIME = 2500; // in milliseconds + +#ifdef RAD_WIN32 + bool done = GuiSFX::Flash( m_missionComplete, + (float)m_elapsedTime[ HUD_MISSION_COMPLETE ], + MISSION_COMPLETE_DISPLAY_TIME, + 3, 0.625f, 0.6f ); +#else + bool done = GuiSFX::Flash( m_missionComplete, + (float)m_elapsedTime[ HUD_MISSION_COMPLETE ], + MISSION_COMPLETE_DISPLAY_TIME, + 3, 1.25f, 1.2f ); +#endif + + if( done ) + { + m_overlays[ HUD_MISSION_COMPLETE ]->SetVisible( false ); + + if( m_isBonusMissionJustCompleted ) + { + // + // Different prompt for different levels + // + RenderEnums::LevelEnum level = GetGameplayManager()->GetCurrentLevelIndex(); + int levelInt = static_cast< int >( level ); + m_pParent->HandleMessage( GUI_MSG_INGAME_DISPLAY_PROMPT, 12 + levelInt ); + } + } + + m_elapsedTime[ HUD_MISSION_COMPLETE ] += elapsedTime; + } + + // update 'damage meter' overlay + // + if( m_overlays[ HUD_DAMAGE_METER ]->IsVisible() ) + { +/* + if( m_isSlidingDamageMeter ) + { + const float SLIDING_TIME = 1000.0f; + + if( m_elapsedTime[ HUD_DAMAGE_METER ] < SLIDING_TIME ) + { + int xPos, yPos; + m_overlays[ HUD_DAMAGE_METER ]->GetOriginPosition( xPos, yPos ); + + int screenWidth = (int)Scrooby::App::GetInstance()->GetScreenWidth(); + + int xTranslation = (int)( (1.0f - m_elapsedTime[ HUD_DAMAGE_METER ] / SLIDING_TIME) * + (screenWidth - xPos) ); + + m_overlays[ HUD_DAMAGE_METER ]->ResetTransformation(); + m_overlays[ HUD_DAMAGE_METER ]->Translate( xTranslation, 0 ); + + m_elapsedTime[ HUD_DAMAGE_METER ] += elapsedTime; + } + else + { + m_overlays[ HUD_DAMAGE_METER ]->ResetTransformation(); + + m_isSlidingDamageMeter = false; + } + } +*/ + const float DAMAGE_METER_BLINK_THRESHOLD = 0.75f; + + if( m_damageMeter.m_value > DAMAGE_METER_BLINK_THRESHOLD ) + { + const unsigned int BLINK_PERIOD = 250; + + bool blinked = GuiSFX::Blink( m_damageMeter.m_pImage, + (float)m_elapsedTime[ HUD_DAMAGE_METER ], + (float)BLINK_PERIOD ); + if( blinked ) + { + m_elapsedTime[ HUD_DAMAGE_METER ] %= BLINK_PERIOD; + } + + m_elapsedTime[ HUD_DAMAGE_METER ] += elapsedTime; + } + else + { + m_damageMeter.m_pImage->SetVisible( true ); + } + } + + // update 'lap counter' overlay + // + if( m_overlays[ HUD_LAP_COUNTER ]->IsVisible() || m_lapUpdated > 0 ) + { + if( m_lapUpdated > 0 ) + { + const int BLINK_PERIOD = 250; // msec + bool blinked = GuiSFX::Blink( m_overlays[ HUD_LAP_COUNTER ], + (float)m_elapsedTime[ HUD_LAP_COUNTER ], + (float)BLINK_PERIOD ); + + if( blinked ) + { + m_elapsedTime[ HUD_LAP_COUNTER ] %= BLINK_PERIOD; + + m_lapUpdated--; + } + + m_elapsedTime[ HUD_LAP_COUNTER ] += elapsedTime; + } + } +/* + // update 'hud map' overlay + // + if( m_overlays[ HUD_MAP ]->IsVisible() ) + { + if( m_isFadingInRadar ) + { + float radarAlpha = m_overlays[ HUD_MAP ]->GetAlpha() + (elapsedTime / (float)RADAR_FADE_TIME); + + if( radarAlpha < 1.0f ) + { + m_overlays[ HUD_MAP ]->SetAlpha( radarAlpha ); + } + else + { + m_overlays[ HUD_MAP ]->SetAlpha( 1.0f ); + + m_isFadingInRadar = false; + } + } + + if( m_isFadingOutRadar ) + { + float radarAlpha = m_overlays[ HUD_MAP ]->GetAlpha() - (elapsedTime / (float)RADAR_FADE_TIME); + + if( radarAlpha > 0.0f ) + { + m_overlays[ HUD_MAP ]->SetAlpha( radarAlpha ); + } + else + { + m_overlays[ HUD_MAP ]->SetAlpha( 0.0f ); + + m_isFadingInRadar = false; + + // turn off radar + // + m_overlays[ HUD_MAP ]->SetVisible( false ); + } + } + } +*/ +} + +void +CGuiScreenHud::UpdateEventHandlers( unsigned int elapsedTime ) +{ + // update HUD event handlers + // + for( int j = 0; j < NUM_HUD_EVENT_HANDLERS; j++ ) + { + if( m_hudEventHandlers[ j ] != NULL ) + { + m_hudEventHandlers[ j ]->Update( (float)elapsedTime ); + } + } +} + +void +CGuiScreenHud::UpdateTimer( unsigned int elapsedTime ) +{ + const int TIMER_BLINKING_STARTING_PERIOD = 500; + const tColour TIMER_BLINKING_COLOUR( 217, 2, 5 ); + + int numMillisecondsRemaining = 0; + + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + if( currentMission != NULL ) + { + if (m_pGetOutOfCarCondition != NULL) + { + //use the condition timer + numMillisecondsRemaining = m_pGetOutOfCarCondition->GetTimeRemainingTilFailuremilliseconds(); + } + else + { + numMillisecondsRemaining = currentMission->GetMissionTimeLeftInMilliSeconds(); + } + } + + if( numMillisecondsRemaining > 1000 ) + { + rAssert( m_timer != NULL ); + + float blinkPercentage = (numMillisecondsRemaining - m_timerBlinkingStartTime) / + (float)(m_timerBlinkingEndTime - m_timerBlinkingStartTime); + + // blink timer if remaining time is btw. timer blinking start + // and end time + // + if( blinkPercentage > 0.0f ) + { + float blinkingPeriod = (float)TIMER_BLINKING_STARTING_PERIOD; + if( blinkPercentage > 0.8f ) + { + blinkingPeriod *= 0.50f; + } + else if( blinkPercentage > 0.5f ) + { + blinkingPeriod *= 0.67f; + } + + tColour currentColour; + GuiSFX::ModulateColour( ¤tColour, + (float)numMillisecondsRemaining, + blinkingPeriod, + m_defaultTimerColour, + TIMER_BLINKING_COLOUR, + rmt::PI_BY2 ); + + m_timer->SetColour( currentColour ); + + if( m_elapsedTime[ HUD_TIMER ] >= blinkingPeriod ) + { + GetEventManager()->TriggerEvent( EVENT_HUD_TIMER_BLINK ); + + m_elapsedTime[ HUD_TIMER ] %= (int)blinkingPeriod; + } + + m_elapsedTime[ HUD_TIMER ] += elapsedTime; + } + else + { + // restore timer's default colours + // + m_timer->SetColour( m_defaultTimerColour ); + + m_elapsedTime[ HUD_TIMER ] = TIMER_BLINKING_STARTING_PERIOD; + } + + int numSecondsRemaining = numMillisecondsRemaining / 1000; + + char buffer[ BITMAP_TEXT_BUFFER_SIZE ]; + sprintf( buffer, "%d:%02d", numSecondsRemaining / 60, numSecondsRemaining % 60 ); + + m_timer->SetBitmapText( buffer ); + } + else + { + this->HandleMessage( GUI_MSG_HIDE_HUD_OVERLAY, HUD_TIMER ); + } +} + +#ifdef SRR2_MOVABLE_HUD_MAP + +void +CGuiScreenHud::UpdateHudMapPosition( unsigned int elapsedTime ) +{ + // update HUD map screen position + // + int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers(); + for( int i = 0; i < numUserInputHandlers; i++ ) + { + CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i ); + if( userInputHandler != NULL ) + { +#ifdef RAD_PS2 + if( userInputHandler->IsButtonDown( GuiInput::Back ) ) // action button (for PS2) +#else + if( userInputHandler->IsButtonDown( GuiInput::AuxY ) ) // action button (for Xbox and GC) +#endif + { + static int NUM_PIXELS_PER_SECOND = 160; + int translationAmount = (int)( (elapsedTime / 1000.0f) * (float)NUM_PIXELS_PER_SECOND ); + + if( userInputHandler->IsButtonDown( GuiInput::Left ) ) + { + this->MoveHudMap( -translationAmount, 0 ); + } + + if( userInputHandler->IsButtonDown( GuiInput::Right ) ) + { + this->MoveHudMap( translationAmount, 0 ); + } + + if( userInputHandler->IsButtonDown( GuiInput::Up ) ) + { + this->MoveHudMap( 0, translationAmount ); + } + + if( userInputHandler->IsButtonDown( GuiInput::Down ) ) + { + this->MoveHudMap( 0, -translationAmount ); + } + } + } + } +} + +void +CGuiScreenHud::MoveHudMap( int x, int y ) +{ + rAssert( m_hudMap[ 0 ] ); + + // clamp HUD map within screen boundaries + // + int mapPosX = 0; + int mapPosY = 0; + int mapWidth = 0; + int mapHeight = 0; + m_hudMap[ 0 ]->GetPure3dObject()->GetOriginPosition( mapPosX, mapPosY ); + m_hudMap[ 0 ]->GetPure3dObject()->GetBoundingBoxSize( mapWidth, mapHeight ); + + if( (mapPosX + x) < 0 || + (mapPosX + x) > (static_cast<int>( Scrooby::App::GetInstance()->GetScreenWidth() ) - mapWidth) ) + { + x = 0; + } + + if( (mapPosY + y) < 0 || + (mapPosY + y) > (static_cast<int>( Scrooby::App::GetInstance()->GetScreenHeight() ) - mapHeight) ) + { + y = 0; + } + + // move the HUD map + // + m_hudMap[ 0 ]->Translate( x, y ); +} + +#endif + +void CGuiScreenHud::AbortFade() +{ + m_elapsedFadeTime = 250.0f; + m_screenCover->SetAlpha( 0.0f ); + Update( 0 ); +} + +#ifdef DEBUGWATCH +const char* CGuiScreenHud::GetWatcherName() const +{ + return "CGuiScreenHud"; +} +#endif
\ No newline at end of file diff --git a/game/code/presentation/gui/ingame/guiscreenhud.h b/game/code/presentation/gui/ingame/guiscreenhud.h new file mode 100644 index 0000000..3b4f6a0 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenhud.h @@ -0,0 +1,271 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenHud +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENHUD_H +#define GUISCREENHUD_H + +//#define SRR2_MOVABLE_HUD_MAP // enable user to move HUD map + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenmultihud.h> +#include <presentation/gui/utility/slider.h> + +#include <events/eventlistener.h> +#include <p3d/p3dtypes.hpp> + +//=========================================================================== +// Forward References +//=========================================================================== + +class HudEventHandler; +class GetOutOfCarCondition; + +class MessageQueue +{ + // This is a very simple queue data structure that uses a circular + // array to store unsigned integer values. + // + // m_front - points to the front slot of the queue + // m_back - points to the next free slot right behind the back of the queue + // +public: + MessageQueue(); + virtual ~MessageQueue(); + + void Enqueue( unsigned int messageID ); + unsigned int Dequeue(); + + void Clear(); + bool IsEmpty() const { return m_isEmpty; } + bool IsFull() const { return m_isFull; } + +private: + static const unsigned short MESSAGE_QUEUE_CAPACITY = 8; + + unsigned int m_messages[ MESSAGE_QUEUE_CAPACITY ]; + unsigned short m_front; + unsigned short m_back; + bool m_isEmpty : 1; + bool m_isFull : 1; + + +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +enum eHudOverlay +{ + // The following are ordered in precendence priority when more than + // one mission-related overlay is enabled (w/ the first one being + // the highest priority). + // + HUD_DAMAGE_METER, + HUD_PROXIMITY_METER, + HUD_COLLECTIBLES, + HUD_TIMER, + HUD_RACE_POSITION, + HUD_LAP_COUNTER, + HUD_TIMER_TEMP, + HUD_PAR_TIME, + + NUM_HUD_MISSION_OVERLAYS, // not really an overlay + + HUD_MISSION_COMPLETE, + HUD_ACTION_BUTTON, + HUD_MESSAGE, + HUD_MAP, + + NUM_HUD_OVERLAYS +}; + +class CGuiScreenHud : public CGuiScreenMultiHud, + public EventListener +{ +public: + CGuiScreenHud( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenHud(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void Update( unsigned int elapsedTime ); + + inline bool IsActive() const; + + // Turns Entire HUD On/Off + // + void SetVisible( bool isVisible ); + + // Set HUD Overlay Info + // + void SetTimerBlinkingInterval( int startTime, int endTime ); + void SetParTime( int parTime ); + void SetCollectibles( int numCollected, int numToCollect ); + void SetRacePosition( int currentPosition, int numPositions ); + void SetLap( int currentLap, int numLaps ); + void SetDamageMeter( float value ); + void SetProximityMeter( float value ); + void SetHitAndRunMeter( float value ); + + // Show/Hide Text Message + // + void DisplayMessage( bool show, const int index = 0 ); + + // Show/Hide All Mission Overlays + // + void DisplayMissionOverlays( bool show ); + + enum eHudEventHandler + { + HUD_EVENT_HANDLER_CARD_COLLECTED, + HUD_EVENT_HANDLER_COIN_COLLECTED, + HUD_EVENT_HANDLER_MISSION_PROGRESS, + HUD_EVENT_HANDLER_MISSION_OBJECTIVE, + HUD_EVENT_HANDLER_COUNTDOWN, + HUD_EVENT_HANDLER_HIT_N_RUN, + HUD_EVENT_HANDLER_WASP_DESTROYED, + HUD_EVENT_HANDLER_ITEM_DROPPED, + + NUM_HUD_EVENT_HANDLERS + }; + + HudEventHandler* GetEventHandler( eHudEventHandler eventHandler ) const; + + // Implements EventListener + // + virtual void HandleEvent( EventEnum id, void* pEventData ); + + static void SetNumCoinsDisplay( Scrooby::Sprite* pSprite ); + static void UpdateNumCoinsDisplay( int numCoins, bool show = true ); + void AbortFade(); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + #ifdef DEBUGWATCH + virtual const char* GetWatcherName() const; + #endif + +private: + static bool IsMissionOverlay( unsigned int overlayIndex ); + + void UpdateOverlays( unsigned int elapsedTime ); + void UpdateEventHandlers( unsigned int elapsedTime ); + void UpdateTimer( unsigned int elapsedTime ); + +#ifdef SRR2_MOVABLE_HUD_MAP + void UpdateHudMapPosition( unsigned int elapsedTime ); + void MoveHudMap( int x, int y ); +#endif + + static const unsigned int BITMAP_TEXT_BUFFER_SIZE = 8; + static const int NUM_HIT_N_RUN_SECTORS = 8; + + static const int MAX_NUM_COIN_DIGITS = 8; + static Scrooby::Sprite* s_numCoinsDisplay; + + Scrooby::Group* m_overlays[ NUM_HUD_OVERLAYS ]; + unsigned int m_elapsedTime[ NUM_HUD_OVERLAYS ]; + + Scrooby::Group* m_missionOverlays; + Scrooby::Sprite* m_missionFailedSprite; + + Scrooby::Text* m_helpMessage; + Scrooby::Sprite* m_messageBox; + MessageQueue m_helpMessageQueue; + +#ifdef RAD_WIN32 + Scrooby::Text* m_actionButton; + Scrooby::Text* m_actionLabel; +#else + Scrooby::Sprite* m_actionButton; +#endif + + Scrooby::Sprite* m_missionComplete; + + Scrooby::Sprite* m_timer; + tColour m_defaultTimerColour; + int m_timerBlinkingStartTime; + int m_timerBlinkingEndTime; + + Scrooby::Sprite* m_parTime; + + Scrooby::Sprite* m_collectibles; + int m_collectiblesUpdated; + + Scrooby::Sprite* m_position; + Scrooby::Text* m_positionOrdinal; + + Scrooby::Sprite* m_lap; + int m_lapUpdated; + + ImageSlider m_damageMeter; + bool m_isSlidingDamageMeter; + + ImageSlider m_proximityMeter; + + bool m_isFadingInRadar : 1; + bool m_isFadingOutRadar : 1; + + Scrooby::Sprite* m_hnrSectors[ NUM_HIT_N_RUN_SECTORS ]; + Scrooby::Sprite* m_hnrLights; + Scrooby::Sprite* m_hnrMeter; + Scrooby::Sprite* m_hnrMeterBgd; + unsigned int m_hnrElapsedTime; + + HudEventHandler* m_hudEventHandlers[ NUM_HUD_EVENT_HANDLERS ]; + + bool m_isFadingIn : 1; + bool m_isFadingOut : 1; + float m_elapsedFadeTime; + + bool m_isBonusMissionJustCompleted : 1; + + bool m_isAvatarOffRoad : 1; + unsigned int m_avatarOffRoadDurationTime; + + GetOutOfCarCondition* m_pGetOutOfCarCondition; + + float m_elapsedFgdFadeInTime; + +}; + +inline bool CGuiScreenHud::IsActive() const +{ + // TC: if the start button was just pressed, we'll treat the screen + // as in-active, since it's about to transition out anyways + // + return ( m_state == GUI_WINDOW_STATE_RUNNING && !m_isStartButtonPressed ); +} + +inline HudEventHandler* CGuiScreenHud::GetEventHandler( eHudEventHandler eventHandler ) const +{ + return m_hudEventHandlers[ eventHandler ]; +} + +inline bool CGuiScreenHud::IsMissionOverlay( unsigned int overlayIndex ) +{ + return( static_cast<int>( overlayIndex ) < NUM_HUD_MISSION_OVERLAYS ); +} + +#endif // GUISCREENHUD_H diff --git a/game/code/presentation/gui/ingame/guiscreenhudmap.cpp b/game/code/presentation/gui/ingame/guiscreenhudmap.cpp new file mode 100644 index 0000000..ebeb36c --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenhudmap.cpp @@ -0,0 +1,279 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenHudMap +// +// Description: Implementation of the CGuiScreenHudMap class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/ingame/guiscreenhudmap.h> +#include <presentation/gui/utility/hudmap.h> + +#include <memory/srrmemory.h> + +#include <p3d/pointcamera.hpp> + +#include <raddebug.hpp> // Foundation +#include <raddebugwatch.hpp> +#include <page.h> +#include <polygon.h> +#include <pure3dobject.h> +#include <screen.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#ifdef DEBUGWATCH + static const char* HUD_MAP_WATCHER_NAMESPACE = "GUI System - HUD Map Screen"; + float g_wCamPosY = 700.0f; + float g_wCamTargetX = 0.0f; + float g_wCamTargetZ = 0.0f; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenHudMap::CGuiScreenHudMap +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenHudMap::CGuiScreenHudMap +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_HUD_MAP ), + m_largeHudMap( NULL ), + m_posX( 0 ), + m_posY( 0 ), + m_width( 0 ), + m_height( 0 ), + m_camera( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenHudMap" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "ViewMap" ); + rAssert( pPage ); + + Scrooby::Polygon* mapBgd = pPage->GetPolygon( "MapBgd" ); + rAssert( mapBgd ); + + // Get map position and size (based on background polygon) + // + mapBgd->GetVertexLocation( 0, m_posX, m_posY ); // assuming first vertex + // is bottom-left co-ord + mapBgd->GetBoundingBoxSize( m_width, m_height ); + + // Create an overhead camera + // + m_camera = new(GMA_LEVEL_HUD) tPointCamera; + rAssert( m_camera ); + m_camera->AddRef(); + m_camera->SetVUp( rmt::Vector( 1, 0, 0 ) ); + m_camera->SetPosition( rmt::Vector( 0, 700, 0 ) ); + m_camera->SetTarget( rmt::Vector( 0, 0, 0 ) ); + +#ifdef DEBUGWATCH + radDbgWatchAddFloat( &g_wCamPosY, + "Camera Height (Y)", + HUD_MAP_WATCHER_NAMESPACE, + NULL, + NULL, + 100.0f, + 1000.0f ); + + radDbgWatchAddFloat( &g_wCamTargetX, + "Camera Target (X)", + HUD_MAP_WATCHER_NAMESPACE, + NULL, + NULL, + -1000.0f, + 1000.0f ); + + radDbgWatchAddFloat( &g_wCamTargetZ, + "Camera Target (Z)", + HUD_MAP_WATCHER_NAMESPACE, + NULL, + NULL, + -1000.0f, + 1000.0f ); +#endif +MEMTRACK_POP_GROUP(); +} + + +//=========================================================================== +// CGuiScreenHudMap::~CGuiScreenHudMap +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenHudMap::~CGuiScreenHudMap() +{ +#ifdef DEBUGWATCH + radDbgWatchDelete( &g_wCamPosY ); + radDbgWatchDelete( &g_wCamTargetX ); + radDbgWatchDelete( &g_wCamTargetZ ); +#endif + + if( m_camera != NULL ) + { + m_camera->Release(); + m_camera = NULL; + } +} + + +//=========================================================================== +// CGuiScreenHudMap::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHudMap::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { +#ifdef DEBUGWATCH + rAssert( m_camera ); + m_camera->SetPosition( rmt::Vector( g_wCamTargetX, g_wCamPosY, g_wCamTargetZ ) ); + m_camera->SetTarget( rmt::Vector( g_wCamTargetX, 0, g_wCamTargetZ ) ); +#endif + rAssert( m_largeHudMap ); + m_largeHudMap->Update( param1 ); + + break; + } + case GUI_MSG_CONTROLLER_START: + { + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenHudMap::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHudMap::InitIntro() +{ + m_largeHudMap = GetCurrentHud()->GetHudMap( 0 ); + rAssert( m_largeHudMap ); + + Scrooby::Pure3dObject* p3dMap = m_largeHudMap->GetPure3dObject(); + rAssert( p3dMap ); + + p3dMap->SetPosition( m_posX, m_posY ); + p3dMap->SetBoundingBoxSize( m_width, m_height ); + + p3dMap->SetCamera( m_camera ); + + m_largeHudMap->Update( 0 ); +} + + +//=========================================================================== +// CGuiScreenHudMap::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHudMap::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenHudMap::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenHudMap::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenhudmap.h b/game/code/presentation/gui/ingame/guiscreenhudmap.h new file mode 100644 index 0000000..ea21d2b --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenhudmap.h @@ -0,0 +1,59 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenHudMap +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENHUDMAP_H +#define GUISCREENHUDMAP_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CHudMap; +class tPointCamera; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenHudMap : public CGuiScreen +{ +public: + CGuiScreenHudMap( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenHudMap(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + CHudMap* m_largeHudMap; + int m_posX; + int m_posY; + int m_width; + int m_height; + + tPointCamera* m_camera; + +}; + +#endif // GUISCREENHUDMAP_H diff --git a/game/code/presentation/gui/ingame/guiscreeniriswipe.cpp b/game/code/presentation/gui/ingame/guiscreeniriswipe.cpp new file mode 100644 index 0000000..8548f3a --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreeniriswipe.cpp @@ -0,0 +1,366 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenIrisWipe +// +// Description: Implementation of the CGuiScreenIrisWipe class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreeniriswipe.h> +#include <presentation/gui/utility/specialfx.h> + +#include <events/eventmanager.h> + +#include <screen.h> +#include <page.h> +#include <pure3dobject.h> +#include <text.h> + +#include <p3d/anim/multicontroller.hpp> +#include <p3d/utility.hpp> + +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +const float DEFAULT_REL_SPEED = 0.5f; +static bool g_doNotOpenOnNextOutro = false; +bool CGuiScreenIrisWipe::g_IsIrisClosed = false; + +const unsigned int MAX_IDLE_TIME_OF_BLACKNESS = 3000; // in msec + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenIrisWipe::CGuiScreenIrisWipe +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenIrisWipe::CGuiScreenIrisWipe +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_IRIS_WIPE ), + m_pIris( 0 ), + m_pMultiController( 0 ), + m_isIrisActive( false ), + m_loadingText( NULL ), + m_elapsedIdleTime( 0 ), + m_elapsedBlinkTime( 0 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "3dIris" ); + rAssert( pPage != NULL ); + + m_pIris = pPage->GetPure3dObject( "p3d_iris" ); + rAssert( m_pIris ); + + // Have to find the multicontroller ourselves because for some stupid reason + // Scrooby doesn't make it accessable via the Pure3dObject until the first render. + // + m_pMultiController = p3d::find<tMultiController>( "IrisController" ); + rAssert( m_pMultiController ); + + m_numFrames = m_pMultiController->GetNumFrames(); + + // get loading text + // + pPage = m_pScroobyScreen->GetPage( "LoadingText" ); + if( pPage != NULL ) + { + m_loadingText = pPage->GetText( "Loading" ); + rAssert( m_loadingText != NULL ); + m_loadingText->SetVisible( false ); // hide by default + } + + m_relativeSpeed = DEFAULT_REL_SPEED; +} + + +//=========================================================================== +// CGuiScreenIrisWipe::~CGuiScreenIrisWipe +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenIrisWipe::~CGuiScreenIrisWipe() +{ +} + +//=========================================================================== +// CGuiScreenIrisWipe::DoNotOpenOnNextOutro +//=========================================================================== +// Description: tells the screen not to transition out next time +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIrisWipe::DoNotOpenOnNextOutro() +{ + g_doNotOpenOnNextOutro = true; +} + +//=========================================================================== +// CGuiScreenIrisWipe::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIrisWipe::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( message == GUI_MSG_UPDATE ) + { + m_elapsedIdleTime += param1; + + if( m_elapsedIdleTime > MAX_IDLE_TIME_OF_BLACKNESS ) + { + m_elapsedBlinkTime += param1; + + if( m_loadingText != NULL ) + { + // blink loading text if idling here on this screen to satisfy + // TRC/TCR requirements + // + const unsigned int BLINKING_PERIOD = 250; + bool isBlinked = GuiSFX::Blink( m_loadingText, + static_cast<float>( m_elapsedBlinkTime ), + static_cast<float>( BLINKING_PERIOD ) ); + if( isBlinked ) + { + m_elapsedBlinkTime %= BLINKING_PERIOD; + } + } + } + } + } + else if( m_state == GUI_WINDOW_STATE_INTRO ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( m_isIrisActive && m_pMultiController->LastFrameReached() ) + { + m_isIrisActive = false; + + m_numTransitionsPending--; + rAssert( m_numTransitionsPending == 0 ); + + GetEventManager()->TriggerEvent( EVENT_GUI_IRIS_WIPE_CLOSED ); + rReleasePrintf( "CGuiScreenIrisWipe => EVENT_GUI_IRIS_WIPE_CLOSED.\n" ); + } + + break; + } + default: + { + break; + } + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( m_isIrisActive && m_pMultiController->LastFrameReached() ) + { + m_isIrisActive = false; + + m_numTransitionsPending--; + rAssert( m_numTransitionsPending == 0 ); + + GetEventManager()->TriggerEvent( EVENT_GUI_IRIS_WIPE_OPEN ); + rReleasePrintf( "CGuiScreenIrisWipe => EVENT_GUI_IRIS_WIPE_OPEN.\n" ); + } + + break; + } + case GUI_MSG_WINDOW_EXIT: + { + // ignore multiple exit requests + // + return; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenIrisWipe::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIrisWipe::InitIntro() +{ + if( m_loadingText != NULL ) + { + // hide loading text + // + m_loadingText->SetVisible( false ); + } + + if( !m_isIrisActive ) + { + m_isIrisActive = true; + + g_IsIrisClosed = true; + m_pIris->SetVisible( true ); + m_pMultiController->SetRelativeSpeed( m_relativeSpeed ); + + rAssertMsg( m_numTransitionsPending == 0, "Bad news if you hit this assert! Please go tell Tony." ); + m_numTransitionsPending++; + + m_pMultiController->Reset(); + m_pMultiController->SetFrameRange( 0.0f, m_numFrames * 0.5f ); + m_pMultiController->SetFrame( 0.0f ); + } +} + + +//=========================================================================== +// CGuiScreenIrisWipe::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIrisWipe::InitRunning() +{ + m_elapsedIdleTime = 0; + m_elapsedBlinkTime = 0; +} + + +//=========================================================================== +// CGuiScreenIrisWipe::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenIrisWipe::InitOutro() +{ + if( m_loadingText != NULL ) + { + // hide loading text + // + m_loadingText->SetVisible( false ); + } + + if( g_doNotOpenOnNextOutro ) + { + g_doNotOpenOnNextOutro = false; + } + else + { + g_IsIrisClosed = false; + if( !m_isIrisActive ) + { + m_isIrisActive = true; + + rAssertMsg( m_numTransitionsPending == 0, "Bad news if you hit this assert! Please go tell Tony." ); + m_numTransitionsPending++; + + m_pMultiController->Reset(); + m_pMultiController->SetFrameRange( m_numFrames * 0.5f, m_numFrames ); + m_pMultiController->SetFrame( m_numFrames * 0.5f ); + + //Reset the relative speed to the default + m_relativeSpeed = DEFAULT_REL_SPEED; + } + } +} + +//=========================================================================== +// CGuiScreenIrisWipe::IsIrisClosed +//=========================================================================== +// Description: Lets you know if the iris is closed at the moment +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +bool CGuiScreenIrisWipe::IsIrisClosed() +{ + return g_IsIrisClosed; +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreeniriswipe.h b/game/code/presentation/gui/ingame/guiscreeniriswipe.h new file mode 100644 index 0000000..c9a24a4 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreeniriswipe.h @@ -0,0 +1,70 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenIrisWipe +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENIRISWIPE_H +#define GUISCREENIRISWIPE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +namespace Scrooby +{ + class Pure3dObject; +}; +class tMultiController; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenIrisWipe : public CGuiScreen +{ +public: + CGuiScreenIrisWipe( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenIrisWipe(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + inline void SetRelativeSpeed( float speed ) { m_relativeSpeed = speed; }; + static void DoNotOpenOnNextOutro(); + static bool IsIrisClosed(); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + Scrooby::Pure3dObject* m_pIris; + tMultiController* m_pMultiController; + float m_numFrames; + float m_relativeSpeed; + static bool g_IsIrisClosed; + + bool m_isIrisActive : 1; + + Scrooby::Text* m_loadingText; + unsigned int m_elapsedIdleTime; + unsigned int m_elapsedBlinkTime; + +}; + +#endif // GUISCREENIRISWIPE_H diff --git a/game/code/presentation/gui/ingame/guiscreenletterbox.cpp b/game/code/presentation/gui/ingame/guiscreenletterbox.cpp new file mode 100644 index 0000000..164b1c4 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenletterbox.cpp @@ -0,0 +1,688 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLetterBox +// +// Description: Implementation of the CGuiScreenLetterBox class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenletterbox.h> + +#include <events/eventmanager.h> +#include <input/inputmanager.h> +#include <interiors/interiormanager.h> +#include <mission/missionmanager.h> +#include <mission/missionstage.h> +#include <mission/objectives/missionobjective.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <page.h> +#include <pure3dobject.h> +#include <screen.h> +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float BAR_SLIDING_TIME = 500.0f; // in msec +bool CGuiScreenLetterBox::m_enableReopen = false; +bool CGuiScreenLetterBox::m_forceOpen = false; +static bool g_SurpressNextSkipButton = false; +GuiSFX::Translator g_TopIn( "Top In" ); +GuiSFX::Translator g_BottomIn( "Bottom In" ); +GuiSFX::Translator g_TopOut( "Top Out" ); +GuiSFX::Translator g_BottomOut( "Bottom Out" ); +GuiSFX::Translator g_TopClose( "Top Close" ); +GuiSFX::Translator g_BottomClose( "Outro bottom close" ); +GuiSFX::SendEvent g_ClosedEvent( "Outro closed event" ); +GuiSFX::Pause s_OutroPauseBetweenCloseAndIris( "Outro pause between close and open" ); +GuiSFX::IrisWipeOpen s_OutroIrisOpen( "Outro Iris Open" ); +bool CGuiScreenLetterBox::s_suppressAcceptCancelButtons = false; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLetterBox::CGuiScreenLetterBox +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLetterBox::CGuiScreenLetterBox +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LETTER_BOX ), + m_topBar( NULL ), + m_bottomBar( NULL ), + m_skipButton( NULL ), + m_skipLabel( NULL ), + m_elapsedTime( 0 ), + m_OutroPending( false ) +{ + // Retrieve the Scrooby drawing elements. + // + m_Page = m_pScroobyScreen->GetPage( "LetterBox" ); rAssert( m_Page != NULL ); + m_IrisPage = m_pScroobyScreen->GetPage( "3dIris" ); rAssert( m_IrisPage != NULL ); + m_Iris = m_IrisPage->GetPure3dObject( "p3d_iris" ); + + // get the top and bottom letterbox bars + // + m_topBar = m_Page->GetGroup( "TopBar" ); + m_bottomBar = m_Page->GetGroup( "BottomBar" ); + + // get letter box buttons from 'LetterBoxButtons.pag' + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LetterBoxButtons" ); + rAssert( pPage != NULL ); + + m_skipButton = pPage->GetGroup( "Skip" ); + rAssert( m_skipButton != NULL ); + + m_skipLabel = m_skipButton->GetGroup( "SkipLabel" ); + m_buttonIcons[ BUTTON_ICON_ACCEPT ] = m_skipButton->GetGroup( "AcceptLabel" ); + m_buttonIcons[ BUTTON_ICON_BACK ] = m_skipButton->GetGroup( "BackLabel" ); + + if( this->IsWideScreenDisplay() ) + { + m_skipButton->ResetTransformation(); + this->ApplyWideScreenCorrectionScale( m_skipButton ); + } + + AddTransition( g_TopIn ); + AddTransition( g_BottomIn ); + AddTransition( g_TopOut ); + AddTransition( g_BottomOut ); + AddTransition( g_TopClose ); + AddTransition( g_BottomClose ); + AddTransition( s_OutroIrisOpen ); + AddTransition( s_OutroPauseBetweenCloseAndIris ); + DoneAddingTransitions(); + + g_TopIn.SetDrawable( m_topBar ); + g_BottomIn.SetDrawable( m_bottomBar ); + g_TopOut.SetDrawable( m_topBar ); + g_BottomOut.SetDrawable( m_bottomBar ); + g_TopClose.SetDrawable( m_topBar ); + g_BottomClose.SetDrawable( m_bottomBar ); + g_ClosedEvent.SetEvent( EVENT_LETTERBOX_CLOSED ); + + SetIntroFromOpen(); + g_TopOut.SetCoordsStart( 0, 240 - 70 ); + g_TopOut.SetCoordsEnd( 0, 240 ); + g_TopOut.SetTimeInterval( BAR_SLIDING_TIME ); + g_BottomOut.SetCoordsStart( 0, -240 + 70 ); + g_BottomOut.SetCoordsEnd( 0, -240 ); + g_BottomOut.SetTimeInterval( BAR_SLIDING_TIME ); + g_TopClose.SetCoordsStart( 0, 240 - 70 ); + g_TopClose.SetCoordsEnd( 0, 0 ); + g_TopClose.SetTimeInterval( BAR_SLIDING_TIME ); + g_BottomClose.SetCoordsStart( 0, -240 + 70 ); + g_BottomClose.SetCoordsEnd( 0, 0 ); + g_BottomClose.SetTimeInterval( BAR_SLIDING_TIME ); + s_OutroPauseBetweenCloseAndIris.SetTimeInterval( 500 ); + s_OutroIrisShow.SetDrawable( m_Iris ); + s_OutroLetterBoxHide.SetDrawable( m_Page ); + + g_BottomClose.SetNextTransition( s_OutroPauseBetweenCloseAndIris ); + s_OutroPauseBetweenCloseAndIris.SetNextTransition( s_OutroIrisShow ); + s_OutroIrisShow.SetNextTransition( s_OutroLetterBoxHide ); + s_OutroLetterBoxHide.SetNextTransition( g_ClosedEvent ); + g_ClosedEvent.SetNextTransition( s_OutroIrisOpen ); +} + + +//=========================================================================== +// CGuiScreenLetterBox::~CGuiScreenLetterBox +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLetterBox::~CGuiScreenLetterBox() +{ +} + +//=========================================================================== +// CGuiScreenLetterBox::CheckIfScreenShouldBeBlank +//=========================================================================== +// Description: this is a huge hack for the one frame glitch you get when +// switching screens sometimes +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::CheckIfScreenShouldBeBlank() +{ + bool irisClosed = GetGameplayManager()->IsIrisClosed(); + if( irisClosed ) + { + m_topBar->ResetTransformation(); + m_topBar->Translate( 0, 0 ); + m_bottomBar->ResetTransformation(); + m_bottomBar->Translate( 0, 0 ); + } + else + { + m_topBar->ResetTransformation(); + m_topBar->Translate( 0, 240 ); + m_bottomBar->ResetTransformation(); + m_bottomBar->Translate( 0, -240 ); + } +} + +//=========================================================================== +// CGuiScreenLetterBox::ForceOpen +//=========================================================================== +// Description: forces the screen to open next time +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::ForceOpen() +{ + m_forceOpen = true; +} + +//=========================================================================== +// CGuiScreenLetterBox::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_UPDATE ) + { + ResetMovableObjects(); + float deltaT = static_cast< float >( param1 ); + UpdateTransitions( deltaT ); + +#ifdef RAD_DEMO + // reset idle timer when we're in a conversation + // + GetGameplayManager()->ResetIdleTime(); +#endif + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + if( m_skipButton->IsVisible() ) + { + if( this->IsButtonVisible( BUTTON_ICON_ACCEPT ) ) + { + this->OnAccept(); + } + else + { + this->OnSkip(); + } + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + if( m_skipButton->IsVisible() && this->IsButtonVisible( BUTTON_ICON_BACK ) ) + { + this->OnCancel(); + } + + break; + } + default: + { + break; + } + } + } + else if( m_state == GUI_WINDOW_STATE_INTRO ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( g_TopIn.IsChainDone() ) + { + --m_numTransitionsPending; + } + break; + } + + default: + { + break; + } + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( m_enableReopen ) + { + } + else + { + if( g_BottomClose.IsChainDone() || g_BottomOut.IsChainDone() ) + { + --m_numTransitionsPending; + } + } + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenLetterBox::HandleEvent( EventEnum id, void* pEventData ) +{ + rAssert( id == EVENT_CONVERSATION_DONE ); + + GetEventManager()->TriggerEvent( EVENT_CONVERSATION_DONE_AND_FINISHED ); +} + + +//=========================================================================== +// CGuiScreenLetterBox::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::InitIntro() +{ + s_OutroIrisOpen.Reset(); + + m_Page->SetVisible( true ); + m_Iris->SetVisible( false ); + m_topBar->SetVisible( true ); + m_bottomBar->SetVisible( true ); + ResetTransitions(); + m_topBar->Translate( 0, 240 ); + m_bottomBar->Translate( 0, -240 ); + g_TopIn.Activate(); + g_BottomIn.Activate(); + m_elapsedTime = 0; + m_numTransitionsPending++; + m_OutroPending = false; + + // + // Is the screen already black from some sort of fade? + // + bool irisClosed = GetGameplayManager()->IsIrisClosed(); + if( irisClosed ) + { + SetIntroFromClosed(); + } + else + { + SetIntroFromOpen(); + } + + + rAssert( m_skipButton != NULL ); + if( g_SurpressNextSkipButton ) + { + m_skipButton->SetVisible( false ); + } + else + { + m_skipButton->SetVisible( true ); + + MissionStage* currentStage = GetGameplayManager()->GetCurrentMission()->GetCurrentStage(); + rAssert( currentStage != NULL ); + bool showAcceptCancel = GetGameplayManager()->IsSundayDrive() && + currentStage->IsMissionAbortAllowed() && + !GetInteriorManager()->IsPlayingISMovieDialog(); + + if( s_suppressAcceptCancelButtons ) + { + showAcceptCancel = false; + } + + rAssert( m_skipLabel != NULL ); + m_skipLabel->SetVisible( !showAcceptCancel ); + this->SetButtonVisible( BUTTON_ICON_ACCEPT, showAcceptCancel ); + this->SetButtonVisible( BUTTON_ICON_BACK, showAcceptCancel ); + } + + s_suppressAcceptCancelButtons = false; // reset this flag + + GetEventManager()->AddListener( this, EVENT_CONVERSATION_DONE ); + + // + // Double check if we were doing a "fade in" beforehand, and abort it + // + bool fadeInProgress = GetGameplayManager()->FadeInProgress(); + GetGameplayManager()->AbortFade(); +} + + +//=========================================================================== +// CGuiScreenLetterBox::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::InitRunning() +{ +} + +//=========================================================================== +// CGuiScreenLetterBox::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::InitOutro() +{ + if( m_OutroPending ) + { + return; + } + m_OutroPending = true; + g_TopIn.Deactivate(); + g_BottomIn.Deactivate(); + bool sundayDrive = GetGameplayManager()->IsSundayDrive(); + int numStages = GetGameplayManager()->GetCurrentMission()->GetNumStages(); + int currentIndex = GetGameplayManager()->GetCurrentMission()->GetCurrentStageIndex(); + Mission* mission = GetGameplayManager()->GetCurrentMission(); + MissionStage* stage = mission->GetCurrentStage(); + MissionObjective* obj = stage->GetObjective(); + bool pattyAndSelma = obj->IsPattyAndSelmaDialog(); + bool raceDialog = obj->IsRaceDialog(); + + g_BottomClose.SetNextTransition( NULL ); + + // + // Sometimes we close the letterbox, sometimes it just opens up. when does + // it do what? If we're going to a hud screen, then it closes first, if + // we're staying in gameplay, then it just opens up + // + if( m_forceOpen ) + { + g_TopOut.Activate(); + g_BottomOut.Activate(); + m_forceOpen = false; + } + else + { + if( ( sundayDrive && (currentIndex >= numStages - 1) ) || pattyAndSelma || raceDialog ) + { + g_TopClose.Activate(); + g_BottomClose.Activate(); + } + else + { + g_TopOut.Activate(); + g_BottomOut.Activate(); + } + } + + rAssert( m_skipButton != NULL ); + m_skipButton->SetVisible( false ); + + m_elapsedTime = 0; + m_numTransitionsPending++; + g_SurpressNextSkipButton = false; + + GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_DONE ); +} + +//=========================================================================== +// CGuiScreenLetterBox::SurpressSkipButton +//=========================================================================== +// Description: Surpresses showing +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::SurpressSkipButton() +{ + g_SurpressNextSkipButton = true; +} + +//=========================================================================== +// CGuiScreenLetterBox::UnSurpressSkipButton +//=========================================================================== +// Description: The skip button will be visible again +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::UnSurpressSkipButton() +{ + g_SurpressNextSkipButton = false; +} + +//=========================================================================== +// CGuiScreenLetterBox::OnAccept +//=========================================================================== +// Description: If necessary, stop conversation. Then, start mission. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::OnAccept() +{ + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect + + // skip conversation in case it's still playing + // + GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP ); +/* + // send event to dialog objective to indicate that user has accepted + // the mission + // + GetEventManager()->TriggerEvent( EVENT_CONVERSATION_DONE_AND_FINISHED ); +*/ +} + +//=========================================================================== +// CGuiScreenLetterBox::OnCancel +//=========================================================================== +// Description: If necessary, stop conversation. Then, return to sunday +// drive. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::OnCancel() +{ + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect + + // don't listen to this event on cancelling + // + GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_DONE ); + + // skip conversation in case it's still playing + // + GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP ); + + if( GetGameplayManager()->IsBonusMissionDesired() ) + { + // cancel bonus mission + // + GetGameplayManager()->CancelBonusMission(); + } + else + { + // go back a stage in sunday drive mode + // + GetGameplayManager()->GetCurrentMission()->PrevStage(); + GetGameplayManager()->GetCurrentMission()->GetCurrentStage()->Start(); + } + + this->ForceOpen(); + + GetInputManager()->SetGameState(Input::ACTIVE_GAMEPLAY); + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); +} + +//=========================================================================== +// CGuiScreenLetterBox::OnSkip +//=========================================================================== +// Description: Skip NIS conversation. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::OnSkip() +{ + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect + + // skip conversation in case it's still playing + // + GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP ); +} + +//=========================================================================== +// CGuiScreenLetterBox::SetIntroFromClosed +//=========================================================================== +// Description: sets things up so the letterbox opens from the start +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::SetIntroFromClosed() +{ + g_TopIn.SetCoordsStart( 0, 0 ); + g_TopIn.SetCoordsEnd( 0, 240 - 70 ); + g_TopIn.SetTimeInterval( BAR_SLIDING_TIME ); + g_BottomIn.SetCoordsStart( 0, 0 ); + g_BottomIn.SetCoordsEnd( 0, -240 + 70 ); + g_BottomIn.SetTimeInterval( BAR_SLIDING_TIME ); + m_topBar->ResetTransformation(); + m_topBar->Translate( 0, 0 ); + m_bottomBar->ResetTransformation(); + m_bottomBar->Translate( 0, 0 ); +} + +//=========================================================================== +// CGuiScreenLetterBox::SetIntroFromOpen +//=========================================================================== +// Description: sets things up so the letterbox closes a little from the start +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLetterBox::SetIntroFromOpen() +{ + g_TopIn.SetCoordsStart( 0, 240 ); + g_TopIn.SetCoordsEnd( 0, 240 - 70 ); + g_TopIn.SetTimeInterval( BAR_SLIDING_TIME ); + g_BottomIn.SetCoordsStart( 0, -240 ); + g_BottomIn.SetCoordsEnd( 0, -240 + 70 ); + g_BottomIn.SetTimeInterval( BAR_SLIDING_TIME ); +} + +#ifdef DEBUGWATCH +const char* CGuiScreenLetterBox::GetWatcherName() const +{ + return "CGuiScreenLetterBox"; +} +#endif
\ No newline at end of file diff --git a/game/code/presentation/gui/ingame/guiscreenletterbox.h b/game/code/presentation/gui/ingame/guiscreenletterbox.h new file mode 100644 index 0000000..f7ddc46 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenletterbox.h @@ -0,0 +1,101 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLetterBox +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLETTERBOX_H +#define GUISCREENLETTERBOX_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/ingame/guiscreenhastransitions.h> +#include <presentation/gui/utility/transitions.h> + +#include <events/eventlistener.h> + +//=========================================================================== +// Forward References +//=========================================================================== +namespace Scrooby +{ + class Group; +} +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLetterBox : + public CGuiScreen, + public CGuiScreenHasTransitions, + public EventListener +{ +public: + CGuiScreenLetterBox( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenLetterBox(); + static void ForceOpen(); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual void HandleEvent( EventEnum id, void* pEventData ); + + static void SurpressSkipButton(); + static void UnSurpressSkipButton(); + + static void SuppressAcceptCancelButtons( bool suppress = true ); + void CheckIfScreenShouldBeBlank(); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + void SetIntroFromClosed(); + void SetIntroFromOpen(); + #ifdef DEBUGWATCH + virtual const char* GetWatcherName() const; + #endif + + +private: + void OnAccept(); + void OnCancel(); + void OnSkip(); + + Scrooby::Page* m_Page; + Scrooby::Page* m_IrisPage; + Scrooby::Group* m_topBar; + Scrooby::Group* m_bottomBar; + Scrooby::Group* m_skipButton; + Scrooby::Group* m_skipLabel; + Scrooby::Pure3dObject* m_Iris; + + unsigned int m_elapsedTime; + static bool m_enableReopen; + static bool m_forceOpen; + bool m_OutroPending : 1; + GuiSFX::Pause s_OutroPauseBetweenCloseAndIris; + GuiSFX::Show s_OutroIrisShow; + GuiSFX::Hide s_OutroLetterBoxHide; + GuiSFX::IrisWipeOpen s_OutroIrisOpen; + + static bool s_suppressAcceptCancelButtons; + +}; + +inline void CGuiScreenLetterBox::SuppressAcceptCancelButtons( bool suppress ) +{ + s_suppressAcceptCancelButtons = suppress; +} + +#endif // GUISCREENLETTERBOX_H diff --git a/game/code/presentation/gui/ingame/guiscreenlevelend.cpp b/game/code/presentation/gui/ingame/guiscreenlevelend.cpp new file mode 100644 index 0000000..ff5a557 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenlevelend.cpp @@ -0,0 +1,202 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLevelEnd +// +// Description: Implementation of the CGuiScreenLevelEnd class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenlevelend.h> + +#include <data/memcard/memorycardmanager.h> +#include <events/eventmanager.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> + +// Scrooby +// +#include <screen.h> +#include <page.h> +#include <text.h> + +// ATG +// +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLevelEnd::CGuiScreenLevelEnd +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLevelEnd::CGuiScreenLevelEnd +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreenLevelStats( pScreen, pParent, GUI_SCREEN_ID_LEVEL_END ) +{ +} + + +//=========================================================================== +// CGuiScreenLevelEnd::~CGuiScreenLevelEnd +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLevelEnd::~CGuiScreenLevelEnd() +{ +} + + +//=========================================================================== +// CGuiScreenLevelEnd::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelEnd::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + m_pParent->HandleMessage( GUI_MSG_QUIT_INGAME_FOR_RELOAD, + GetGameplayManager()->GetCurrentLevelIndex() + 1, + 0 ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenLevelEnd::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelEnd::InitIntro() +{ + // set heading to "Level Complete" + // + rAssert( m_levelStatsHeading != NULL ); + m_levelStatsHeading->SetIndex( 1 ); + + // show "use mission select" info text + // + if( m_useMissionSelect != NULL ) + { + m_useMissionSelect->SetVisible( true ); + } + + // update current level stats + // + this->UpdateLevelStats(); + + // load memory card info (in case user decides to save before advancing + // to next level) + // + GetMemoryCardManager()->LoadMemcardInfo( dynamic_cast<IMemoryCardInfoLoadCallback*>( m_pParent ) ); +} + + +//=========================================================================== +// CGuiScreenLevelEnd::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelEnd::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenLevelEnd::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelEnd::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenlevelend.h b/game/code/presentation/gui/ingame/guiscreenlevelend.h new file mode 100644 index 0000000..861b2e2 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenlevelend.h @@ -0,0 +1,48 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLevelEnd +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLEVELEND_H +#define GUISCREENLEVELEND_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenlevelstats.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLevelEnd : public CGuiScreenLevelStats +{ +public: + CGuiScreenLevelEnd( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenLevelEnd(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENLEVELEND_H diff --git a/game/code/presentation/gui/ingame/guiscreenlevelstats.cpp b/game/code/presentation/gui/ingame/guiscreenlevelstats.cpp new file mode 100644 index 0000000..13f7ae3 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenlevelstats.cpp @@ -0,0 +1,270 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLevelStats +// +// Description: Implementation of the CGuiScreenLevelStats class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenlevelstats.h> + +#include <cards/cardgallery.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <render/enums/renderenums.h> + +// Scrooby +// +#include <screen.h> +#include <page.h> +#include <group.h> +#include <text.h> + +// ATG +// +#include <raddebug.hpp> + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenLevelStats::CGuiScreenLevelStats +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLevelStats::CGuiScreenLevelStats +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID windowID +) +: CGuiScreen( pScreen, pParent, windowID ), + m_levelStatsHeading( NULL ), + m_useMissionSelect( NULL ) +{ + memset( m_levelStats, 0, sizeof( m_levelStats ) ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LevelStats" ); + rAssert( pPage != NULL ); + + this->AutoScaleFrame( pPage ); + + m_levelStatsHeading = pPage->GetText( "LevelProgress" ); + rAssert( m_levelStatsHeading != NULL ); + + Scrooby::Group* pGroup = pPage->GetGroup( "Stats" ); + rAssert( pGroup != NULL ); + + m_levelStats[ STAT_STORY_MISSIONS ] = pGroup->GetText( "StoryMissions_Unlocked" ); + m_levelStats[ STAT_BONUS_MISSIONS ] = pGroup->GetText( "BonusMissions_Unlocked" ); + m_levelStats[ STAT_STREET_RACES ] = pGroup->GetText( "StreetRaces_Unlocked" ); + m_levelStats[ STAT_CARDS ] = pGroup->GetText( "Cards_Unlocked" ); + m_levelStats[ STAT_CLOTHING ] = pGroup->GetText( "Clothing_Unlocked" ); + m_levelStats[ STAT_VEHICLES ] = pGroup->GetText( "Vehicles_Unlocked" ); + m_levelStats[ STAT_WASPS ] = pGroup->GetText( "Wasps_Unlocked" ); + m_levelStats[ STAT_GAGS ] = pGroup->GetText( "Gags_Unlocked" ); + m_levelStats[ STAT_LEVEL_COMPLETE ] = pGroup->GetText( "LevelComplete_Value" ); + +#ifdef RAD_DEBUG + for( int i = 0; i < NUM_LEVEL_STATS; i++ ) + { + rAssert( m_levelStats[ i ] != NULL ); + } +#endif + + m_useMissionSelect = pPage->GetText( "UseMissionSelect" ); + if( m_useMissionSelect != NULL ) + { + m_useMissionSelect->SetVisible( false ); // hide by default + + m_useMissionSelect->SetTextMode( Scrooby::TEXT_WRAP ); + m_useMissionSelect->SetDisplayOutline( true ); + } +} + + +//=========================================================================== +// CGuiScreenLevelStats::~CGuiScreenLevelStats +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenLevelStats::~CGuiScreenLevelStats() +{ +} + + +//=========================================================================== +// CGuiScreenLevelStats::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelStats::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenLevelStats::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelStats::InitIntro() +{ + // update current level stats + // + this->UpdateLevelStats(); +} + + +//=========================================================================== +// CGuiScreenLevelStats::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelStats::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenLevelStats::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenLevelStats::InitOutro() +{ +} + + +void +CGuiScreenLevelStats::UpdateLevelStats() +{ + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + char buffer[ 32 ]; + RenderEnums::LevelEnum currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + + sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumMissionsCompleted( currentLevel ), 7 ); + m_levelStats[ STAT_STORY_MISSIONS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryBonusMissionCompleted( currentLevel ) ? 1 : 0, 1 ); + m_levelStats[ STAT_BONUS_MISSIONS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumStreetRacesCompleted( currentLevel ), 3 ); + m_levelStats[ STAT_STREET_RACES ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", GetCardGallery()->GetCollectedCards( currentLevel )->m_numCards, 7 ); + m_levelStats[ STAT_CARDS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumSkinsUnlocked( currentLevel ), 3 ); + m_levelStats[ STAT_CLOTHING ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumCarUnlocked( currentLevel ), 5 ); + m_levelStats[ STAT_VEHICLES ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumWaspsDestroyed( currentLevel ), + GetRewardsManager()->GetTotalWasps( currentLevel ) ); + m_levelStats[ STAT_WASPS ]->SetString( 0, buffer ); + + sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumGagsViewed( currentLevel ), + GetRewardsManager()->GetTotalGags( currentLevel ) ); + m_levelStats[ STAT_GAGS ]->SetString( 0, buffer ); + + sprintf( buffer, "%.1f %%", GetCharacterSheetManager()->QueryPercentLevelCompleted( currentLevel ) ); + m_levelStats[ STAT_LEVEL_COMPLETE ]->SetString( 0, buffer ); + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenlevelstats.h b/game/code/presentation/gui/ingame/guiscreenlevelstats.h new file mode 100644 index 0000000..8c1051d --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenlevelstats.h @@ -0,0 +1,71 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenLevelStats +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENLEVELSTATS_H +#define GUISCREENLEVELSTATS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenLevelStats : public CGuiScreen +{ +public: + CGuiScreenLevelStats( Scrooby::Screen* pScreen, CGuiEntity* pParent, + eGuiWindowID windowID = GUI_SCREEN_ID_LEVEL_STATS ); + virtual ~CGuiScreenLevelStats(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void UpdateLevelStats(); + + enum eLevelStats + { + STAT_STORY_MISSIONS, + STAT_BONUS_MISSIONS, + STAT_STREET_RACES, + STAT_CARDS, + STAT_CLOTHING, + STAT_VEHICLES, + STAT_WASPS, + STAT_GAGS, + STAT_LEVEL_COMPLETE, + + NUM_LEVEL_STATS + }; + + Scrooby::Text* m_levelStatsHeading; + Scrooby::Text* m_levelStats[ NUM_LEVEL_STATS ]; + + Scrooby::Text* m_useMissionSelect; + +}; + +#endif // GUISCREENLEVELSTATS_H diff --git a/game/code/presentation/gui/ingame/guiscreenmissionbase.cpp b/game/code/presentation/gui/ingame/guiscreenmissionbase.cpp new file mode 100644 index 0000000..bfdcf48 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionbase.cpp @@ -0,0 +1,1419 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionLoad +// +// Description: Implementation of the CGuiScreenMissionSuccess class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/04/07 ian gipson Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <camera/animatedcam.h> +#include <camera/supercammanager.h> +#include <events/eventmanager.h> +#include <gameflow/gameflow.h> +#include <memory/classsizetracker.h> +#include <mission/gameplaymanager.h> +#include <mission/objectives/coinobjective.h> +#include <mission/objectives/raceobjective.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/missionmanager.h> +#include <p3d/imagefactory.hpp> +#include <p3d/sprite.hpp> +#include <presentation/gui/ingame/guiscreenmissionbase.h> +#include <presentation/gui/ingame/guiscreenmissionselect.h> +#include <presentation/gui/utility/transitions.h> +#include <sound/soundmanager.h> +#include <worldsim/redbrick/vehicle.h> +#include <worldsim/coins/coinmanager.h> +#include <worldsim/worldphysicsmanager.h> +#include <worldsim/character/charactermanager.h> + +#include <ai/actor/actormanager.h> + +#include <group.h> +#include <layer.h> +#include <page.h> +#include <polygon.h> +#include <pure3dobject.h> +#include <screen.h> +#include <sprite.h> +#include <text.h> + + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +#define CLIP_PAUSE_TIME 300.0f +#define CLIP_MOVE_TIME 300.0f + + +//Chuck +//Intialize the special case patty and selma screen pointer +tSprite* CGuiScreenMissionBase::sp_PattyAndSelmaScreenPNG = NULL; + +char CGuiScreenMissionBase::s_AnimatedBitmapName[ 256 ] = ""; +char CGuiScreenMissionBase::s_AnimatedBitmapShortName[ 32 ] = ""; +tSprite* CGuiScreenMissionBase::s_AnimatedBitmapSprite = NULL; +bool CGuiScreenMissionBase::s_BitmapLoadPending = false; + +static tColour g_BackgroundColorLeft( 255, 255, 255, 255 ); +static tColour g_BackgroundColorRight( 255, 255, 255, 255 ); + +const tColour g_BackgroundBlue ( 59, 76, 129 ); +const tColour g_BackgroundRed ( 100, 6, 6 ); +const tColour g_BackgroundGreen( 7, 73, 30 ); + +const tColour g_ColorNormalLeft ( 255, 255, 255, 255 ); +const tColour g_ColorNormalRight( 255, 255, 255, 255 ); +const tColour g_ColorBonusLeft ( 255, 255, 255, 255 ); +const tColour g_ColorBonusRight ( 255, 255, 255, 255 ); +const tColour g_ColorRaceLeft ( 255, 255, 255, 255 ); +const tColour g_ColorRaceRight ( 255, 255, 255, 255 ); +const tColour g_ColorWagerLeft ( 255, 255, 255, 255 ); +const tColour g_ColorWagerRight ( 255, 255, 255, 255 ); + +GuiSFX::Dummy g_IntroStart( "IntroStart" ); +GuiSFX::Junction3 g_IntroJunction; +GuiSFX::Show g_ForegroundShow( "ForeGroundShow" ); +GuiSFX::Show g_ClipLeftShow( "ClipLeftShow" ); +GuiSFX::PauseInFrames g_IntroPause( "Pause" ); +GuiSFX::Translator g_ScreenSlideIn( "ScreenSlideIn" ); +GuiSFX::Pause g_ClipLeftPause( "ClipLeftPause" ); +GuiSFX::Translator g_ClipLeftSlideOut( "ClipLeftSlideOut" ); +GuiSFX::Hide g_ClipLeftHide( "ClipLeftHide" ); +GuiSFX::Show g_BackgroundShow( "BackgroundShow" ); +GuiSFX::ColorChange g_DarkenPolyFade( "DarkenPolyFade" ); + +GuiSFX::Dummy g_OutroStart( "OutroStart" ); +GuiSFX::Junction3 g_OutroJunction; +GuiSFX::Translator g_OutroBottomOut( "OutroBottomOut" ); +GuiSFX::Translator g_OutroTopOut( "OutroTopOut" ); +GuiSFX::Show g_ClipRightShow( "ClipRightShow" ); +GuiSFX::Pause g_ClipRightPause( "ClipRightPause" ); +GuiSFX::Translator g_ClipRightSlideIn( "ClipRightSlideIn" ); +GuiSFX::Translator g_ScreenSlideOut( "ScreenSlideOut" ); +GuiSFX::Hide g_OutroHideEverything( "OutroHideEverything" ); +GuiSFX::Dummy g_OutroDone( "OutroDone" ); + +GuiSFX::IrisWipeOpen g_IrisOpen( "IrisOpen" ); +GuiSFX::IrisWipeOpen g_IrisClose( "IrisClose" ); + +GuiSFX::PulseScale g_TitlePulse( "TitlePulse" ); + +const float VEHICLE_ODDS_HARD_THRESHOLD = 3.0f; +const float VEHICLE_ODDS_MEDIUM_THRESHOLD = 2.0f; + +#ifdef RAD_WIN32 +const float MISSION_BITMAP_CORRECTION_SCALE = 0.67f; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMissionSuccess::CGuiScreenMissionSuccess +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionBase::CGuiScreenMissionBase( Scrooby::Screen* pScreen, CGuiEntity* pParent, eGuiWindowID id ): + CGuiScreen( pScreen, pParent, id ), + m_missionTitle( NULL ), + m_loadCompleted( NULL ), + m_PlayAnimatedCamera( false ), + m_gamblingInfo( NULL ), + m_gamblingEntryFee( NULL ), + m_gamblingTimeToBeat( NULL ), + m_gamblingBestTime( NULL ), + m_gamblingVehicleOdds( NULL ), + m_gamblingPayout( NULL ), + m_ReadyToExitScreen( false ) +{ + CLASSTRACKER_CREATE( CGuiScreenMissionBase ); + + unsigned char* leftChar = reinterpret_cast< unsigned char* >( &g_BackgroundColorLeft ); + radDbgWatchAddUnsignedChar( leftChar + 2, "Red", "gui\\missionloading\\left" ); + radDbgWatchAddUnsignedChar( leftChar + 1, "Green", "gui\\missionloading\\left" ); + radDbgWatchAddUnsignedChar( leftChar + 0, "Blue", "gui\\missionloading\\left" ); + //radDbgWatchAddUnsignedChar( leftChar + 3, "Alpha", "gui\\missionloading\\left" ); + + unsigned char* rightChar = reinterpret_cast< unsigned char* >( &g_BackgroundColorRight ); + radDbgWatchAddUnsignedChar( rightChar + 2, "Red", "gui\\missionloading\\right" ); + radDbgWatchAddUnsignedChar( rightChar + 1, "Green", "gui\\missionloading\\right" ); + radDbgWatchAddUnsignedChar( rightChar + 0, "Blue", "gui\\missionloading\\right" ); + //radDbgWatchAddUnsignedChar( rightChar + 3, "Alpha", "gui\\missionloading\\right" ); + + + + + // + // Add All the transitions to the screen + // + AddTransition( g_DarkenPolyFade ); + AddTransition( g_TitlePulse ); + AddTransition( g_ScreenSlideIn ); + AddTransition( g_ScreenSlideOut ); + AddTransition( g_ClipLeftSlideOut ); + AddTransition( g_ClipRightSlideIn ); + AddTransition( g_OutroBottomOut ); + AddTransition( g_OutroTopOut ); + AddTransition( g_IntroPause ); + AddTransition( g_ClipLeftPause ); + AddTransition( g_ClipRightPause ); + DoneAddingTransitions(); + + // + // Retrieve the Scrooby drawing elements. + // + + // + // Iris wipe stuff + // + Scrooby::Page* irisPage; + irisPage = m_pScroobyScreen->GetPage( "3dIris" ); + rAssert( irisPage != NULL ); + + m_Iris = irisPage->GetPure3dObject( "p3d_iris" ); + rAssert( m_Iris != NULL ); + + m_MultiController = p3d::find< tMultiController >( "IrisController" ); + rAssert( m_MultiController ); + m_irisWipeNumFrames = m_MultiController->GetNumFrames(); + + // + // Functional page stuff + // + + Scrooby::Layer* overlay; + + // + // Get the elements out of scrooby + // + m_Page = m_pScroobyScreen->GetPage( "MissionLoad" ); rAssert( m_Page != NULL ); + m_LetterboxPage = m_pScroobyScreen->GetPage( "LetterBox" ); rAssert( m_LetterboxPage != NULL ); + m_FgLayer = m_Page-> GetGroup( "foreground" ); rAssert( m_FgLayer != NULL ); + m_loadCompleted = m_Page->GetGroup( "LoadCompleted" ); rAssert( m_loadCompleted != NULL ); + m_Line0 = m_FgLayer->GetText( "MissionInfo" ); rAssert( m_Line0 != NULL ); + m_missionTitle = m_FgLayer->GetText( "MissionTitle" ); rAssert( m_missionTitle != NULL ); + m_BgLayer = m_Page->GetLayer( "Background" ); rAssert( m_BgLayer != NULL ); + m_missionStartBitmap = m_Page->GetSprite( "MissionStartBitmap" ); rAssert( m_missionStartBitmap != NULL); + overlay = m_Page->GetLayer( "Overlay" ); rAssert( overlay != NULL ); + m_darkenPolys = overlay->GetGroup( "dark_polys" ); rAssert( m_darkenPolys != NULL ); + m_darkenTop = m_LetterboxPage->GetGroup( "TopBar" ); rAssert( m_darkenTop != NULL ); + m_darkenBottom = m_LetterboxPage->GetGroup( "BottomBar" ); rAssert( m_darkenBottom != NULL ); + m_backgroundPoly = m_Page->GetPolygon( "background" ); rAssert( m_backgroundPoly!= NULL ); + m_textOverlays = m_Page->GetGroup( "Text" ); rAssert( m_textOverlays != NULL ); + m_Flag = m_Page->GetSprite( "flag" ); rAssert( m_Flag != NULL ); + m_ClipLeftGroup = m_Page->GetGroup( "ClipLeftGroup"); rAssert( m_ClipLeftGroup != NULL ); + m_ClipRightGroup= m_Page->GetGroup( "ClipRightGroup"); rAssert( m_ClipRightGroup!= NULL ); + m_ClipLeft = m_Page->GetSprite( "clipLeft" ); rAssert( m_ClipLeft != NULL ); + m_ClipRight = m_Page->GetSprite( "clipRight1"); rAssert( m_ClipRight != NULL ); + m_ClipLeftArm = m_Page->GetSprite( "clipArmLeft1" ); rAssert( m_ClipLeftArm != NULL ); + m_ClipRightArm = m_Page->GetSprite( "clipArmRight1" ); rAssert( m_ClipRightArm != NULL ); + m_Foreground = m_Page->GetLayer( "Background" ); rAssert( m_Foreground != NULL ); + m_LetterboxLayer=m_LetterboxPage->GetLayer( "Background" ); rAssert( m_LetterboxLayer!= NULL ); + + if( IsWideScreenDisplay() ) + { + m_Page->ResetTransformation(); + ApplyWideScreenCorrectionScale( m_Page ); + } + + + m_buttonIcons[ BUTTON_ICON_ACCEPT ] = m_loadCompleted->GetGroup( "Continue" ); + m_buttonIcons[ BUTTON_ICON_BACK ] = m_loadCompleted->GetGroup( "Abort" ); + + // + // add some scrooby elements to the watcher + // + const char* screenName = GetWatcherName(); + + #ifdef DEBUGWATCH + m_missionStartBitmap-> WatchAll( screenName ); + m_missionTitle-> WatchAll( screenName ); + m_Line0-> WatchAll( screenName ); + m_LetterboxPage-> WatchAll( screenName ); + m_LetterboxLayer-> WatchAll( screenName ); + m_darkenTop-> WatchAll( screenName ); + m_darkenBottom-> WatchAll( screenName ); + m_Flag-> WatchAll( screenName ); + m_ClipLeft-> WatchAll( screenName ); + m_ClipRight-> WatchAll( screenName ); + m_ClipLeftArm-> WatchAll( screenName ); + m_ClipRightArm-> WatchAll( screenName ); + m_ClipLeftGroup-> WatchAll( screenName ); + m_ClipRightGroup-> WatchAll( screenName ); + #endif + + this->SetFadingEnabled( false ); + m_ClipRight->Scale( -1.0f, 1.0f, 1.0f ); + + // Get gambling info group and text + // + m_gamblingInfo = m_Page->GetGroup( "GamblingInfo" ); + rAssert( m_gamblingInfo != NULL ); + + m_gamblingEntryFee = m_gamblingInfo->GetText( "EntryFee_Value" ); + m_gamblingTimeToBeat = m_gamblingInfo->GetText( "TimeToBeat_Value" ); + m_gamblingBestTime = m_gamblingInfo->GetText( "BestTime_Value" ); + m_gamblingVehicleOdds = m_gamblingInfo->GetText( "VehicleOdds_Value" ); + m_gamblingPayout = m_gamblingInfo->GetText( "Payout_Value" ); + + g_BackgroundColorLeft = m_backgroundPoly->GetVertexColour( 0 ); + g_BackgroundColorRight = m_backgroundPoly->GetVertexColour( 2 ); + + m_Flag->ResizeToBoundingBox(); + + // + // Set Up Transitions + // + + // Continuous + g_TitlePulse.SetDrawable( m_textOverlays ); + g_TitlePulse.Activate(); + g_TitlePulse.SetAmplitude( 0.05f ); + g_TitlePulse.SetFrequency( 2.0f ); + WATCH( g_TitlePulse, GetWatcherName() ); + + // Intro + WATCH( g_IntroStart, GetWatcherName() ); + + g_ForegroundShow.SetDrawable( m_Foreground ); + + g_ClipLeftShow.SetDrawable( m_ClipLeftGroup ); + + g_IntroPause.SetNumberOfFrames( 1 ); + + g_ScreenSlideIn.SetDrawable( m_Foreground ); + g_ScreenSlideIn.SetStartOffscreenLeft( m_Foreground ); + g_ScreenSlideIn.SetTimeInterval( 400.0f ); + WATCH( g_ScreenSlideIn, GetWatcherName() ); + + g_ClipLeftPause.SetTimeInterval( CLIP_PAUSE_TIME ); + WATCH( g_ClipLeftPause, GetWatcherName() ); + + g_ClipLeftSlideOut.SetDrawable( m_ClipLeftGroup ); + g_ClipLeftSlideOut.SetEndOffscreenLeft( m_ClipLeftGroup ); + g_ClipLeftSlideOut.SetTimeInterval( CLIP_MOVE_TIME ); + WATCH( g_ClipLeftSlideOut, GetWatcherName() ); + + g_ClipLeftHide.SetDrawable( m_ClipLeftGroup ); + + // Outro + WATCH( g_OutroStart, GetWatcherName() ); + + g_ClipRightShow.SetDrawable( m_ClipRightGroup ); + + g_OutroTopOut.SetDrawable( m_darkenTop ); + g_OutroTopOut.SetEndOffscreenTop( m_darkenTop ); + g_OutroTopOut.SetTimeInterval( 1000.0f ); + WATCH( g_OutroTopOut, GetWatcherName() ); + + g_OutroBottomOut.SetDrawable( m_darkenBottom ); + g_OutroBottomOut.SetEndOffscreenBottom( m_darkenBottom ); + g_OutroBottomOut.SetTimeInterval( 1000.0f ); + WATCH( g_OutroBottomOut, GetWatcherName() ); + + g_ClipRightSlideIn.SetDrawable( m_ClipRightGroup ); + g_ClipRightSlideIn.SetStartOffscreenRight( m_ClipRightGroup ); + g_ClipRightSlideIn.SetTimeInterval( CLIP_MOVE_TIME ); + WATCH( g_ClipRightSlideIn, GetWatcherName() ); + + g_ClipRightPause.SetTimeInterval( CLIP_PAUSE_TIME ); + WATCH( g_ClipRightPause, GetWatcherName() ); + + g_ScreenSlideOut.SetDrawable( m_Foreground ); + g_ScreenSlideOut.SetEndOffscreenRight( m_Foreground ); + g_ScreenSlideOut.SetTimeInterval( 400.0f ); + WATCH( g_ScreenSlideOut, GetWatcherName() ); + + g_BackgroundShow.SetDrawable( m_BgLayer ); + + g_DarkenPolyFade.SetDrawable( m_darkenPolys ); + g_DarkenPolyFade.SetStartColour( tColour( 255, 255, 255, 255 ) ); + g_DarkenPolyFade.SetEndColour( tColour( 255, 255, 255, 0 ) ); + g_DarkenPolyFade.SetTimeInterval( 100.0f ); + + g_OutroHideEverything.SetDrawable( m_Foreground ); + + m_missionStartBitmap->SetRawSprite( NULL ); +#ifdef RAD_WIN32 + m_missionStartBitmap->ResetTransformation(); + m_missionStartBitmap->ScaleAboutCenter( MISSION_BITMAP_CORRECTION_SCALE ); + m_missionStartBitmap->Translate( -71, -32 ); // These are trial & error numbers that hopefully work. +#endif + + // text wrap mission info title and description + // + m_missionTitle->SetTextMode( Scrooby::TEXT_WRAP ); + m_Line0->SetTextMode( Scrooby::TEXT_WRAP ); + + // + // Set up transitions for lines of text + // + + // + // Transition sequencing + // + g_IntroStart. SetNextTransition( g_IntroJunction ); + g_IntroJunction. SetNextTransition( 0, g_IntroPause ); + g_IntroJunction. SetNextTransition( 1, g_ClipLeftShow ); + g_IntroJunction. SetNextTransition( 2, g_ScreenSlideIn ); + g_ForegroundShow. SetNextTransition( NULL ); + g_ClipLeftShow. SetNextTransition( NULL ); + g_IntroPause. SetNextTransition( g_ForegroundShow ); + g_ScreenSlideIn. SetNextTransition( g_ClipLeftPause ); + g_ClipLeftPause. SetNextTransition( g_ClipLeftSlideOut ); + g_ClipLeftSlideOut. SetNextTransition( g_ClipLeftHide ); + g_ClipLeftHide. SetNextTransition( g_BackgroundShow ); + g_BackgroundShow. SetNextTransition( g_DarkenPolyFade ); + g_DarkenPolyFade. SetNextTransition( NULL ); + + g_OutroStart. SetNextTransition( g_OutroJunction ); + g_OutroJunction. SetNextTransition( 0, g_ClipRightShow ); + g_OutroJunction. SetNextTransition( 1, g_OutroBottomOut ); + g_OutroJunction. SetNextTransition( 2, g_OutroTopOut ); + g_OutroBottomOut. SetNextTransition( NULL ); + g_OutroTopOut. SetNextTransition( NULL ); + g_ClipRightShow. SetNextTransition( g_ClipRightSlideIn ); + g_ClipRightSlideIn. SetNextTransition( g_ClipRightPause ); + g_ClipRightPause. SetNextTransition( g_ScreenSlideOut ); + g_ScreenSlideOut. SetNextTransition( g_OutroHideEverything ); + g_OutroHideEverything. SetNextTransition( g_OutroDone ); + g_OutroDone. SetNextTransition( NULL ); +} + +//=========================================================================== +// CGuiScreenMissionBase::~CGuiScreenMissionBase +//=========================================================================== +// Description: destructor +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionBase::~CGuiScreenMissionBase() +{ + CLASSTRACKER_DESTROY( CGuiScreenMissionBase ); + if( s_AnimatedBitmapSprite) + { + tRefCounted::Release(s_AnimatedBitmapSprite); + } + + //Chuck release the special patty and selma screen if we are still holding on to it. + if(sp_PattyAndSelmaScreenPNG) + { + tRefCounted::Release(sp_PattyAndSelmaScreenPNG); + sp_PattyAndSelmaScreenPNG = NULL; + } + s_BitmapLoadPending = false; + p3d::inventory->RemoveSectionElements( tEntity::MakeUID( "DynamicHud" ) ); +} + +//=========================================================================== +// CGuiScreenMissionBase::ClearBitmap +//=========================================================================== +// Description: clears the currently loaded animated bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the abort bitmap group +// +//=========================================================================== +void CGuiScreenMissionBase::ClearBitmap() +{ + s_AnimatedBitmapSprite = NULL; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetAbortBitmap +//=========================================================================== +// Description: Allows access to the stored group pointer +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the abort bitmap group +// +//=========================================================================== +Scrooby::Group* CGuiScreenMissionBase::GetAbortBitmap() +{ + return m_buttonIcons[ BUTTON_ICON_BACK ]; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetBitmapName +//=========================================================================== +// Description: Allows access to the name of the mission briefing pic +// +// Constraints: None. +// +// Parameters: buffer - filled in with the name +// +// Return: pointer to the flag +// +//=========================================================================== +void CGuiScreenMissionBase::GetBitmapName( char* buffer ) +{ + if( buffer != NULL ) + { + ::strcpy( buffer, s_AnimatedBitmapName ); + } +} + +//=========================================================================== +// CGuiScreenMissionBase::GetFlag +//=========================================================================== +// Description: Allows access to the flag bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the flag +// +//=========================================================================== +Scrooby::Drawable* CGuiScreenMissionBase::GetFlag() +{ + return m_Flag; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetLoadCompletedGroup +//=========================================================================== +// Description: Allows access to the stored group pointer +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the pace +// +//=========================================================================== +Scrooby::Group* CGuiScreenMissionBase::GetLoadCompletedGroup() +{ + return m_loadCompleted; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetMissionInfoText +//=========================================================================== +// Description: Allows access to the stored text pointer +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the text +// +//=========================================================================== +Scrooby::Text* CGuiScreenMissionBase::GetMissionInfoText() +{ + return m_Line0; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetMissionStartBitmap +//=========================================================================== +// Description: Allows access to the stored mission start bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the drawable +// +//=========================================================================== +Scrooby::BoundedDrawable* CGuiScreenMissionBase::GetMissionStartBitmap() +{ + return m_missionStartBitmap; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetPage +//=========================================================================== +// Description: Allows access to the stored page pointer +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the pace +// +//=========================================================================== +Scrooby::Page* CGuiScreenMissionBase::GetPage() +{ + return m_Page; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetPage +//=========================================================================== +// Description: Allows access to the stored page pointer +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the pace +// +//=========================================================================== +Scrooby::Text* CGuiScreenMissionBase::GetTitleText() +{ + return m_missionTitle; +} + +//=========================================================================== +// CGuiScreenMissionBase::GetWatcherName +//=========================================================================== +// Description: Allows access to the stored page pointer +// +// Constraints: None. +// +// Parameters: None. +// +// Return: pointer to the pace +// +//=========================================================================== +const char* CGuiScreenMissionBase::GetWatcherName() const +{ + return "GuiScreenMissionBase"; +} + +//=========================================================================== +// CGuiScreenMissionBase::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_UPDATE ) + { + float deltaT = static_cast< float >( param1 ); + ResetMovableObjects(); + m_ClipLeftArm->ResizeToBoundingBox(); + m_ClipRightArm->ResizeToBoundingBox(); + m_ClipLeftGroup->ResetTransformation(); + UpdateTransitions( deltaT ); + m_FgLayer->SetColour( tColour( 255, 255, 255, 255 ) ); + m_missionStartBitmap->SetColour( tColour( 255, 255, 255, 255 ) ); + m_backgroundPoly->SetVertexColour( 0, g_BackgroundColorLeft ); + m_backgroundPoly->SetVertexColour( 1, g_BackgroundColorLeft ); + m_backgroundPoly->SetVertexColour( 2, g_BackgroundColorRight ); + m_backgroundPoly->SetVertexColour( 3, g_BackgroundColorRight ); + } + + if( message == GUI_MSG_WINDOW_EXIT ) + { + } + + if( m_state == GUI_WINDOW_STATE_INTRO ) + { + if( message == GUI_MSG_UPDATE ) + { +// --m_numTransitionsPending; //get us out of the intro state + float deltaT = static_cast< float >( param1 ); + UpdateAnimatedBitmap( deltaT ); + } + } + + if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + if( message == GUI_MSG_UPDATE ) + { + if( g_OutroDone.IsDone() ) + { + --m_numTransitionsPending; + OutroDone(); + } + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + UpdateAnimatedBitmap( static_cast< float >( param1 ) ); + break; + } + default: + { + break; + } + }; + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenMissionBase::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::InitIntro() +{ + m_ReadyToExitScreen = false; + if( ( !s_BitmapLoadPending ) && ( s_AnimatedBitmapSprite == NULL) ) + { + ReplaceBitmap(); + } + + // + // Need to reset all the transitions + // + this->SetButtonVisible( BUTTON_ICON_BACK, true ); + m_LetterboxPage->SetVisible( true ); + m_Page-> SetVisible( true ); + m_Line0-> SetVisible( false ); + m_BgLayer-> SetVisible( true ); + m_FgLayer-> SetVisible( true ); + m_Iris-> SetVisible( false ); + m_missionTitle-> SetVisible( false ); + m_Flag-> SetVisible( false ); + m_ClipLeftGroup->SetVisible( true ); + m_ClipRightGroup->SetVisible( false ); + m_Foreground-> SetVisible( false ); + m_darkenPolys-> SetColour( tColour( 255, 255, 255, 255 ) ); + m_darkenBottom-> ResetTransformation(); + m_darkenTop-> ResetTransformation(); + m_ClipLeft-> ResetTransformation(); + + + m_MultiController->Reset(); + m_MultiController->SetRelativeSpeed( 1.0f ); + m_MultiController->SetFrameRange( 0.0f, m_irisWipeNumFrames ); + m_MultiController->SetFrame( 0.0f ); + unsigned int size = m_textOverlays->Size(); + unsigned int i; + for( i = 0; i < size; ++i ) + { + Scrooby::Drawable* drawable = m_textOverlays->GetChildDrawable( i ); + drawable->SetVisible( false ); + } + + ResetTransitions(); + + g_IntroStart.Activate(); + g_OutroStart.DeactivateChain(); + + const int currentLevelIndex = GetGameplayManager()->GetCurrentLevelIndex(); + int currentMissionIndex = GetGameplayManager()->GetCurrentMissionIndex(); + + int currentMissionNum = GetGameplayManager()->GetCurrentMissionNum(); + if( currentMissionNum >= GameplayManager::MAX_MISSIONS ) + { + // current mission must be either a street race or a bonus mission + // + currentMissionIndex = currentMissionNum - GameplayManager::MAX_MISSIONS + + MAX_NUM_REGULAR_MISSIONS; + } + else + { + // special case for level 1 due to tutorial mission + // + if( currentLevelIndex == RenderEnums::L1 ) + { + currentMissionIndex--; + } + +#ifdef RAD_E3 + // TC: *** quick and dirty E3 hack! + // + if( currentLevelIndex == RenderEnums::L2 ) + { + currentMissionIndex = RenderEnums::M5; + } +#endif + } + + int textIndex = currentLevelIndex * MAX_NUM_MISSIONS_PER_LEVEL + currentMissionIndex; + int missionNumber = textIndex % MAX_NUM_MISSIONS_PER_LEVEL ; + + // special case for level 1 due to tutorial mission + // + if( currentLevelIndex == 0 ) + { + if( textIndex < 0 ) // meaning it must be the tutorial mission + { + const int NUM_LEVELS = 7; + textIndex = MAX_NUM_MISSIONS_PER_LEVEL * NUM_LEVELS; + missionNumber = MAX_NUM_MISSIONS_PER_LEVEL; + } + } + + m_missionTitle->SetIndex( textIndex ); + m_Line0->SetIndex( textIndex ); + + // + // Set the Background Color of the screen + // + bool bonusMission = GetGameplayManager()->GetCurrentMission()->IsBonusMission(); + bool raceMission = GetGameplayManager()->GetCurrentMission()->IsRaceMission(); + bool wagerMission = GetGameplayManager()->GetCurrentMission()->IsWagerMission(); + + if( wagerMission ) + { + m_backgroundPoly->SetColour( g_BackgroundGreen ); + g_BackgroundColorLeft = g_ColorWagerLeft; + g_BackgroundColorRight = g_ColorWagerRight; + } + else if( bonusMission ) + { + m_backgroundPoly->SetColour( g_BackgroundRed ); + g_BackgroundColorLeft = g_ColorBonusLeft; + g_BackgroundColorRight = g_ColorBonusRight; + } + else if( raceMission ) + { + m_backgroundPoly->SetColour( g_BackgroundBlue ); + g_BackgroundColorLeft = g_ColorRaceLeft; + g_BackgroundColorRight = g_ColorRaceRight; + } + else + { + m_backgroundPoly->SetColour( g_BackgroundBlue ); + g_BackgroundColorLeft = g_ColorNormalLeft; + g_BackgroundColorRight = g_ColorNormalRight; + } + + if( wagerMission || bonusMission || raceMission ) + { + s_AnimatedBitmapSprite = NULL; + //SetBitmapName( NULL ); + } + + rAssert( m_gamblingInfo != NULL ); + m_gamblingInfo->SetVisible( false ); // hide by default + + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); // show by default + + // + // Inform the sound manager that it's time to turn the sound down a bit + // + GetSoundManager()->OnMissionBriefingStart(); +} + +//=========================================================================== +// CGuiScreenMissionLoad::InitIntroWagerMission +//=========================================================================== +// Description: sets up stuff for the wager mission screen +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::InitIntroWagerMission() +{ + int textIndex = m_Line0->GetNumOfStrings() - 2; + int entryFee = 0; // in coins + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + MissionStage* ms = currentMission->GetStage( 0 ); + rAssert( ms != NULL ); + CoinObjective* coinObjective = dynamic_cast<CoinObjective*>( ms->GetObjective() ); + rAssertMsg( coinObjective != NULL, "No coin objective in first stage!" ); + entryFee = coinObjective->GetCoinAmount(); + + if( entryFee > GetCoinManager()->GetBankValue() ) + { + // + // Disable accept button + // + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + + // + // Change the info text to the "You need (x) coins to continue" message + // + m_Line0->SetIndex( textIndex ); + UnicodeString us = m_Line0->GetString( textIndex ); + char number[ 256 ] = ""; + sprintf( number, "%d", entryFee ); + us.Replace( "%D", number ); + + m_Line0->SetString( textIndex + 1, us ); + m_Line0->SetIndex ( textIndex + 1 ); + } +} + +//=========================================================================== +// CGuiScreenMissionLoad::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::InitOutro() +{ + //This is a hack to get the stage setup before we start showing the world after + //the mission briefing screen. This simulates a one frame step that sets up and + //"starts" the mission before we leave the pause context. NOTE: There may be + //seom other managers that need to be run here. + GetMissionManager()->Update( 16 ); + GetSuperCamManager()->GetSCC( 0 )->NoTransition(); + GetSuperCamManager()->Update( 16, true ); + GetCharacterManager()->PreSimUpdate( 0.0001f ); + GetCharacterManager()->PreSubstepUpdate( 0.0001f ); + GetCharacterManager()->Update( 0.0001f ); + GetCharacterManager()->PostSubstepUpdate( 0.0001f ); + GetCharacterManager()->PostSimUpdate( 0.0001f ); + + g_OutroDone.Reset(); + g_OutroStart.Activate(); + ++m_numTransitionsPending; + + // + // Turn the sound back up + // + GetSoundManager()->OnMissionBriefingEnd(); +} + +//=========================================================================== +// CGuiScreenMissionBase::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::InitRunning() +{ +} + +//=========================================================================== +// CGuiScreenMissionBase::IsCurrentBitmap +//=========================================================================== +// Description: deetermines if the current bitmap loaded corresponds to this +// name +// +// Constraints: None. +// +// Parameters: name - the string name to check. +// +// Return: N/A. +// +//=========================================================================== +bool CGuiScreenMissionBase::IsCurrentBitmap( const char* name ) +{ + bool returnMe = ( strcmp( name, s_AnimatedBitmapName ) == 0 ); + return returnMe; +} + +//=========================================================================== +// CGuiScreenMissionBase::OutroDone +//=========================================================================== +// Description: called when the outro is done and we're ready to leave this +// screen +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::OutroDone() +{ + UnloadBitmap(); + + // + // If this is a race, we need to play a camera + // + if( m_PlayAnimatedCamera ) + { + // + // If it's a race mission, don't allow skipping of the animated cam + // + bool raceMission = GetGameplayManager()->GetCurrentMission()->IsRaceMission(); + if( raceMission ) + { + AnimatedCam::AllowSkipping( false ); + AnimatedCam::CheckPendingCameraSwitch(); + + // + // we need to go to the gameplay context. This is so not cool it almost makes me sick - IAN + // + GetGameFlow()->SetContext( CONTEXT_GAMEPLAY ); + } + m_PlayAnimatedCamera = false; + } + else + { + AnimatedCam::SetCamera( "" ); + AnimatedCam::SetMulticontroller( "" ); + } +} + +//=========================================================================== +// CGuiScreenMissionBase::RemoveAnimatedBitmap +//=========================================================================== +// Description: gets rid of the animated bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::RemoveAnimatedBitmap() +{ + if( s_AnimatedBitmapSprite != NULL ) + { + s_AnimatedBitmapSprite->Release(); + s_AnimatedBitmapSprite = NULL; + } +} + +//=========================================================================== +// CGuiScreenMissionBase::ReplaceBitmap +//=========================================================================== +// Description: replaces the bitmap with a sprite from a file +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::ReplaceBitmap() +{ + p3d::pddi->DrawSync(); + p3d::inventory->RemoveSectionElements( tEntity::MakeUID( "DynamicHud" ) ); + RemoveAnimatedBitmap(); + + rWarning( s_BitmapLoadPending != true ); + s_BitmapLoadPending = true; + rAssert( strlen( s_AnimatedBitmapName ) != 0 ); + if( strlen( s_AnimatedBitmapName ) != 0 ) + { + tRefCounted::Release( s_AnimatedBitmapSprite ); + tFileHandler* fileHandler = p3d::loadManager->GetHandler( "png" ); + rAssert( fileHandler != NULL ); + tImageHandler* pngHandler = dynamic_cast< tImageHandler* >( fileHandler ); + rAssert( pngHandler != NULL ); + pngHandler->SetLoadType( tImageHandler::SPRITE ); + LoadingManager::GetInstance()->AddRequest + ( + FILEHANDLER_PURE3D, + s_AnimatedBitmapName, + GMA_LEVEL_OTHER, + "DynamicHud" + ); + } +} + +//=========================================================================== +// CGuiScreenMissionBase::SetBitmapName +//=========================================================================== +// Description: sets up the name of the animated bitmap that will be loaded +// for this mission +// +// Constraints: None. +// +// Parameters: name - string representing the name of this bitmap on disk +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::SetBitmapName( const char* name ) +{ + // + // If we're erasing the bitmap + // + if( name == NULL ) + { + strcpy( s_AnimatedBitmapName, "" ); + strcpy( s_AnimatedBitmapShortName, "" ); + return; + } + + // + // If we're not really changing anything, early out + // + if( strcmp( name, s_AnimatedBitmapName ) == 0 ) + { + return; + } + + //save the whole filename + + //chuck: we need to somehow release the sprite or + //not set the s_AnimatedBitmapSprite = NULL because it + //will leak the the patty and selma screen. + //tRefCounted::Release(s_AnimatedBitmapSprite); + + //check if our static pointer is to the patty and selma screen + if (s_AnimatedBitmapSprite != NULL) + { +// s_AnimatedBitmapSprite->Release(); + + if ( + s_AnimatedBitmapSprite->GetUID() == tName::MakeUID("misXX_PS.png") + || + s_AnimatedBitmapSprite->GetUID() == tName::MakeUID("misXX_HW.png") + ) + { + //if it is then we make a switch + //tRefCounted::Assign(sp_PattyAndSelmaScreenPNG,s_AnimatedBitmapSprite); + rAssert(sp_PattyAndSelmaScreenPNG == NULL); + sp_PattyAndSelmaScreenPNG = s_AnimatedBitmapSprite; + } + } + + s_AnimatedBitmapSprite = NULL; + size_t length = strlen( name ); + rAssert( length < sizeof( s_AnimatedBitmapName ) ); + + // + // If there's no text just return + // + if( length == 0 ) + { + return; + } + + // + // if we're not actually changing anything, return + // + if( strcmp( s_AnimatedBitmapName, name ) == 0 ) + { + return; + } + strcpy( s_AnimatedBitmapName, name ); + + //figure out and save the name of the sprite from the filename + if( length >= 12 ) + { + const char* spriteName = name + length - 12; + strcpy( s_AnimatedBitmapShortName, spriteName ); + //s_AnimatedBitmapShortName[ 09 ] = 'p'; + s_AnimatedBitmapShortName[ 10 ] = 'n'; + s_AnimatedBitmapShortName[ 11 ] = 'g'; + } + else + { + strcpy( s_AnimatedBitmapShortName, "" ); + } +} + +//=========================================================================== +// CGuiScreenMissionBase::SetPlayAnimatedCamera +//=========================================================================== +// Description: sets a flag to tell us whether or not to play the animated +// camera after we exit this screen +// +// Constraints: None. +// +// Parameters: None +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::SetPlayAnimatedCamera( bool play ) +{ + m_PlayAnimatedCamera = play; +} + +//=========================================================================== +// CGuiScreenMissionBase::StartIrisWipeClose +//=========================================================================== +// Description: starts the transition to close the iris +// +// Constraints: None. +// +// Parameters: None +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::StartIrisWipeClose() +{ +// ++m_numTransitionsPending; + m_MultiController->Reset(); + float frames = m_MultiController->GetNumFrames(); + m_MultiController->SetFrameRange( 0.0f, frames * 0.5f ); + m_MultiController->SetFrame( 0.0f ); +} +//=========================================================================== +// CGuiScreenMissionBase::StartIrisWipeOpen +//=========================================================================== +// Description: starts the transition to open the iris +// +// Constraints: None. +// +// Parameters: None +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::StartIrisWipeOpen() +{ +// ++m_numTransitionsPending; + m_MultiController->Reset(); + float frames = m_MultiController->GetNumFrames(); + m_MultiController->SetFrameRange( frames * 0.5f, frames ); + m_MultiController->SetFrame( frames * 0.5f ); +} + +//=========================================================================== +// CGuiScreenMissionBase::UnloadBitmap +//=========================================================================== +// Description: unloads the bitmap, and reclaims all lost memory +// +// Constraints: None. +// +// Parameters: None +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::UnloadBitmap() +{ + p3d::pddi->DrawSync(); + //::radThreadSleep (500); // Hmmmm, this shouldn't be required + tRefCounted::Release( s_AnimatedBitmapSprite ); + m_missionStartBitmap->SetRawSprite( NULL ); + m_missionStartBitmap->SetVisible( false ); +} + +//=========================================================================== +// CGuiScreenMissionBase::UpdateAnimatedBitmap +//=========================================================================== +// Description: Updates animation of the bitmap +// +// Constraints: None. +// +// Parameters: deltaT - how much time has elapsed +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionBase::UpdateAnimatedBitmap( const float deltaT ) +{ + if( s_AnimatedBitmapSprite == NULL ) + { + p3d::inventory->PushSection(); + + p3d::pddi->DrawSync(); + p3d::inventory->SelectSection( "DynamicHud" ); + p3d::inventory->SetCurrentSectionOnly( false ); + tEntityTable* currentSection = p3d::inventory->GetSection( "DynamicHud" ); + + HeapMgr()->PushHeap( GMA_TEMP ); + tInventory::Iterator< tEntity > it( p3d::inventory ); + HeapMgr()->PopHeap( GMA_TEMP ); + + tEntity* entity = it.First(); + while( entity != NULL ) + { + if( entity->GetNameObject() == s_AnimatedBitmapShortName ) + { + tSprite* sprite = dynamic_cast< tSprite* >( entity ); + tRefCounted::Assign( s_AnimatedBitmapSprite, sprite ); + } + entity = it.Next(); + } + + if( s_AnimatedBitmapSprite == NULL ) + { + tRefCounted::Assign( s_AnimatedBitmapSprite, p3d::find< tSprite >( s_AnimatedBitmapShortName ) ); + } + if( s_AnimatedBitmapSprite == NULL ) + { + //loading is not yet complete + m_missionStartBitmap->SetVisible( false ); + } + else + { + p3d::inventory->RemoveSectionElements( tEntity::MakeUID( "DynamicHud" ) ); + #ifdef RAD_DEBUG + tSprite* stillThere = p3d::find< tSprite >( s_AnimatedBitmapShortName ); + rWarningMsg( stillThere == NULL, "We're leaking memory if we can't remove this" ); + #endif + m_missionStartBitmap->SetVisible( true ); + s_BitmapLoadPending = false; + } + + p3d::inventory->PopSection(); + + } + m_missionStartBitmap->SetRawSprite( s_AnimatedBitmapSprite ); + + //Chuck I hope this a safe place to release the patty and selma screen + if (sp_PattyAndSelmaScreenPNG != NULL) + { + tRefCounted::Release(sp_PattyAndSelmaScreenPNG); + sp_PattyAndSelmaScreenPNG= NULL; + } +} + +void +CGuiScreenMissionBase::UpdateGamblingInfo() +{ + rAssert( m_gamblingInfo != NULL ); + m_gamblingInfo->SetVisible( true ); + + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + char buffer[ 32 ]; + + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + + // set entry fee + // + int entryFee = 0; // in coins + + CoinObjective* coinObjective = dynamic_cast<CoinObjective*>( currentMission->GetStage( 0 )->GetObjective() ); + if( coinObjective != NULL ) + { + entryFee = coinObjective->GetCoinAmount(); + } + else + { + rAssertMsg( false, "No coin objective in first stage!" ); + } + + sprintf( buffer, "%d", entryFee ); + rAssert( m_gamblingEntryFee != NULL ); + m_gamblingEntryFee->SetString( 0, buffer ); + + // if not enough coins to gamble, disable 'accept button'\ + // + InitIntroWagerMission(); + + // set time to beat + // + int timeToBeat = 0; // in seconds + + RaceObjective* raceObjective = dynamic_cast<RaceObjective*>( currentMission->GetStage( 1 )->GetObjective() ); + if( raceObjective != NULL ) + { + timeToBeat = raceObjective->GetParTime(); + } + else + { + rAssertMsg( false, "No race objective in second stage!" ); + } + + sprintf( buffer, "%d:%02d", timeToBeat / 60, timeToBeat % 60 ); + rAssert( m_gamblingTimeToBeat != NULL ); + m_gamblingTimeToBeat->SetString( 0, buffer ); + + // set best time + // + RenderEnums::LevelEnum currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + int bestTime = GetCharacterSheetManager()->GetGambleRaceBestTime( currentLevel ); + if( bestTime < 0 ) + { + // if no best time set yet, just set it to the time to beat + // + bestTime = timeToBeat; + } + + sprintf( buffer, "%d:%02d", bestTime / 60, bestTime % 60 ); + rAssert( m_gamblingBestTime != NULL ); + m_gamblingBestTime->SetString( 0, buffer ); + + // set vehicle odds + // + float oddsRatio = 1.0f; + + Vehicle* currentVehicle = GetGameplayManager()->GetCurrentVehicle(); + if( currentVehicle != NULL ) + { + oddsRatio = currentVehicle->GetGamblingOdds(); + } + else + { + rAssertMsg( false, "What? How do you expect to race w/out a vehicle??" ); + } + + rAssert( m_gamblingVehicleOdds != NULL ); + if( oddsRatio >= VEHICLE_ODDS_HARD_THRESHOLD ) // hard + { + m_gamblingVehicleOdds->SetIndex( VEHICLE_ODDS_HARD ); + } + else if( oddsRatio >= VEHICLE_ODDS_MEDIUM_THRESHOLD ) // medium + { + m_gamblingVehicleOdds->SetIndex( VEHICLE_ODDS_MEDIUM ); + } + else // easy + { + m_gamblingVehicleOdds->SetIndex( VEHICLE_ODDS_EASY ); + } +/* + sprintf( buffer, "%.1f : 1", oddsRatio ); + rAssert( m_gamblingVehicleOdds != NULL ); + m_gamblingVehicleOdds->SetString( 0, buffer ); +*/ + + // set payout amount + // + int payoutAmount = entryFee + (int)( entryFee * oddsRatio ); + + sprintf( buffer, "%d", payoutAmount ); + rAssert( m_gamblingPayout != NULL ); + m_gamblingPayout->SetString( 0, buffer ); + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); +} + diff --git a/game/code/presentation/gui/ingame/guiscreenmissionbase.h b/game/code/presentation/gui/ingame/guiscreenmissionbase.h new file mode 100644 index 0000000..3ff6ec6 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionbase.h @@ -0,0 +1,132 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionSuccess +// +// Description: +// +// +// Authors: Ian Gipson +// +// Revisions Date Author Revision +// 2003/04/07 igipson Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMISSIONBASE_H +#define GUISCREENMISSIONBASE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <events/eventlistener.h> +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/ingame/guiscreenhastransitions.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class tSprite; +namespace Scrooby +{ + class BoundedDrawable; + class Drawable; +} + + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMissionBase: + public CGuiScreen, + public CGuiScreenHasTransitions +{ +public: + CGuiScreenMissionBase( Scrooby::Screen* pScreen, CGuiEntity* pParent, eGuiWindowID id ); + ~CGuiScreenMissionBase(); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual void InitIntro(); + virtual void InitRunning(); + virtual void InitOutro(); + static void ClearBitmap(); + static void GetBitmapName( char* buffer ); + static bool IsCurrentBitmap( const char* name ); + static void ReplaceBitmap(); + static void SetBitmapName( const char* name ); + +protected: + Scrooby::Group* GetAbortBitmap(); + Scrooby::Drawable* GetFlag(); + Scrooby::Group* GetLoadCompletedGroup(); + Scrooby::Text* GetMissionInfoText(); + Scrooby::BoundedDrawable* GetMissionStartBitmap(); + Scrooby::Page* GetPage(); + Scrooby::Text* GetTitleText(); + void InitIntroWagerMission(); + virtual void OutroDone(); + static void RemoveAnimatedBitmap(); + void StartIrisWipeClose(); + void StartIrisWipeOpen(); + void UpdateAnimatedBitmap( const float deltaT ); + void UnloadBitmap(); + void UpdateGamblingInfo(); + void SetPlayAnimatedCamera( bool play ); + const char* GetWatcherName() const; + +private: + Scrooby::Text* m_missionTitle; + Scrooby::Page* m_Page; + Scrooby::Page* m_LetterboxPage; + Scrooby::Sprite* m_missionStartBitmap; + Scrooby::Sprite* m_background; + Scrooby::Sprite* m_Flag; + Scrooby::Drawable* m_ClipLeftGroup; + Scrooby::Drawable* m_ClipRightGroup; + Scrooby::Drawable* m_ClipLeft; + Scrooby::Drawable* m_ClipRight; + Scrooby::Sprite* m_ClipLeftArm; + Scrooby::Sprite* m_ClipRightArm; + Scrooby::Drawable* m_Foreground; + Scrooby::Group* m_darkenPolys; + Scrooby::Group* m_loadCompleted; + Scrooby::Group* m_textOverlays; + Scrooby::Group* m_darkenTop; + Scrooby::Group* m_darkenBottom; + Scrooby::Polygon* m_backgroundPoly; + Scrooby::Layer* m_LetterboxLayer; + Scrooby::Layer* m_BgLayer; + Scrooby::Group* m_FgLayer; + Scrooby::Pure3dObject* m_Iris; + tMultiController* m_MultiController; + float m_irisWipeNumFrames; + Scrooby::Text* m_Line0; + static tSprite* s_AnimatedBitmapSprite; + static char s_AnimatedBitmapName[ 256 ]; + static char s_AnimatedBitmapShortName[ 32 ]; + static bool s_BitmapLoadPending; + static tSprite* sp_PattyAndSelmaScreenPNG; + bool m_PlayAnimatedCamera; + + enum eGamblingVehicleOdds + { + VEHICLE_ODDS_EASY, + VEHICLE_ODDS_MEDIUM, + VEHICLE_ODDS_HARD, + + NUM_VEHICLE_ODDS + }; + + Scrooby::Group* m_gamblingInfo; + Scrooby::Text* m_gamblingEntryFee; + Scrooby::Text* m_gamblingTimeToBeat; + Scrooby::Text* m_gamblingBestTime; + Scrooby::Text* m_gamblingVehicleOdds; + Scrooby::Text* m_gamblingPayout; + + bool m_ReadyToExitScreen : 1; + +}; + +#endif // GUISCREENMISSIONBASE_H diff --git a/game/code/presentation/gui/ingame/guiscreenmissionload.cpp b/game/code/presentation/gui/ingame/guiscreenmissionload.cpp new file mode 100644 index 0000000..2a6c4e2 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionload.cpp @@ -0,0 +1,511 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionLoad +// +// Description: Implementation of the CGuiScreenMissionLoad class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <camera/animatedcam.h> +#include <events/eventmanager.h> +#include <mission/gameplaymanager.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenmissionload.h> +#include <presentation/gui/ingame/guiscreenmissionselect.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/utility/specialfx.h> +#include <p3d/utility.hpp> +#include <raddebug.hpp> // Foundation +#include <radmath/matrix.hpp> +#include <radmath/util.hpp> +#include <loading/loadingmanager.h> +#include <strings/unicodestring.h> + +#include <screen.h> +#include <page.h> + +#include <p3d/unicode.hpp> +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +#ifndef PAL + // convert mission title string to all caps + // + #define MISSION_TITLE_ALL_CAPS +#endif + +#define TRANSITION_IN_TIME 250.0f + +const UnicodeChar EMPTY_MISSION_HINT = '*'; +const float startDelayTimeMs = 500.0f; +const float DARKEN_ANIMATION_DELAY_BEFORE_STARTING = startDelayTimeMs; +const float DARKEN_ANIMATION_INTRO_TIME = 1000.0f; +int g_BitmapPositionX; +int g_BitmapPositionY; +int g_BitmapSizeX; +int g_BitmapSizeY; +int g_TitlePositionX; +int g_TitlePositionY; + +int g_BitmapPositionWagerX = 0; +int g_BitmapPositionWagerY = 200; +int g_BitmapSizeWagerX = 20; +int g_BitmapSizeWagerY = 20; +int g_TitlePositionWagerX = 200; +int g_TitlePositionWagerY = 370; + +GuiSFX::Show g_LoadCompletedShow( "LoadCompletedShow" ); +GuiSFX::ColorChange g_LoadCompletedTransitionIn( "LoadCompletedTransitionIn" ); + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMissionLoad::CGuiScreenMissionLoad +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionLoad::CGuiScreenMissionLoad +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +): + CGuiScreenMissionBase( pScreen, pParent, GUI_SCREEN_ID_MISSION_LOAD ), + m_LoadIsDone( true ), + m_loadingText( NULL ), + m_elapsedIdleTime( 0 ) +{ + ExtractNormalPositions(); + Scrooby::Group* loadCompleted = GetLoadCompletedGroup(); + g_LoadCompletedShow.SetDrawable( loadCompleted ); + + g_LoadCompletedTransitionIn.SetDrawable( loadCompleted ); + g_LoadCompletedTransitionIn.SetStartColour( tColour( 255, 255, 255, 0 ) ); + g_LoadCompletedTransitionIn.SetEndColour ( tColour( 255, 255, 255, 255 ) ); + g_LoadCompletedTransitionIn.SetTimeInterval( TRANSITION_IN_TIME ); + g_LoadCompletedTransitionIn.Deactivate(); + WATCH( g_LoadCompletedTransitionIn, GetWatcherName() ); + + g_LoadCompletedShow. SetNextTransition( g_LoadCompletedTransitionIn ); + g_LoadCompletedTransitionIn.SetNextTransition( NULL ); + + AddTransition( g_LoadCompletedTransitionIn ); + + AddListeners(); + + // get loading text + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LoadingText" ); + if( pPage != NULL ) + { + m_loadingText = pPage->GetText( "Loading" ); + rAssert( m_loadingText != NULL ); + m_loadingText->SetVisible( false ); // hide by default + } +} + + +//=========================================================================== +// CGuiScreenMissionLoad::~CGuiScreenMissionLoad +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionLoad::~CGuiScreenMissionLoad() +{ + RemoveListeners(); + p3d::pddi->DrawSync(); +} + +//=========================================================================== +// CGuiScreenMissionLoad::AddListeners +//=========================================================================== +// Description: Adds all the listeners this class is ever going to need +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::AddListeners() +{ + GetEventManager()->AddListener( this, EVENT_GUI_MISSION_LOAD_COMPLETE ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::ExtractNormalPositions +//=========================================================================== +// Description: the default positions of the objects are taken out of scrooby +// this function actually goes and gets them +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::ExtractNormalPositions() +{ + // extract the position of the mission loading bitmap + Scrooby::Drawable* missionStartBitmap = GetMissionStartBitmap(); + missionStartBitmap->GetOriginPosition( g_BitmapPositionX, g_BitmapPositionY ); + missionStartBitmap->GetBoundingBoxSize( g_BitmapSizeX, g_BitmapSizeY ); + + // extract the position of the title + Scrooby::Text* text = GetTitleText(); + text->GetOriginPosition( g_TitlePositionX, g_TitlePositionY ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::HandleEvent +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void +CGuiScreenMissionLoad::HandleEvent( EventEnum id, void* pEventData ) +{ + if( id == EVENT_GUI_MISSION_LOAD_COMPLETE ) + { + // mission load completed, show "Press Start" message + // + m_LoadIsDone = true; + g_LoadCompletedShow.Activate(); + + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + if( currentMission->IsWagerMission() ) + { + this->UpdateGamblingInfo(); + } + + // hide loading text + // + if( m_loadingText != NULL ) + { + m_loadingText->SetVisible( false ); + } + } +} + +//=========================================================================== +// CGuiScreenMissionSuccess::HandleMessage +//=========================================================================== +// Description: Handles messages, and passes them up the hierarchy when done +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + m_elapsedIdleTime += param1; + + if( m_loadingText != NULL && !m_LoadIsDone ) + { + // blink loading text if idling here on this screen to satisfy + // TRC/TCR requirements + // + const unsigned int BLINKING_PERIOD = 250; + bool isBlinked = GuiSFX::Blink( m_loadingText, + static_cast<float>( m_elapsedIdleTime ), + static_cast<float>( BLINKING_PERIOD ) ); + if( isBlinked ) + { + m_elapsedIdleTime %= BLINKING_PERIOD; + } + } + + break; + } + case GUI_MSG_CONTROLLER_SELECT: + { + if( m_LoadIsDone && this->IsButtonVisible( BUTTON_ICON_ACCEPT ) ) + { + SetPlayAnimatedCamera( true ); + + // resume game and start mission + // + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); + + // trigger this event ONLY for wager race missions + // + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + if( currentMission->IsWagerMission() ) + { + GetEventManager()->TriggerEvent( EVENT_ATTEMPT_TO_ENTER_GAMBLERACE ); + } + + GetEventManager()->TriggerEvent( EVENT_FE_CONTINUE ); + GetEventManager()->TriggerEvent( EVENT_MISSION_BRIEFING_ACCEPTED ); + } + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + if( m_LoadIsDone && this->IsButtonVisible( BUTTON_ICON_BACK ) ) + { + // resume game and abort mission + // + SetPlayAnimatedCamera( false ); + AnimatedCam::SetCamera( "" ); + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME, ON_HUD_ENTER_ABORT_MISSION ); + + GetEventManager()->TriggerEvent(EVENT_USER_CANCEL_MISSION_BRIEFING); + GetEventManager()->TriggerEvent( EVENT_FE_CANCEL ); + } + break; + } + default: + { + break; + } + } + } + CGuiScreenMissionBase::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::InitializePermanentVariables +//=========================================================================== +// Description: Stuff that goes into permanent memory gets initialized in +// here +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::InitializePermanentVariables() +{ + p3d::inventory->AddSection( "DynamicHud" ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::InitIntro() +{ + CGuiScreenMissionBase::InitIntro(); + + Scrooby::Text* missionTitle = GetTitleText(); + rAssert( missionTitle != NULL ); + +#ifdef MISSION_TITLE_ALL_CAPS + // convert mission title to all caps + // + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + UnicodeString unicodeString; + unicodeString.ReadUnicode( missionTitle->GetStringBuffer() ); + p3d::UnicodeStrUpr( unicodeString.GetBuffer() ); + + missionTitle->SetString( missionTitle->GetIndex(), unicodeString ); + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); +#endif // MISSION_TITLE_ALL_CAPS + + // + // Turn on the titles + // + missionTitle->SetVisible( true ); + GetMissionInfoText()->SetVisible( true ); + + Scrooby::Group* loadCompleted = GetLoadCompletedGroup(); + loadCompleted->SetVisible( false ); + m_LoadIsDone = false; + + if( m_loadingText != NULL ) + { + // hide loading text + // + m_loadingText->SetVisible( false ); + + this->SetAlphaForLayers( 1.0f, m_foregroundLayers, m_numForegroundLayers ); + } + + m_elapsedIdleTime = 0; + + // + // is this a normal mission or a wager mission + // + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + if( currentMission->IsWagerMission() ) + { + InitPositionsWager(); + } + else + { + InitPositionsNormal(); + } + + // only show "cancel" button for wager missions + // + this->SetButtonVisible( BUTTON_ICON_BACK, currentMission->IsWagerMission() ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::InitOutro() +{ + CGuiScreenMissionBase::InitOutro(); + rWarning( m_LoadIsDone ); + m_LoadIsDone = false; + + if( m_loadingText != NULL ) + { + // hide loading text + // + m_loadingText->SetVisible( false ); + } +} + +//=========================================================================== +// CGuiScreenMissionLoad::InitPositionsNormal +//=========================================================================== +// Description: Move scroobyelements to where they need to be for normal +// missions +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::InitPositionsNormal() +{ + Scrooby::BoundedDrawable* missionStart = GetMissionStartBitmap(); + missionStart->SetPosition ( g_BitmapPositionX, g_BitmapPositionY ); + missionStart->SetBoundingBoxSize( g_BitmapSizeX, g_BitmapSizeY ); + + Scrooby::Text* title = GetTitleText(); +#ifndef RAD_WIN32 // temp fix. + title->SetPosition( g_TitlePositionX, g_TitlePositionY ); +#endif + + Scrooby::Text* info = GetMissionInfoText(); + info->SetHorizontalJustification( Scrooby::Center ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::InitPositionsWager +//=========================================================================== +// Description: Move scrooby elements to where they need to be for wager +// missions +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::InitPositionsWager() +{ + Scrooby::BoundedDrawable* missionStart = GetMissionStartBitmap(); + missionStart->SetPosition( g_BitmapPositionWagerX, g_BitmapPositionWagerY ); + missionStart->SetBoundingBoxSize( g_BitmapSizeWagerX, g_BitmapSizeWagerY ); + + Scrooby::Text* title = GetTitleText(); + title->SetPosition( g_TitlePositionWagerX, g_TitlePositionWagerY ); + + // turn on the flag bitmap + Scrooby::Drawable* flag = GetFlag(); + flag->SetVisible( true ); + + Scrooby::Text* info = GetMissionInfoText(); + info->SetHorizontalJustification( Scrooby::Left ); +} + +//=========================================================================== +// CGuiScreenMissionLoad::RemoveListeners +//=========================================================================== +// Description: removes all the listeners that have been set up in this class +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionLoad::RemoveListeners() +{ +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenmissionload.h b/game/code/presentation/gui/ingame/guiscreenmissionload.h new file mode 100644 index 0000000..8193b3c --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionload.h @@ -0,0 +1,73 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionLoad +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMISSIONLOAD_H +#define GUISCREENMISSIONLOAD_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenmissionbase.h> +#include <presentation/gui/utility/transitions.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu; +class tSprite; +namespace Scrooby +{ + class Group; +} + +const int MAX_NUM_BULLETS = 2; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMissionLoad : + public CGuiScreenMissionBase, + public EventListener +{ +public: + CGuiScreenMissionLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMissionLoad(); + + // Implements EventListener + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual void HandleEvent( EventEnum id, void* pEventData ); + static void InitializePermanentVariables(); + virtual void InitIntro(); + virtual void InitOutro(); + +protected: + virtual void AddListeners(); + void ExtractNormalPositions(); + void InitPositionsNormal(); + void InitPositionsWager(); + virtual void RemoveListeners(); + +private: + bool m_LoadIsDone : 1; //the mission load is done + + Scrooby::Text* m_loadingText; + unsigned int m_elapsedIdleTime; + +}; + +#endif // GUISCREENMISSIONLOAD_H diff --git a/game/code/presentation/gui/ingame/guiscreenmissionover.cpp b/game/code/presentation/gui/ingame/guiscreenmissionover.cpp new file mode 100644 index 0000000..64ad4f4 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionover.cpp @@ -0,0 +1,450 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionOver +// +// Description: Implementation of the CGuiScreenMissionOver class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenmissionover.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> + +#include <events/eventmanager.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/mission.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <sound/soundmanager.h> + +#include <p3d/unicode.hpp> +#include <raddebug.hpp> // Foundation +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +#include <stdlib.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const int NUM_ATTEMPTS_REQUIRED_FOR_SKIPPING = 7; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMissionOver::CGuiScreenMissionOver +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionOver::CGuiScreenMissionOver +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MISSION_OVER ), + m_pMenu( NULL ), + m_failureReason( NULL ), + m_failureHint( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenMissionOver" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "MissionOver" ); + rAssert( pPage ); + + Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" ); + rAssert( foreground != NULL ); + + // get 'mission failed' text bible string + // + P3D_UNICODE* text = GetTextBibleString( "MISSION_FAILED" ); + rAssert( text != NULL ); + int textLength = p3d::UnicodeStrLen( text ) + 1; + + Scrooby::Sprite* missionFailedText = foreground->GetSprite( "MissionFailed" ); + if( missionFailedText != NULL ) + { + missionFailedText->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + missionFailedText->CreateBitmapTextBuffer( textLength ); + missionFailedText->SetBitmapText( text ); + missionFailedText->SetBitmapTextLineSpacing( 10 ); +#ifdef RAD_WIN32 + missionFailedText->ResetTransformation(); + missionFailedText->ScaleAboutCenter( 0.5f ); +#endif + } + + m_failureReason = foreground->GetText( "MissionFailureReason" ); + rAssert( m_failureReason != NULL ); + m_failureReason->SetTextMode( Scrooby::TEXT_WRAP ); + + m_failureHint = foreground->GetText( "MissionFailureHint" ); + rAssert( m_failureHint != NULL ); + m_failureHint->SetTextMode( Scrooby::TEXT_WRAP ); + + // Create a menu. + // + m_pMenu = new CGuiMenuPrompt( this, pPage, 3 ); + rAssert( m_pMenu != NULL ); + + // register events to listen for + // + GetEventManager()->AddListener( this, EVENT_MISSION_FAILURE ); + +MEMTRACK_POP_GROUP("CGUIScreenMissionOver"); +} + + +//=========================================================================== +// CGuiScreenMissionOver::~CGuiScreenMissionOver +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionOver::~CGuiScreenMissionOver() +{ + // unregister events + // + GetEventManager()->RemoveListener( this, EVENT_MISSION_FAILURE ); + + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenMissionOver::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionOver::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + if( param1 == 0 ) // 'yes' response + { + // restart mission + // + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME, + ON_HUD_ENTER_RESTART_MISSION ); + } + else if( param1 == 1 ) // 'no' response + { + // abort mission + // + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME, + ON_HUD_ENTER_ABORT_MISSION ); + } + else if( param1 == 2 ) // 'skip' response + { + // skip to next mission + // + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME, + ON_HUD_ENTER_SKIP_MISSION ); +/* + CurrentMissionStruct currentMission = GetCharacterSheetManager()->QueryCurrentMission(); + + unsigned int nextLevel = currentMission.mLevel; + unsigned int nextMission = currentMission.mMissionNumber + 1; + + if( currentMission.mMissionNumber == RenderEnums::M7 ) // last mission + { + // go to next level's first mission + // + nextLevel++; + nextMission = RenderEnums::M1; + + rAssert( nextLevel < RenderEnums::numLevels ); + } +*/ + } + else + { + rAssertMsg( 0, "WARNING: *** Unexpected response!\n" ); + } + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenMissionOver::HandleEvent( EventEnum id, void* pEventData ) +{ + switch( id ) + { + case EVENT_MISSION_FAILURE: + { + MissionCondition* failureCondition = reinterpret_cast<MissionCondition*>( pEventData ); + rAssert( failureCondition != NULL ); + + this->SetFailureMessage( failureCondition->GetType() ); + + break; + } + default: + { + rWarningMsg( false, "Unhandled event ID!" ); + + break; + } + } +} + + +//=========================================================================== +// CGuiScreenMissionOver::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionOver::InitIntro() +{ + rAssert( m_pMenu != NULL ); + + // reset menu to "Yes" selection + // + m_pMenu->Reset(); + + // show/hide 'skip' menu response + // + CurrentMissionStruct currentMission = GetCharacterSheetManager()->QueryCurrentMission(); + int numAttemps = GetCharacterSheetManager()->QueryNumberOfAttempts( currentMission.mLevel, currentMission.mMissionNumber ); + bool isSkipAllowed = (numAttemps >= NUM_ATTEMPTS_REQUIRED_FOR_SKIPPING); + + if( currentMission.mLevel == RenderEnums::L7 && static_cast<int>( currentMission.mMissionNumber ) >= RenderEnums::M5 ) + { + // can't skip the last mission of the game + // + isSkipAllowed = false; + } + +#ifdef RAD_E3 + // no skipping mission allowed on E3 build + // + isSkipAllowed = false; +#endif + + m_pMenu->SetMenuItemEnabled( 2, isSkipAllowed, true ); + + GetSoundManager()->OnStoreScreenStart( false ); +} + + +//=========================================================================== +// CGuiScreenMissionOver::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionOver::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenMissionOver::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionOver::InitOutro() +{ + GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP ); + GetSoundManager()->OnStoreScreenEnd(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMissionOver::SetFailureMessage( MissionCondition::ConditionTypeEnum conditionType ) +{ + int failureMessageIndex = 0; + + switch( conditionType ) + { + case MissionCondition::COND_VEHICLE_DAMAGE: + { + failureMessageIndex = 1; + + break; + } + case MissionCondition::COND_PLAYER_HIT: + { + failureMessageIndex = 2; + + break; + } + case MissionCondition::COND_TIME_OUT: + { + failureMessageIndex = 3; + + break; + } + case MissionCondition::COND_PLAYER_OUT_OF_VEHICLE: + { + failureMessageIndex = 4; + + break; + } + case MissionCondition::COND_FOLLOW_DISTANCE: + { + failureMessageIndex = 5; + + break; + } + case MissionCondition::COND_OUT_OF_BOUNDS: + { + failureMessageIndex = 6; + + break; + } + case MissionCondition::COND_RACE: + { + failureMessageIndex = 7; + + break; + } + case MissionCondition::COND_NOT_ABDUCTED: + { + failureMessageIndex = 8; + + break; + } + case MissionCondition::COND_POSITION: + { + failureMessageIndex = 9; + + break; + } + case MissionCondition::COND_HIT_AND_RUN_CAUGHT: + { + failureMessageIndex = 10; + + break; + } + case MissionCondition::COND_GET_COLLECTIBLES: + { + failureMessageIndex = 11; + + break; + } + default: + { + rAssertMsg( false, "Unknown failure reason!" ); + + break; + } + } + + rAssert( m_failureReason != NULL ); + m_failureReason->SetIndex( failureMessageIndex ); + + // set associated mission failure hint (randomly chosen) + // + int hintMessageIndex = 0; + + if( failureMessageIndex > 0 ) + { + rAssert( GetGameplayManager()->GetCurrentMission() != NULL ); + + int numValidFailureHints = GetGameplayManager()->GetCurrentMission()->GetNumValidFailureHints(); + if( numValidFailureHints < 0 ) + { + numValidFailureHints = MAX_NUM_HINTS_PER_FAILURE; + } + + int randomHintIndex = rand() % numValidFailureHints; + + hintMessageIndex = (failureMessageIndex - 1) * MAX_NUM_HINTS_PER_FAILURE + 1 + randomHintIndex; + } + + rAssert( m_failureHint != NULL ); + m_failureHint->SetIndex( hintMessageIndex ); +} + diff --git a/game/code/presentation/gui/ingame/guiscreenmissionover.h b/game/code/presentation/gui/ingame/guiscreenmissionover.h new file mode 100644 index 0000000..82a9ce6 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionover.h @@ -0,0 +1,72 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionOver +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMISSIONOVER_H +#define GUISCREENMISSIONOVER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +#include <events/eventlistener.h> +#include <mission/conditions/missioncondition.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +namespace Scrooby +{ + class Screen; + class Text; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMissionOver : public CGuiScreen, + public EventListener +{ +public: + CGuiScreenMissionOver( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMissionOver(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual void HandleEvent( EventEnum id, void* pEventData ); + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + static const int MAX_NUM_HINTS_PER_FAILURE = 8; + + void SetFailureMessage( MissionCondition::ConditionTypeEnum conditionType ); + + CGuiMenu* m_pMenu; + + Scrooby::Text* m_failureReason; + Scrooby::Text* m_failureHint; + +}; + +#endif // GUISCREENMISSIONOVER_H diff --git a/game/code/presentation/gui/ingame/guiscreenmissionselect.cpp b/game/code/presentation/gui/ingame/guiscreenmissionselect.cpp new file mode 100644 index 0000000..b043188 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionselect.cpp @@ -0,0 +1,493 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionSelect +// +// Description: Implementation of the CGuiScreenMissionSelect class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenmissionselect.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiuserinputhandler.h> + +#include <cheats/cheatinputsystem.h> +#include <events/eventmanager.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/charactersheet/charactersheet.h> +#include <render/enums/renderenums.h> + +#include <raddebug.hpp> // Foundation +#include <page.h> +#include <polygon.h> +#include <screen.h> +#include <sprite.h> +#include <string.h> + + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#ifdef RAD_WIN32 +const float LEVEL_BAR_CORRECTION_SCALE = 1.0f; +#else +const float LEVEL_BAR_CORRECTION_SCALE = 2.0f; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMissionSelect::CGuiScreenMissionSelect +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionSelect::CGuiScreenMissionSelect +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MISSION_SELECT ), + m_pMenuLevel( NULL ), + m_pMenu( NULL ), + m_numLevelSelections( 0 ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenMissionSelect" ); + HeapMgr()->PushHeap (GMA_LEVEL_HUD); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MissionSelect" ); + rAssert( pPage ); + + Scrooby::Group* levelBar = pPage->GetGroup( "Level" ); + rAssert( levelBar != NULL ); + +#ifdef RAD_WIN32 + m_leftArrow = levelBar->GetSprite( "LArrowBgd" ); + rAssert( m_leftArrow != NULL ); + m_leftArrow->ScaleAboutCenter( 1.7f ); + m_leftArrow->Translate( -5, 3 ); + + m_rightArrow = levelBar->GetSprite( "RArrowBgd" ); + rAssert( m_rightArrow != NULL ); + m_rightArrow->ScaleAboutCenter( 1.7f ); + m_rightArrow->Translate( -6, 3 ); +#endif + + Scrooby::Sprite* levelBarBgd = levelBar->GetSprite( "LevelBar" ); + if( levelBarBgd != NULL ) + { + levelBarBgd->ResetTransformation(); + levelBarBgd->ScaleAboutCenter( LEVEL_BAR_CORRECTION_SCALE ); + } + + // Create menu for level selection. + // + m_pMenuLevel = new CGuiMenu( this, 1, GUI_TEXT_MENU, MENU_SFX_NONE ); + rAssert( m_pMenuLevel != NULL ); + m_pMenuLevel->SetHighlightColour( false, tColour( 0, 0, 0 ) ); + + m_pMenuLevel->AddMenuItem( levelBar->GetText( "Level" ), + levelBar->GetText( "Level" ), + NULL, + NULL, + levelBar->GetSprite( "LArrowBgd" ), + levelBar->GetSprite( "RArrowBgd" ), + SELECTION_ENABLED | VALUES_WRAPPED ); + + // Create a menu. + // + m_pMenu = new CGuiMenu( this, MAX_NUM_REGULAR_MISSIONS, GUI_TEXT_MENU, MENU_SFX_NONE ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + Scrooby::Group* missions = pPage->GetGroup( "Missions" ); + Scrooby::Group* missionMenu = pPage->GetGroup( "Menu" ); + Scrooby::Group* status = pPage->GetGroup( "Status" ); + Scrooby::Group* initials = pPage->GetGroup( "Initials" ); + Scrooby::Group* times = pPage->GetGroup( "Times" ); + rAssert( missions != NULL ); + rAssert( missionMenu != NULL ); + rAssert( status != NULL ); + + for( int i = 0; i < MAX_NUM_REGULAR_MISSIONS; i++ ) + { + char name[ 32 ]; + + // mission number and titles + // + sprintf( name, "MissionNum%d", i ); + m_missionInfo[ i ].m_number = missions->GetText( name ); + + sprintf( name, "Mission%d", i ); + Scrooby::Text* pText = missionMenu->GetText( name ); + if( pText != NULL ) + { + m_pMenu->AddMenuItem( pText ); + } + + m_missionInfo[ i ].m_title = pText; + + // mission status + // + sprintf( name, "MissionStatus%d", i ); + m_missionInfo[ i ].m_status = status->GetSprite( name ); + } + + Scrooby::Group* highlightBar = pPage->GetGroup( "HighlightBar" ); + if( highlightBar != NULL ) + { + m_pMenu->SetCursor( highlightBar ); + +#ifdef PAL + highlightBar->ResetTransformation(); + highlightBar->ScaleAboutCenter( 1.035f, 1.0f, 1.0f ); +#endif // PAL + } + + this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) ); + + HeapMgr()->PopHeap (GMA_LEVEL_HUD); +MEMTRACK_POP_GROUP("CGUIScreenMissionSelect"); +} + + +//=========================================================================== +// CGuiScreenMissionSelect::~CGuiScreenMissionSelect +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionSelect::~CGuiScreenMissionSelect() +{ + if( m_pMenuLevel != NULL ) + { + delete m_pMenuLevel; + m_pMenuLevel = NULL; + } + + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenMissionSelect::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionSelect::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + if( !m_pMenu->HasSelectionBeenMade() ) + { + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + } + + break; + } + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + rAssert( param1 == 0 ); + + this->OnLevelSelectionChange( static_cast<int>( param2 ) ); + + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( m_pMenuLevel != NULL ); + int currentLevel = m_pMenuLevel->GetSelectionValue( 0 ); + + // special case for level 1: all missions are offset by 1 + // due to the tutorial mission treated as mission 0 + // + unsigned int selectedMission = currentLevel == 0 ? param1 + 1 : param1; + + m_pParent->HandleMessage( GUI_MSG_QUIT_INGAME_FOR_RELOAD, + currentLevel, + selectedMission ); + + // stop any dialog that may still be in progress + // + GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP ); + + break; + } + default: + { + break; + } + } + +#ifdef RAD_DEMO + // can't change level in demo builds; only missions in current level + // are selectable + // + if( message == GUI_MSG_CONTROLLER_LEFT || message == GUI_MSG_CONTROLLER_RIGHT ) + { + // ignore left/right controller inputs + // + return; + } +#endif + + // relay message to level menu + // + if( m_pMenuLevel != NULL ) + { + m_pMenuLevel->HandleMessage( message, param1, param2 ); + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiScreenMissionSelect::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreenMissionSelect::CheckCursorAgainstHotspots( float x, float y ) +{ + eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y ); + if( hotSpotType == HOTSPOT_NONE ) + { + if( m_leftArrow ) + { + if( m_leftArrow->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWLEFT; + } + } + if( m_rightArrow ) + { + if( m_rightArrow->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWRIGHT; + } + } + + } + return hotSpotType; +} +#endif + +//=========================================================================== +// CGuiScreenMissionSelect::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionSelect::InitIntro() +{ + m_numLevelSelections = GetCharacterSheetManager()->QueryHighestMission().mLevel + 1; + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) ) + { + m_numLevelSelections = RenderEnums::numLevels; + } + + rAssert( m_pMenuLevel != NULL ); + m_pMenuLevel->SetSelectionValueCount( 0, m_numLevelSelections ); + + int currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + m_pMenuLevel->SetSelectionValue( 0, currentLevel ); + this->OnLevelSelectionChange( currentLevel ); +} + + +//=========================================================================== +// CGuiScreenMissionSelect::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionSelect::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenMissionSelect::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionSelect::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMissionSelect::OnLevelSelectionChange( int currentLevel ) +{ + rAssert( m_pMenu != NULL ); + m_pMenu->Reset(); + + // update mission info for new level + // + for( int i = 0; i < MAX_NUM_REGULAR_MISSIONS; i++ ) + { + // mission title + // + Scrooby::Text* missionTitle = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( missionTitle != NULL ); + missionTitle->SetIndex( currentLevel ); + + // mission info (status, best time, initials) + // + MissionRecord* missionRecord = GetCharacterSheetManager()->QueryMissionStatus( static_cast<RenderEnums::LevelEnum>( currentLevel ), + currentLevel == 0 ? i + 1 : i ); + rAssert( missionRecord != NULL ); + + bool isMissionUnlocked = true; + if( currentLevel == (m_numLevelSelections - 1) ) + { + int highestMissionPlayed = GetCharacterSheetManager()->QueryHighestMission().mMissionNumber; + if( currentLevel == 0 ) + { + highestMissionPlayed--; + } + + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) ) + { + highestMissionPlayed = RenderEnums::M7; + } + +#ifdef RAD_DEMO + highestMissionPlayed = (currentLevel == RenderEnums::L7) ? RenderEnums::M4 : RenderEnums::M7; +#endif // RAD_DEMO + + isMissionUnlocked = ( i <= highestMissionPlayed ); + } + + if( isMissionUnlocked ) + { + this->UpdateMissionStatus( i, missionRecord ); + } + + // show unlocked missions only + // + m_pMenu->SetMenuItemEnabled( i, isMissionUnlocked ); + + m_missionInfo[ i ].m_number->SetVisible( isMissionUnlocked ); + m_missionInfo[ i ].m_title->SetVisible( isMissionUnlocked ); + m_missionInfo[ i ].m_status->SetVisible( isMissionUnlocked ); + } +} + +void +CGuiScreenMissionSelect::UpdateMissionStatus( int index, + MissionRecord* missionRecord ) +{ + rAssert( missionRecord != NULL ); + rAssert( m_missionInfo[ index ].m_status ); + + if( missionRecord->mCompleted ) + { + m_missionInfo[ index ].m_status->SetIndex( 2 ); // 2 = green check + } + else + { + if( missionRecord->mNumAttempts > 0 && + !missionRecord->mSkippedMission ) + { + m_missionInfo[ index ].m_status->SetIndex( 1 ); // 1 = red cross + } + else + { + m_missionInfo[ index ].m_status->SetIndex( 0 ); // 0 = yellow dash + } + } +} + diff --git a/game/code/presentation/gui/ingame/guiscreenmissionselect.h b/game/code/presentation/gui/ingame/guiscreenmissionselect.h new file mode 100644 index 0000000..9db8041 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionselect.h @@ -0,0 +1,83 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionSelect +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/09/20 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMISSIONSELECT_H +#define GUISCREENMISSIONSELECT_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/utility/numerictext.h> + +const int MAX_NUM_REGULAR_MISSIONS = 7; +const int MAX_NUM_MISSIONS_PER_LEVEL = MAX_NUM_REGULAR_MISSIONS + 4 + 1; // +4 street races, +1 bonus + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; +struct MissionRecord; + +struct MissionDisplayInfo +{ + static const unsigned int MAX_NUM_INITIALS = 3; + + Scrooby::Text* m_number; + Scrooby::Text* m_title; + Scrooby::Sprite* m_status; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMissionSelect : public CGuiScreen +{ +public: + CGuiScreenMissionSelect( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMissionSelect(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } +#ifdef RAD_WIN32 + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); +#endif + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void OnLevelSelectionChange( int currentLevel ); + void UpdateMissionStatus( int index, MissionRecord* missionRecord ); + + CGuiMenu* m_pMenuLevel; + CGuiMenu* m_pMenu; + int m_numLevelSelections; + +#ifdef RAD_WIN32 + Scrooby::Sprite* m_leftArrow; + Scrooby::Sprite* m_rightArrow; +#endif + + MissionDisplayInfo m_missionInfo[ MAX_NUM_REGULAR_MISSIONS ]; + +}; + +#endif // GUISCREENMISSIONSELECT_H diff --git a/game/code/presentation/gui/ingame/guiscreenmissionsuccess.cpp b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.cpp new file mode 100644 index 0000000..a7879ee --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.cpp @@ -0,0 +1,211 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionLoad +// +// Description: Implementation of the CGuiScreenMissionSuccess class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/04/07 ian gipson Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <mission/charactersheet/charactersheet.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/gameplaymanager.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenmissionsuccess.h> +#include <group.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMissionSuccess::CGuiScreenMissionSuccess +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMissionSuccess::CGuiScreenMissionSuccess +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +): + CGuiScreenMissionBase( pScreen, pParent, GUI_SCREEN_ID_MISSION_SUCCESS ) +{ + Scrooby::Page* page = pScreen->GetPage( "MissionLoad" ); rAssert( page != NULL ); + m_PattyAndSelmaTitle = page->GetText( "PattyAndSelmaTitle" ); rAssert( m_PattyAndSelmaTitle != NULL ); + m_PattyAndSelmaTitle->SetTextMode( Scrooby::TEXT_WRAP ); + m_PattyAndSelmaInfo = page->GetText( "PattyAndSelmaInfo" ); rAssert( m_PattyAndSelmaInfo != NULL ); + m_PattyAndSelmaInfo->SetTextMode( Scrooby::TEXT_WRAP ); + m_PattyAndSelmaTitle->SetVisible( false ); + m_PattyAndSelmaInfo->SetVisible( false ); +} + +//=========================================================================== +// CGuiScreenMissionSuccess::HandleMessage +//=========================================================================== +// Description: Handles messages, and passes them up the hierarchy when done +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionSuccess::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + // resume game and start mission + // + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + // resume game and abort mission + // + //m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME, ON_HUD_ENTER_ABORT_MISSION ); + break; + } + default: + { + break; + } + } + } + CGuiScreenMissionBase::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenMissionSuccess::InitIntro +//=========================================================================== +// Description: sets up the screen when you enter it +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionSuccess::InitIntro() +{ + // + // Check the level - level 7 rerquires the zombie picture + // + int level = GetGameplayManager()->GetCurrentLevelIndex(); + if( level == 6 ) + { + SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" ); + } + else + { + SetBitmapName( "art/frontend/dynaload/images/misXX_PS.p3d" ); + } + ReplaceBitmap(); + + // + // Call the parent's initIntro function + // + CGuiScreenMissionBase::InitIntro(); + + // + // Hide the "cancel bitmap" + // + Scrooby::Group* abortBitmap = GetAbortBitmap(); + abortBitmap->SetVisible( false ); + + // + // Show the correct titles + // + m_PattyAndSelmaTitle->SetVisible( true ); + m_PattyAndSelmaInfo->SetVisible( true ); + + // + // Figure out how many races have been completed, and display it + // + CurrentMissionStruct mission = GetCharacterSheetManager()->QueryCurrentMission(); + int racesComplete = GetCharacterSheetManager()->QueryNumStreetRacesCompleted( mission.mLevel ); + char outputString[ 256 ] = ""; + if( racesComplete < 3 ) + { + m_PattyAndSelmaTitle->SetIndex( 0 ); + m_PattyAndSelmaInfo->SetIndex( 0 ); + UnicodeString title = m_PattyAndSelmaTitle->GetString(); + char numberString[ 256 ] = ""; + sprintf( numberString, "%d", racesComplete ); + title.Replace( "%d", numberString ); + title.Replace( "%d", "3" ); + m_PattyAndSelmaTitle->SetString( 2, title ); + m_PattyAndSelmaTitle->SetIndex( 2 ); + + // + // Check if the info just says "*" if so, then hide it + // + UnicodeChar* uc = m_PattyAndSelmaInfo->GetStringBuffer(); + if( uc[ 0 ] == '*' ) + { + m_PattyAndSelmaInfo->SetVisible( false ); + } + else + { + m_PattyAndSelmaInfo->SetVisible( true ); + } + } + else + { + int level = GetGameplayManager()->GetCurrentLevelIndex(); + m_PattyAndSelmaTitle->SetIndex( 1 ); + m_PattyAndSelmaInfo->SetIndex( 1 + level ); + } +} + +//=========================================================================== +// CGuiScreenMissionSuccess::OutroDone +//=========================================================================== +// Description: sets up the screen when you enter it +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMissionSuccess::OutroDone() +{ + m_PattyAndSelmaTitle->SetVisible( false ); + m_PattyAndSelmaInfo->SetVisible( false ); +} diff --git a/game/code/presentation/gui/ingame/guiscreenmissionsuccess.h b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.h new file mode 100644 index 0000000..fd79194 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.h @@ -0,0 +1,47 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMissionSuccess +// +// Description: +// +// +// Authors: Ian Gipson +// +// Revisions Date Author Revision +// 2003/04/07 igipson Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMISSIONSUCCESS_H +#define GUISCREENMISSIONSUCCESS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenmissionload.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMissionSuccess : + public CGuiScreenMissionBase +{ +public: + CGuiScreenMissionSuccess( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual void InitIntro(); +protected: + virtual void OutroDone(); +private: + Scrooby::Text* m_PattyAndSelmaTitle; + Scrooby::Text* m_PattyAndSelmaInfo; +}; + +#endif // GUISCREENMISSIONSUCCESS_H diff --git a/game/code/presentation/gui/ingame/guiscreenmultihud.cpp b/game/code/presentation/gui/ingame/guiscreenmultihud.cpp new file mode 100644 index 0000000..3f76788 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmultihud.cpp @@ -0,0 +1,825 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMultiHud +// +// Description: Implementation of the CGuiScreenMultiHud class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/tutorialmanager.h> +#include <presentation/gui/ingame/guiscreenmultihud.h> +#include <presentation/gui/utility/hudmap.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/utility/transitions.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/presentation.h> +#include <contexts/gameplay/gameplaycontext.h> +#include <input/inputmanager.h> +#include <gameflow/gameflow.h> +#include <main/commandlineoptions.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <worldsim/avatarmanager.h> +#include <worldsim/character/character.h> +#include <worldsim/character/charactertarget.h> +#include <worldsim/redbrick/vehicle.h> + +#include <raddebug.hpp> // Foundation + +#include <group.h> +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <polygon.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#define SRR2_SHOW_SPEEDOMETER +#define WHITE_WASH_IN_TIME 1000.0f + +const float ENTER_INGAME_FADE_IN_TIME = 500.0f; // in milliseconds +const float transitionIn = 250.0f; +const float minDisplayTime = 3000.0f; +const float maxDisplayTime = 50000.0f; +const float transitionOut = transitionIn; +Scrooby::Polygon* g_WhiteWash = NULL; +GuiSFX::Show g_WhiteWashShow( "WhiteWashShow" ); +GuiSFX::ColorChange g_WhiteWashIn( "WhiteWashIn" ); +GuiSFX::Pause g_WhiteWashPause( "WhiteWashPause" ); +GuiSFX::Hide g_WhiteWashHide( "WhiteWashHide" ); +GuiSFX::ResumeGame g_WhiteWashResumeGame( "WhiteWashResumeGame" ); +GuiSFX::PulseScale g_TutorialPulse( "TutorialPulse" ); +float g_TimeSinceLastDeathVolume = 0.0f; +Vehicle* g_Vehicle = NULL; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +class ResetCar : public GuiSFX::SendEvent +{ +public: + ResetCar(); + void Activate(); + void SetVehicle( Vehicle* vehicle ); + +protected: + Vehicle* m_Vehicle; +}; +ResetCar g_ResetCar; + +//=========================================================================== +// CGuiScreenMultiHud::CGuiScreenMultiHud +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMultiHud::CGuiScreenMultiHud +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID id, + int numActivePlayers +) +: + CGuiScreen( pScreen, pParent, id ), + m_numActivePlayers( numActivePlayers ), + m_tutorialWalkie( NULL ), + m_tutorialMessage( NULL ), + m_isStartButtonPressed( false ), + m_TutorialBitmapTimeShown( 0.0f ) +{ + for( unsigned int i = 0; i < sizeof( m_hudMap ) / + sizeof( m_hudMap[ 0 ] ); i++ ) + { + m_hudMap[ i ] = NULL; + } + + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "Hud" ); + rAssert( pPage ); + + m_LetterboxPage = m_pScroobyScreen->GetPage( "LetterBox" ); + m_LetterboxPage->SetVisible( false ); + rAssert( m_LetterboxPage != NULL ); + + m_tutorialWalkie = pPage->GetGroup( "walkietalkie" ); + rAssert( m_tutorialWalkie != NULL ); + m_tutorialWalkie->SetVisible( false ); + + Scrooby::Sprite* bartImage = m_tutorialWalkie->GetSprite( "walkietalkie" ); + if( bartImage != NULL ) + { + bartImage->ResetTransformation(); + bartImage->ScaleAboutCenter( 0.75f ); + } + + m_tutorialMessage = m_tutorialWalkie->GetSprite( "TutorialMessage" ); + rAssert( m_tutorialMessage != NULL ); + m_tutorialMessage->ScaleAboutCenter( 0.4f ); + m_tutorialMessage->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_tutorialMessage->CreateBitmapTextBuffer( MAX_TUTORIAL_MESSAGE_LENGTH ); + + pPage = m_pScroobyScreen->GetPage( "WhiteCover" ); + rAssert( pPage != NULL ); + + Scrooby::Layer* whiteOverlay = pPage->GetLayer( "WhiteOverlay" ); + rAssert( whiteOverlay != NULL ); + whiteOverlay->SetVisible( true ); + + g_WhiteWash = pPage->GetPolygon( "WhiteOverlay" ); + rAssert( g_WhiteWash != NULL ); + g_WhiteWash->SetVisible( false ); + + g_TutorialPulse.SetDrawable( m_tutorialWalkie ); + g_TutorialPulse.SetAmplitude( 0.1f ); + g_TutorialPulse.SetFrequency( 2.5f ); + g_TutorialPulse.Activate(); + g_WhiteWashShow.SetDrawable( g_WhiteWash ); + g_WhiteWashShow.SetNextTransition( g_WhiteWashIn ); + g_WhiteWashIn.SetDrawable( g_WhiteWash ); + g_WhiteWashIn.SetTimeInterval( WHITE_WASH_IN_TIME ); + g_WhiteWashIn.SetStartColour( tColour( 255, 255, 255, 0 ) ); + g_WhiteWashIn.SetEndColour( tColour( 255, 255, 255, 255 ) ); + g_ResetCar.SetEvent( EVENT_DEATH_VOLUME_SCREEN_BLANK ); + g_ResetCar.SetEventData( NULL ); + + + + g_WhiteWashIn.SetNextTransition( g_ResetCar ); + g_ResetCar.SetNextTransition( g_WhiteWashResumeGame ); + g_WhiteWashResumeGame.SetNextTransition( g_WhiteWashPause ); + g_WhiteWashPause.SetTimeInterval( 250.0f ); + g_WhiteWashPause.SetNextTransition( g_WhiteWashHide ); + g_WhiteWashHide.SetDrawable( g_WhiteWash ); + g_WhiteWashHide.SetNextTransition( NULL ); + + int xMin; + int xMax; + int yMin; + int yMax; + m_tutorialWalkie->GetBoundingBox( xMin, yMin, xMax, yMax ); + int height = yMax - yMin; + + // + // Set up transitions for the tutorial bitmap + // + m_TutorialBitmapTransitionIn.SetDrawable( m_tutorialWalkie ); + m_TutorialBitmapTransitionIn.SetFrequency( 5.0f ); + m_TutorialBitmapTransitionIn.SetTimeInterval( transitionIn * 2.0f ); + m_TutorialBitmapTransitionIn.SetStartOffscreenTop( m_tutorialWalkie ); + m_TutorialBitmapTransitionIn.SetCoordsEnd( 0, 0 ); + + m_TutorialBitmapSteadyState.SetDrawable( m_tutorialWalkie ); + m_TutorialBitmapSteadyState.SetTimeInterval( maxDisplayTime ); + m_TutorialBitmapSteadyState.SetCoordsStart( 0, 0 ); + m_TutorialBitmapSteadyState.SetCoordsEnd( 0, 0 ); + + m_TutorialBitmapTransitionOut.SetDrawable( m_tutorialWalkie ); + m_TutorialBitmapTransitionOut.SetTimeInterval( transitionOut ); + m_TutorialBitmapTransitionOut.SetCoordsStart( 0, 0 ); + m_TutorialBitmapTransitionOut.SetEndOffscreenTop( m_tutorialWalkie ); + + m_TurorialBitmapStayOut.SetDrawable( m_tutorialWalkie ); + m_TurorialBitmapStayOut.SetTimeInterval( FLT_MAX ); + m_TurorialBitmapStayOut.SetCoordsStart( 0, -height * 2 - yMin ); + m_TurorialBitmapStayOut.SetCoordsEnd( 0, -height * 2 - yMin ); + + // + // Chain the transitions together + // + m_TutorialBitmapTransitionIn.SetNextTransition( m_TutorialBitmapSteadyState ); + m_TutorialBitmapSteadyState.SetNextTransition( m_TutorialBitmapTransitionOut ); + m_TutorialBitmapTransitionOut.SetNextTransition( m_TurorialBitmapStayOut ); + + // override default fade time + this->SetFadeTime( ENTER_INGAME_FADE_IN_TIME ); +} + +CGuiScreenMultiHud::CGuiScreenMultiHud +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MULTI_HUD ), + m_numActivePlayers( MAX_PLAYERS ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "MultiHud" ); + rAssert( pPage ); + + // Get dynamic elements + this->RetrieveElements( pPage ); +} + + +//=========================================================================== +// CGuiScreenMultiHud::~CGuiScreenMultiHud +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMultiHud::~CGuiScreenMultiHud() +{ + for( unsigned int i = 0; i < sizeof( m_hudMap ) / + sizeof( m_hudMap[ 0 ] ); i++ ) + { + if( m_hudMap[ i ] != NULL ) + { + delete m_hudMap[ i ]; + m_hudMap[ i ] = NULL; + } + } +} + + +//=========================================================================== +// CGuiScreenMultiHud::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + switch( message ) + { + case GUI_MSG_UPDATE: + { + // update HUD elements for all players + this->UpdateElements( param1 ); + + if( m_isStartButtonPressed ) + { + m_isStartButtonPressed = false; + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + m_pParent->HandleMessage( GUI_MSG_PAUSE_INGAME ); + } + } + + break; + } + + case GUI_MSG_CONTROLLER_START: + { + // queue this up to be processed in the next update frame + // + m_isStartButtonPressed = true; + + break; + } + +#ifdef RAD_WIN32 + case GUI_MSG_CONTROLLER_BACK: + { + // This is our start button for PC. + if( GetInputManager()->GetValue( 0, InputManager::KeyboardEsc ) > 0.0f ) + { + m_isStartButtonPressed = true; + } + break; + } +#endif + + case GUI_MSG_DEATH_VOLUME_START: + { + // + // Need to start the transition for the death volume + // + if( g_TimeSinceLastDeathVolume > WHITE_WASH_IN_TIME + 1000.0 && GetGameFlow()->GetCurrentContext() != CONTEXT_PAUSE && GetGameFlow()->GetNextContext() != CONTEXT_PAUSE) + { + g_ResetCar.SetEventData( reinterpret_cast< void* >( param1 ) ); + GameplayContext::GetInstance()->PauseAllButPresentation( true ); + g_WhiteWashShow.Reset(); + g_WhiteWashIn.Reset(); + g_WhiteWashHide.Reset(); + g_WhiteWashPause.Reset(); + g_WhiteWashShow.Activate(); + g_TimeSinceLastDeathVolume = 0.0f; + } + break; + } + + case GUI_MSG_MANUAL_RESET: + { + // + // Need to start the transition for the death volume + // + if( g_TimeSinceLastDeathVolume > WHITE_WASH_IN_TIME + 1000.0 && GetGameFlow()->GetCurrentContext() != CONTEXT_PAUSE && GetGameFlow()->GetNextContext() != CONTEXT_PAUSE) + { + g_ResetCar.SetVehicle( reinterpret_cast< Vehicle* >( param1 ) ); + g_ResetCar.SetEventData( NULL ); + GameplayContext::GetInstance()->PauseAllButPresentation( true ); + g_WhiteWashShow.Reset(); + g_WhiteWashIn.Reset(); + g_WhiteWashHide.Reset(); + g_WhiteWashPause.Reset(); + g_WhiteWashShow.Activate(); + g_TimeSinceLastDeathVolume = 0.0f; + } + break; + } + + default: + { + break; + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMultiHud::GetHudMap +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CHudMap* +CGuiScreenMultiHud::GetHudMap( unsigned int playerID ) const +{ + rAssert( playerID < static_cast<unsigned int>( m_numActivePlayers ) ); + + return m_hudMap[ playerID ]; +} + + +//=========================================================================== +// CGuiScreenMultiHud::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::InitIntro() +{ + for( int i = 0; i < m_numActivePlayers; i++ ) + { + Avatar* pAvatar = GetAvatarManager()->GetAvatarForPlayer( i ); + rAssert( pAvatar ); + + rAssert( m_hudMap[ i ] ); + m_hudMap[ i ]->SetCameraTarget( pAvatar->GetCharacter()->GetTarget() ); + m_hudMap[ i ]->Reset(); +/* + m_hudMap[ i ]->RegisterIcon( HudMapIcon::ICON_PLAYER, + rmt::Vector( 0, 0, 0 ), + pAvatar->GetCharacter()->GetTarget() ); +*/ + } +} + + +//=========================================================================== +// CGuiScreenMultiHud::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenMultiHud::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMultiHud::RetrieveElements( Scrooby::Page* pPage ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenMultiHud" ); + char objectName[ 32 ]; + for( int i = 0; i < m_numActivePlayers; i++ ) + { +#ifdef SRR2_SHOW_SPEEDOMETER + sprintf( objectName, "Speed%d", i ); + Scrooby::Group* speedGroup = pPage->GetGroup( objectName ); + + rAssert( speedGroup != NULL ); + m_speedDigital[ i ].SetScroobyText( speedGroup, objectName ); +// m_speedDigital[ i ].SetColour( tColour( 255, 255, 255 ) ); + + // speedometer is turned on w/ commandline option "speedometer" + // + m_speedDigital[ i ].SetVisible( CommandLineOptions::Get( CLO_SHOW_SPEED ) ); + + // hide speed units in final build + #ifdef FINAL + sprintf( objectName, "SpeedUnit%d", i ); + Scrooby::Text* speedUnit = speedGroup->GetText( objectName ); + if( speedUnit != NULL ) + { + speedUnit->SetVisible( false ); + } + #endif +#endif + + char p3dFile[ 16 ]; + sprintf( p3dFile, "l%dhudmap", GetGameplayManager()->GetCurrentLevelIndex() + 1 ); + m_hudMap[ i ] = new CHudMap( pPage, i, p3dFile ); + rAssert( m_hudMap[ i ] != NULL ); + + // Get Hud Map Icons + // + Scrooby::Group* playerCars = pPage->GetGroup( "PlayerCars" ); + Scrooby::Group* aiCarsGroup = pPage->GetGroup( "AICars" ); + Scrooby::Group* aiHarassCars = pPage->GetGroup( "AIHarassCars" ); + Scrooby::Group* waypointFlags = pPage->GetGroup( "WaypointFlags" ); + Scrooby::Group* checkeredFlags = pPage->GetGroup( "CheckeredFlags" ); + Scrooby::Group* collectables = pPage->GetGroup( "Collectibles" ); + Scrooby::Group* icons0 = pPage->GetGroup( "Icons0" ); + Scrooby::Group* missions = pPage->GetGroup( "Missions" ); + Scrooby::Group* bonusMissions = pPage->GetGroup( "BonusMissions" ); + Scrooby::Group* streetRaces = pPage->GetGroup( "StreetRaces" ); + Scrooby::Group* wagerRaces = pPage->GetGroup( "WagerRaces" ); + Scrooby::Group* purchaseCentres = pPage->GetGroup( "PurchaseCentres" ); + Scrooby::Group* phoneBooths = pPage->GetGroup( "PhoneBooths" ); + rAssert( playerCars != NULL ); + rAssert( aiCarsGroup != NULL ); + rAssert( aiHarassCars != NULL ); + rAssert( waypointFlags != NULL ); + rAssert( checkeredFlags != NULL ); + rAssert( collectables != NULL ); + rAssert( icons0 != NULL ); + rAssert( missions != NULL ); + rAssert( bonusMissions != NULL ); + rAssert( streetRaces != NULL ); + rAssert( wagerRaces != NULL ); + rAssert( purchaseCentres != NULL ); + rAssert( phoneBooths != NULL ); + + sprintf( objectName, "IconPlayer%d", i ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PLAYER, icons0->GetSprite( objectName ) ); + + for( unsigned int j = 0; j < MAX_NUM_ICONS_PER_TYPE; j++ ) + { + sprintf( objectName, "IconMission%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_MISSION, missions->GetSprite( objectName ) ); + + sprintf( objectName, "IconCollectible%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_COLLECTIBLE, collectables->GetSprite( objectName ) ); + + sprintf( objectName, "IconPlayerCar%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PLAYER_CAR, playerCars->GetSprite( objectName ) ); + + sprintf( objectName, "IconAICar%d_%d", i, j ); + Scrooby::Sprite* aiCarIcon = aiCarsGroup->GetSprite( objectName ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_CHASE, aiCarIcon ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_RACE, aiCarIcon ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_EVADE, aiCarIcon ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_TARGET, aiCarIcon ); + + sprintf( objectName, "IconHarass%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_HIT_N_RUN, aiHarassCars->GetSprite( objectName ) ); + + sprintf( objectName, "IconWaypoint%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_FLAG_WAYPOINT, waypointFlags->GetSprite( objectName ) ); + + sprintf( objectName, "IconChecker%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_FLAG_CHECKERED, checkeredFlags->GetSprite( objectName ) ); + + sprintf( objectName, "BonusMission%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_BONUS_MISSION, bonusMissions->GetSprite( objectName ) ); + + sprintf( objectName, "StreetRace%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_STREET_RACE, streetRaces->GetSprite( objectName ) ); + + sprintf( objectName, "WagerRace%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_WAGER_RACE, wagerRaces->GetSprite( objectName ) ); + + sprintf( objectName, "PhoneBooth%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PHONE_BOOTH, phoneBooths->GetSprite( objectName ) ); + + sprintf( objectName, "PurchaseCentre%d_%d", i, j ); + m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PURCHASE_CENTRE, purchaseCentres->GetSprite( objectName ) ); + } + + m_hudMap[ i ]->RestoreAllRegisteredIcons(); + } +MEMTRACK_POP_GROUP("CGUIScreenMultiHud"); +} + +void +CGuiScreenMultiHud::UpdateElements( unsigned int elapsedTime ) +{ + float elapsedTimeFloat = static_cast< float >( elapsedTime ); + g_TimeSinceLastDeathVolume += elapsedTimeFloat; + g_WhiteWashIn.Update( elapsedTimeFloat ); + g_WhiteWashPause.Update( elapsedTimeFloat ); + g_TutorialPulse.Update( elapsedTimeFloat ); + + for( int i = 0; i < m_numActivePlayers; i++ ) + { +#ifdef SRR2_SHOW_SPEEDOMETER + // update speedometer + // + if( CommandLineOptions::Get( CLO_SHOW_SPEED ) || + GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_SHOW_SPEEDOMETER ) ) + { + unsigned int speed = 0; + + Avatar* pAvatar = GetAvatarManager()->GetAvatarForPlayer( i ); + rAssert( pAvatar ); + if( pAvatar->IsInCar() ) + { + Vehicle* vehicle = pAvatar->GetVehicle(); + rAssert( vehicle ); + + speed = (unsigned int)vehicle->GetSpeedKmh(); + } + else + { + Character* pCharacter = pAvatar->GetCharacter(); + rAssert( pCharacter ); + + speed = (unsigned int)pCharacter->GetSpeed(); + } + + m_speedDigital[ i ].SetVisible( true ); + m_speedDigital[ i ].SetValue( speed ); + } + else + { + m_speedDigital[ i ].SetVisible( false ); + } +#endif // SRR2_SHOW_SPEEDOMETER + + // update hud map + // + rAssert( m_hudMap[ i ] ); + m_hudMap[ i ]->Update( elapsedTime ); + } +} + +//=========================================================================== +// CGuiScreenHud::TutorialBitmapHide +//=========================================================================== +// Description: hides the tutorial mode bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::TutorialBitmapHide() +{ + m_tutorialWalkie->SetVisible( false ); + m_TutorialBitmapVisible = false; +} + +//=========================================================================== +// CGuiScreenHud::TutorialBitmapInitOutro +//=========================================================================== +// Description: starts the outro transition of the tutorial bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::TutorialBitmapInitOutro() +{ + m_TutorialBitmapTransitionIn.Deactivate(); + m_TutorialBitmapSteadyState.Deactivate(); + m_TutorialBitmapTransitionOut.Activate(); + m_TurorialBitmapStayOut.Deactivate(); + m_TutorialBitmapTimeShown = maxDisplayTime; +} +//=========================================================================== +// CGuiScreenHud::TutorialBitmapShow +//=========================================================================== +// Description: shows the tutorial mode bitmap. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::TutorialBitmapShow() +{ + m_tutorialWalkie->SetVisible( true ); + m_TutorialBitmapVisible = true; + m_TutorialBitmapTimeShown = 0.0f; + m_TutorialBitmapTransitionIn.Reset(); + m_TutorialBitmapTransitionOut.Reset(); + m_TutorialBitmapSteadyState.Reset(); + m_TutorialBitmapTransitionIn.Activate(); + m_TutorialBitmapTransitionOut.Deactivate(); + m_TutorialBitmapSteadyState.Deactivate(); + m_TurorialBitmapStayOut.Deactivate(); +} + +//=========================================================================== +// CGuiScreenHud::TutorialBitmapHide +//=========================================================================== +// Description: hides the tutorial mode bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::UpdateTutorialMode( const float deltaT ) +{ + m_tutorialWalkie->ResetTransformation(); + m_TutorialBitmapTransitionIn.Update( deltaT ); + m_TutorialBitmapSteadyState.Update( deltaT ); + if( m_TutorialBitmapTransitionOut.IsActive() ) + { + m_TutorialBitmapTransitionOut.Update( deltaT ); + if( m_TutorialBitmapTransitionOut.IsDone() ) + { + this->TutorialBitmapHide(); + } + } + m_TurorialBitmapStayOut.Update( deltaT ); +} + +//=========================================================================== +// CGuiScreenMultiHud::SetTutorialMessage +//=========================================================================== +// Description: hides the tutorial mode bitmap +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::SetTutorialMessage( int index ) +{ + char textBibleID[ 32 ]; + sprintf( textBibleID, "TUTORIAL_%03d", index ); + + rAssert( m_tutorialMessage != NULL ); + m_tutorialMessage->SetBitmapText( GetTextBibleString( textBibleID ) ); +} + +//=========================================================================== +// CGuiScreenMultiHud::ShowLetterBox +//=========================================================================== +// Description: shows the letterbox +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMultiHud::ShowLetterBox() +{ + m_LetterboxPage->SetVisible( true ); +} + +//=========================================================================== +// ResetCar::ResetCar +//=========================================================================== +// Description: constructor for the reset car transition +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +ResetCar::ResetCar() +{ +} + +//=========================================================================== +// ResetCar::Activate +//=========================================================================== +// Description: Activate - does the work of the reset car trasntition +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void ResetCar::Activate() +{ + if( this->mEventData == NULL ) + { + bool manualDamageReset = CommandLineOptions::Get( CLO_MANUAL_RESET_DAMAGE ); + rAssert( m_Vehicle != NULL ); + if( m_Vehicle != NULL ) + { + m_Vehicle->ResetOnSpot( manualDamageReset ); + m_Vehicle = NULL; + } + } + else + { + SendEvent::Activate(); + } + ContinueChain(); +} + +//=========================================================================== +// ResetCar::SetVehicle +//=========================================================================== +// Description: sets the vehicle that's going to get reset +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void ResetCar::SetVehicle( Vehicle* vehicle ) +{ + m_Vehicle = vehicle; +} diff --git a/game/code/presentation/gui/ingame/guiscreenmultihud.h b/game/code/presentation/gui/ingame/guiscreenmultihud.h new file mode 100644 index 0000000..b6aff7c --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenmultihud.h @@ -0,0 +1,91 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMultiHud +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMULTIHUD_H +#define GUISCREENMULTIHUD_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/utility/numerictext.h> +#include <presentation/gui/utility/slider.h> +#include <presentation/gui/utility/transitions.h> +#include <constants/maxplayers.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CHudMap; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMultiHud : public CGuiScreen +{ +public: + CGuiScreenMultiHud( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMultiHud(); + + CGuiScreenMultiHud( Scrooby::Screen* pScreen, CGuiEntity* pParent, + eGuiWindowID id, int numActivePlayers ); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CHudMap* GetHudMap( unsigned int playerID ) const; + + void TutorialBitmapShow(); + void TutorialBitmapHide(); + void TutorialBitmapInitOutro(); + void SetTutorialMessage( int index ); + void ShowLetterBox(); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void RetrieveElements( Scrooby::Page* pPage ); + void UpdateElements( unsigned int elapsedTime ); + void UpdateTutorialMode( const float deltaT ); + + int m_numActivePlayers; + + NumericText<Scrooby::Text> m_speedDigital[ MAX_PLAYERS ]; + + static const int MAX_TUTORIAL_MESSAGE_LENGTH = 256; + + ImageSlider m_gasMeter[ MAX_PLAYERS ]; + CHudMap* m_hudMap[ MAX_PLAYERS ]; + Scrooby::Group* m_tutorialWalkie; + Scrooby::Sprite* m_tutorialMessage; + bool m_TutorialBitmapVisible : 1; + bool m_isStartButtonPressed : 1; + float m_TutorialBitmapTimeShown; + GuiSFX::UnderdampedTranslator m_TutorialBitmapTransitionIn; + GuiSFX::Translator m_TutorialBitmapSteadyState; + GuiSFX::Translator m_TutorialBitmapTransitionOut; + GuiSFX::Translator m_TurorialBitmapStayOut; + Scrooby::Page* m_LetterboxPage; + +}; + + +#endif // GUISCREENMULTIHUD_H diff --git a/game/code/presentation/gui/ingame/guiscreenpause.cpp b/game/code/presentation/gui/ingame/guiscreenpause.cpp new file mode 100644 index 0000000..1962dbc --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpause.cpp @@ -0,0 +1,646 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPause +// +// Description: Implementation of the CGuiScreenPause class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpause.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/ingame/guihudtextbox.h> +#include <presentation/gui/ingame/hudevents/hudmissionobjective.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <data/memcard/memorycardmanager.h> + +#include <cards/card.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <worldsim/coins/coinmanager.h> + +// Pure3D +#include <p3d/utility.hpp> +#include <p3d/sprite.hpp> + +#include <raddebug.hpp> // Foundation +#include <radtime.hpp> + +#include <stdlib.h> +#include <string.h> + +#include <app.h> +#include <group.h> +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <sprite.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPause::CGuiScreenPause +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPause::CGuiScreenPause +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID id +) +: CGuiScreen( pScreen, pParent, id ), + m_pMenu( NULL ), + m_MissionObjectiveBox( NULL ), + m_pressStart( NULL ), + m_missionObjective( NULL ), + m_objectiveIcon( NULL ), + m_numVisibleCards( NUM_CARDS_PER_LEVEL ), + m_elapsedTime( 0 ) +{ + memset( m_collectedCards, 0, sizeof( m_collectedCards ) ); +/* + // Retrieve the Scrooby drawing elements (from Pause Cards page). + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseCards" ); + rAssert( pPage ); + + Scrooby::Group* collectableCards = pPage->GetGroup( "CollectedCards" ); + rAssert( collectableCards != NULL ); + + char cardName[ 32 ]; + for( unsigned int i = 0; i < sizeof( m_collectedCards ) / + sizeof( m_collectedCards[ 0 ] ); i++ ) + { + sprintf( cardName, "Card%d", i ); + m_collectedCards[ i ] = collectableCards->GetSprite( cardName ); + rAssert( m_collectedCards[ i ] ); + } +*/ + // Retrieve the Scrooby drawing elements (from Coins page). + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Coins" ); + rAssert( pPage != NULL ); + CGuiScreenHud::SetNumCoinsDisplay( pPage->GetSprite( "NumCoins" ) ); + + // Retrieve the Scrooby drawing elements (from PauseMissionObjective page). + // + pPage = m_pScroobyScreen->GetPage( "PauseMissionObjective" ); + rAssert( pPage != NULL ); + + Scrooby::Group* pGroup = pPage->GetGroup( "MissionObjective" ); + m_MissionObjectiveBox = pGroup; + rAssert( pGroup != NULL ); + + m_missionObjective = pGroup->GetText( "MissionObjective" ); + rAssert( m_missionObjective != NULL ); + m_missionObjective->SetTextMode( Scrooby::TEXT_WRAP ); + m_missionObjective->ResetTransformation(); + m_missionObjective->Translate( 0, MESSAGE_TEXT_VERTICAL_TRANSLATION ); + m_missionObjective->ScaleAboutPoint( MESSAGE_TEXT_SCALE * MESSGAE_TEXT_HORIZONTAL_STRETCH, + MESSAGE_TEXT_SCALE, + 1.0f, 0, 0 ); + + m_objectiveIcon = pGroup->GetSprite( "ObjectiveIcon" ); + rAssert( m_objectiveIcon != NULL ); + m_objectiveIcon->SetVisible( false ); + m_objectiveIcon->ResetTransformation(); + m_objectiveIcon->ScaleAboutCenter( MISSION_ICON_SCALE ); + + // apply correction scale to message box + // + Scrooby::Sprite* messageBox = pGroup->GetSprite( "MessageBox" ); + rAssert( messageBox != NULL ); + messageBox->ResetTransformation(); + messageBox->ScaleAboutCenter( MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_HORIZONTAL_STRETCH, + MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_VERTICAL_STRETCH, + 1.0f ); + + // Retrieve the Scrooby drawing elements (from Pause Foreground page). + // + pPage = m_pScroobyScreen->GetPage( "PauseFgd" ); + if( pPage != NULL ) + { +#ifdef RAD_WIN32 + pPage->SetVisible( false ); +#endif + + // Wrap "Press Start" help text + // + m_pressStart = pPage->GetText( "PressStartResumePlay" ); + if( m_pressStart != NULL ) + { + m_pressStart->SetTextMode( Scrooby::TEXT_WRAP ); + + // add text outline + // + m_pressStart->SetDisplayOutline( true ); + + // set platform-specific text + // + m_pressStart->SetIndex( PLATFORM_TEXT_INDEX ); + } + } + + this->AutoScaleFrame( m_pScroobyScreen->GetPage( "XSmallBoard" ) ); + + this->SetZoomingEnabled( true ); + + #ifdef DEBUGWATCH + const char* screenName = GetWatcherName(); + m_MissionObjectiveBox->WatchAll( screenName ); + m_objectiveIcon-> WatchAll( screenName ); + m_missionObjective-> WatchAll( screenName ); + m_pressStart-> WatchAll( screenName ); + #endif +} + + +//=========================================================================== +// CGuiScreenPause::~CGuiScreenPause +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPause::~CGuiScreenPause() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenPause::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPause::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ +#ifdef RAD_WIN32 + if( message == GUI_MSG_MENU_PROMPT_RESPONSE && + param1 == PROMPT_CONFIRM_QUIT_TO_SYSTEM ) + { + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + // Tell the current screen to shut down. + // + m_pParent->HandleMessage( GUI_MSG_QUIT_TO_SYSTEM ); + + break; + } + + case (CGuiMenuPrompt::RESPONSE_NO): + { + this->ReloadScreen(); + + break; + } + + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + } +#endif + + if( message == GUI_MSG_MENU_PROMPT_RESPONSE && + param1 == PROMPT_CONFIRM_QUIT ) + { + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + m_pParent->HandleMessage( GUI_MSG_QUIT_INGAME ); + + break; + } + + case (CGuiMenuPrompt::RESPONSE_NO): + { + this->ReloadScreen(); + + break; + } + + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + } + + if ( message==GUI_MSG_PROMPT_START_RESPONSE ) + { + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + } + + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + + case GUI_MSG_UPDATE: + { + GetMemoryCardManager()->Update( param1 ); + HudMissionObjective* hudMissionObjective = static_cast<HudMissionObjective*>( GetCurrentHud()->GetEventHandler( CGuiScreenHud::HUD_EVENT_HANDLER_MISSION_OBJECTIVE ) ); + hudMissionObjective->UpdateIcon(); + break; + } + + case GUI_MSG_CONTROLLER_START: + { + if( !m_pMenu->HasSelectionBeenMade() ) + { + this->HandleResumeGame(); + } + + break; + } + +#ifdef RAD_WIN32 + case GUI_MSG_CONTROLLER_BACK: + { + // This is our start button for PC. + this->HandleResumeGame(); + break; + } +#endif + + default: + { + break; + } + } + + // relay message to menu + // + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + if( m_numTransitionsPending <= 0 ) + { + // restore press start text + // + if( m_pressStart != NULL ) + { + m_pressStart->ResetTransformation(); + m_pressStart->SetHorizontalJustification( Scrooby::Left ); + } + + rAssert( m_objectiveIcon != NULL ); + m_objectiveIcon->SetRawSprite( NULL ); + m_objectiveIcon->SetVisible( false ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPause::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPause::InitIntro() +{ +/* + // update collect cards display for current level + // + unsigned int currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + const CardList* collectedCards = GetCardGallery()->GetCollectedCards( currentLevel ); + rAssert( collectedCards ); + + for( unsigned int i = 0; i < sizeof( m_collectedCards ) / + sizeof( m_collectedCards[ 0 ] ); i++ ) + { + rAssert( m_collectedCards[ i ] ); + + if( collectedCards->m_cards[ i ] != NULL ) + { + unsigned int cardID = collectedCards->m_cards[ i ]->GetID(); + rAssert( cardID < static_cast<unsigned int>( m_collectedCards[ i ]->GetNumOfImages() ) ); + m_collectedCards[ i ]->SetIndex( cardID + 1 ); + } + else + { + m_collectedCards[ i ]->SetIndex( 0 ); + } + } + + this->HideCards(); +*/ + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + if( currentMission != NULL ) + { + MissionStage* currentStage = currentMission->GetCurrentStage(); + if( currentStage != NULL ) + { + // update mission objective text + // + rAssert( m_missionObjective != NULL ); + + int currentMissionObjective = currentStage->GetStartMessageIndex(); + if( currentMissionObjective >= 0 ) // && currentStage->GetMissionLocked() ) + { + rAssert( currentMissionObjective < m_missionObjective->GetNumOfStrings() ); + m_missionObjective->SetIndex( currentMissionObjective ); + m_missionObjective->SetVisible( true ); + m_MissionObjectiveBox->SetVisible( true ); + } + else + { + rWarningMsg( false, "Invalid mission objective message index!" ); + m_missionObjective->SetVisible( false ); + m_MissionObjectiveBox->SetVisible( false ); + } + + // update mission objective icon + // + tSprite* pSprite = NULL; + const char* iconName = currentStage->GetHUDIcon(); + if( iconName[ 0 ] != '\0' ) + { + pSprite = p3d::find<tSprite>( iconName ); + rTuneWarningMsg( pSprite != NULL, "Can't find mission objective icon!" ); + } + + rAssert( m_objectiveIcon != NULL ); + m_objectiveIcon->SetVisible( pSprite != NULL ); + m_objectiveIcon->SetRawSprite( pSprite, true ); + } + else + { + m_MissionObjectiveBox->SetVisible( false ); + } + } + else + { + m_MissionObjectiveBox->SetVisible( false ); + } + + // move press start text to bottom center of pause menu box + // + if( m_pressStart != NULL ) + { + int centerX, centerY; + m_pressStart->GetBoundingBoxCenter( centerX, centerY ); + + int screenCenterX = static_cast<int>( Scrooby::App::GetInstance()->GetScreenWidth() / 2 ); + + m_pressStart->ResetTransformation(); + m_pressStart->Translate( screenCenterX - centerX, 85 ); + m_pressStart->SetHorizontalJustification( Scrooby::Centre ); + } + + // reset pause menu to default selection + if( m_pMenu != NULL ) + { + m_pMenu->Reset(); + } +} + + +//=========================================================================== +// CGuiScreenPause::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPause::InitRunning() +{ + // show coins + // + CGuiScreenHud::UpdateNumCoinsDisplay( GetCoinManager()->GetBankValue() ); + + // disable screen zooming + // + this->SetZoomingEnabled( false ); +} + + +//=========================================================================== +// CGuiScreenPause::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPause::InitOutro() +{ + // hide coins + // + CGuiScreenHud::UpdateNumCoinsDisplay( 0, false ); +} + + +//=========================================================================== +// CGuiScreenPause::HandleResumeGame +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPause::HandleResumeGame( unsigned int param1, + unsigned int param2 ) +{ + // enable zoom-out when returning to game + // + this->SetZoomingEnabled( true ); + + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPause::HandleQuitGame +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPause::HandleQuitGame() +{ + rAssert( m_guiManager ); + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT, this ); +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiScreenPause::HandleQuitToSystem +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPause::HandleQuitToSystem() +{ + rAssert( m_guiManager ); + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT_TO_SYSTEM, this ); +} +#endif + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +/* +void +CGuiScreenPause::HideCards() +{ + // hide all cards + // + for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ ) + { + rAssert( m_collectedCards[ i ] ); + m_collectedCards[ i ]->SetVisible( false ); + } + + // set num visible cards to zero + // + m_numVisibleCards = 0; +} + +void +CGuiScreenPause::ShowNextCard() +{ + // randomize next card to show + // + int nextCard = 0; + + int numHiddenCards = NUM_CARDS_PER_LEVEL - m_numVisibleCards; + if( numHiddenCards > 1 ) + { + nextCard = rand() % numHiddenCards; + } + + // show next card + // + for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ ) + { + rAssert( m_collectedCards[ i ] ); + + if( m_collectedCards[ i ]->IsVisible() ) + { + continue; + } + else + { + if( nextCard == 0 ) + { + m_collectedCards[ i ]->SetVisible( true ); + break; + } + else + { + nextCard--; + } + } + } + + m_numVisibleCards++; +} +*/ + +#ifdef DEBUGWATCH +const char* CGuiScreenPause::GetWatcherName() const +{ + return "GuiScreenPause"; +} +#endif diff --git a/game/code/presentation/gui/ingame/guiscreenpause.h b/game/code/presentation/gui/ingame/guiscreenpause.h new file mode 100644 index 0000000..1082f23 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpause.h @@ -0,0 +1,83 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPause +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPAUSE_H +#define GUISCREENPAUSE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <cards/cardgallery.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPause : public CGuiScreen +{ +public: + CGuiScreenPause( Scrooby::Screen* pScreen, + CGuiEntity* pParent, + eGuiWindowID id ); + virtual ~CGuiScreenPause(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void HandleResumeGame( unsigned int param1 = 0, + unsigned int param2 = 0 ); + void HandleQuitGame(); +#ifdef RAD_WIN32 + void HandleQuitToSystem(); +#endif + #ifdef DEBUGWATCH + virtual const char* GetWatcherName() const; + #endif + + + CGuiMenu* m_pMenu; + Scrooby::Group* m_MissionObjectiveBox; + Scrooby::Text* m_pressStart; + Scrooby::Text* m_missionObjective; + Scrooby::Sprite* m_objectiveIcon; + +private: +/* + void HideCards(); + void ShowNextCard(); +*/ + + Scrooby::Sprite* m_collectedCards[ NUM_CARDS_PER_LEVEL ]; + int m_numVisibleCards; + unsigned int m_elapsedTime; + +}; + +#endif // GUISCREENPAUSE_H diff --git a/game/code/presentation/gui/ingame/guiscreenpausecontroller.cpp b/game/code/presentation/gui/ingame/guiscreenpausecontroller.cpp new file mode 100644 index 0000000..b175d81 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausecontroller.cpp @@ -0,0 +1,224 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseController +// +// Description: Implementation of the CGuiScreenPauseController class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpausecontroller.h> + +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/gameplaymanager.h> +#include <worldsim/avatarmanager.h> +#include <worldsim/avatar.h> + +#include <raddebug.hpp> // Foundation + +#include <screen.h> +#include <layer.h> +#include <page.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float CONTROLLER_IMAGE_CORRECTION_SCALE = 2.0f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPauseController::CGuiScreenPauseController +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseController::CGuiScreenPauseController +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreenController( pScreen, pParent ) +{ +#ifndef RAD_WIN32 + rAssert( pScreen != NULL ); + Scrooby::Page* pPage = pScreen->GetPage( "ControllerImageS" ); + rAssert( pPage != NULL ); + Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" ); + rAssert( foreground != NULL ); + + Scrooby::Sprite* controllerImage = foreground->GetSprite( "Controller" ); + if( controllerImage != NULL ) + { + controllerImage->ScaleAboutCenter( CONTROLLER_IMAGE_CORRECTION_SCALE ); + } +#endif +} + + +//=========================================================================== +// CGuiScreenPauseController::~CGuiScreenPauseController +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseController::~CGuiScreenPauseController() +{ +} + + +//=========================================================================== +// CGuiScreenPauseController::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseController::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenController::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPauseController::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseController::InitIntro() +{ + CGuiScreenController::InitIntro(); +} + + +//=========================================================================== +// CGuiScreenPauseController::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseController::InitRunning() +{ + CGuiScreenController::InitRunning(); +} + + +//=========================================================================== +// CGuiScreenPauseController::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseController::InitOutro() +{ + CGuiScreenController::InitOutro(); + + // apply vibration/rumble setting right away + // + int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 ); + bool vibrationOn = GetInputManager()->IsRumbleEnabled(); + + if ( GetGameplayManager()->GetGameType() == GameplayManager::GT_NORMAL && + GetAvatarManager()->GetAvatarForPlayer( 0 )->GetVehicle() ) + { +#ifdef RAD_PS2 + if ( GetInputManager()->GetController( Input::USB0 )->IsConnected() ) + { + GetInputManager()->SetRumbleForDevice( Input::USB0, vibrationOn ); + } + else if ( GetInputManager()->GetController( Input::USB1 )->IsConnected() ) + { + GetInputManager()->SetRumbleForDevice( Input::USB1, vibrationOn ); + } + else + { + GetInputManager()->SetRumbleForDevice( controllerID, vibrationOn ); + } +#else + GetInputManager()->SetRumbleForDevice( controllerID, vibrationOn ); +#endif + + } +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenpausecontroller.h b/game/code/presentation/gui/ingame/guiscreenpausecontroller.h new file mode 100644 index 0000000..e1b46bf --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausecontroller.h @@ -0,0 +1,52 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseController +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPAUSECONTROLLER_H +#define GUISCREENPAUSECONTROLLER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#ifdef RAD_WIN32 +#include <presentation/gui/frontend/guiscreencontrollerWin32.h> +#else +#include <presentation/gui/frontend/guiscreencontroller.h> +#endif + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPauseController : public CGuiScreenController +{ +public: + CGuiScreenPauseController( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPauseController(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENPAUSECONTROLLER_H diff --git a/game/code/presentation/gui/ingame/guiscreenpausedisplay.cpp b/game/code/presentation/gui/ingame/guiscreenpausedisplay.cpp new file mode 100644 index 0000000..a6cd844 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausedisplay.cpp @@ -0,0 +1,164 @@ +/****************************************************************************** + File: CGuiScreenPauseDisplay.cpp + Desc: Defines the CGuiScreenPauseDisplay class. + Authors: Tony Chu, Neil Haran + Date: August 14, 2003 + History: +*****************************************************************************/ + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpausedisplay.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float CONTROLLER_IMAGE_CORRECTION_SCALE = 2.0f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPauseDisplay::CGuiScreenPauseDisplay +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseDisplay::CGuiScreenPauseDisplay +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreenDisplay( pScreen, pParent ) +{ +} + + +//=========================================================================== +// CGuiScreenPauseDisplay::~CGuiScreenPauseDisplay +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseDisplay::~CGuiScreenPauseDisplay() +{ +} + + +//=========================================================================== +// CGuiScreenPauseDisplay::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseDisplay::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenDisplay::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPauseDisplay::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseDisplay::InitIntro() +{ + CGuiScreenDisplay::InitIntro(); +} + + +//=========================================================================== +// CGuiScreenPauseDisplay::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseDisplay::InitRunning() +{ + CGuiScreenDisplay::InitRunning(); +} + + +//=========================================================================== +// CGuiScreenPauseDisplay::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseDisplay::InitOutro() +{ + CGuiScreenDisplay::InitOutro(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenpausedisplay.h b/game/code/presentation/gui/ingame/guiscreenpausedisplay.h new file mode 100644 index 0000000..200be24 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausedisplay.h @@ -0,0 +1,44 @@ +/****************************************************************************** + + File: CGuiScreenPauseDisplay.h + Desc: Interface for the CGuiScreenController class. + + Date: August 14, 2003 + Authors: Tony Chu, Neil Haran + History: + +*****************************************************************************/ + +#ifndef GUISCREENPAUSEDISPLAY_H +#define GUISCREENPAUSEDISPLAY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreendisplay.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPauseDisplay : public CGuiScreenDisplay +{ +public: + CGuiScreenPauseDisplay( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPauseDisplay(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENPAUSEDISPLAY_H diff --git a/game/code/presentation/gui/ingame/guiscreenpausemission.cpp b/game/code/presentation/gui/ingame/guiscreenpausemission.cpp new file mode 100644 index 0000000..368c83b --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausemission.cpp @@ -0,0 +1,366 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseMission +// +// Description: Implementation of the CGuiScreenPauseMission class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenmissionload.h> +#include <presentation/gui/ingame/guiscreenpausemission.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guisystem.h> +#include <events/eventmanager.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/mission.h> +#include <worldsim/hitnrunmanager.h> +#include <worldsim/avatarmanager.h> +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <page.h> +#include <screen.h> +#include <text.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +enum eMenuItem +{ + MENU_ITEM_CONTINUE, +// MENU_ITEM_VIEW_MAP, + MENU_ITEM_RESTART_MISSION, + MENU_ITEM_ABORT_MISSION, + MENU_ITEM_OPTIONS, + MENU_ITEM_QUIT_GAME, + + NUM_MENU_ITEMS +}; + +static const char* MENU_ITEMS[] = +{ + "Continue", +// "ViewMap", + "RestartMission", + "AbortMission", + "Options", + "QuitGame" +}; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPauseMission::CGuiScreenPauseMission +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseMission::CGuiScreenPauseMission +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreenPause( pScreen, pParent, GUI_SCREEN_ID_PAUSE_MISSION ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenPauseMission" ); + // Create a menu. + // + m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseMission" ); + rAssert( pPage != NULL ); + + // Add menu items + // + Scrooby::Group* menu = pPage->GetGroup( "Menu" ); + rAssert( menu != NULL ); + Scrooby::Text* pText = NULL; + for( int i = 0; i < NUM_MENU_ITEMS; i++ ) + { + pText = menu->GetText( MENU_ITEMS[ i ] ); + rAssert( pText ); + + m_pMenu->AddMenuItem( pText ); + } +MEMTRACK_POP_GROUP("CGUIScreenPauseMission" ); +} + + +//=========================================================================== +// CGuiScreenPauseMission::~CGuiScreenPauseMission +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseMission::~CGuiScreenPauseMission() +{ +} + + +//=========================================================================== +// CGuiScreenPauseMission::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseMission::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + if( param1 == PROMPT_CONFIRM_RESTART ) + { + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + CGuiScreenMissionLoad::ReplaceBitmap(); + this->HandleResumeGame( ON_HUD_ENTER_RESTART_MISSION ); + break; + } + + case (CGuiMenuPrompt::RESPONSE_NO): + { + this->ReloadScreen(); + + break; + } + + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + } + else if( param1 == PROMPT_CONFIRM_ABORT ) + { + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + this->HandleResumeGame( ON_HUD_ENTER_ABORT_MISSION ); + GetEventManager()->TriggerEvent(EVENT_USER_CANCEL_PAUSE_MENU); + + break; + } + + case (CGuiMenuPrompt::RESPONSE_NO): + { + this->ReloadScreen(); + + break; + } + + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + switch( param1 ) + { + case MENU_ITEM_CONTINUE: + { + this->HandleResumeGame(); + + break; + } +/* + case MENU_ITEM_VIEW_MAP: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_HUD_MAP ); + + break; + } +*/ + case MENU_ITEM_RESTART_MISSION: + { + rAssert( m_guiManager ); + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_RESTART, this ); + +// this->HandleResumeGame( ON_HUD_ENTER_RESTART_MISSION ); + + break; + } + case MENU_ITEM_ABORT_MISSION: + { + rAssert( m_guiManager ); + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_ABORT, this ); + +// this->HandleResumeGame( ON_HUD_ENTER_ABORT_MISSION ); + + break; + } + case MENU_ITEM_OPTIONS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_OPTIONS ); + + break; + } + case MENU_ITEM_QUIT_GAME: + { + this->HandleQuitGame(); + + break; + } + default: + { + rAssertMsg( 0, "WARNING: Invalid case for switch statement!\n" ); + break; + } + } + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenPause::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPauseMission::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseMission::InitIntro() +{ + CGuiScreenPause::InitIntro(); + + // enable 'restart mission' and 'abort mission' only if current mission + // isn't completed yet; otherwise, disable these selections + // + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + rAssert( currentMission != NULL ); + + HitnRunManager* hnrm = GetHitnRunManager(); + rAssert( hnrm != NULL ); + + AvatarManager* pAvatarManager= GetAvatarManager(); + rAssert( pAvatarManager != NULL ); + + CGuiManagerInGame* guiManagerIngame = static_cast<CGuiManagerInGame*>( m_pParent ); + rAssert( guiManagerIngame != NULL ); + + bool isRestartAndAbortAllowed = !currentMission->IsSundayDrive() && + !currentMission->IsComplete() && + !hnrm->BustingPlayer() && + !pAvatarManager->IsAvatarGettingInOrOutOfCar(0) && + (guiManagerIngame->GetResumeGameScreenID() != GUI_SCREEN_ID_TUTORIAL); + + rAssert( m_pMenu != NULL ); + m_pMenu->SetMenuItemEnabled( MENU_ITEM_RESTART_MISSION, isRestartAndAbortAllowed ); + m_pMenu->SetMenuItemEnabled( MENU_ITEM_ABORT_MISSION, isRestartAndAbortAllowed ); +} + + +//=========================================================================== +// CGuiScreenPauseMission::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseMission::InitRunning() +{ + CGuiScreenPause::InitRunning(); +} + + +//=========================================================================== +// CGuiScreenPauseMission::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseMission::InitOutro() +{ + CGuiScreenPause::InitOutro(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- diff --git a/game/code/presentation/gui/ingame/guiscreenpausemission.h b/game/code/presentation/gui/ingame/guiscreenpausemission.h new file mode 100644 index 0000000..f19fa6c --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausemission.h @@ -0,0 +1,50 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseMission +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPAUSEMISSION_H +#define GUISCREENPAUSEMISSION_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpause.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPauseMission : public CGuiScreenPause +{ +public: + CGuiScreenPauseMission( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPauseMission(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENPAUSEMISSION_H diff --git a/game/code/presentation/gui/ingame/guiscreenpauseoptions.cpp b/game/code/presentation/gui/ingame/guiscreenpauseoptions.cpp new file mode 100644 index 0000000..99f90e4 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpauseoptions.cpp @@ -0,0 +1,315 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseOptions +// +// Description: Implementation of the CGuiScreenPauseOptions class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpauseoptions.h> +#include <presentation/gui/guimenu.h> + +#include <cheats/cheatinputsystem.h> +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <screen.h> +#include <page.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +enum ePauseMenuItem +{ +#ifdef RAD_WIN32 + MENU_ITEM_DISPLAY, +#endif + MENU_ITEM_CONTROLLER, + MENU_ITEM_SOUND, + MENU_ITEM_SETTINGS, +// MENU_ITEM_CAMERA, + + NUM_PAUSE_MENU_ITEMS +}; + + +static const char* PAUSE_MENU_ITEMS[] = +{ +#ifdef RAD_WIN32 + "Display", +#endif + "Controller", + "Sound", + "Settings", +// "Camera", + + "" +}; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPauseOptions::CGuiScreenPauseOptions +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseOptions::CGuiScreenPauseOptions +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_OPTIONS ), + m_pMenu( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenPauseOptions" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage; + pPage = m_pScroobyScreen->GetPage( "PauseOptions" ); + rAssert( pPage ); + + // Create a menu. + // + m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_PAUSE_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + Scrooby::Group* menu = pPage->GetGroup( "Menu" ); + rAssert( menu != NULL ); + char itemName[ 32 ]; + for( int i = 0; i < NUM_PAUSE_MENU_ITEMS; i++ ) + { + sprintf( itemName, "%s_Value", PAUSE_MENU_ITEMS[ i ] ); + Scrooby::Text* pTextValue = pPage->GetText( itemName ); + + sprintf( itemName, "%s_LArrow", PAUSE_MENU_ITEMS[ i ] ); + Scrooby::Sprite* pLArrow = pPage->GetSprite( itemName ); + + sprintf( itemName, "%s_RArrow", PAUSE_MENU_ITEMS[ i ] ); + Scrooby::Sprite* pRArrow = pPage->GetSprite( itemName ); + + m_pMenu->AddMenuItem( menu->GetText( PAUSE_MENU_ITEMS[ i ] ), + pTextValue, + NULL, + NULL, + pLArrow, + pRArrow ); + } + + // TC: [TEMP] disable controller screen for now to free up some memory for HUD map + // +#ifndef RAD_WIN32 + m_pMenu->SetMenuItemEnabled( MENU_ITEM_CONTROLLER, false, true ); +#endif + +#ifdef RAD_E3 + // disable pause menu settings for E3 build + // + m_pMenu->SetMenuItemEnabled( MENU_ITEM_SETTINGS, false ); +#endif +MEMTRACK_POP_GROUP("CGUIScreenPauseOptions"); +} + + +//=========================================================================== +// CGuiScreenPauseOptions::~CGuiScreenPauseOptions +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseOptions::~CGuiScreenPauseOptions() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenPauseOptions::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseOptions::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( this->IsControllerMessage( message ) && + GetCheatInputSystem()->IsActivated( param1 ) ) + { + // ignore all controller inputs when cheat input system is activated + return; + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + if( !m_pMenu->HasSelectionBeenMade() ) + { + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + } + + break; + } + + case GUI_MSG_MENU_SELECTION_MADE: + { + if( param1 == MENU_ITEM_CONTROLLER ) + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_CONTROLLER ); + } + else if( param1 == MENU_ITEM_SOUND ) + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SOUND ); + } + else if( param1 == MENU_ITEM_SETTINGS ) + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SETTINGS ); + } +#ifdef RAD_WIN32 + else if( param1 == MENU_ITEM_DISPLAY ) + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_DISPLAY ); + } +#endif + else + { + rAssertMsg( false, "Invalid menu selection!" ); + } + + break; + } +/* + case GUI_MSG_MENU_SELECTION_CHANGED: + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, (param1 != MENU_ITEM_CAMERA) ); + + break; + } +*/ + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPauseOptions::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseOptions::InitIntro() +{ +// this->SetButtonVisible( BUTTON_ICON_ACCEPT, (m_pMenu->GetSelection() != MENU_ITEM_CAMERA) ); + +#ifndef RAD_E3 + GetCheatInputSystem()->SetEnabled( true ); +#endif +} + + +//=========================================================================== +// CGuiScreenPauseOptions::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseOptions::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenPauseOptions::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseOptions::InitOutro() +{ +#ifndef RAD_E3 + GetCheatInputSystem()->SetEnabled( false ); +#endif +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenpauseoptions.h b/game/code/presentation/gui/ingame/guiscreenpauseoptions.h new file mode 100644 index 0000000..49f43b1 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpauseoptions.h @@ -0,0 +1,59 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseOptions +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPAUSEOPTIONS_H +#define GUISCREENPAUSEOPTIONS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +namespace Scrooby +{ + class Screen; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPauseOptions : public CGuiScreen +{ +public: + CGuiScreenPauseOptions( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPauseOptions(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + CGuiMenu* m_pMenu; + +}; + +#endif // GUISCREENPAUSEOPTIONS_H diff --git a/game/code/presentation/gui/ingame/guiscreenpausesettings.cpp b/game/code/presentation/gui/ingame/guiscreenpausesettings.cpp new file mode 100644 index 0000000..479efb4 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausesettings.cpp @@ -0,0 +1,557 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseSettings +// +// Description: Implementation of the CGuiScreenPauseSettings class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpausesettings.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guisystem.h> + +#include <camera/supercammanager.h> +#include <camera/supercamcentral.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <presentation/tutorialmanager.h> +#include <worldsim/avatarmanager.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <screen.h> +#include <page.h> +#include <text.h> +#include <strings/unicodestring.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +enum ePauseSettingsMenuItem +{ + MENU_ITEM_CAMERA, + MENU_ITEM_JUMP_CAMERAS, +#ifndef RAD_WIN32 + MENU_ITEM_INVERT_CAM_CONTROL, +#endif + MENU_ITEM_INTERSECT_NAV_SYSTEM, + MENU_ITEM_RADAR, +#ifndef RAD_WIN32 + MENU_ITEM_VIBRATION, +#endif + MENU_ITEM_TUTORIAL, + + NUM_PAUSE_SETTINGS_MENU_ITEMS +}; + + +const char* PAUSE_SETTINGS_MENU_ITEMS[] = +{ + "Camera", + "JumpCamera", +#ifndef RAD_WIN32 + "InvertCamControl", +#endif + "IntersectNavSystem", + "Radar", +#ifndef RAD_WIN32 + "Vibration", +#endif + "Tutorial", + + "" +}; + +#ifdef RAD_WIN32 +SuperCam::Type PC_CAMERAS_FOR_WALKING[] = +{ + SuperCam::WALKER_CAM, + SuperCam::DEBUG_CAM, + SuperCam::KULL_CAM +}; + +const int NUM_PC_CAMERAS_FOR_WALKING = sizeof(PC_CAMERAS_FOR_WALKING)/sizeof(SuperCam::Type); +const int NUM_PC_CAMERAS_FOR_WALKING_WITHOUT_CHEAT = 1; +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPauseSettings::CGuiScreenPauseSettings +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseSettings::CGuiScreenPauseSettings +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SETTINGS ), + m_pMenu( NULL ), + m_currentCameraSelectionMode( CAMERA_SELECTION_NOT_AVAILABLE ) +{ +MEMTRACK_PUSH_GROUP( "CGuiScreenPauseSettings" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseSettings" ); + rAssert( pPage ); + + // Create a menu. + // + m_pMenu = new CGuiMenu( this, NUM_PAUSE_SETTINGS_MENU_ITEMS, GUI_TEXT_MENU, MENU_SFX_NONE ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + char itemName[ 32 ]; + + for( int i = 0; i < NUM_PAUSE_SETTINGS_MENU_ITEMS; i++ ) + { + Scrooby::Group* group = pPage->GetGroup( PAUSE_SETTINGS_MENU_ITEMS[ i ] ); + rAssert( group != NULL ); + + Scrooby::Text* pText = group->GetText( PAUSE_SETTINGS_MENU_ITEMS[ i ] ); + rAssert( pText != NULL ); + pText->SetTextMode( Scrooby::TEXT_WRAP ); + + sprintf( itemName, "%s_Value", PAUSE_SETTINGS_MENU_ITEMS[ i ] ); + Scrooby::Text* pTextValue = group->GetText( itemName ); + rAssert( pTextValue != NULL ); + pTextValue->SetTextMode( Scrooby::TEXT_WRAP ); + + sprintf( itemName, "%s_LArrow", PAUSE_SETTINGS_MENU_ITEMS[ i ] ); + Scrooby::Sprite* pLArrow = group->GetSprite( itemName ); + + sprintf( itemName, "%s_RArrow", PAUSE_SETTINGS_MENU_ITEMS[ i ] ); + Scrooby::Sprite* pRArrow = group->GetSprite( itemName ); + + m_pMenu->AddMenuItem( pText, + pTextValue, + NULL, + NULL, + pLArrow, + pRArrow, + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); + } + +#ifdef RAD_GAMECUBE + // change "Vibration" text to "Rumble" + // + Scrooby::Text* vibrationText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_VIBRATION )->GetItem() ); + rAssert( vibrationText != NULL ); + vibrationText->SetIndex( 1 ); +#endif // RAD_GAMECUBE + + for( int j = 0; j < NUM_CAMERA_SELECTION_MODES; j++ ) + { + m_cameraSelections[ j ] = NULL; + m_numCameraSelections[ j ] = 0; + } + + m_cameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = CAMERAS_FOR_DRIVING; +#ifdef RAD_WIN32 + m_cameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = PC_CAMERAS_FOR_WALKING; +#else + m_cameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = CAMERAS_FOR_WALKING; +#endif + + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_CAMERAS ) ) + { + m_numCameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = NUM_CAMERAS_FOR_DRIVING; + +#ifdef RAD_WIN32 + m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_PC_CAMERAS_FOR_WALKING; +#else + m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_CAMERAS_FOR_WALKING; +#endif + } + else + { + m_numCameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = NUM_CAMERAS_FOR_DRIVING_WITHOUT_CHEAT; +#ifdef RAD_WIN32 + m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_PC_CAMERAS_FOR_WALKING_WITHOUT_CHEAT; +#else + m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_CAMERAS_FOR_WALKING_WITHOUT_CHEAT; +#endif + } + + GetCheatInputSystem()->RegisterCallback( this ); +MEMTRACK_POP_GROUP("CGuiScreenPauseSettings"); +} + + +//=========================================================================== +// CGuiScreenPauseSettings::~CGuiScreenPauseSettings +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseSettings::~CGuiScreenPauseSettings() +{ + GetCheatInputSystem()->UnregisterCallback( this ); + + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenPauseSettings::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSettings::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + // resume game + // + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } + + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + if( param1 == MENU_ITEM_CAMERA ) + { + // set new super cam + // + SuperCam::Type superCamType = m_cameraSelections[ m_currentCameraSelectionMode ][ param2 ]; + GetSuperCamManager()->GetSCC( 0 )->SelectSuperCam( superCamType, SuperCamCentral::CUT, 0 ); + + // and apply it right away + // + GetSuperCamManager()->GetSCC( 0 )->Update( 0 ); + } +#ifndef RAD_WIN32 + else if( param1 == MENU_ITEM_VIBRATION ) + { + if( param2 == 1 ) // vibration turned ON + { + // send vibration pulse to controller + // + int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 ); +#ifdef RAD_PS2 + if ( GetInputManager()->IsControllerInPort( Input::USB0 ) ) + { + GetInputManager()->TriggerRumblePulse( Input::USB0 ); + } + else if ( GetInputManager()->IsControllerInPort( Input::USB1 ) ) + { + GetInputManager()->TriggerRumblePulse( Input::USB1 ); + } + else +#endif + { + GetInputManager()->TriggerRumblePulse( controllerID ); + } + + } + } +#endif + + break; + } + + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenPauseSettings::OnCheatEntered( eCheatID cheatID, bool isEnabled ) +{ + if( cheatID == CHEAT_ID_UNLOCK_CAMERAS && isEnabled ) + { + m_numCameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = NUM_CAMERAS_FOR_DRIVING; + m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_CAMERAS_FOR_WALKING; + } +} + +//=========================================================================== +// CGuiScreenPauseSettings::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSettings::InitIntro() +{ + // update camera setting + // + bool allowCameraToggle = GetSuperCamManager()->GetSCC( 0 )->AllowCameraToggle(); + + rAssert( m_pMenu ); + m_pMenu->SetMenuItemEnabled( MENU_ITEM_CAMERA, allowCameraToggle ); + + if( allowCameraToggle ) + { + // update camera selections + // + this->UpdateCameraSelections(); + } + else + { + m_currentCameraSelectionMode = CAMERA_SELECTION_NOT_AVAILABLE; + } + + // update other gameplay settings + // + bool isSettingOn = false; + +#ifndef RAD_WIN32 + isSettingOn = GetSuperCamManager()->GetSCC( 0 )->IsInvertedCameraEnabled(); + m_pMenu->SetSelectionValue( MENU_ITEM_INVERT_CAM_CONTROL, + isSettingOn ? 1 : 0 ); +#endif + + isSettingOn = GetSuperCamManager()->GetSCC( 0 )->JumpCamsEnabled(); + m_pMenu->SetSelectionValue( MENU_ITEM_JUMP_CAMERAS, + isSettingOn ? 1: 0 ); + + isSettingOn = GetCharacterSheetManager()->QueryNavSystemSetting(); + m_pMenu->SetSelectionValue( MENU_ITEM_INTERSECT_NAV_SYSTEM, + isSettingOn ? 1 : 0 ); + + isSettingOn = GetGuiSystem()->IsRadarEnabled(); + m_pMenu->SetSelectionValue( MENU_ITEM_RADAR, + isSettingOn ? 1 : 0 ); +#ifndef RAD_WIN32 + isSettingOn = GetInputManager()->IsRumbleEnabled(); + m_pMenu->SetSelectionValue( MENU_ITEM_VIBRATION, + isSettingOn ? 1 : 0 ); +#endif + + isSettingOn = GetTutorialManager()->IsTutorialEventsEnabled(); + m_pMenu->SetSelectionValue( MENU_ITEM_TUTORIAL, + isSettingOn ? 1 : 0 ); + + // show/hide tutorial setting depending on whether or not tutorial mode is enabled + // + if( GetTutorialManager()->IsTutorialModeEnabled() ) + { + CGuiManagerInGame* guiManagerIngame = static_cast<CGuiManagerInGame*>( m_pParent ); + rAssert( guiManagerIngame != NULL ); + + bool isTutorialToggleAllowed = (guiManagerIngame->GetResumeGameScreenID() != GUI_SCREEN_ID_TUTORIAL); + m_pMenu->SetMenuItemEnabled( MENU_ITEM_TUTORIAL, isTutorialToggleAllowed ); + } + else + { + m_pMenu->SetMenuItemEnabled( MENU_ITEM_TUTORIAL, false, true ); + } +} + + +//=========================================================================== +// CGuiScreenPauseSettings::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSettings::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenPauseSettings::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSettings::InitOutro() +{ + // apply new gameplay settings + // + rAssert( m_pMenu != NULL ); + bool isSettingOn = false; + +#ifndef RAD_WIN32 + isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_INVERT_CAM_CONTROL ) == 1); + GetSuperCamManager()->GetSCC( 0 )->EnableInvertedCamera( isSettingOn ); +#endif + + isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_JUMP_CAMERAS ) == 1); + GetSuperCamManager()->GetSCC( 0 )->EnableJumpCams( isSettingOn ); + + isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_INTERSECT_NAV_SYSTEM ) == 1); + GetCharacterSheetManager()->SetNavSystemOn( isSettingOn ); + + isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_RADAR ) == 1); + GetGuiSystem()->SetRadarEnabled( isSettingOn ); + +#ifndef RAD_WIN32 + isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_VIBRATION ) == 1); + GetInputManager()->SetRumbleEnabled( isSettingOn ); +#endif + + isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_TUTORIAL ) == 1) +#ifdef RAD_WIN32 + && !(GetInputManager()->GetController(0)->IsTutorialDisabled()) +#endif + ; + GetTutorialManager()->EnableTutorialEvents( isSettingOn ); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenPauseSettings::UpdateCameraSelections() +{ + rAssert( m_pMenu ); + + // set current camera selection mode + // + bool isPlayerInCar = GetAvatarManager()->GetAvatarForPlayer( 0 )->IsInCar(); + m_currentCameraSelectionMode = isPlayerInCar ? CAMERA_SELECTION_FOR_DRIVING : CAMERA_SELECTION_FOR_WALKING; + + // get current active camera + // + SuperCam* currentSuperCam = GetSuperCamManager()->GetSCC( 0 )->GetActiveSuperCam(); + rAssert( currentSuperCam ); + SuperCam::Type currentSuperCamType = currentSuperCam->GetType(); + + int currentCameraIndex = -1; + + // check to see if current camera is in the selection list + // + for( int i = 0; i < m_numCameraSelections[ m_currentCameraSelectionMode ]; i++ ) + { + if( m_cameraSelections[ m_currentCameraSelectionMode ][ i ] == currentSuperCamType ) + { + currentCameraIndex = i; + + break; + } + } + + if( currentCameraIndex == -1 ) + { + // current camera not found in selection list, disable camera selection + // + m_pMenu->SetMenuItemEnabled( MENU_ITEM_CAMERA, false ); + + m_currentCameraSelectionMode = CAMERA_SELECTION_NOT_AVAILABLE; + + return; + } + + m_pMenu->SetMenuItemEnabled( MENU_ITEM_CAMERA, true ); + + // set number of camera selections available + // + m_pMenu->SetSelectionValueCount( MENU_ITEM_CAMERA, + m_numCameraSelections[ m_currentCameraSelectionMode ] ); + + // update camera names + // + for( int i = 0; i < m_numCameraSelections[ m_currentCameraSelectionMode ]; i++ ) + { + GuiMenuItem* menuItemCamera = m_pMenu->GetMenuItem( MENU_ITEM_CAMERA ); + rAssert( menuItemCamera != NULL ); + + SuperCam* superCam = GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( m_cameraSelections[ m_currentCameraSelectionMode ][ i ] ); + rAssert( superCam ); + + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + P3D_UNICODE* stringBuffer = GetTextBibleString( superCam->GetName() ); + rAssert( stringBuffer ); + + UnicodeString unicodeString; + unicodeString.ReadUnicode( static_cast<UnicodeChar*>( stringBuffer ) ); + + Scrooby::Text* menuItemValue = dynamic_cast<Scrooby::Text*>( menuItemCamera->GetItemValue() ); + rAssert( menuItemValue != NULL ); + menuItemValue->SetString( i, unicodeString ); + + HeapMgr()->PopHeap(GMA_LEVEL_HUD); + } + + // set current camera selection + // + m_pMenu->SetSelectionValue( MENU_ITEM_CAMERA, currentCameraIndex ); +} + diff --git a/game/code/presentation/gui/ingame/guiscreenpausesettings.h b/game/code/presentation/gui/ingame/guiscreenpausesettings.h new file mode 100644 index 0000000..9518687 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausesettings.h @@ -0,0 +1,81 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseSettings +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPAUSESETTINGS_H +#define GUISCREENPAUSESETTINGS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +#include <camera/supercam.h> +#include <cheats/cheatinputsystem.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +namespace Scrooby +{ + class Screen; +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPauseSettings : public CGuiScreen, + public ICheatEnteredCallback +{ +public: + CGuiScreenPauseSettings( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPauseSettings(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + virtual void OnCheatEntered( eCheatID cheatID, bool isEnabled ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void UpdateCameraSelections(); + + CGuiMenu* m_pMenu; + + enum eCameraSelectionMode + { + CAMERA_SELECTION_NOT_AVAILABLE = -1, + + CAMERA_SELECTION_FOR_DRIVING, + CAMERA_SELECTION_FOR_WALKING, + + NUM_CAMERA_SELECTION_MODES + }; + + eCameraSelectionMode m_currentCameraSelectionMode; + + SuperCam::Type* m_cameraSelections[ NUM_CAMERA_SELECTION_MODES ]; + int m_numCameraSelections[ NUM_CAMERA_SELECTION_MODES ]; + +}; + +#endif // GUISCREENPAUSEOPTIONS_H diff --git a/game/code/presentation/gui/ingame/guiscreenpausesound.cpp b/game/code/presentation/gui/ingame/guiscreenpausesound.cpp new file mode 100644 index 0000000..92ff581 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausesound.cpp @@ -0,0 +1,173 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseSound +// +// Description: Implementation of the CGuiScreenPauseSound class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpausesound.h> + +#include <memory/srrmemory.h> + +#include <raddebug.hpp> // Foundation + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPauseSound::CGuiScreenPauseSound +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseSound::CGuiScreenPauseSound +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreenSound( pScreen, pParent ) +{ +} + + +//=========================================================================== +// CGuiScreenPauseSound::~CGuiScreenPauseSound +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseSound::~CGuiScreenPauseSound() +{ +} + + +//=========================================================================== +// CGuiScreenPauseSound::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSound::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenSound::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenPauseSound::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSound::InitIntro() +{ + CGuiScreenSound::InitIntro(); +} + + +//=========================================================================== +// CGuiScreenPauseSound::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSound::InitRunning() +{ + CGuiScreenSound::InitRunning(); +} + + +//=========================================================================== +// CGuiScreenPauseSound::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSound::InitOutro() +{ + CGuiScreenSound::InitOutro(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenpausesound.h b/game/code/presentation/gui/ingame/guiscreenpausesound.h new file mode 100644 index 0000000..8215dd2 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausesound.h @@ -0,0 +1,48 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseSound +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPAUSESOUND_H +#define GUISCREENPAUSESOUND_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreensound.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPauseSound : public CGuiScreenSound +{ +public: + CGuiScreenPauseSound( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPauseSound(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENPAUSESOUND_H diff --git a/game/code/presentation/gui/ingame/guiscreenpausesunday.cpp b/game/code/presentation/gui/ingame/guiscreenpausesunday.cpp new file mode 100644 index 0000000..a817094 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausesunday.cpp @@ -0,0 +1,331 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseSunday +// +// Description: Implementation of the CGuiScreenPauseSunday class. +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpausesunday.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guiscreenmemorycard.h> + +#include <memory/srrmemory.h> +#include <mission/charactersheet/charactersheetmanager.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +enum ePauseSundayMenuItem +{ + MENU_ITEM_PAUSE_SUNDAY_CONTINUE, + MENU_ITEM_MISSION_SELECT, + MENU_ITEM_PAUSE_SUNDAY_LEVEL_PROGRESS, + MENU_ITEM_PAUSE_SUNDAY_VIEW_CARDS, + MENU_ITEM_PAUSE_SUNDAY_OPTIONS, + MENU_ITEM_SAVE_GAME, + MENU_ITEM_PAUSE_SUNDAY_QUIT_GAME, +#ifdef RAD_WIN32 + MENU_ITEM_PAUSE_SUNDAY_EXIT_GAME, +#endif + + NUM_PAUSE_SUNDAY_MENU_ITEMS +}; + +static const char* PAUSE_SUNDAY_MENU_ITEMS[] = +{ + "Continue", + "MissionSelect", + "LevelProgress", + "ViewCards", + "Options", + "SaveGame", + "QuitGame" +#ifdef RAD_WIN32 + ,"ExitToSystem" +#endif +}; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPauseSunday::CGuiScreenPauseSunday +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseSunday::CGuiScreenPauseSunday +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreenPause( pScreen, pParent, GUI_SCREEN_ID_PAUSE_SUNDAY ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenPauseSunday" ); + // Create a menu. + // + m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_PAUSE_SUNDAY_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseSunday" ); + rAssert( pPage != NULL ); + + // Add menu items + // + Scrooby::Group* menu = pPage->GetGroup( "Menu" ); + rAssert( menu != NULL ); + Scrooby::Text* pText = NULL; + for( int i = 0; i < NUM_PAUSE_SUNDAY_MENU_ITEMS; i++ ) + { + pText = menu->GetText( PAUSE_SUNDAY_MENU_ITEMS[ i ] ); + rAssert( pText ); + + m_pMenu->AddMenuItem( pText ); + } + +#ifdef RAD_DEMO + // disable certain menu items for demos + // + m_pMenu->SetMenuItemEnabled( MENU_ITEM_SAVE_GAME, false ); +#endif +MEMTRACK_POP_GROUP("CGUIScreenPauseSunday"); +} + + +//=========================================================================== +// CGuiScreenPauseSunday::~CGuiScreenPauseSunday +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPauseSunday::~CGuiScreenPauseSunday() +{ +} + + +//=========================================================================== +// CGuiScreenPauseSunday::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSunday::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { +/* + if( !GetMemoryCardManager()->IsMemcardInfoLoaded() ) + { + if( message == GUI_MSG_CONTROLLER_SELECT || + message == GUI_MSG_CONTROLLER_START ) + { + // ignore all menu selection inputs and start input + // until memcard info is loaded + // + return; + } + } +*/ + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + switch( param1 ) + { + case MENU_ITEM_PAUSE_SUNDAY_CONTINUE: + { + this->HandleResumeGame(); + + break; + } + case MENU_ITEM_MISSION_SELECT: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MISSION_SELECT ); + + break; + } + case MENU_ITEM_PAUSE_SUNDAY_LEVEL_PROGRESS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_LEVEL_STATS ); + + break; + } + case MENU_ITEM_PAUSE_SUNDAY_VIEW_CARDS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VIEW_CARDS ); + + break; + } + case MENU_ITEM_PAUSE_SUNDAY_OPTIONS: + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_OPTIONS ); + + break; + } + case MENU_ITEM_SAVE_GAME: + { +#ifdef RAD_XBOX + // Xbox TCR Requirement: always prompt user to select memory + // device before loading/saving + // + CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = true; +#endif + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SAVE_GAME ); + + break; + } + case MENU_ITEM_PAUSE_SUNDAY_QUIT_GAME: + { + this->HandleQuitGame(); + + break; + } +#ifdef RAD_WIN32 + case MENU_ITEM_PAUSE_SUNDAY_EXIT_GAME: + { + this->HandleQuitToSystem(); + + break; + } +#endif + default: + { + rAssertMsg( 0, "WARNING: Invalid case for switch statement!\n" ); + + break; + } + } + + break; + } + + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenPause::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenPauseSunday::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSunday::InitIntro() +{ + if( GetCharacterSheetManager()->QueryHighestMission().mLevel > 0 || + GetCharacterSheetManager()->QueryHighestMission().mMissionNumber > 0 || + GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) ) + { + m_pMenu->SetMenuItemEnabled( MENU_ITEM_MISSION_SELECT, true ); + } + else + { + // this means the user's just started a new game and is + // currently on the level 1 tutorial mission; hence, cannot + // select any other missions + // + m_pMenu->SetMenuItemEnabled( MENU_ITEM_MISSION_SELECT, false ); + } + + CGuiScreenPause::InitIntro(); +} + + +//=========================================================================== +// CGuiScreenPauseSunday::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSunday::InitRunning() +{ + CGuiScreenPause::InitRunning(); +} + + +//=========================================================================== +// CGuiScreenPauseSunday::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPauseSunday::InitOutro() +{ + CGuiScreenPause::InitOutro(); +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- diff --git a/game/code/presentation/gui/ingame/guiscreenpausesunday.h b/game/code/presentation/gui/ingame/guiscreenpausesunday.h new file mode 100644 index 0000000..38ef85b --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpausesunday.h @@ -0,0 +1,50 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPauseSunday +// +// Description: +// +// +// Authors: Darwin Chau +// Tony Chu +// +// Revisions Date Author Revision +// 2000/11/20 DChau Created +// 2002/06/06 TChu Modified for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPAUSESUNDAY_H +#define GUISCREENPAUSESUNDAY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpause.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPauseSunday : public CGuiScreenPause +{ +public: + CGuiScreenPauseSunday( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPauseSunday(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENPAUSESUNDAY_H diff --git a/game/code/presentation/gui/ingame/guiscreenphonebooth.cpp b/game/code/presentation/gui/ingame/guiscreenphonebooth.cpp new file mode 100644 index 0000000..addef2c --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenphonebooth.cpp @@ -0,0 +1,1104 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPhoneBooth +// +// Description: Implementation of the CGuiScreenPhoneBooth class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenphonebooth.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> + +#include <ai/actionbuttonhandler.h> +#include <camera/relativeanimatedcam.h> +#include <camera/supercam.h> +#include <camera/supercammanager.h> +#include <cheats/cheatinputsystem.h> +#include <events/eventmanager.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/missionmanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <mission/rewards/reward.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <sound/soundmanager.h> +#include <worldsim/character/charactermanager.h> +#include <worldsim/character/character.h> +#include <worldsim/coins/coinmanager.h> +#include <worldsim/vehiclecentral.h> + +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <sprite.h> +#include <text.h> +#include <pure3dobject.h> + +#include <p3d/anim/cameraanimation.hpp> + +#include <raddebug.hpp> // Foundation + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +#ifdef RAD_WIN32 +const float VEHICLE_CORRECTION_SCALE = 0.93f; +const float VEHICLE_DAMAGED_CORRECTION_SCALE = 0.93f; +const float HUSK_CORRECTION_SCALE = 1.4f; +#else +const float VEHICLE_CORRECTION_SCALE = 1.0f / 0.75f; +const float VEHICLE_DAMAGED_CORRECTION_SCALE = 1.0f / 0.5f; +const float HUSK_CORRECTION_SCALE = 1.0f / 0.5f; +#endif + +const float VEHICLE_LOCKED_IMAGE_ALPHA = 0.5f; + +const tUID CHARACTER_VEHICLE_NAMES[] = +{ + tEntity::MakeUID( "apu_v" ), + tEntity::MakeUID( "bart_v" ), + tEntity::MakeUID( "comic_v" ), + tEntity::MakeUID( "cletu_v" ), + tEntity::MakeUID( "frink_v" ), + tEntity::MakeUID( "gramp_v" ), + tEntity::MakeUID( "homer_v" ), + tEntity::MakeUID( "lisa_v" ), + tEntity::MakeUID( "marge_v" ), + tEntity::MakeUID( "skinn_v" ), + tEntity::MakeUID( "smith_v" ), + tEntity::MakeUID( "snake_v" ), + tEntity::MakeUID( "wiggu_v" ), + + 0 // dummy terminator +}; + +const int NUM_CHARACTER_VEHICLE_NAMES = + sizeof( CHARACTER_VEHICLE_NAMES ) / sizeof( CHARACTER_VEHICLE_NAMES[ 0 ] ) - 1; + +static int GetVehicleIndex( const char* vehicleName ) +{ + int vehicleIndex = -1; + + tUID vehicleNameUID = tEntity::MakeUID( vehicleName ); + + for( int i = 0; i < NUM_CHARACTER_VEHICLE_NAMES; i++ ) + { + if( CHARACTER_VEHICLE_NAMES[ i ] == vehicleNameUID ) + { + // found it! + // + vehicleIndex = i; + + // stop searching + // + break; + } + } + + return vehicleIndex; +} + +#ifdef SRR2_OVERRIDE_CAR_SELECTION + const char* OVERRIDE_VEHICLE_NAMES[] = + { + "snake_v", + "bookb_v", + "marge_v", + "carhom_v", + "krust_v", + "bbman_v", + "elect_v", + "famil_v", + "bart_v", + "scorp_v", + "honor_v", + "hbike_v", + "frink_v", + "comic_v", + "lisa_v", + "smith_v", + "mrplo_v", + "fone_v", + "cletu_v", + "apu_v", + "plowk_v", + "wiggu_v", + "otto_v", + "moe_v", + "skinn_v", + "homer_v", + "zombi_v", + "burns_v", + "willi_v", + "gramp_v", + "gramR_v", + + "atv_v", + "knigh_v", + "mono_v", + "oblit_v", + "hype_v", + "dune_v", + "rocke_v", + + "cArmor", + "cCellA", + "cCellB", + "cCellC", + "cCellD", + "cSedan", + "cCola", + "cCube", + "cCurator", + "cDonut", + "cDuff", + "cBlbart", + "cHears", + "cKlimo", + "cLimo", + "cMilk", + "cNerd", + "cNonup", + "cPolice", + "cVan", + + //"huskA", + "compactA", + "minivanA", + "pickupA", + "sedanA", + "sedanB", + "sportsA", + "sportsB", + "wagonA", + "SUVA", + "taxiA", + "coffin", + "ship", + "hallo", + "witchcar", + + "ambul", + "burnsarm", + "fishtruc", + "garbage", + "icecream", + "IStruck", + "nuctruck", + "pizza", + "schoolbu", + "votetruc", + "glastruc", + "cFire_v", + "cBone", + "redbrick", + + "" // dummy terminator + }; + + const unsigned int NUM_OVERRIDE_VEHICLES = + sizeof( OVERRIDE_VEHICLE_NAMES ) / sizeof( OVERRIDE_VEHICLE_NAMES[ 0 ] ) - 1; + + const char* VEHICLES_DIR = "art\\cars\\"; + + int CGuiScreenPhoneBooth::s_currentDebugVehicleSelection = 0; + unsigned CGuiScreenPhoneBooth::s_currentTeleportSelection = 0; +#endif + +//=========================================================================== +// CGuiScreenPhoneBooth:: +//=========================================================================== + +//=========================================================================== +// CGuiScreenPhoneBooth::CGuiScreenPhoneBooth +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPhoneBooth::CGuiScreenPhoneBooth +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: IGuiScreenRewards( pScreen, + pScreen->GetPage( "PhoneBooth" ), + pParent, + GUI_SCREEN_ID_PHONE_BOOTH ), + m_damagedInfo( NULL ), + m_vehicleDamaged( NULL ), + m_repairCostInfo( NULL ), + m_vehicleRepairCost( NULL ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenPhoneBooth" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PhoneBooth" ); + rAssert( pPage != NULL ); + +#ifdef RAD_WIN32 + m_leftArrow = pPage->GetGroup( "Arrows" )->GetSprite( "LeftArrow" ); + m_rightArrow = pPage->GetGroup( "Arrows" )->GetSprite( "RightArrow" ); + m_leftArrow->ScaleAboutCenter( 1.3f ); + m_rightArrow->ScaleAboutCenter( 1.3f ); +#endif + + // get vehicle damaged info + // + m_damagedInfo = pPage->GetGroup( "DamagedInfo" ); + rAssert( m_damagedInfo != NULL ); + m_vehicleDamaged = m_damagedInfo->GetText( "VehicleDamaged_Value" ); + + m_repairCostInfo = m_damagedInfo->GetGroup( "RepairCostInfo" ); + rAssert( m_repairCostInfo != NULL ); + m_vehicleRepairCost = m_repairCostInfo->GetText( "CostToFix_Value" ); + + // always show vehicle stats + // + rAssert( m_statsOverlay != NULL ); + m_statsOverlay->SetVisible( true ); + +#ifdef PAL + // re-position damaged info text + // + const int DAMAGED_INFO_TRANSLATE_X = +60; + + m_vehicleDamaged->ResetTransformation(); + m_vehicleDamaged->Translate( DAMAGED_INFO_TRANSLATE_X, 0 ); + + m_vehicleRepairCost->ResetTransformation(); + m_vehicleRepairCost->Translate( DAMAGED_INFO_TRANSLATE_X, 0 ); + + Scrooby::Text* repairCostCoins = m_repairCostInfo->GetText( "Coins" ); + if( repairCostCoins != NULL ) + { + repairCostCoins->ResetTransformation(); + repairCostCoins->Translate( DAMAGED_INFO_TRANSLATE_X, 0 ); +#ifdef RAD_WIN32 + repairCostCoins->Translate( 70, 0 ); + repairCostCoins->ScaleAboutCenter( 0.5f ); +#endif + } + + // move stats over to the left a bit to avoid safe zone + // boundary clipping + // + m_statsOverlay->ResetTransformation(); + m_statsOverlay->Translate( -15, 0 ); + + // scale-down vehicle name a bit + // + m_previewName->ResetTransformation(); + m_previewName->ScaleAboutCenter( 0.9f ); +#endif // PAL + + // apply correction scale to spotlight + // + Scrooby::Sprite* spotLight = pPage->GetSprite( "Spotlight" ); + if( spotLight != NULL ) + { + spotLight->ResetTransformation(); + spotLight->ScaleAboutCenter( 4.0f ); + } + + // apply correction scale to spotlight overlay + // + spotLight = pPage->GetSprite( "Overlay" ); + if( spotLight != NULL ) + { + spotLight->ResetTransformation(); + spotLight->ScaleAboutCenter( 4.0f ); + } + + rAssert( m_pRewardsMenu != NULL ); + m_pRewardsMenu->SetHighlightColour( false, tColour( 255, 255, 255 ) ); + m_pRewardsMenu->Reset(); + + this->AutoScaleFrame( pPage ); + +#ifdef SRR2_OVERRIDE_CAR_SELECTION + pPage = m_pScroobyScreen->GetPage( "CarSelect" ); + if( pPage != NULL ) + { + m_carSelectOverlay = pPage->GetLayerByIndex( 0 ); + rAssert( m_carSelectOverlay ); + } + + // Create a menu. + // + m_pMenu = new CGuiMenu( this ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + m_pMenu->AddMenuItem( pPage->GetText( "Car" ), + pPage->GetText( "Car_Value" ) ); + + // clamp number of vehicle selections w/ only what's available + // + m_pMenu->SetSelectionValueCount( 0, NUM_OVERRIDE_VEHICLES ); + + // wrap vehicle names + // + Scrooby::Text* vehicleNames = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( 0 )->GetItemValue() ); + rAssert( vehicleNames != NULL ); + vehicleNames->SetTextMode( Scrooby::TEXT_WRAP ); + + m_menuTeleport = false; +#endif +MEMTRACK_POP_GROUP("CGUIScreenPhoneBooth"); +} + +//=========================================================================== +// CGuiScreenPhoneBooth::~CGuiScreenPhoneBooth +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPhoneBooth::~CGuiScreenPhoneBooth() +{ +#ifdef SRR2_OVERRIDE_CAR_SELECTION + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +#endif +} + +//=========================================================================== +// CGuiScreenPhoneBooth::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPhoneBooth::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_isLoading ) + { + if( message == GUI_MSG_CONTROLLER_SELECT || + message == GUI_MSG_CONTROLLER_BACK ) + { + // don't allow user to select or back out of screen + // during loading + // + return; + } + } + + rAssert( m_pRewardsMenu != NULL ); + if( m_pRewardsMenu->HasSelectionBeenMade() || m_isLoadingReward ) + { + if( this->IsControllerMessage( message ) ) + { + // selection has already been made or reward is currently loading, + // ignore all controller inputs + // + return; + } + } + +#ifdef SRR2_OVERRIDE_CAR_SELECTION + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( message == GUI_MSG_CONTROLLER_L1 || message == GUI_MSG_CONTROLLER_R1 ) + { +#ifdef FINAL + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) && + GetCharacterSheetManager()->QueryPercentGameCompleted() > 99.999f ) +#endif + { + rAssert( m_carSelectOverlay != NULL ); + + // toggle visibility of car selection overlay + // + m_carSelectOverlay->SetVisible( !m_carSelectOverlay->IsVisible() ); + + if( m_carSelectOverlay->IsVisible() ) + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + +// Teleportation menu disabled in final build +#ifndef FINAL + m_menuTeleport = (message == GUI_MSG_CONTROLLER_L1); +#endif + Scrooby::Text* menuLabel = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( 0 )->GetItem() ); + rAssert( menuLabel != NULL ); + + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + if( !m_menuTeleport ) + { + menuLabel->SetString( 0, "Vehicle:" ); + m_pMenu->SetSelectionValue( 0, s_currentDebugVehicleSelection ); + } + else + { + menuLabel->SetString( 0, "Teleport:" ); + m_pMenu->SetSelectionValue( 0, s_currentTeleportSelection ); + } + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + } + else + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, + this->GetCurrentPreviewObject()->isUnlocked ); + } + } + } + } + + if( m_carSelectOverlay->IsVisible() ) + { + this->HandleMessageForCar( message, param1, param2 ); + } + else +#endif + { + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject(); + + if( currentPreviewObject->isUnlocked ) + { + // check if selecting a damaged out vehicle; if so, reduce current bank + // value by repair cost amount + // + int carIndex = GetCharacterSheetManager()->GetCarIndex( currentPreviewObject->name ); + if( carIndex >= 0 ) + { + bool isVehicleDamagedOut = ( GetCharacterSheetManager()->GetCarDamageState( carIndex ) == eHusk ); + if( isVehicleDamagedOut ) + { + int repairCost = currentPreviewObject->pReward->GetRepairCost(); + + // TC: *** Joe says to always allow car repair, even if user + // doesn't quite have enough money +/* + if( GetCoinManager()->GetBankValue() < repairCost ) + { + // doh... not enough money in the bank to repair damaged vehicle + // + return; + } +*/ + GetCoinManager()->AdjustBankValue( -repairCost ); + + // trigger HUD event + // + GetEventManager()->TriggerEvent( EVENT_LOST_COINS ); + + //Chuck: Adding Record that the car has full hitpoints restored + GetCharacterSheetManager()->UpdateCarHealth(carIndex,1.0f); + } + } + + Character* pWalkerCharacter = GetCharacterManager()->GetCharacter( 0 ); + rWarning( pWalkerCharacter != NULL ); + + GetEventManager()->TriggerEvent( EVENT_PHONE_BOOTH_RIDE_REQUEST, reinterpret_cast<void*>( pWalkerCharacter ) ); + + bool isBonusVehicle = (m_previewVehicles[ m_currentPreviewVehicle ].pReward->GetQuestType() == Reward::eBonusMission); + if( isBonusVehicle ) + { + Character* pDriverCharacter = NULL; + + Vehicle* pCurrentVehicle = GetGameplayManager()->GetCurrentVehicle(); + rAssert( pCurrentVehicle != NULL ); + + bool isNewVehicle = ( strcmp( pCurrentVehicle->GetName(), currentPreviewObject->name ) != 0 ); + if( !isNewVehicle ) + { + // + // Re-requesting old vehicle. Send some dialogue if there's a driver. + // + pDriverCharacter = pCurrentVehicle->GetDriver(); + if( pDriverCharacter != NULL ) + { + GetEventManager()->TriggerEvent( EVENT_PHONE_BOOTH_OLD_VEHICLE_RESELECTED, pDriverCharacter ); + } + } + } + } + else + { + GetEventManager()->TriggerEvent( EVENT_FE_LOCKED_OUT ); + return; + } + + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + // load selected reward item + // + this->LoadSelectedReward(); + + break; + } + case GUI_MSG_CONTROLLER_LEFT: + { + m_currentPreviewVehicle = (m_currentPreviewVehicle - 1 + m_numPreviewVehicles) % m_numPreviewVehicles; + + this->On3DModelSelectionChange( &m_previewVehicles[ m_currentPreviewVehicle ] ); + this->UpdateDamagedInfo(); + + break; + } + case GUI_MSG_CONTROLLER_RIGHT: + { + m_currentPreviewVehicle = (m_currentPreviewVehicle + 1 + m_numPreviewVehicles) % m_numPreviewVehicles; + + this->On3DModelSelectionChange( &m_previewVehicles[ m_currentPreviewVehicle ] ); + this->UpdateDamagedInfo(); + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + IGuiScreenRewards::HandleMessage( message, param1, param2 ); + } +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiScreenPhoneBooth::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreenPhoneBooth::CheckCursorAgainstHotspots( float x, float y ) +{ + eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y ); + if( hotSpotType == HOTSPOT_NONE ) + { + if( m_leftArrow ) + { + if( m_leftArrow->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWLEFT; + } + } + if( m_rightArrow ) + { + if( m_rightArrow->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWRIGHT; + } + } + + } + return hotSpotType; +} +#endif + +//=========================================================================== +// CGuiScreenPhoneBooth::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPhoneBooth::InitIntro() +{ + IGuiScreenRewards::InitIntro(); + + // hide lock by default + // + rAssert( m_lockedOverlay != NULL ); + m_lockedOverlay->SetVisible( false ); + + // set level default vehicle as default garage vehicle selection + // + Reward* pDefaultCar = GetRewardsManager()->GetReward( GetGameplayManager()->GetCurrentLevelIndex(), + Reward::eDefaultCar ); + if( pDefaultCar != NULL ) + { + for( int i = 0; i < m_numPreviewVehicles; i++ ) + { + if( m_previewVehicles[ i ].pReward == pDefaultCar ) + { + m_currentPreviewVehicle = i; + + break; + } + } + } + + this->UpdateDamagedInfo(); + + // load current 3D model object + // + this->On3DModelSelectionChange( this->GetCurrentPreviewObject() ); + + // notify sound manager that game is paused + // + GetSoundManager()->OnStoreScreenStart(); +} + +//=========================================================================== +// CGuiScreenPhoneBooth::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPhoneBooth::InitRunning() +{ + IGuiScreenRewards::InitRunning(); + + CGuiScreenHud::UpdateNumCoinsDisplay( GetCoinManager()->GetBankValue() ); +} + +//=========================================================================== +// CGuiScreenPhoneBooth::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPhoneBooth::InitOutro() +{ + if( m_isLoadingReward ) + { + RelativeAnimatedCam::AllowSkipping( true ); + RelativeAnimatedCam::Reset(); + RelativeAnimatedCam::SetCamera( "phonecameraShape" ); + RelativeAnimatedCam::SetMulticontroller( "phonecamera" ); + tCameraAnimationController* camController = p3d::find< tCameraAnimationController >( "CAM_phonecameraShape" ); + + SuperCam* sc = GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( SuperCam::RELATIVE_ANIMATED_CAM ); + RelativeAnimatedCam* rac = dynamic_cast< RelativeAnimatedCam* >( sc ); + rac->SetCameraAnimationController( camController ); + GetSuperCamManager()->GetSCC( 0 )->SelectSuperCam( SuperCam::RELATIVE_ANIMATED_CAM ); + RelativeAnimatedCam::CheckPendingCameraSwitch(); + + GetMissionManager()->Update( 16 ); + GetSuperCamManager()->GetSCC( 0 )->NoTransition(); + GetSuperCamManager()->Update( 16, true ); + } + + CGuiScreenHud::UpdateNumCoinsDisplay( 0, false ); + + IGuiScreenRewards::InitOutro(); + + // notify sound manager that game is un-paused + // + GetSoundManager()->OnStoreScreenEnd(); +} + +void +CGuiScreenPhoneBooth::On3DModelLoaded( const PreviewObject* previewObject ) +{ + p3d::pddi->DrawSync(); + + rAssert( m_previewImage != NULL ); + m_previewImage->SetVisible( true ); + m_previewImage->ResetTransformation(); + + // apply alpha to locked vehicles + // + m_previewImage->SetAlpha( previewObject->isUnlocked ? 1.0f : VEHICLE_LOCKED_IMAGE_ALPHA ); + + CarDamageStateEnum damageState = eNull; + if( previewObject->isUnlocked ) + { + int carIndex = GetCharacterSheetManager()->GetCarIndex( previewObject->name ); + if( carIndex >= 0 ) + { + damageState = GetCharacterSheetManager()->GetCarDamageState( carIndex ); + } + } + + if( damageState == eHusk ) + { + m_previewImage->ScaleAboutCenter( HUSK_CORRECTION_SCALE ); + + // show generic husk + // + m_previewImage->SetRawSprite( NULL, true ); + } + else + { + // search for 2D image(s) in inventory + // + char name[ 16 ]; + + if( damageState == eDamaged ) + { + // show damaged vehicle + // +#ifdef LOAD_DAMAGED_VEHICLE_IMAGES + sprintf( name, "%sD.png", previewObject->nameModel ); + m_previewImage->ScaleAboutCenter( VEHICLE_DAMAGED_CORRECTION_SCALE ); +#else + sprintf( name, "%s.png", previewObject->nameModel ); + m_previewImage->ScaleAboutCenter( VEHICLE_CORRECTION_SCALE ); +#endif + } + else + { + // show normal vehicle + // + sprintf( name, "%s.png", previewObject->nameModel ); + + m_previewImage->ScaleAboutCenter( VEHICLE_CORRECTION_SCALE ); + } + + tSprite* pSprite = p3d::find<tSprite>( name ); + if( pSprite != NULL ) + { + m_previewImage->SetRawSprite( pSprite, true ); + } + else + { + rAssertMsg( false, "*** Can't find 2D vehicle image!!" ); + } + } +} + +const PreviewObject* +CGuiScreenPhoneBooth::GetCurrentPreviewObject() const +{ + const PreviewObject* previewObject = NULL; + + if( m_numPreviewVehicles > 0 ) + { + previewObject = &m_previewVehicles[ m_currentPreviewVehicle ]; + } + + return previewObject; +} + +void +CGuiScreenPhoneBooth::InitMenu() +{ + const int highestLevelPlayed = GetCharacterSheetManager()->QueryHighestMission().mLevel; + + for( int i = 0; i <= highestLevelPlayed; i++ ) + { + Reward* pReward = NULL; + + for( int j = (Reward::eBlank + 1); j < Reward::NUM_QUESTS; j++ ) + { + pReward = GetRewardsManager()->GetReward( i, (Reward::eQuestType)j ); + if( pReward != NULL && + pReward->GetRewardType() == Reward::ALT_PLAYERCAR ) + { + rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES - 1 ); + m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles, + m_numPreviewVehicles, + pReward, + true ); + } + } + + for( pReward = GetRewardsManager()->FindFirstMerchandise( i, Merchandise::SELLER_SIMPSON ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( i, Merchandise::SELLER_SIMPSON ) ) + { + rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES - 1 ); + m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles, + m_numPreviewVehicles, + pReward, + true ); + } + + for( pReward = GetRewardsManager()->FindFirstMerchandise( i, Merchandise::SELLER_GIL ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( i, Merchandise::SELLER_GIL ) ) + { + rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES - 1 ); + m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles, + m_numPreviewVehicles, + pReward, + true ); + } + } + + rAssertMsg( m_numPreviewVehicles > 0, "No vehicle selections!" ); + + // apply cheats, if enabled + // + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) ) + { + for( int i = 0; i < m_numPreviewVehicles; i++ ) + { + m_previewVehicles[ i ].isUnlocked = true; + } + } +} + +void CGuiScreenPhoneBooth::OnUpdate( unsigned int elapsedTime ) +{ + IGuiScreenRewards::OnUpdate( elapsedTime ); +} + +void +CGuiScreenPhoneBooth::LoadSelectedReward() +{ + // unload 3D model first before loading reward + // + this->Unload3DModel(); + + m_isLoading = true; // set loading flag + m_isLoadingReward = true; // we're loading the selected reward + + const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject(); + + VehicleCentral::DriverInit driverInit = VehicleCentral::ALLOW_DRIVER; + ActionButton::SummonVehiclePhone::LoadVehicle( currentPreviewObject->name, + currentPreviewObject->filename, + driverInit ); +} + +void +CGuiScreenPhoneBooth::UpdateDamagedInfo() +{ + if( this->GetCurrentPreviewObject()->isUnlocked ) + { + m_damagedInfo->SetVisible( true ); + + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + Reward* pReward = this->GetCurrentPreviewObject()->pReward; + rAssert( pReward != NULL ); + + char buffer[ 16 ]; + + int carIndex = GetCharacterSheetManager()->GetCarIndex( pReward->GetName() ); + if( carIndex != -1 ) + { + float damagedAmount = 1.0f - GetCharacterSheetManager()->GetCarHealth( carIndex ); + if( damagedAmount >= 0.0f && damagedAmount <= 1.0f ) + { + sprintf( buffer, "%.0f %%", damagedAmount * 100 ); + rAssert( m_vehicleDamaged != NULL ); + m_vehicleDamaged->SetString( 0, buffer ); + } + else + { + rAssertMsg( false, "Why is the damage amount not between 0 and 1??" ); + } + + rAssert( m_repairCostInfo != NULL ); + m_repairCostInfo->SetVisible( damagedAmount == 1.0f ); + + sprintf( buffer, "%d", pReward->GetRepairCost() ); + rAssert( m_vehicleRepairCost != NULL ); + m_vehicleRepairCost->SetString( 0, buffer ); + } + else + { + rAssertMsg( false, "Why is the car index -1??" ); + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + } + else + { + m_damagedInfo->SetVisible( false ); + } +} + +#ifdef SRR2_OVERRIDE_CAR_SELECTION + +void +CGuiScreenPhoneBooth::HandleMessageForCar( eGuiMessage message, + unsigned int param1, + unsigned int param2 ) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_MENU_SELECTION_MADE: + { + rAssert( param1 == 0 ); + + if( m_menuTeleport ) + { + if( s_currentTeleportSelection >= 0 && + s_currentTeleportSelection < CharacterManager::GetNumTeleportDests() ) + { + CharacterManager::Teleport(s_currentTeleportSelection ); + + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); + } + else + { + rAssertMsg( 0, "WARNING: *** Invalid teleport destination selection!" ); + } + } + else + { + if( s_currentDebugVehicleSelection >= 0 && + s_currentDebugVehicleSelection < static_cast<int>( NUM_OVERRIDE_VEHICLES ) ) + { + char vehicleFileName[ 32 ]; + sprintf( vehicleFileName, "%s%s.p3d", + VEHICLES_DIR, + OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ] ); + + ActionButton::SummonVehiclePhone::CarSelectionInfo* pInfo = + ActionButton::SummonVehiclePhone::GetDebugCarSelectInfo(); + + rAssert( pInfo ); + pInfo->AddDebugVehicleSelectionInfo( vehicleFileName, + OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ], + "" ); + + this->Unload3DModel(); // unload 3D model first + + ActionButton::SummonVehiclePhone::LoadDebugVehicle(); + + m_state = GUI_WINDOW_STATE_IDLE; + } + else + { + rAssertMsg( 0, "WARNING: *** Invalid vehicle selection!" ); + } + } + + break; + } + case GUI_MSG_MENU_SELECTION_VALUE_CHANGED: + { + rAssert( param1 == 0 ); + + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + Scrooby::Text* vehicleNames = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( 0 )->GetItemValue() ); + rAssert( vehicleNames != NULL ); + + if( m_menuTeleport ) + { + s_currentTeleportSelection = static_cast<int>( param2 ); + + if( s_currentTeleportSelection == 99 ) + { + s_currentTeleportSelection = CharacterManager::GetNumTeleportDests() - 1; + m_pMenu->SetSelectionValue( 0, s_currentTeleportSelection); + } + + if( s_currentTeleportSelection >= CharacterManager::GetNumTeleportDests() ) + { + s_currentTeleportSelection = 0; + m_pMenu->SetSelectionValue( 0, s_currentTeleportSelection); + } + + vehicleNames->SetString( s_currentTeleportSelection, CharacterManager::GetTeleportDest(s_currentTeleportSelection) ); + } + else + { + s_currentDebugVehicleSelection = static_cast<int>( param2 ); + + if( param2 < NUM_OVERRIDE_VEHICLES ) + { + char textBibleEntry[ 16 ]; + strcpy( textBibleEntry, OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ] ); + UnicodeChar* textBibleString = GetTextBibleString( strupr( textBibleEntry ) ); + UnicodeString unicodeString; + if( textBibleString != NULL ) + { + unicodeString.ReadUnicode( textBibleString ); + } + else + { + unicodeString.ReadAscii( OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ] ); + } + + vehicleNames->SetString( s_currentDebugVehicleSelection, unicodeString ); + } + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + + break; + } + default: + { + break; + } + } + + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + } + + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +#endif + diff --git a/game/code/presentation/gui/ingame/guiscreenphonebooth.h b/game/code/presentation/gui/ingame/guiscreenphonebooth.h new file mode 100644 index 0000000..c37fd57 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenphonebooth.h @@ -0,0 +1,94 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPhoneBooth +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPHONEBOOTH_H +#define GUISCREENPHONEBOOTH_H + +#ifndef RAD_E3 + // enable car selection overlay for selecting any car + // + #define SRR2_OVERRIDE_CAR_SELECTION +#endif + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenrewards.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPhoneBooth : public IGuiScreenRewards +{ +public: + CGuiScreenPhoneBooth( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPhoneBooth(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +#ifdef RAD_WIN32 + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); +#endif + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + virtual void On3DModelLoaded( const PreviewObject* previewObject ); + virtual const PreviewObject* GetCurrentPreviewObject() const; + virtual void InitMenu(); + +private: + virtual void OnUpdate( unsigned int elapsedTime ); + void LoadSelectedReward(); + void UpdateDamagedInfo(); + + Scrooby::Group* m_damagedInfo; + Scrooby::Text* m_vehicleDamaged; + Scrooby::Group* m_repairCostInfo; + Scrooby::Text* m_vehicleRepairCost; + +#ifdef RAD_WIN32 + Scrooby::Sprite* m_leftArrow; + Scrooby::Sprite* m_rightArrow; +#endif + +#ifdef SRR2_OVERRIDE_CAR_SELECTION + void HandleMessageForCar( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + CGuiMenu* m_pMenu; + Scrooby::Layer* m_carSelectOverlay; + bool m_menuTeleport; + + static int s_currentDebugVehicleSelection; + static unsigned s_currentTeleportSelection; +#endif + +}; + +#endif // GUISCREENPHONEBOOTH_H diff --git a/game/code/presentation/gui/ingame/guiscreenpurchaserewards.cpp b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.cpp new file mode 100644 index 0000000..ccec82a --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.cpp @@ -0,0 +1,1078 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPurchaseRewards +// +// Description: Implementation of the CGuiScreenPurchaseRewards class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenpurchaserewards.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/ingame/hudevents/hudcoincollected.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> + +#include <ai/actionbuttonhandler.h> +#include <cheats/cheatinputsystem.h> +#include <mission/gameplaymanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/rewards/reward.h> +#include <sound/soundmanager.h> + +#include <worldsim/character/charactermanager.h> +#include <worldsim/character/character.h> +#include <worldsim/coins/coinmanager.h> + +#include <p3d/anim/animate.hpp> +#include <p3d/anim/poseanimation.hpp> +#include <p3d/anim/skeleton.hpp> +#include <raddebug.hpp> // Foundation + +// Scrooby Header Files +// +#include <screen.h> +#include <page.h> +#include <group.h> +#include <sprite.h> +#include <pure3dobject.h> + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float PREVIEW_CHARACTER_SCALE = 2.0f; +const float PREVIEW_PEDESTAL_SCALE_FOR_SKINS = 0.75f; + +const float PREVIEW_VEHICLE_RADIUS = 3.6f; + +const tUID CHARACTER_NAME_HOMER = tEntity::MakeUID( "homer" ); +const tUID CHARACTER_NAME_BART = tEntity::MakeUID( "bart" ); +const tUID CHARACTER_NAME_LISA = tEntity::MakeUID( "lisa" ); +const tUID CHARACTER_NAME_MARGE = tEntity::MakeUID( "marge" ); +const tUID CHARACTER_NAME_APU = tEntity::MakeUID( "apu" ); + +const char* PURCHASE_REWARDS_INVENTORY_SECTION = "FE_PurchaseRewardsScreen"; +const char* PURCHASE_REWARDS_BGD = "art\\frontend\\scrooby\\resource\\pure3d\\rewardbg.p3d"; +const char* PURCHASE_REWARDS_BGD_DRAWABLE = "Pedestal_Scenegraph"; +const char* PURCHASE_REWARDS_BGD_CAMERA = "Pedestal_Camera"; +const char* PURCHASE_REWARDS_BGD_MULTICONTROLLER = "Pedestal_MasterController"; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenPurchaseRewards::CGuiScreenPurchaseRewards +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPurchaseRewards::CGuiScreenPurchaseRewards +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: IGuiScreenRewards( pScreen, + pScreen->GetPage( "Rewards" ), + pParent, + GUI_SCREEN_ID_PURCHASE_REWARDS ), + m_currentType( Merchandise::INVALID_SELLER_TYPE ), + m_isPurchasingReward( false ), + m_elapsedCoinDecrementTotalTime( 0 ), + m_elapsedCoinDecrementTime( 0 ), + m_bankValueBeforePurchase( 0 ), + m_purchaseLabel( NULL ), + m_skinMultiController( NULL ), + m_skinAnimController( NULL ) +{ + this->SetFadingEnabled( false ); + this->SetIrisWipeEnabled( true ); + + // Retrieve the Scrooby drawing elements (from Rewards page). + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Rewards" ); + rAssert( pPage != NULL ); + +#ifdef RAD_WIN32 + m_leftArrow = pPage->GetGroup( "Arrows" )->GetSprite( "LeftArrow" ); + m_rightArrow = pPage->GetGroup( "Arrows" )->GetSprite( "RightArrow" ); + m_leftArrow->ScaleAboutCenter( 1.3f ); + m_rightArrow->ScaleAboutCenter( 1.3f ); +#endif + + // Retrieve the Scrooby drawing elements (from Coins page). + // + pPage = m_pScroobyScreen->GetPage( "Coins" ); + rAssert( pPage != NULL ); + CGuiScreenHud::SetNumCoinsDisplay( pPage->GetSprite( "NumCoins" ) ); + +// m_numCoins.SetScroobyText( pPage->GetGroup( "NumCoins" ), "NumCoins" ); + + // get purchase button label + // + rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL ); + m_purchaseLabel = m_buttonIcons[ BUTTON_ICON_ACCEPT ]->GetText( "Accept" ); + rAssert( m_purchaseLabel != NULL ); +/* + pPage = m_pScroobyScreen->GetPage( "Buy" ); + if( pPage != NULL ) + { + m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "AcceptLabel" ); + rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL ); + + m_purchaseLabel = m_buttonIcons[ BUTTON_ICON_ACCEPT ]->GetText( "Accept" ); + rAssert( m_purchaseLabel != NULL ); + } +*/ + + // create and setup controllers for character animations + // + m_skinMultiController = new tMultiController( 1, 90.0f ); + rAssert( m_skinMultiController != NULL ); + m_skinMultiController->AddRef(); + m_skinMultiController->SetFramerate( 30.0f ); + + m_skinAnimController = new tPoseAnimationController; + rAssert( m_skinAnimController != NULL ); + m_skinAnimController->AddRef(); + m_skinMultiController->SetTrack( 0, m_skinAnimController ); + + m_skinTrackInfo.startTime = 0.0f; + m_skinTrackInfo.endTime = 0.0f; + m_skinTrackInfo.offset = 0.0f; + m_skinTrackInfo.scale = 1.0f; + m_skinMultiController->SetTrackInfo( 0, &m_skinTrackInfo ); + + rAssert( m_previewWindow != NULL ); + m_previewWindow->SetMultiController( m_skinMultiController ); + + p3d::inventory->AddSection( PURCHASE_REWARDS_INVENTORY_SECTION ); +} + + +//=========================================================================== +// CGuiScreenPurchaseRewards::~CGuiScreenPurchaseRewards +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenPurchaseRewards::~CGuiScreenPurchaseRewards() +{ + p3d::pddi->DrawSync(); + + p3d::inventory->DeleteSection( PURCHASE_REWARDS_INVENTORY_SECTION ); + + if( m_skinAnimController != NULL ) + { + m_skinAnimController->Release(); + m_skinAnimController = NULL; + } + + if( m_skinMultiController != NULL ) + { + m_skinMultiController->Release(); + m_skinMultiController = NULL; + } +} + + +//=========================================================================== +// CGuiScreenPurchaseRewards::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== + +void CGuiScreenPurchaseRewards::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_WINDOW_ENTER ) + { + // set current purchase center type + // + m_currentType = static_cast<Merchandise::eSellerType>( param1 ); + rAssert( m_currentType != Merchandise::INVALID_SELLER_TYPE ); + } + + if( m_isLoading ) + { + if( message == GUI_MSG_CONTROLLER_SELECT || + message == GUI_MSG_CONTROLLER_BACK ) + { + // don't allow user to select or back out of screen + // during loading + // + return; + } + } + + rAssert( m_pRewardsMenu != NULL ); + if( m_pRewardsMenu->HasSelectionBeenMade() || m_isLoadingReward || m_isPurchasingReward ) + { + if( this->IsControllerMessage( message ) ) + { + // selection has already been made or reward is currently loading, + // ignore all controller inputs + // + return; + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + int selectionDelta = 0; + + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + if( !this->IsButtonVisible( BUTTON_ICON_ACCEPT ) ) + { + // not enough coins to purchase reward + // + GetEventManager()->TriggerEvent( EVENT_FE_LOCKED_OUT ); + + return; + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + if( !m_pRewardsMenu->HasSelectionBeenMade() ) + { + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); + + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); + } + + break; + } + case GUI_MSG_MENU_SELECTION_MADE: + { + // load selected reward item + // + this->PurchaseReward(); + + break; + } + case GUI_MSG_CONTROLLER_LEFT: + { + selectionDelta = -2; + + // follow-thru + // + } + case GUI_MSG_CONTROLLER_RIGHT: + { + selectionDelta++; + + int previousSelection = 0; + + if( m_currentType == Merchandise::SELLER_INTERIOR ) + { + if( m_numPreviewClothing > 1 ) + { + previousSelection = m_currentPreviewClothing; + + m_currentPreviewClothing = (m_currentPreviewClothing + m_numPreviewClothing + selectionDelta) % m_numPreviewClothing; + + this->On3DModelSelectionChange( &m_previewClothing[ m_currentPreviewClothing ] ); + } + } + else + { + if( m_numPreviewVehicles > 1 ) + { + previousSelection = m_currentPreviewVehicle; + + m_currentPreviewVehicle = (m_currentPreviewVehicle + m_numPreviewVehicles + selectionDelta) % m_numPreviewVehicles; + + this->On3DModelSelectionChange( &m_previewVehicles[ m_currentPreviewVehicle ] ); + } + } + + this->UpdateRewardPrice(); + + break; + } + default: + { + break; + } + } + } + else if( m_state == GUI_WINDOW_STATE_INTRO ) + { + if( message == GUI_MSG_UPDATE ) + { + if( m_numTransitionsPending == 1 && m_currentIrisState == IRIS_STATE_CLOSED ) + { + // resume iris wipe + // + this->IrisWipeOpen(); + + // show the preview pedestal + // + rAssert( m_previewPedestal != NULL ); + m_previewPedestal->SetVisible( true ); + rAssert( m_previewBgd != NULL ); + m_previewBgd->SetVisible( true ); + } + } + } + else if( m_state == GUI_WINDOW_STATE_OUTRO ) + { + if( message == GUI_MSG_UPDATE ) + { + if( m_numTransitionsPending == 1 && m_currentIrisState == IRIS_STATE_CLOSED ) + { + // resume iris wipe + // + this->IrisWipeOpen(); + + p3d::pddi->DrawSync(); + + // hide the preview pedestal + // + rAssert( m_previewPedestal != NULL ); + m_previewPedestal->SetVisible( false ); + rAssert( m_previewBgd != NULL ); + m_previewBgd->SetVisible( false ); + + m_previewBgd->SetDrawable( NULL ); + m_previewBgd->SetCamera( NULL ); + m_previewBgd->SetMultiController( NULL ); + + p3d::inventory->RemoveSectionElements( PURCHASE_REWARDS_INVENTORY_SECTION ); + } + } + } + + // Propogate the message up the hierarchy. + // + IGuiScreenRewards::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenPurchaseRewards::OnProcessRequestsComplete( void* pUserData ) +{ + if( reinterpret_cast<Scrooby::Pure3dObject*>( pUserData ) == m_previewBgd ) + { + m_numTransitionsPending--; + + // push and select inventory section for searching + // + p3d::inventory->PushSection(); + p3d::inventory->SelectSection( PURCHASE_REWARDS_INVENTORY_SECTION ); + bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly(); + p3d::inventory->SetCurrentSectionOnly( true ); + + // search for pedestal drawable + // + tDrawable* drawable = p3d::find<tDrawable>( PURCHASE_REWARDS_BGD_DRAWABLE ); + if( drawable != NULL ) + { + rAssert( m_previewBgd != NULL ); + m_previewBgd->SetDrawable( drawable ); + + tCamera* camera = p3d::find<tCamera>( PURCHASE_REWARDS_BGD_CAMERA ); + rAssert( camera != NULL ); + m_previewBgd->SetCamera( camera ); + m_previewPedestal->SetCamera( camera ); + m_previewWindow->SetCamera( camera ); + + tMultiController* multiController = p3d::find<tMultiController>( PURCHASE_REWARDS_BGD_MULTICONTROLLER ); + m_previewBgd->SetMultiController( multiController ); + } + else + { + rAssertMsg( false, "*** Can't find 3D pedestal drawable!" ); + } + + // pop inventory section and restore states + // + p3d::inventory->SetCurrentSectionOnly( currentSectionOnly ); + p3d::inventory->PopSection(); + } + else if( m_isLoadingReward ) + { + // this means we were waiting for the selected character skin to load; + // so, now that it's loaded, let's exit outa here + // + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); + } + else + { + IGuiScreenRewards::OnProcessRequestsComplete( pUserData ); + } +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiScreenPurchaseRewards::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreenPurchaseRewards::CheckCursorAgainstHotspots( float x, float y ) +{ + eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y ); + if( hotSpotType == HOTSPOT_NONE ) + { + if( m_leftArrow ) + { + if( m_leftArrow->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWLEFT; + } + } + if( m_rightArrow ) + { + if( m_rightArrow->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWRIGHT; + } + } + + } + return hotSpotType; +} +#endif + +//=========================================================================== +// CGuiScreenPurchaseRewards::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPurchaseRewards::InitIntro() +{ + // load 3D pedestal + // + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + PURCHASE_REWARDS_BGD, + GMA_LEVEL_MISSION, + PURCHASE_REWARDS_INVENTORY_SECTION, + PURCHASE_REWARDS_INVENTORY_SECTION, + this, + reinterpret_cast<void*>( m_previewBgd ) ); + m_numTransitionsPending++; + + IGuiScreenRewards::InitIntro(); + + // load current 3D model object + // + this->On3DModelSelectionChange( this->GetCurrentPreviewObject() ); + + // show and update reward price + // + rAssert( m_rewardPrice != NULL ); + m_rewardPrice->SetVisible( true ); + this->UpdateRewardPrice(); + + // show/hide stats button label + // + rAssert( m_statsOverlayButton ); + m_statsOverlayButton->SetVisible( m_currentType != Merchandise::SELLER_INTERIOR ); + + // hide vehicle stats by default + // + this->SetVehicleStatsVisible( false ); + + // adjust pedestal scale + // + rAssert( m_previewPedestal != NULL ); + if( m_currentType == Merchandise::SELLER_INTERIOR ) + { + // scale down pedestal a bit + // + m_previewPedestal->SetDrawableScale( PREVIEW_PEDESTAL_SCALE_FOR_SKINS ); + + // notify sound manager that game is paused, include dialogue in + // ducking to kill gag sounds -- Esan + // + GetSoundManager()->DuckEverythingButMusicBegin( true ); + } + else + { + m_previewPedestal->SetDrawableScale( 1.0f ); + + // notify sound manager that game is paused, don't duck dialogue + // so we can still hear ol' Gil -- Esan + // + GetSoundManager()->OnStoreScreenStart( true ); + } + + // enable/disable L/R arrows + // + if( m_numPreviewClothing > 1 || m_numPreviewVehicles > 1 ) + { + m_pRewardsMenu->SetSelectionValueCount( 0, 2 ); + } + else + { + m_pRewardsMenu->SetSelectionValueCount( 0, 1 ); + } + + m_bankValueBeforePurchase = GetCoinManager()->GetBankValue(); +} + +//=========================================================================== +// CGuiScreenPurchaseRewards::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPurchaseRewards::InitRunning() +{ + IGuiScreenRewards::InitRunning(); + + CGuiScreenHud::UpdateNumCoinsDisplay( m_bankValueBeforePurchase ); +} + +//=========================================================================== +// CGuiScreenPurchaseRewards::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenPurchaseRewards::InitOutro() +{ + // hide 3D coin on FE render layer + // + CGuiScreenHud::UpdateNumCoinsDisplay( 0, false ); + + IGuiScreenRewards::InitOutro(); + + if( m_currentType == Merchandise::SELLER_INTERIOR ) + { + // notify sound manager that game is paused + // + GetSoundManager()->DuckEverythingButMusicEnd( true ); + } + else + { + GetSoundManager()->OnStoreScreenEnd(); + } +} + +void +CGuiScreenPurchaseRewards::On3DModelLoaded( const PreviewObject* previewObject ) +{ + p3d::pddi->DrawSync(); + + // search for 3D model in inventory + // + tDrawable* drawable = p3d::find<tDrawable>( previewObject->nameModel ); + if( drawable != NULL ) + { + rAssert( m_previewWindow != NULL ); + m_previewWindow->SetDrawable( drawable ); + + if( m_currentType != Merchandise::SELLER_INTERIOR ) + { + // place vehicles (w/ wheels) on the ground (y = 0) + // + rmt::Box3D box3D; + drawable->GetBoundingBox( &box3D ); + float groundOffset = box3D.low.y; + m_previewWindow->SetDrawableTranslation( 0.0f, -groundOffset, 0.0f ); + + // scale vehicles so that they fit nicely on pedestal + // + rmt::Sphere sphere; + drawable->GetBoundingSphere( &sphere ); + m_previewWindow->SetDrawableScale( PREVIEW_VEHICLE_RADIUS / sphere.radius ); + } + else + { + // assume characters are already placed on ground (y = 0) + // + m_previewWindow->SetDrawableTranslation( 0.0f, 0.0f, 0.0f ); + + // scale characters larger to fill the screen + // + m_previewWindow->SetDrawableScale( PREVIEW_CHARACTER_SCALE ); + + // set character animation + // + HeapMgr()->PushHeap( GMA_LEVEL_MISSION ); + tDrawablePose *drawable_pose = dynamic_cast<tDrawablePose *>(drawable); + rAssert( drawable_pose != NULL ); + + m_skinAnimController->SetPose( drawable_pose->GetPose() ); + + p3d::inventory->SetCurrentSectionOnly( false ); + char anim_name[32]; + switch(GetGameplayManager()->GetCurrentLevelIndex()) + { + case 0: + case 6: + strcpy(anim_name,"hom"); + break; + case 1: + case 5: + strcpy(anim_name,"brt"); + break; + case 2: + strcpy(anim_name,"lsa"); + break; + case 3: + strcpy(anim_name,"mrg"); + break; + case 4: + strcpy(anim_name,"apu"); + break; + default: + strcpy( anim_name,"hom" ); + break; + } + strcat(anim_name, "_loco_idle_rest"); + tAnimation* anim = p3d::find<tAnimation>( anim_name ); + rAssert( anim != NULL ); + anim->SetCyclic( true ); + + rAssert( m_skinAnimController != NULL ); + m_skinAnimController->SetAnimation( anim, 0.0f, 0.0f ); + + m_skinTrackInfo.endTime = anim->GetNumFrames(); + + rAssert( m_skinMultiController != NULL ); + m_skinMultiController->Reset(); + m_skinMultiController->SetFrame( 0.0f ); + m_skinMultiController->SetTrackInfo( 0, &m_skinTrackInfo ); + + HeapMgr()->PopHeap( GMA_LEVEL_MISSION ); + + } + } + else + { + rAssertMsg( false, "*** Can't find drawable for 3D model!!" ); + } +} + +const PreviewObject* +CGuiScreenPurchaseRewards::GetCurrentPreviewObject() const +{ + const PreviewObject* previewObject = NULL; + + switch( m_currentType ) + { + case Merchandise::SELLER_INTERIOR: + { + if( m_numPreviewClothing > 0 ) + { + previewObject = &m_previewClothing[ m_currentPreviewClothing ]; + } + + break; + } + case Merchandise::SELLER_SIMPSON: + case Merchandise::SELLER_GIL: + { + if( m_numPreviewVehicles > 0 ) + { + previewObject = &m_previewVehicles[ m_currentPreviewVehicle ]; + } + + break; + } + default: + { + rAssert( false ); + break; + } + } + + return previewObject; +} + +void +CGuiScreenPurchaseRewards::InitMenu() +{ + int currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + Reward* pReward = NULL; + + m_numPreviewClothing = 0; + m_numPreviewVehicles = 0; + + switch( m_currentType ) + { + case Merchandise::SELLER_INTERIOR: + { + Character* currentCharacter = GetCharacterManager()->GetCharacter( 0 ); + rAssert( currentCharacter != NULL ); + const char* currentSkinName = GetCharacterManager()->GetModelName( currentCharacter ); + + // insert default character skin first + // + pReward = GetRewardsManager()->GetReward( currentLevel, Reward::eDefaultSkin ); + if( pReward != NULL ) + { + if( strcmp( currentSkinName, pReward->GetName() ) != 0 ) + { + m_numPreviewClothing = this->InsertPreviewObject( m_previewClothing, + m_numPreviewClothing, + pReward ); + } + } + + // insert all other purchasable skins + // + for( pReward = GetRewardsManager()->FindFirstMerchandise( currentLevel, m_currentType ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( currentLevel, m_currentType ) ) + { + if( strcmp( currentSkinName, pReward->GetName() ) != 0 ) + { + rAssert( m_numPreviewClothing < MAX_NUM_PREVIEW_CLOTHING ); + m_numPreviewClothing = this->InsertPreviewObject( m_previewClothing, + m_numPreviewClothing, + pReward ); + } + } + + if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_SKINS ) ) + { + for( int i = 0; i < m_numPreviewClothing; i++ ) + { + m_previewClothing[ i ].isUnlocked = true; + } + } + + break; + } + case Merchandise::SELLER_SIMPSON: + case Merchandise::SELLER_GIL: + { + for( pReward = GetRewardsManager()->FindFirstMerchandise( currentLevel, m_currentType ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( currentLevel, m_currentType ) ) + { + // only display locked rewards + // + if( !pReward->RewardStatus() ) + { + rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES ); + m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles, + m_numPreviewVehicles, + pReward, + true ); + } + } + + break; + } + default: + { + rAssert( false ); + break; + } + } +} + +void +CGuiScreenPurchaseRewards::OnUpdate( unsigned int elapsedTime ) +{ +/* + // always show accept button + // + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); +*/ +/* + // rotate reward object + // + const unsigned int ROTATION_PERIOD = 3000; + + m_elapsedRotationTime = (m_elapsedRotationTime + elapsedTime) % ROTATION_PERIOD; + + rAssert( m_previewWindow != NULL ); + m_previewWindow->ResetTransformation(); + + float rotation = (m_elapsedRotationTime / (float)ROTATION_PERIOD) * 360.0f; + m_previewWindow->RotateAboutCenter( rotation, + rmt::Vector( 0.0f, 1.0f, 0.0f ) ); +*/ + if( m_isPurchasingReward ) + { + const unsigned int COINS_DECREMENT_DURATION = 1000; // in msec + const unsigned int COINS_DECREMENT_PERIOD = 100; // in msec + + m_elapsedCoinDecrementTotalTime += elapsedTime; + if( m_elapsedCoinDecrementTotalTime < COINS_DECREMENT_DURATION ) + { + m_elapsedCoinDecrementTime += elapsedTime; + if( m_elapsedCoinDecrementTime > COINS_DECREMENT_PERIOD ) + { + int deltaCoins = m_bankValueBeforePurchase - GetCoinManager()->GetBankValue(); + int bankValue = m_bankValueBeforePurchase - (int)( m_elapsedCoinDecrementTotalTime / (float)COINS_DECREMENT_DURATION * deltaCoins ); + + CGuiScreenHud::UpdateNumCoinsDisplay( bankValue ); + + GetCoinManager()->AddFlyDownCoin(); + + m_elapsedCoinDecrementTime %= COINS_DECREMENT_PERIOD; + } + } + else + { + CGuiScreenHud::UpdateNumCoinsDisplay( GetCoinManager()->GetBankValue() ); + + m_isPurchasingReward = false; + + // ok, we've reached the real current bank value; + // now load the purchased reward now + // + this->LoadSelectedReward(); +/* + if( m_currentType == Merchandise::SELLER_INTERIOR ) + { + this->LoadSelectedReward(); + } + else + { + // don't load vehicles, user must go to the phone + // booth to do that + // + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); + } +*/ + } + } + + IGuiScreenRewards::OnUpdate( elapsedTime ); +} + +void +CGuiScreenPurchaseRewards::UpdateRewardPrice() +{ + const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject(); + rAssert( currentPreviewObject != NULL ); + + if( currentPreviewObject->isUnlocked ) + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + } + else + { + Merchandise* pMerchandise = GetRewardsManager()->GetMerchandise( GetGameplayManager()->GetCurrentLevelIndex(), + currentPreviewObject->name ); + if( pMerchandise != NULL ) + { + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + int rewardCost = pMerchandise->GetCost(); + rAssertMsg( rewardCost > 0, "Reward price should be a positive integer!" ); + + // get "coins" text + // + char coinsText[ 32 ]; + p3d::UnicodeToAscii( GetTextBibleString( "COINS" ), coinsText, sizeof( coinsText ) ); + + char buffer[ 32 ]; +#ifdef PAL + if( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_GERMAN ) + { + // special case for German for proper grammar + // + sprintf( buffer, "Für %d %s", rewardCost, coinsText ); + } + else +#endif // PAL + { + sprintf( buffer, "%d %s", rewardCost, coinsText ); + } + + rAssert( strlen( buffer ) < sizeof( buffer ) ); + + rAssert( m_rewardPrice != NULL ); + m_rewardPrice->SetString( 0, buffer ); + + // only show accept label if user has enough money to purchase OR + // if reward is already unlocked + // + this->SetButtonVisible( BUTTON_ICON_ACCEPT, GetCoinManager()->GetBankValue() >= rewardCost ); + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + } + } + + // update purchase label + // + rAssert( m_purchaseLabel != NULL ); + m_purchaseLabel->SetIndex( currentPreviewObject->isUnlocked ? 1 : 0 ); +} + +void +CGuiScreenPurchaseRewards::PurchaseReward() +{ + const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject(); + rAssert( currentPreviewObject != NULL ); + + if( currentPreviewObject->isUnlocked ) + { + // reward is already unlocked, so just load it + // + this->LoadSelectedReward(); + } + else + { + bool boughtReward = GetRewardsManager()->BuyMerchandise( GetGameplayManager()->GetCurrentLevelIndex(), + currentPreviewObject->name ); + + if( boughtReward ) + { + // hide lock overlay + // + rAssert( m_lockedOverlay != NULL ); + m_lockedOverlay->SetVisible( false ); + + // update hud coins current item count + // + CGuiScreenHud* currentHud = GetCurrentHud(); + if( currentHud != NULL ) + { + HudCoinCollected* hudCoinCollected = static_cast<HudCoinCollected*>( currentHud->GetEventHandler( CGuiScreenHud::HUD_EVENT_HANDLER_COIN_COLLECTED ) ); + rAssert( hudCoinCollected != NULL ); + hudCoinCollected->SetCurrentItemCount( GetCoinManager()->GetBankValue() ); + hudCoinCollected->Start(); + } + + m_isPurchasingReward = true; + m_elapsedCoinDecrementTotalTime = 0; + m_elapsedCoinDecrementTime = 0; + } + else + { + rAssertMsg( false, "This should not happen!" ); + } + } +} + +void +CGuiScreenPurchaseRewards::LoadSelectedReward() +{ + // unload 3D model first before loading reward + // + this->Unload3DModel(); + + m_isLoading = true; // set loading flag + m_isLoadingReward = true; // we're loading the selected reward + + if( m_currentType == Merchandise::SELLER_INTERIOR ) + { + Character* currentCharacter = GetCharacterManager()->GetCharacter( 0 ); + + char characterName[ 16 ]; + tUID characterUID = currentCharacter->GetUID(); + + if( characterUID == CHARACTER_NAME_HOMER ) + { + strcpy( characterName, "homer" ); + } + else if( characterUID == CHARACTER_NAME_BART ) + { + strcpy( characterName, "bart" ); + } + else if( characterUID == CHARACTER_NAME_LISA ) + { + strcpy( characterName, "lisa" ); + } + else if( characterUID == CHARACTER_NAME_MARGE ) + { + strcpy( characterName, "marge" ); + } + else if( characterUID == CHARACTER_NAME_APU ) + { + strcpy( characterName, "apu" ); + } + else + { + rAssert( false ); + } + + GetCharacterManager()->SwapData( currentCharacter, + m_previewClothing[ m_currentPreviewClothing ].name, + characterName ); + + //Chuck: Save the skin they are buy/changing into as the current skin + GetCharacterSheetManager()->SetCurrentSkin(GetGameplayManager()->GetCurrentLevelIndex(),m_previewClothing[ m_currentPreviewClothing ].name); + + GetCharacterManager()->PreloadCharacter( m_previewClothing[ m_currentPreviewClothing ].name, + characterName, + this ); + + //for the HitnRun system + GetEventManager()->TriggerEvent( EVENT_SWITCH_SKIN, NULL ); + + } + else + { + ActionButton::SummonVehiclePhone::LoadVehicle( m_previewVehicles[ m_currentPreviewVehicle ].name, + m_previewVehicles[ m_currentPreviewVehicle ].filename, + VehicleCentral::ALLOW_DRIVER ); + } +} + diff --git a/game/code/presentation/gui/ingame/guiscreenpurchaserewards.h b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.h new file mode 100644 index 0000000..6b972ca --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.h @@ -0,0 +1,87 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenPurchaseRewards +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENPURCHASEREWARDS_H +#define GUISCREENPURCHASEREWARDS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenrewards.h> +#include <mission/rewards/merchandise.h> +#include <p3d/anim/multicontroller.hpp> + +//=========================================================================== +// Forward References +//=========================================================================== + +class tMultiController; +class tPoseAnimationController; +class tPose; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenPurchaseRewards : public IGuiScreenRewards +{ +public: + CGuiScreenPurchaseRewards( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenPurchaseRewards(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void OnProcessRequestsComplete( void* pUserData ); + +#ifdef RAD_WIN32 + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); +#endif + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + virtual void On3DModelLoaded( const PreviewObject* previewObject ); + virtual const PreviewObject* GetCurrentPreviewObject() const; + virtual void InitMenu(); + +private: + void OnUpdate( unsigned int elapsedTime ); + void UpdateRewardPrice(); + void UpdateBankValue(); + void PurchaseReward(); + void LoadSelectedReward(); + + Merchandise::eSellerType m_currentType; + bool m_isPurchasingReward; + unsigned int m_elapsedCoinDecrementTotalTime; + unsigned int m_elapsedCoinDecrementTime; + int m_bankValueBeforePurchase; + Scrooby::Text* m_purchaseLabel; + +#ifdef RAD_WIN32 + Scrooby::Sprite* m_leftArrow; + Scrooby::Sprite* m_rightArrow; +#endif + + tMultiController::TrackInfo m_skinTrackInfo; + tMultiController* m_skinMultiController; + tPoseAnimationController* m_skinAnimController; + +}; + +#endif // GUISCREENPURCHASEREWARDS_H diff --git a/game/code/presentation/gui/ingame/guiscreenrewards.cpp b/game/code/presentation/gui/ingame/guiscreenrewards.cpp new file mode 100644 index 0000000..997c67e --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenrewards.cpp @@ -0,0 +1,854 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: IGuiScreenRewards +// +// Description: Implementation of the IGuiScreenRewards class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenrewards.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> + +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <mission/rewards/reward.h> +#include <worldsim/coins/coinmanager.h> + +#include <screen.h> +#include <page.h> +#include <sprite.h> +#include <text.h> +#include <pure3dobject.h> +#include <group.h> +#include <polygon.h> + +#include <p3d/unicode.hpp> +#include <raddebug.hpp> // Foundation + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* REWARDS_INVENTORY_SECTION = "FE_RewardsScreen"; + +#ifdef RAD_XBOX + const float PHONE_BOOTH_BGD_CORRECTION_SCALE = 8.0f; +#else + const float PHONE_BOOTH_BGD_CORRECTION_SCALE = 8.8f; +#endif + +const float LIGHT_OPEN_CLOSE_TRANSITION_TIME = 500.0f; // in msec + +const char* PHONE_BOOTH_3DMODEL_CARS_DIR = "art\\frontend\\dynaload\\cars\\"; +const char* PHONE_BOOTH_2DMODEL_CARS_DIR = "art\\frontend\\dynaload\\images\\cars2D\\"; + +//=========================================================================== +// PhoneBoothStars:: +//=========================================================================== + +PhoneBoothStars::PhoneBoothStars( Scrooby::Page* pPage, const char* namePrefix ) +{ + rAssert( pPage ); + for( int i = 0; i < MAX_NUM_STARS; i++ ) + { + char name[ 32 ]; + sprintf( name, "%s_Stars%d", namePrefix, i ); + m_stars[ i ] = pPage->GetSprite( name ); + } +} + +void +PhoneBoothStars::SetNumStars( float numStars ) +{ + rWarningMsg( numStars >= 0.0f && numStars <= static_cast<float>( MAX_NUM_STARS ), + "Number of stars exceeds boundaries!" ); + + for( int i = 0; i < MAX_NUM_STARS; i++ ) + { + bool isOn = (i < static_cast<int>( numStars )); + + // check if half on + // + bool isHalfOn = !isOn && (static_cast<float>( i ) < numStars); + + rAssert( m_stars[ i ] != NULL ); + if( isOn ) + { + m_stars[ i ]->SetIndex( 2 ); +// m_stars[ i ]->SetAlpha( 1.0f ); + } + else if( isHalfOn ) + { + m_stars[ i ]->SetIndex( 1 ); +// m_stars[ i ]->SetAlpha( 1.0f ); + } + else + { + m_stars[ i ]->SetIndex( 0 ); +// m_stars[ i ]->SetAlpha( 0.5f ); + } + } +} + + +//=========================================================================== +// IGuiScreenRewards:: +//=========================================================================== + +IGuiScreenRewards::IGuiScreenRewards( Scrooby::Screen* pScreen, + Scrooby::Page* pPage, + CGuiEntity* pParent, + eGuiWindowID windowID ) +: CGuiScreen( pScreen, pParent, windowID ), + m_pRewardsMenu( NULL ), + m_currentState( REWARDS_SCREEN_LIGHT_CLOSED ), + m_elapsedTime( 0.0f ), + m_previewLightCover( NULL ), + m_previewWindow( NULL ), + m_previewPedestal( NULL ), + m_previewBgd( NULL ), + m_previewImage( NULL ), + m_previewName( NULL ), + m_numPreviewVehicles( 0 ), + m_currentPreviewVehicle( 0 ), + m_numPreviewClothing( 0 ), + m_currentPreviewClothing( 0 ), + m_isLoading( false ), + m_isLoadingReward( false ), + m_lockedOverlay( NULL ), + m_lockedLevel( NULL ), + m_rewardPrice( NULL ), + m_statsOverlay( NULL ), + m_statsOverlayButton( NULL ), + m_statsOverlayButtonLabel( NULL ), + m_statsOverlayToggle( false ) +{ + // Retrieve the Scrooby drawing elements. + // + rAssert( pPage != NULL ); + + Scrooby::Sprite* previewLightL = pPage->GetSprite( "PreviewLightL" ); + Scrooby::Sprite* previewLightR = pPage->GetSprite( "PreviewLightR" ); + if( previewLightL != NULL && previewLightR != NULL ) + { + previewLightL->ResetTransformation(); + previewLightR->ResetTransformation(); + + // apply image correction scales + // + previewLightL->ScaleAboutCenter( PHONE_BOOTH_BGD_CORRECTION_SCALE ); + previewLightR->ScaleAboutCenter( PHONE_BOOTH_BGD_CORRECTION_SCALE ); + + // flip the right light image horizontally to mirror the + // left light image + // + previewLightR->RotateAboutCenter( 180.0f, rmt::Vector( 0.0f, 1.0f, 0.0f ) ); + } + + // get preview light cover (for opening/closing light) + // + m_previewLightCover = pPage->GetPolygon( "PreviewLightCover" ); + + // get preview image + // + m_previewImage = pPage->GetSprite( "PreviewImage" ); + + // create rewards menu w/ preview name + // + m_previewName = pPage->GetText( "PreviewName" ); + rAssert( m_previewName ); + m_previewName->SetTextMode( Scrooby::TEXT_WRAP ); + + m_pRewardsMenu = new CGuiMenu( this, 1, GUI_TEXT_MENU, MENU_SFX_NONE ); + rAssert( m_pRewardsMenu != NULL ); + + m_pRewardsMenu->AddMenuItem( m_previewName, + pPage->GetText( "PreviewNameDummy" ), + NULL, + NULL, + pPage->GetSprite( "LeftArrow" ), + pPage->GetSprite( "RightArrow" ) ); + + // get preview window and pedestal + // + m_previewWindow = pPage->GetPure3dObject( "PreviewWindow" ); + if( m_previewWindow != NULL ) + { + m_previewWindow->SetVisible( false ); + m_previewWindow->SetClearDepthBuffer( true ); + } + + m_previewPedestal = pPage->GetPure3dObject( "RewardFG" ); + if ( m_previewPedestal != NULL ) + { + m_previewPedestal->SetVisible( false ); + } + + m_previewBgd = pPage->GetPure3dObject( "RewardBG" ); + if( m_previewBgd != NULL ) + { + m_previewBgd->SetVisible( false ); + m_previewBgd->SetClearDepthBuffer( true ); + } + + // get lock overlay + // + m_lockedOverlay = pPage->GetGroup( "Locked" ); + rAssert( m_lockedOverlay ); + + // get locked level + // + m_lockedLevel = pPage->GetText( "Level" ); + +#ifdef RAD_E3 + if( m_lockedLevel != NULL ) + { + m_lockedLevel->SetVisible( false ); // hide level display on E3 build + } +#endif + + // get reward price + // + m_rewardPrice = m_lockedOverlay->GetText( "Price" ); + if( m_rewardPrice != NULL ) + { + m_rewardPrice->SetDisplayOutline( true ); + + Scrooby::Text* toPurchase = m_lockedOverlay->GetText( "ToPurchase" ); + if( toPurchase != NULL ) + { + toPurchase->SetDisplayOutline( true ); + } + } + + // get stats overlay and button label + // + m_statsOverlay = pPage->GetGroup( "VehicleStats" ); + m_statsOverlayButton = pPage->GetGroup( "ToggleView" ); + m_statsOverlayButtonLabel = pPage->GetText( "ToggleView" ); + + // get vehicle star ratings + // + for( int i = 0; i < NUM_VEHICLE_RATINGS; i++ ) + { + m_vehicleRatings[ i ] = NULL; + } + + m_vehicleRatings[ VEHICLE_RATING_SPEED ] = new PhoneBoothStars( pPage, "Spe" ); + m_vehicleRatings[ VEHICLE_RATING_ACCELERATION ] = new PhoneBoothStars( pPage, "Acc" ); + m_vehicleRatings[ VEHICLE_RATING_TOUGHNESS ] = new PhoneBoothStars( pPage, "Tou" ); + m_vehicleRatings[ VEHICLE_RATING_STABILITY ] = new PhoneBoothStars( pPage, "Sta" ); + + // create inventory section for loading rewards + // + p3d::inventory->AddSection( REWARDS_INVENTORY_SECTION ); +} + +IGuiScreenRewards::~IGuiScreenRewards() +{ + for( int i = 0; i < NUM_VEHICLE_RATINGS; i++ ) + { + if( m_vehicleRatings[ i ] != NULL ) + { + delete m_vehicleRatings[ i ]; + m_vehicleRatings[ i ] = NULL; + } + } + + if( m_pRewardsMenu != NULL ) + { + delete m_pRewardsMenu; + m_pRewardsMenu = NULL; + } + + // destroy inventory section for loading rewards + // + p3d::pddi->DrawSync(); + + p3d::inventory->DeleteSection( REWARDS_INVENTORY_SECTION ); +} + +void +IGuiScreenRewards::HandleMessage( eGuiMessage message, + unsigned int param1, + unsigned int param2 ) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->OnUpdate( param1 ); + + break; + } + case GUI_MSG_CONTROLLER_AUX_X: + { + // toggle vehicle stats overlay + // + if( m_statsOverlayButton != NULL && m_statsOverlayButton->IsVisible() ) + { + this->SetVehicleStatsVisible( !m_statsOverlayToggle ); + } + + break; + } + default: + { + break; + } + } + + rAssert( m_pRewardsMenu != NULL ); + m_pRewardsMenu->HandleMessage( message, param1, param2 ); + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +IGuiScreenRewards::OnProcessRequestsComplete( void* pUserData ) +{ + m_isLoading = false; // reset loading flag + + const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject(); +/* + if( m_state != GUI_WINDOW_STATE_RUNNING ) + { + // hmmm... the user must have backed out of this screen before + // the preview object has been loaded; fine, we'll just unload it then + // + this->Unload3DModel(); + } + else +*/ + { + if( reinterpret_cast<PreviewObject*>( pUserData ) != currentPreviewObject ) + { + // selection must have changed while loading, so let's try + // to catch up + // + this->On3DModelSelectionChange( currentPreviewObject ); + } + else + { + // push and select inventory section for searching + // + p3d::inventory->PushSection(); + p3d::inventory->SelectSection( REWARDS_INVENTORY_SECTION ); + bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly(); + p3d::inventory->SetCurrentSectionOnly( true ); + + this->On3DModelLoaded( currentPreviewObject ); + + // pop inventory section and restore states + // + p3d::inventory->SetCurrentSectionOnly( currentSectionOnly ); + p3d::inventory->PopSection(); +/* + // turn on/off lights depending on whether or not reward is unlocked + // + rAssert( m_previewBgd ); + tView* pView = m_previewBgd->GetView(); + if( pView != NULL ) + { + for( unsigned int i = 0; i < MAX_VIEW_LIGHTS; i++ ) + { + tLight* pLight = pView->GetLight( i ); + if( pLight != NULL ) + { + pLight->Enable( currentPreviewObject->isUnlocked ); + } + else + { + break; + } + } + } +*/ + } + } +} + +void +IGuiScreenRewards::InitIntro() +{ + m_numPreviewVehicles = 0; + m_currentPreviewVehicle = 0; + + m_numPreviewClothing = 0; + m_currentPreviewClothing = 0; + + // close light by default + // + this->SetLightOpening( 0.0f ); + m_currentState = REWARDS_SCREEN_LIGHT_CLOSED; + + // initialize menu w/ level-specific selections + // + this->InitMenu(); + + GetCoinManager()->SetDrawAfterGui(true); + +} + +void +IGuiScreenRewards::InitRunning() +{ +} + +void +IGuiScreenRewards::InitOutro() +{ + m_isLoading = false; + m_isLoadingReward = false; + + // unload current 3D vehicle + // + this->Unload3DModel(); + + GetCoinManager()->SetDrawAfterGui(false); +} + +int +IGuiScreenRewards::InsertPreviewObject( PreviewObject* previewObjects, + int numPreviewObjects, + Reward* pReward, + bool isSorted ) +{ + rAssert( previewObjects != NULL ); + rAssert( pReward != NULL ); + + int newSlot = numPreviewObjects; + + if( isSorted ) + { + // *** assumes array is already sorted *** + + // sort by unlock status first (unlocked rewards before locked rewards); + // then sort unlocked rewards alphabetically, and sort locked rewards by level + // + for( int i = 0; i < numPreviewObjects; i++ ) + { + bool insertHere = false; + + if( static_cast<int>( pReward->RewardStatus() ) > static_cast<int>( previewObjects[ i ].isUnlocked ) ) + { + insertHere = true; + } + else if( pReward->RewardStatus() && previewObjects[ i ].isUnlocked ) + { + char stringID[ 16 ]; + char string1[ 64 ]; + char string2[ 64 ]; + + strcpy( stringID, pReward->GetName() ); + p3d::UnicodeToAscii( GetTextBibleString( strupr( stringID ) ), string1, sizeof( string1 ) ); + + strcpy( stringID, previewObjects[ i ].name ); + p3d::UnicodeToAscii( GetTextBibleString( strupr( stringID ) ), string2, sizeof( string2 ) ); + + insertHere = ( strcmp( string1, string2 ) < 0 ); + } + else if( !pReward->RewardStatus() && !previewObjects[ i ].isUnlocked ) + { + insertHere = ( pReward->GetLevel() < previewObjects[ i ].pReward->GetLevel() ); + } + + if( insertHere ) + { + // OK, found it! + // + newSlot = i; + + // move all remaining preview objects up a slot to make room + // for the new guy + // + for( int j = numPreviewObjects - 1; j >= i; j-- ) + { + strcpy( previewObjects[ j + 1 ].name, previewObjects[ j ].name ); + strcpy( previewObjects[ j + 1 ].filename, previewObjects[ j ].filename ); + strcpy( previewObjects[ j + 1 ].nameModel, previewObjects[ j ].nameModel ); + strcpy( previewObjects[ j + 1 ].filenameModel, previewObjects[ j ].filenameModel ); + previewObjects[ j + 1 ].isUnlocked = previewObjects[ j ].isUnlocked; + previewObjects[ j + 1 ].pReward = previewObjects[ j ].pReward; + } + + // we're done + // + break; + } + } + } + + // insert new object into the available slot + // + strncpy( previewObjects[ newSlot ].name, pReward->GetName(), + sizeof( previewObjects[ newSlot ].name ) ); + + strncpy( previewObjects[ newSlot ].filename, pReward->GetFile(), + sizeof( previewObjects[ newSlot ].filename ) ); + + if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH ) + { + // use 2D images for phone booth + // + strcpy( previewObjects[ newSlot ].nameModel, pReward->GetName() ); + + sprintf( previewObjects[ newSlot ].filenameModel, "%s%s", + PHONE_BOOTH_2DMODEL_CARS_DIR, + pReward->GetName() ); + } + else + { + if( pReward->GetRewardType() == Reward::ALT_PLAYERCAR ) + { + sprintf( previewObjects[ newSlot ].nameModel, "%s", + pReward->GetName() ); + + // 3D models for cars are not the same as the in-game ones + // (they use less memory than the in-game ones) + // + sprintf( previewObjects[ newSlot ].filenameModel, "%s%s.p3d", + PHONE_BOOTH_3DMODEL_CARS_DIR, + pReward->GetName() ); + } + else + { + sprintf( previewObjects[ newSlot ].nameModel, "%s_h", + pReward->GetName() ); + + strncpy( previewObjects[ newSlot ].filenameModel, pReward->GetFile(), + sizeof( previewObjects[ newSlot ].filenameModel ) ); + } + } + + previewObjects[ newSlot ].isUnlocked = pReward->RewardStatus(); + previewObjects[ newSlot ].pReward = pReward; + + // return the new number of preview objects + // + return (numPreviewObjects + 1); +} + +void +IGuiScreenRewards::OnUpdate( unsigned int elapsedTime ) +{ + switch( m_currentState ) + { + case REWARDS_SCREEN_OPENING_LIGHT: + { + if( m_elapsedTime < LIGHT_OPEN_CLOSE_TRANSITION_TIME ) + { + float lightOpening = m_elapsedTime / LIGHT_OPEN_CLOSE_TRANSITION_TIME; + + this->SetLightOpening( lightOpening ); + } + else + { + // set light fully opened + // + this->SetLightOpening( 1.0f ); + + m_currentState = REWARDS_SCREEN_LIGHT_OPENED; + } + + break; + } + case REWARDS_SCREEN_LIGHT_OPENED: + { + // do nothing + + break; + } + case REWARDS_SCREEN_CLOSING_LIGHT: + { + if( m_elapsedTime < LIGHT_OPEN_CLOSE_TRANSITION_TIME ) + { + float lightOpening = 1.0f - m_elapsedTime / LIGHT_OPEN_CLOSE_TRANSITION_TIME; + + this->SetLightOpening( lightOpening ); + } + else + { + // set light fully closed + // + this->SetLightOpening( 0.0f ); + + m_currentState = REWARDS_SCREEN_LIGHT_CLOSED; + } + + break; + } + case REWARDS_SCREEN_LIGHT_CLOSED: + { + this->SetLightOpening( 0.0f ); + + // check if loading is done yet + // + if( !m_isLoading ) + { + // ok, re-open light + // + m_currentState = REWARDS_SCREEN_OPENING_LIGHT; + m_elapsedTime = 0.0f; + + // show 3D model + // + if( m_previewWindow != NULL ) + { + m_previewWindow->SetVisible( true ); + } + } + + break; + } + default: + { + break; + } + } + + m_elapsedTime += static_cast<float>( elapsedTime ); +} + +void +IGuiScreenRewards::SetLightOpening( float amount ) +{ + if( m_previewLightCover != NULL ) + { + const float MAX_LIGHT_AMOUNT_CLOSED = 0.85f; + float amountClosed = (1.0f - amount) * MAX_LIGHT_AMOUNT_CLOSED; + amount = 1.0f - amountClosed; + + m_previewLightCover->SetAlpha( amountClosed ); + } +} + +void +IGuiScreenRewards::On3DModelSelectionChange( const PreviewObject* nextModel ) +{ + if( nextModel != NULL ) + { + // update preview object display name + // + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + char textBibleEntry[ sizeof( nextModel->name ) ]; + strcpy( textBibleEntry, nextModel->name ); + UnicodeChar* textBibleString = GetTextBibleString( strupr( textBibleEntry ) ); + UnicodeString unicodeString; + if( textBibleString != NULL ) + { + unicodeString.ReadUnicode( textBibleString ); + } + else + { + rAssertMsg( false, "Skin/Vehicle name not found in text bible!" ); + unicodeString.ReadAscii( nextModel->name ); + } + +#ifdef PAL + if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH && + CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_GERMAN ) + { + if( strcmp( textBibleEntry, "BOOKB_V" ) == 0 ) + { + UnicodeString str1; + str1.ReadAscii( "mobil" ); + + UnicodeString str2; + str2.ReadAscii( "-\nmobil" ); + + unicodeString.Replace( str1, str2 ); + } + + if( strcmp( textBibleEntry, "SCORP_V") == 0 ) + { + UnicodeString str1; + str1.ReadAscii( "Auto" ); + + UnicodeString str2; + str2.ReadAscii( "\nAuto" ); + + unicodeString.Replace( str1, str2 ); + } + } +#endif // PAL + + rAssert( m_previewName ); + m_previewName->SetString( 0, unicodeString ); + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + + // update locked/unlocked status + // + rAssert( m_lockedOverlay ); + m_lockedOverlay->SetVisible( !nextModel->isUnlocked ); + + if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH ) + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, nextModel->isUnlocked ); + } + + // update locked level display + // + if( m_lockedLevel != NULL ) + { + m_lockedLevel->SetIndex( nextModel->pReward->GetLevel() ); + } + + // update vehicle stats + // + this->UpdateVehicleStats(); + + if( !m_isLoading ) + { + // unload current 3D model + // + this->Unload3DModel(); + + // load next 3D model + // + this->Load3DModel( nextModel ); + } + } +} + +void +IGuiScreenRewards::Load3DModel( const PreviewObject* previewObject ) +{ + m_isLoading = true; // set loading flag + m_isLoadingReward = false; // not loading reward + + rAssert( previewObject != NULL ); + + if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH ) + { + char filename[ 64 ]; + + // load normal 2D car image + // + sprintf( filename, "%s.p3d", previewObject->filenameModel ); + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + filename, + GMA_LEVEL_OTHER, + REWARDS_INVENTORY_SECTION, + REWARDS_INVENTORY_SECTION ); + +#ifdef LOAD_DAMAGED_VEHICLE_IMAGES + // load damaged 2D car image + // + sprintf( filename, "%sD.p3d", previewObject->filenameModel ); + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + filename, + GMA_LEVEL_OTHER, + REWARDS_INVENTORY_SECTION, + REWARDS_INVENTORY_SECTION ); +#endif + } + else + { + // add request to load 3D model + // + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + previewObject->filenameModel, + GMA_LEVEL_MISSION, + REWARDS_INVENTORY_SECTION, + REWARDS_INVENTORY_SECTION ); + } + + GetLoadingManager()->AddCallback( this, (void*)previewObject ); +} + +void +IGuiScreenRewards::Unload3DModel() +{ + p3d::pddi->DrawSync(); + + if( m_previewWindow != NULL ) + { + m_previewWindow->SetDrawable( NULL ); + m_previewWindow->SetVisible( false ); + } + + if( m_previewImage != NULL ) + { + m_previewImage->SetRawSprite( NULL ); + m_previewImage->SetVisible( false ); + } + + // remove 3D model from inventory + // + p3d::inventory->RemoveSectionElements( REWARDS_INVENTORY_SECTION ); + + // change current state to closing light, if not already closed + // or in the progress of closing + // + if( m_currentState != REWARDS_SCREEN_CLOSING_LIGHT && + m_currentState != REWARDS_SCREEN_LIGHT_CLOSED ) + { + if( m_currentState == REWARDS_SCREEN_OPENING_LIGHT && + m_elapsedTime < LIGHT_OPEN_CLOSE_TRANSITION_TIME ) + { + m_elapsedTime = LIGHT_OPEN_CLOSE_TRANSITION_TIME - m_elapsedTime; + } + else + { + m_elapsedTime = 0.0f; + } + + m_currentState = REWARDS_SCREEN_CLOSING_LIGHT; + } +} + +void +IGuiScreenRewards::SetVehicleStatsVisible( bool isVisible ) +{ + m_statsOverlayToggle = isVisible; + + rAssert( m_statsOverlay ); + m_statsOverlay->SetVisible( m_statsOverlayToggle ); + + rAssert( m_statsOverlayButtonLabel ); + m_statsOverlayButtonLabel->SetIndex( m_statsOverlayToggle ? 1 : 0 ); +} + +void +IGuiScreenRewards::UpdateVehicleStats() +{ + const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject(); + CarAttributeRecord* carAttributes = GetRewardsManager()->GetCarAttributeRecord( const_cast<char*>( currentPreviewObject->name ) ); + if( carAttributes != NULL ) + { + m_vehicleRatings[ VEHICLE_RATING_SPEED ]->SetNumStars( carAttributes->mSpeed ); + m_vehicleRatings[ VEHICLE_RATING_ACCELERATION ]->SetNumStars( carAttributes->mAcceleration ); + m_vehicleRatings[ VEHICLE_RATING_TOUGHNESS ]->SetNumStars( carAttributes->mToughness ); + m_vehicleRatings[ VEHICLE_RATING_STABILITY ]->SetNumStars( carAttributes->mStability ); + } +/* + else + { + rAssert( false ); + rTunePrintf( "*** WARNING: No car attributes found for [%s]!\n", + currentPreviewObject->name ); + } +*/ +} + diff --git a/game/code/presentation/gui/ingame/guiscreenrewards.h b/game/code/presentation/gui/ingame/guiscreenrewards.h new file mode 100644 index 0000000..0251113 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenrewards.h @@ -0,0 +1,171 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: IGuiScreenRewards +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENREWARDS_H +#define GUISCREENREWARDS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +#include <loading/loadingmanager.h> +#include <memory/srrmemory.h> + +#ifdef RAD_WIN32 +#define LOAD_DAMAGED_VEHICLE_IMAGES +#endif + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu; +class Reward; + +struct PreviewObject +{ + char name[ 16 ]; // object name + char filename[ 64 ]; // object filename + + char nameModel[ 16 ]; // model drawable name + char filenameModel[ 64 ]; // model filename + + bool isUnlocked : 1; // unlocked flag + Reward* pReward; // reference to reward object +}; + +class PhoneBoothStars +{ +public: + PhoneBoothStars( Scrooby::Page* pPage, const char* namePrefix ); + void SetNumStars( float numStars ); + +private: + static const int MAX_NUM_STARS = 5; + Scrooby::Sprite* m_stars[ MAX_NUM_STARS ]; + +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class IGuiScreenRewards : public CGuiScreen, + public LoadingManager::ProcessRequestsCallback +{ +public: + IGuiScreenRewards( Scrooby::Screen* pScreen, + Scrooby::Page* pPage, + CGuiEntity* pParent, + eGuiWindowID windowID ); + + virtual ~IGuiScreenRewards(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void OnProcessRequestsComplete( void* pUserData ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + virtual void On3DModelLoaded( const PreviewObject* previewObject ) = 0; + virtual const PreviewObject* GetCurrentPreviewObject() const = 0; + virtual void InitMenu() = 0; + + int InsertPreviewObject( PreviewObject* previewObjects, + int numPreviewObjects, + Reward* pReward, + bool isSorted = false ); + + virtual void OnUpdate( unsigned int elapsedTime ); + + void SetLightOpening( float amount ); // 0.0f <= amount <= 1.0f + + void On3DModelSelectionChange( const PreviewObject* nextModel ); + + void Load3DModel( const PreviewObject* previewObject ); + void Unload3DModel(); + + void SetVehicleStatsVisible( bool isVisible ); + void UpdateVehicleStats(); + + static const int MAX_NUM_PREVIEW_VEHICLES = 64; + static const int MAX_NUM_PREVIEW_CLOTHING = 4; + + CGuiMenu* m_pRewardsMenu; + + enum eRewardsScreenState + { + REWARDS_SCREEN_OPENING_LIGHT, + REWARDS_SCREEN_LIGHT_OPENED, + REWARDS_SCREEN_CLOSING_LIGHT, + REWARDS_SCREEN_LIGHT_CLOSED, + + NUM_REWARDS_SCREEN_STATES + }; + + eRewardsScreenState m_currentState; + float m_elapsedTime; + + Scrooby::Polygon* m_previewLightCover; + Scrooby::Pure3dObject* m_previewWindow; + Scrooby::Pure3dObject* m_previewPedestal; + Scrooby::Pure3dObject* m_previewBgd; + Scrooby::Sprite* m_previewImage; + Scrooby::Text* m_previewName; + + // list of garage vehicles + // + PreviewObject m_previewVehicles[ MAX_NUM_PREVIEW_VEHICLES ]; + int m_numPreviewVehicles; + int m_currentPreviewVehicle; + + // list of character skins + // + PreviewObject m_previewClothing[ MAX_NUM_PREVIEW_CLOTHING ]; + int m_numPreviewClothing; + int m_currentPreviewClothing; + + bool m_isLoading : 1; + bool m_isLoadingReward : 1; + + Scrooby::Group* m_lockedOverlay; + Scrooby::Text* m_lockedLevel; + Scrooby::Text* m_rewardPrice; + + Scrooby::Group* m_statsOverlay; + Scrooby::Group* m_statsOverlayButton; + Scrooby::Text* m_statsOverlayButtonLabel; + bool m_statsOverlayToggle; + + enum eVehicleRatingType + { + VEHICLE_RATING_SPEED, + VEHICLE_RATING_ACCELERATION, + VEHICLE_RATING_TOUGHNESS, + VEHICLE_RATING_STABILITY, + + NUM_VEHICLE_RATINGS + }; + + PhoneBoothStars* m_vehicleRatings[ NUM_VEHICLE_RATINGS ]; + +}; + +#endif // GUISCREENREWARDS_H diff --git a/game/code/presentation/gui/ingame/guiscreensavegame.cpp b/game/code/presentation/gui/ingame/guiscreensavegame.cpp new file mode 100644 index 0000000..48dd64a --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreensavegame.cpp @@ -0,0 +1,1011 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSaveGame +// +// Description: Implementation of the CGuiScreenSaveGame class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/04 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreensavegame.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guiscreenmessage.h> +#include <presentation/gui/guiscreenprompt.h> + +#include <data/gamedatamanager.h> +#include <data/savegameinfo.h> +#include <data/memcard/memorycardmanager.h> +#include <memory/srrmemory.h> +#include <gameflow/gameflow.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <layer.h> +#include <page.h> +#include <screen.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +#ifdef RAD_XBOX +extern char gGameFileName[NUM_GAME_SLOTS][radFileFilenameMax+1]; +#endif +//=========================================================================== +// CGuiScreenSaveGame::CGuiScreenSaveGame +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSaveGame::CGuiScreenSaveGame +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: + CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SAVE_GAME ), + CGuiScreenLoadSave( pScreen ), + m_pMenu( NULL ), + m_pFullText( NULL ), + m_StatusPromptShown(false), + m_nonEmptySlots( 0 ) +{ +MEMTRACK_PUSH_GROUP( "CGUIScreenSaveGame" ); + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "GameSlots" ); + rAssert( pPage ); + + Scrooby::Group* menu = pPage->GetGroup( "Menu" ); + rAssert( menu != NULL ); + + m_pFullText = pPage->GetText( "FullMessage" ); + rAssert( m_pFullText != NULL ); + m_pFullText->SetVisible(false); + m_pFullText->SetTextMode( Scrooby::TEXT_WRAP ); + // Create a menu. + // + m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_GAME_SLOTS ); + rAssert( m_pMenu != NULL ); + + // Add menu items + // + for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ ) + { + char objectName[ 32 ]; + sprintf( objectName, "Slot%d", i ); + + m_pMenu->AddMenuItem( menu->GetText( objectName ) ); + } + +#ifdef RAD_WIN32 + Scrooby::Text* pText = pPage->GetText( "LoadSaveMessage" ); + if( pText != NULL ) + { + pText->SetIndex( 1 ); + } +#else + pPage = m_pScroobyScreen->GetPage( "SelectMemoryDevice" ); + rAssert( pPage != NULL ); + Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" ); + rAssert( foreground != NULL ); + + Scrooby::Text* pText = foreground->GetText( "LoadSave" ); + if( pText != NULL ) + { + pText->SetIndex( 1 ); + } +#endif + + this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) ); +MEMTRACK_POP_GROUP("CGUIScreenSaveGame"); +} + + +//=========================================================================== +// CGuiScreenSaveGame::~CGuiScreenSaveGame +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenSaveGame::~CGuiScreenSaveGame() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenSaveGame::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSaveGame::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if (message == GUI_MSG_MESSAGE_UPDATE) + { + if (m_formatState) + { + m_elapsedFormatTime += param1; + if (m_elapsedFormatTime > m_minimumFormatTime && m_formatDone) + { + m_StatusPromptShown = true; + m_formatState = false; + + if( m_formatResult == Success ) + { +#ifdef RAD_PS2 + m_currentSlot = 0; // on ps2 continue to save + this->SaveGame(); +#else + m_guiManager->DisplayPrompt(PROMPT_FORMAT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format success +#endif + } + else + { + m_guiManager->DisplayPrompt(PROMPT_FORMAT_FAIL_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format fail + } + } + } + } + else if (message == GUI_MSG_PROMPT_UPDATE) + { + GetMemoryCardManager()->Update( param1 ); // update so we know the status + + if (m_StatusPromptShown==false) { // check for user unplugging memcard if not showing status + int current_drive = GetMemoryCardManager()->GetCurrentDriveIndex(); + + if( !GetMemoryCardManager()->IsCurrentDrivePresent(current_drive) ) + ReloadScreen(); + } + } + else if( message == GUI_MSG_ON_DISPLAY_MESSAGE ) + { + if( m_operation == SAVE ) + { + // start the save game process + // + rAssert( m_currentSlot != -1 ); +#ifdef RAD_XBOX + // has existing filename + radFileError err = Success; + if (gGameFileName[m_currentSlot][0]!=0) // delete existing file if overwriting (on xbox each filename is unique) + { + err = GetGameDataManager()->DeleteGame(gGameFileName[m_currentSlot]); + } + if (err!=Success) + OnSaveGameComplete(err); + else + GetGameDataManager()->SaveGame( m_currentSlot, this ); +#else + GetGameDataManager()->SaveGame( m_currentSlot, this ); +#endif + } + else if( m_operation == DELETE_GAME ) + { + // get the filename + char filename[ radFileFilenameMax + 1 ]; +#ifdef RAD_XBOX + strcpy(filename, gGameFileName[m_currentSlot]); +#else + GetGameDataManager()->FormatSavedGameFilename( filename, + sizeof( filename ), + m_currentSlot ); +#endif + radFileError err = GetGameDataManager()->DeleteGame( filename, true, this ); + } + else + { + FormatCurrentDrive(); + } + } + else if ( message==GUI_MSG_PROMPT_START_RESPONSE ) + { + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + } + else if (message == GUI_MSG_ERROR_PROMPT_RESPONSE ) + { + this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) ); + } + else if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + switch( param1 ) + { + + case PROMPT_FORMAT_CONFIRM_GC: + case PROMPT_FORMAT_CONFIRM_PS2: + case PROMPT_FORMAT_CONFIRM_XBOX: // do you really want to format + { + if (param2==CGuiMenuPrompt::RESPONSE_YES) + m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this); + else + { + this->GotoMemoryCardScreen( true ); + } + break; + } + case PROMPT_FORMAT_CONFIRM2_GC: + case PROMPT_FORMAT_CONFIRM2_PS2: + case PROMPT_FORMAT_CONFIRM2_XBOX: // really format + { + if (param2==CGuiMenuPrompt::RESPONSE_YES) + { + m_operation = FORMAT; + m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this); + } + else + { + this->GotoMemoryCardScreen( true ); + } + break; + } + case PROMPT_LOAD_DELETE_CORRUPT_GC: + case PROMPT_LOAD_DELETE_CORRUPT_PS2: + case PROMPT_LOAD_DELETE_CORRUPT_XBOX: + case PROMPT_LOAD_DELETE_CORRUPT_XBOX_HD: + { + if (param2==CGuiMenuPrompt::RESPONSE_NO) + { + this->ReloadScreen(); + } + else if (param2==CGuiMenuPrompt::RESPONSE_YES) + { +#ifdef RAD_PS2 + m_operation = DELETE_GAME; + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_DELETING_GC + PLATFORM_TEXT_INDEX, this ); +#else + // get the filename + char filename[ radFileFilenameMax + 1 ]; + #ifdef RAD_XBOX + strcpy(filename, gGameFileName[m_currentSlot]); + #else + GetGameDataManager()->FormatSavedGameFilename( filename, + sizeof( filename ), + m_currentSlot ); + #endif + radFileError err = GetGameDataManager()->DeleteGame(filename); + this->OnDeleteGameComplete( err ); +#endif // RAD_PS2 + } + else + { + rTuneAssert(!"not reached"); + } + + break; + } + + case PROMPT_FORMAT_SUCCESS_GC: + case PROMPT_FORMAT_SUCCESS_PS2: + case PROMPT_FORMAT_SUCCESS_XBOX: // format ok + { + // m_currentSlot = 0; on ps2 we don't come here + // this->SaveGame(); + this->ReloadScreen(); + break; + } + + case PROMPT_FORMAT_FAIL_GC: + case PROMPT_FORMAT_FAIL_PS2: + case PROMPT_FORMAT_FAIL_XBOX: // format fail + { + GetMemoryCardManager()->ClearCurrentDrive(); + this->GotoMemoryCardScreen( true ); + + break; + } + + case PROMPT_DELETE_CORRUPT_SUCCESS_GC: + case PROMPT_DELETE_CORRUPT_SUCCESS_PS2: + case PROMPT_DELETE_CORRUPT_SUCCESS_XBOX: + + case PROMPT_DELETE_CORRUPT_FAIL_GC: + case PROMPT_DELETE_CORRUPT_FAIL_PS2: + case PROMPT_DELETE_CORRUPT_FAIL_XBOX: + { + this->ReloadScreen(); + break; + } + + case PROMPT_SAVE_CONFIRM_OVERWRITE_GC: + { + if( param2 == CGuiMenuPrompt::RESPONSE_YES ) + { + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_GC, this, PROMPT_TYPE_SAVE ); + } + else + { + rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO ); + + this->ReloadScreen(); + } + + break; + } + case PROMPT_SAVE_CONFIRM_GC: + case PROMPT_SAVE_CONFIRM_PS2: + case PROMPT_SAVE_CONFIRM_XBOX: + case PROMPT_SAVE_CONFIRM_OVERWRITE_PS2: + case PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX: + { + if( param2 == CGuiMenuPrompt::RESPONSE_YES || + param2 == CGuiMenuPrompt::RESPONSE_SAVE ) + { + this->SaveGame(); + } + else + { + rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO ); + + this->ReloadScreen(); + } + + break; + } + + case PROMPT_SAVE_SUCCESSFUL: + { + m_pParent->HandleMessage( GUI_MSG_ON_SAVE_GAME_COMPLETE ); + + break; + } + + default: + { + // handle normal error response, "continue", etc + this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) ); + + break; + } + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( message == GUI_MSG_CONTROLLER_SELECT && + !GetMemoryCardManager()->IsMemcardInfoLoaded() ) + { + // ignore user select inputs until memcard info is loaded + // + return; + } + + switch( message ) + { +#ifdef RAD_PS2 + case GUI_MSG_CONTROLLER_START: + { + if ( GetGameFlow()->GetCurrentContext() == CONTEXT_PAUSE ) + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + + break; + } +#endif + case GUI_MSG_MENU_SELECTION_MADE: + { + m_currentSlot = param1; // // param1 = slot + + SaveGameInfo saveGameInfo; + bool corrupt = false; + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo, &corrupt ); + + if (corrupt) + { + int plat_index = PLATFORM_TEXT_INDEX; +#ifdef RAD_XBOX + if (GetMemoryCardManager()->GetCurrentDriveIndex()==0) + plat_index++; +#endif +#ifdef RAD_GAMECUBE + int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_SAVING ); + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE ); + m_operation = SAVE; +#else + m_guiManager->DisplayPrompt( PROMPT_LOAD_DELETE_CORRUPT_GC + plat_index, this ); +#endif + } + else if( (m_nonEmptySlots & (1 << m_currentSlot)) > 0 ) + { + // saved game exists in current slot; prompt w/ overwrite + // confirmation message + // +#ifdef RAD_GAMECUBE + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_GC, this ); +#endif + +#ifdef RAD_PS2 + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_PS2, this ); +#endif + +#ifdef RAD_XBOX + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX, this ); +#endif + +#ifdef RAD_WIN32 + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX, this ); +#endif + } + else + { +#ifdef RAD_GAMECUBE + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_GC, this, PROMPT_TYPE_SAVE ); +#endif + +#ifdef RAD_PS2 + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_PS2, this ); +#endif + +#ifdef RAD_XBOX + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_XBOX, this ); +#endif + +#ifdef RAD_WIN32 + m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_XBOX, this ); +#endif + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { +#ifdef RAD_XBOX + s_forceGotoMemoryCardScreen = true; + this->GotoMemoryCardScreen(); +#endif + break; + } + default: + { + break; + } + } + + // relay message to menu + if( m_pMenu != NULL ) + { + m_pMenu->HandleMessage( message, param1, param2 ); + } + + CGuiScreenLoadSave::HandleMessage( message, param1, param2 ); + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +void +CGuiScreenSaveGame::OnSaveGameComplete( radFileError errorCode ) +{ + m_lastError = errorCode; + m_StatusPromptShown = true; + + if( errorCode == Success ) + { + m_guiManager->DisplayPrompt( PROMPT_SAVE_SUCCESSFUL, this, PROMPT_TYPE_CONTINUE ); + } + else + { + int errorMessage = GetErrorMessageIndex( errorCode, ERROR_DURING_SAVING ); + +#ifdef RAD_GAMECUBE + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } + case MediaCorrupt: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE ); + + break; + } + case MediaEncodingErr: + case MediaNotFormatted: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT ); + + } + default: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY ); + + break; + } + } +#endif // RAD_GAMECUBE + +#ifdef RAD_PS2 + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } + default: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE ); + + break; + } + } +#endif // RAD_PS2 + +#ifdef RAD_XBOX + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } + default: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE ); + + break; + } + } +#endif // RAD_XBOX + +#ifdef RAD_WIN32 + switch( errorCode ) + { + case Success: + { + rAssert( false ); + break; + } + default: + { + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE ); + break; + } + } +#endif // RAD_WIN32 + } +} + +void +CGuiScreenSaveGame::OnDeleteGameComplete( radFileError errorCode ) +{ + m_operation = SCREEN_OP_IDLE; + m_StatusPromptShown = true; + + if( errorCode == Success ) + { + m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_SUCCESS_GC + PLATFORM_TEXT_INDEX, + this, + PROMPT_TYPE_CONTINUE ); + } + else + { + m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_FAIL_GC + PLATFORM_TEXT_INDEX, + this, + PROMPT_TYPE_CONTINUE ); + } +} + +void +CGuiScreenSaveGame::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ) +{ + switch( response ) + { + case (CGuiMenuPrompt::RESPONSE_CONTINUE): + case (CGuiMenuPrompt::RESPONSE_CONTINUE_WITHOUT_SAVE): + { + if( m_operation == SAVE ) + { + this->ReloadScreen(); + } + else if( m_operation == FORMAT ) + { + this->ReloadScreen(); + } + else + { + this->GotoMemoryCardScreen( true ); + } + + break; + } + case (CGuiMenuPrompt::RESPONSE_RETRY): + { + if( m_operation == SAVE ) + { +#ifdef RAD_GAMECUBE + SaveGameInfo saveGameInfo; + bool corrupt = false; + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo, &corrupt ); + if( corrupt ) + { + int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_SAVING ); + m_guiManager->DisplayErrorPrompt( errorMessage, this, + ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE ); + } + else +#endif + { + this->SaveGame(); + } + } + else if( m_operation == FORMAT ) + { + m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this); + } + else + { + this->ReloadScreen(); + } + + break; + } + +#ifdef RAD_GAMECUBE + case (CGuiMenuPrompt::RESPONSE_DELETE): + { + m_guiManager->DisplayPrompt( PROMPT_LOAD_DELETE_CORRUPT_GC, this ); + + break; + } +#endif // RAD_GAMECUBE + + case (CGuiMenuPrompt::RESPONSE_FORMAT_GC): + case (CGuiMenuPrompt::RESPONSE_FORMAT_XBOX): + case (CGuiMenuPrompt::RESPONSE_FORMAT_PS2): + { + m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this); + break; + } + default: + { + rTunePrintf( "*** WARNING: Unhandled response for error [%d]!\n", m_lastError ); + rAssert( false ); + + this->ReloadScreen(); + + break; + } + } + + CGuiScreenLoadSave::HandleErrorResponse( response ); +} + + +//=========================================================================== +// CGuiScreenSaveGame::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSaveGame::InitIntro() +{ + unsigned int num_empty_slots = 0; + bool unformatted = false; + IRadDrive::MediaInfo::MediaState mediaState; + + m_StatusPromptShown = false; + m_operation = SCREEN_OP_IDLE; + + if( s_forceGotoMemoryCardScreen || !GetMemoryCardManager()->IsCurrentDriveReady( true, &unformatted, &mediaState )) + { + if (unformatted && !s_forceGotoMemoryCardScreen) + { +#ifdef RAD_GAMECUBE + int errorMessage; + + errorMessage = GetErrorMessageIndex( mediaState ); + m_guiManager->DisplayErrorPrompt( errorMessage, + this, + ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT ); +#else + m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM_GC+PLATFORM_TEXT_INDEX,this); +#endif + m_numTransitionsPending = -1; // disable all transitions + } + else + { + this->GotoMemoryCardScreen(); + m_numTransitionsPending = -1; // disable all transitions + } + return; + } + + m_nonEmptySlots = 0; // reset non-empty slots bitmask + + this->UpdateCurrentMemoryDevice(); + + rAssert( m_pMenu ); + m_pMenu->Reset(); + + IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive(); + + int currentDriveIndex = GetMemoryCardManager()->GetCurrentDriveIndex(); + bool enoughFreeSpace = GetMemoryCardManager()->EnoughFreeSpace( currentDriveIndex ); + + radDate mostRecentTimestamp; + mostRecentTimestamp.m_Year = 0; + + // update all save game slots display info + // + for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ ) + { + SaveGameInfo saveGameInfo; + bool corrupt; + bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, i, &saveGameInfo, &corrupt ); +// saveGameExists = saveGameExists && saveGameInfo.CheckData(); + + Scrooby::Text* slotText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( i )->GetItem() ); + rAssert( slotText != NULL ); + + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); +#ifdef RAD_XBOX + gGameFileName[i][0] = 0; +#endif + if( saveGameExists ) + { + if (corrupt) + { + UnicodeString corruptSlot; +#ifdef RAD_XBOX + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) ); +#endif +#ifdef RAD_WIN32 + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) ); +#endif +#ifdef RAD_PS2 + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(PS2)" ) ); +#endif +#ifdef RAD_GAMECUBE + corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(GC)" ) ); +#endif + slotText->SetString(0,corruptSlot); +#ifdef RAD_XBOX + strcpy(gGameFileName[i], saveGameInfo.m_displayFilename); // cache filename in the slot +#endif + } + else + { + slotText->SetString( 0, saveGameInfo.m_displayFilename ); + #ifdef RAD_XBOX + strcpy(gGameFileName[i], saveGameInfo.m_displayFilename); // cache filename in the slot + #endif + } + + // default to slot with most recent saved game file + // + const SaveGameInfoData* pData = saveGameInfo.GetData(); + rAssert( pData != NULL ); + if( SaveGameInfo::CompareTimeStamps( pData->m_timeStamp, mostRecentTimestamp ) > 0 ) + { + memcpy( &mostRecentTimestamp, &pData->m_timeStamp, sizeof( radDate ) ); + + m_pMenu->Reset( i ); + } + + // update non-empty slots bitmask + // + m_nonEmptySlots |= (1 << i); + } + else + { + UnicodeString emptySlot; + if (enoughFreeSpace) + emptySlot.ReadUnicode( GetTextBibleString( "EMPTY_SLOT" ) ); + else + emptySlot.ReadUnicode( GetTextBibleString( "FULL_SLOT" ) ); + +#ifdef RAD_XBOX + if (num_empty_slots) // blank out extra empty slot item + emptySlot.ReadUnicode( GetTextBibleString ("SPACE") ); +#endif + slotText->SetString( 0, emptySlot ); + num_empty_slots++; + } + HeapMgr()->PopHeap(GMA_LEVEL_HUD); + + // enable slot selection only if save game exists or there's enough + // free space to save a new game + // + m_pMenu->SetMenuItemEnabled( i, saveGameExists || enoughFreeSpace ); +#ifdef RAD_XBOX + if (num_empty_slots > 1) // disable extra empty slot for xbox + m_pMenu->SetMenuItemEnabled( i, false ); +#endif + } + + /* display/hide full message */ + if (!enoughFreeSpace) + { + int message_index = 0; // no existing slot + if (num_empty_slots < NUM_GAME_SLOTS ) + message_index = 1; // has existing slot + // we have 2 group of per platform messages, gc,ps2,xbox_mu, xbox_hd + message_index = message_index * 4 + PLATFORM_TEXT_INDEX; +#ifdef RAD_XBOX + if (currentDriveIndex==0) + { + message_index++; // xbox hard disk + } +#endif +#ifdef RAD_WIN32 + message_index = 9; +#endif + m_pFullText->SetIndex(message_index); + m_pFullText->SetVisible(true); + +#ifdef RAD_GAMECUBE + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + // append "Use Memory Card Screen" text to message; this is done in + // code because the text bible compiler can't handle strings with + // more than 255 characters + // + UnicodeString useMemCardScreen; + useMemCardScreen.ReadUnicode( GetTextBibleString( "USE_MEMORY_CARD_SCREEN" ) ); + + UnicodeString newString; + newString.ReadUnicode( GetTextBibleString( "MEMCARD_FULL_HAS_EXISTING_(GC)" ) ); + newString.Append( ' ' ); + newString += useMemCardScreen; + + m_pFullText->SetString( message_index, newString ); + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); +#endif // RAD_GAMECUBE + } + else + { + m_pFullText->SetVisible(false); + } + this->SetButtonVisible( BUTTON_ICON_ACCEPT, m_pMenu->GetSelection() != -1 ); +} + + +//=========================================================================== +// CGuiScreenSaveGame::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSaveGame::InitRunning() +{ +// rAssertMsg( GetMemoryCardManager()->IsMemcardInfoLoaded(), +// "WARNING: *** Memory card info not loaded yet!" ); +} + + +//=========================================================================== +// CGuiScreenSaveGame::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenSaveGame::InitOutro() +{ +} + + +void +CGuiScreenSaveGame::GotoMemoryCardScreen( bool isFromPrompt ) +{ +#ifdef RAD_WIN32 + m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN ); +#else + if( isFromPrompt ) + { + s_forceGotoMemoryCardScreen = true; + this->ReloadScreen(); + } + else + { + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MEMORY_CARD ); + } +#endif // RAD_WIN32 +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenSaveGame::SaveGame() +{ + m_operation = SAVE; + +#ifdef RAD_GAMECUBE + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_GC, this ); +#endif + +#ifdef RAD_PS2 + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_PS2, this ); +#endif + +#ifdef RAD_XBOX + if( m_currentDriveIndex == 0 ) // xbox hard disk + { + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_XBOX_HD, this ); + } + else // xbox memory unit + { + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_XBOX, this ); + } +#endif + +#ifdef RAD_WIN32 + m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_PC, this ); +#endif +} + diff --git a/game/code/presentation/gui/ingame/guiscreensavegame.h b/game/code/presentation/gui/ingame/guiscreensavegame.h new file mode 100644 index 0000000..361b21f --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreensavegame.h @@ -0,0 +1,72 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenSaveGame +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/30 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENSAVEGAME_H +#define GUISCREENSAVEGAME_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/guiscreenmemorycard.h> +#include <data/gamedatamanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenSaveGame : public CGuiScreen, + public CGuiScreenLoadSave, + public GameDataSaveCallback, + public GameDataDeleteCallback +{ +public: + CGuiScreenSaveGame( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenSaveGame(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + // Implements GameDataSaveCallback and GameDataDeleteCallback + // + virtual void OnSaveGameComplete( radFileError errorCode ); + virtual void OnDeleteGameComplete( radFileError errorCode ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + void GotoMemoryCardScreen( bool isFromPrompt = false ); + void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response ); + +private: + void SaveGame(); + + CGuiMenu* m_pMenu; + Scrooby::Text* m_pFullText; + bool m_StatusPromptShown; + unsigned short m_nonEmptySlots; + +}; + +#endif // GUISCREENSAVEGAME_H diff --git a/game/code/presentation/gui/ingame/guiscreentutorial.cpp b/game/code/presentation/gui/ingame/guiscreentutorial.cpp new file mode 100644 index 0000000..7ff9536 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreentutorial.cpp @@ -0,0 +1,373 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenTutorial +// +// Description: Implementation of the CGuiScreenTutorial class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/04/15 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreentutorial.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/utility/specialfx.h> + +#include <presentation/tutorialmanager.h> + +#include <events/eventmanager.h> +#include <main/commandlineoptions.h> +#include <sound/soundmanager.h> + +// Scrooby +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <sprite.h> + +// ATG +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#define WAIT_UNTIL_DIALOG_DONE + +const float BART_ICON_CORRECTION_SCALE = 1.0f; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenTutorial::CGuiScreenTutorial +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenTutorial::CGuiScreenTutorial +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_TUTORIAL, SCREEN_FX_ZOOM ), + m_tutorialMessage( NULL ), + m_bartsHead( NULL ), + m_disableTutorial( NULL ), + m_elapsedDialogTime( 0 ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Tutorial" ); + rAssert( pPage != NULL ); + + Scrooby::Group* iconAndMessage = pPage->GetGroup( "IconAndMessage" ); + rAssert( iconAndMessage != NULL ); + + m_bartsHead = iconAndMessage->GetSprite( "BartIcon" ); + + m_tutorialMessage = iconAndMessage->GetSprite( "TutorialMessage" ); + rAssert( m_tutorialMessage != NULL ); + m_tutorialMessage->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_tutorialMessage->CreateBitmapTextBuffer( MAX_TUTORIAL_MESSAGE_LENGTH ); +#ifdef RAD_WIN32 + m_tutorialMessage->ScaleAboutCenter( 0.25f ); +#else + m_tutorialMessage->ScaleAboutCenter( 0.5f ); +#endif + +#ifdef PAL + iconAndMessage->ResetTransformation(); + iconAndMessage->Translate( 0, 15 ); +#endif // PAL + + m_disableTutorial = pPage->GetGroup( "DisableTutorial" ); + rAssert( m_disableTutorial != NULL ); + + Scrooby::Text* disableTutorial = m_disableTutorial->GetText( "DisableTutorial" ); + if( disableTutorial != NULL ) + { + disableTutorial->SetDisplayOutline( true ); + disableTutorial->SetTextMode( Scrooby::TEXT_WRAP ); + } + + Scrooby::Page* pPageSmallBoard = m_pScroobyScreen->GetPage( "SmallBoard" ); + if( pPageSmallBoard != NULL ) + { + this->AutoScaleFrame( pPageSmallBoard ); + +#ifdef PAL + Scrooby::Group* frame = pPageSmallBoard->GetGroup( "Frame" ); + if( frame != NULL ) + { + frame->ResetTransformation(); + frame->ScaleAboutCenter( 1.0f, 1.2f, 1.0f ); + } +#endif // PAL + } + +/* + // get continue icon button + // + pPage = m_pScroobyScreen->GetPage( "Continue" ); + if( pPage != NULL ) + { + m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "Continue" ); + rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL ); + } +*/ +} + +//=========================================================================== +// CGuiScreenTutorial::~CGuiScreenTutorial +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenTutorial::~CGuiScreenTutorial() +{ +} + +//=========================================================================== +// CGuiScreenTutorial::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenTutorial::HandleMessage( eGuiMessage message, + unsigned int param1, + unsigned int param2 ) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + // pulse bart's head + // + m_elapsedDialogTime += param1; + + float currentScale = GuiSFX::Pulse( (float)m_elapsedDialogTime, + 600.0f, + BART_ICON_CORRECTION_SCALE, + 0.1f ); + + rAssert( m_bartsHead != NULL ); + m_bartsHead->ResetTransformation(); + m_bartsHead->ScaleAboutCenter( currentScale ); + +#ifdef WAIT_UNTIL_DIALOG_DONE +/* + #ifndef FINAL + if( m_elapsedDialogTime > MAX_TUTORIAL_DIALOG_TIME ) + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); + + rAssert( m_disableTutorial != NULL ); + m_disableTutorial->SetVisible( true ); + } + else + #endif // !FINAL +*/ + { + this->SetButtonVisible( BUTTON_ICON_ACCEPT, !GetTutorialManager()->IsDialogPlaying() ); + +// rAssert( m_disableTutorial != NULL ); +// m_disableTutorial->SetVisible( !GetTutorialManager()->IsDialogPlaying() ); + } +#endif // WAIT_UNTIL_DIALOG_DONE + + break; + } + case GUI_MSG_CONTROLLER_AUX_X: + { + rAssert( m_disableTutorial != NULL ); + if( m_disableTutorial->IsVisible() ) + { + // disable tutorial events + // + GetTutorialManager()->EnableTutorialEvents( false ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect + + if( GetTutorialManager()->IsDialogPlaying() && + !CommandLineOptions::Get( CLO_MUTE ) ) + { + // if dialog is still playing, stop it! + // (unless all sounds are muted) + // + GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP ); + } + + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); + } + + break; + } + case GUI_MSG_CONTROLLER_SELECT: + { +#ifdef WAIT_UNTIL_DIALOG_DONE + if( !this->IsButtonVisible( BUTTON_ICON_ACCEPT ) ) + { + // ignore input + // + return; + } +#endif + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect + + m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME ); + + break; + } + case GUI_MSG_CONTROLLER_START: + { + // only pause if dialog is still playing + // + if( GetTutorialManager()->IsDialogPlaying() ) + { + m_pParent->HandleMessage( GUI_MSG_PAUSE_INGAME ); + } + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +//=========================================================================== +// CGuiScreenTutorial::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenTutorial::InitIntro() +{ + int index = GetTutorialManager()->GetCurrentEventID(); + + char textBibleID[ 32 ]; + sprintf( textBibleID, "TUTORIAL_%03d", index ); + P3D_UNICODE* text = GetTextBibleString( textBibleID ); + + // check for platform-specific text; if found, override default text + // +#ifdef RAD_GAMECUBE + strcat( textBibleID, "_(GC)" ); +#endif +#ifdef RAD_PS2 + strcat( textBibleID, "_(PS2)" ); +#endif +#ifdef RAD_XBOX + strcat( textBibleID, "_(XBOX)" ); +#endif + P3D_UNICODE* platformText = GetTextBibleString( textBibleID ); + if( platformText != NULL ) + { + text = platformText; + + rTunePrintf( "Replacing default tutorial text with entry: %s\n", textBibleID ); + } + + rAssert( m_tutorialMessage != NULL ); + m_tutorialMessage->SetBitmapText( text ); + +#ifdef WAIT_UNTIL_DIALOG_DONE + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); // hide by default + +// rAssert( m_disableTutorial != NULL ); +// m_disableTutorial->SetVisible( false ); // hide by default + + rAssert( m_bartsHead != NULL ); + m_bartsHead->ResetTransformation(); + m_bartsHead->ScaleAboutCenter( BART_ICON_CORRECTION_SCALE ); + + m_elapsedDialogTime = 0; +#endif + + // + // Inform the sound manager that it's time to turn the sound down a bit + // + GetSoundManager()->OnMissionBriefingStart(); +} + +//=========================================================================== +// CGuiScreenTutorial::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenTutorial::InitRunning() +{ +} + +//=========================================================================== +// CGuiScreenTutorial::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenTutorial::InitOutro() +{ + // + // Turn the sound back up + // + GetSoundManager()->OnMissionBriefingEnd(); +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreentutorial.h b/game/code/presentation/gui/ingame/guiscreentutorial.h new file mode 100644 index 0000000..ad13bc4 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreentutorial.h @@ -0,0 +1,58 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenTutorial +// +// Description: +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/04/15 TChu Created +// +//=========================================================================== + +#ifndef GUISCREENTUTORIAL_H +#define GUISCREENTUTORIAL_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenTutorial : public CGuiScreen +{ +public: + CGuiScreenTutorial( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenTutorial(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + void SetTutorialMessage( int index ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + + static const int MAX_TUTORIAL_MESSAGE_LENGTH = 256; + Scrooby::Sprite* m_tutorialMessage; + Scrooby::Sprite* m_bartsHead; + Scrooby::Group* m_disableTutorial; + + static const unsigned int MAX_TUTORIAL_DIALOG_TIME = 10000; // in msec + unsigned int m_elapsedDialogTime; + +}; + + +#endif // GUISCREENTUTORIAL_H diff --git a/game/code/presentation/gui/ingame/guiscreenviewcards.cpp b/game/code/presentation/gui/ingame/guiscreenviewcards.cpp new file mode 100644 index 0000000..be6bef2 --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenviewcards.cpp @@ -0,0 +1,213 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenViewCards +// +// Description: Implementation of the CGuiScreenViewCards class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/guiscreenviewcards.h> + +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> + +// Scrooby +// +#include <screen.h> +#include <page.h> +#include <layer.h> + +// ATG +// +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenViewCards::CGuiScreenViewCards +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenViewCards::CGuiScreenViewCards +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreenCardGallery( pScreen, pParent, GUI_SCREEN_ID_VIEW_CARDS ), + m_pauseFgdLayer( NULL ), + m_bigBoardFgdLayer( NULL ) +{ + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseFgd" ); + if( pPage != NULL ) + { + m_pauseFgdLayer = pPage->GetLayerByIndex( 0 ); + } + + pPage = m_pScroobyScreen->GetPage( "BigBoard" ); + if( pPage != NULL ) + { + m_bigBoardFgdLayer = pPage->GetLayerByIndex( 0 ); + } + +#ifndef RAD_WIN32 + m_cardScaleLarge = (1.0f / m_cardScaleSmall) * 0.8f; + m_cardScaleSmall = 1.0f; +#endif +} + + +//=========================================================================== +// CGuiScreenViewCards::~CGuiScreenViewCards +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenViewCards::~CGuiScreenViewCards() +{ +} + + +//=========================================================================== +// CGuiScreenViewCards::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCards::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_UPDATE: + { + if( m_pauseFgdLayer != NULL ) + { + m_pauseFgdLayer->SetVisible( m_cardGalleryState == STATE_BROWSING_CARDS ); + } + + if( m_bigBoardFgdLayer != NULL ) + { + m_bigBoardFgdLayer->SetVisible( m_cardGalleryState == STATE_BROWSING_CARDS ); + } + + break; + } + case GUI_MSG_CONTROLLER_START: + { + if( !m_pMenu->HasSelectionBeenMade() && m_cardGalleryState == STATE_BROWSING_CARDS ) + { + // resume game + m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME ); + } + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreenCardGallery::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenViewCards::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCards::InitIntro() +{ + this->UpdateCards( GetGameplayManager()->GetCurrentLevelIndex() ); +} + + +//=========================================================================== +// CGuiScreenViewCards::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCards::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenViewCards::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenViewCards::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/ingame/guiscreenviewcards.h b/game/code/presentation/gui/ingame/guiscreenviewcards.h new file mode 100644 index 0000000..b70e8ca --- /dev/null +++ b/game/code/presentation/gui/ingame/guiscreenviewcards.h @@ -0,0 +1,52 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenViewCards +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENVIEWCARDS_H +#define GUISCREENVIEWCARDS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/frontend/guiscreencardgallery.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenViewCards : public CGuiScreenCardGallery +{ +public: + CGuiScreenViewCards( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenViewCards(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + Scrooby::Layer* m_pauseFgdLayer; + Scrooby::Layer* m_bigBoardFgdLayer; + +}; + +#endif // GUISCREENVIEWCARDS_H diff --git a/game/code/presentation/gui/ingame/hudevents/allhudevents.cpp b/game/code/presentation/gui/ingame/hudevents/allhudevents.cpp new file mode 100644 index 0000000..7a3724f --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/allhudevents.cpp @@ -0,0 +1,9 @@ +#include <presentation/gui/ingame/hudevents/hudeventhandler.cpp> +#include <presentation/gui/ingame/hudevents/hudcardcollected.cpp> +#include <presentation/gui/ingame/hudevents/hudcoincollected.cpp> +#include <presentation/gui/ingame/hudevents/hudmissionprogress.cpp> +#include <presentation/gui/ingame/hudevents/hudmissionobjective.cpp> +#include <presentation/gui/ingame/hudevents/hudcountdown.cpp> +#include <presentation/gui/ingame/hudevents/hudhitnrun.cpp> +#include <presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp> +#include <presentation/gui/ingame/hudevents/huditemdropped.cpp> diff --git a/game/code/presentation/gui/ingame/hudevents/hudcardcollected.cpp b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.cpp new file mode 100644 index 0000000..00d801d --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.cpp @@ -0,0 +1,429 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudCardCollected +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudcardcollected.h> +#include <presentation/gui/utility/specialfx.h> + +#include <cards/cardgallery.h> +#include <mission/gameplaymanager.h> + +// Scrooby +#include <app.h> +#include <page.h> +#include <group.h> +#include <sprite.h> +#include <text.h> + +#ifdef RAD_WIN32 +const float HUDCARD_THUMBNAIL_SCALE = 0.44f; +#endif + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudCardCollected::HudCardCollected( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "ItemCollected" ) ), + m_currentSubState( 0 ), + m_cardImage( NULL ), + m_cardText( NULL ), + m_cardGet( NULL ), + m_cardTitle( NULL ), + m_itemsCount( NULL ), + m_numCards( NULL ), + m_itemsComplete( NULL ), + m_cardDeckComplete( NULL ), + m_isCardDeckComplete( false ), + m_itemsUnlocked( NULL ) +{ + rAssert( pPage != NULL ); + Scrooby::Group* itemCollected = pPage->GetGroup( "ItemCollected" ); + rAssert( itemCollected != NULL ); + m_cardImage = itemCollected->GetSprite( "CardCollected" ); + rAssert( m_cardImage != NULL ); + + m_cardText = itemCollected->GetGroup( "CardText" ); + rAssert( m_cardText != NULL ); + + m_cardGet = m_cardText->GetText( "CardGet" ); + rAssert( m_cardGet != NULL ); + + m_cardTitle = m_cardText->GetText( "CardTitle" ); + rAssert( m_cardTitle != NULL ); + m_cardTitle->SetTextMode( Scrooby::TEXT_WRAP ); + + m_itemsCount = itemCollected->GetGroup( "ItemsCount" ); + rAssert( m_itemsCount != NULL ); + + m_numCards = m_itemsCount->GetSprite( "ItemsCount" ); + rAssert( m_numCards != NULL ); + m_numCards->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_numCards->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE ); + m_numCards->SetBitmapTextSpacing( -8 ); + + m_itemsComplete = itemCollected->GetGroup( "ItemsComplete" ); + rAssert( m_itemsComplete != NULL ); + + m_cardDeckComplete = m_itemsComplete->GetText( "ItemsComplete" ); + rAssert( m_cardDeckComplete != NULL ); + m_cardDeckComplete->SetTextMode( Scrooby::TEXT_WRAP ); + + m_itemsUnlocked = m_itemsComplete->GetText( "ItemsUnlocked" ); + rAssert(m_itemsUnlocked != NULL ); + m_itemsUnlocked->SetTextMode( Scrooby::TEXT_WRAP ); +} + +HudCardCollected::~HudCardCollected() +{ +} + +void +HudCardCollected::Start() +{ + this->OnStart(); + + m_currentSubState = STATE_CARD_TRANSITION_IN; + + // restore drawable properties + // + rAssert( m_cardImage != NULL ); + m_cardImage->ResetTransformation(); + m_cardImage->SetAlpha( 1.0f ); + + rAssert( m_cardText != NULL ); + m_cardText->ResetTransformation(); + m_cardText->SetAlpha( 1.0f ); + + rAssert( m_itemsCount != NULL ); + m_itemsCount->ResetTransformation(); + m_itemsCount->SetAlpha( 1.0f ); + + rAssert( m_itemsComplete != NULL ); + m_itemsComplete->ResetTransformation(); + m_itemsComplete->SetAlpha( 1.0f ); + m_itemsComplete->SetVisible( false ); + + // show all the cards sub-groups + // + m_cardImage->SetVisible( true ); + m_cardText->SetVisible( true ); + + // update card count + // + int currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + const CardList* cardList = GetCardGallery()->GetCollectedCards( currentLevel ); + rAssert( cardList != NULL ); + this->SetCardCount( cardList->m_numCards, NUM_CARDS_PER_LEVEL ); +} + +void +HudCardCollected::Stop() +{ + this->OnStop(); +} + +void +HudCardCollected::Update( float elapsedTime ) +{ + if( m_currentState == STATE_RUNNING ) + { + m_elapsedTime += elapsedTime; + + switch( m_currentSubState ) + { + case STATE_CARD_TRANSITION_IN: + { + const float CARD_TRANSITION_IN_TIME = 500.0f; + + const float centerX = Scrooby::App::GetInstance()->GetScreenWidth() / 2.0f; + const float centerY = Scrooby::App::GetInstance()->GetScreenHeight() / 2.0f; + + rAssert( m_cardImage != NULL ); + m_cardImage->ResetTransformation(); + + int cardCenterX = 0; + int cardCenterY = 0; + m_cardImage->GetBoundingBoxCenter( cardCenterX, cardCenterY ); + + rAssert( m_cardText != NULL ); + m_cardText->ResetTransformation(); + + rAssert( m_itemsCount != NULL ); + + if( m_elapsedTime < CARD_TRANSITION_IN_TIME ) + { + float percentageDone = m_elapsedTime / CARD_TRANSITION_IN_TIME; + + // fade in card image (and scale up) + // + m_cardImage->SetAlpha( percentageDone ); +#ifdef RAD_WIN32 + m_cardImage->ScaleAboutCenter( percentageDone * HUDCARD_THUMBNAIL_SCALE ); +#else + m_cardImage->ScaleAboutCenter( percentageDone ); +#endif + + // apply projectile motion effect to card image + // + const float CARD_GRAVITY = 0.005f; + GuiSFX::Projectile( m_cardImage, + m_elapsedTime, + CARD_TRANSITION_IN_TIME, + rmt::Vector( (float)cardCenterX, (float)cardCenterY, 0.0f ), + rmt::Vector( centerX, centerY, 0.0f ), + true, + CARD_GRAVITY ); + + // scale up card text + // + m_cardText->ScaleAboutCenter( percentageDone ); + + // apply projectile motion effect to card text + // + const float TEXT_GRAVITY = 0.0005f; + GuiSFX::Projectile( m_cardText, + m_elapsedTime, + CARD_TRANSITION_IN_TIME, + rmt::Vector( 0.0f, 0.0f, 0.0f ), + rmt::Vector( 0.0f, 0.0f, 0.0f ), + false, + TEXT_GRAVITY ); + + // fade in card count + // + m_itemsCount->SetAlpha( percentageDone ); +/* + // flash card text + // + GuiSFX::Flash( m_cardGet, m_elapsedTime, CARD_TRANSITION_IN_TIME, 1, 1.1f, 1.0f ); + GuiSFX::Flash( m_cardTitle, m_elapsedTime, CARD_TRANSITION_IN_TIME, 1, 1.1f, 1.0f ); +*/ + } + else + { + m_cardImage->SetAlpha( 1.0f ); + m_itemsCount->SetAlpha( 1.0f ); +#ifdef RAD_WIN32 + m_cardImage->ScaleAboutCenter( HUDCARD_THUMBNAIL_SCALE ); +#endif + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_CARD_DISPLAY_HOLD: + { + const float CARD_DISPLAY_HOLD_TIME = 2000.0f; + + if( m_elapsedTime < CARD_DISPLAY_HOLD_TIME ) + { + // do nothing + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_CARD_TRANSITION_OUT: + { + const float CARD_TRANSITION_OUT_TIME = 300.0f; + + m_itemsComplete->ResetTransformation(); + + if( m_elapsedTime < CARD_TRANSITION_OUT_TIME ) + { + float percentageDone = m_elapsedTime / CARD_TRANSITION_OUT_TIME; + + // slide out card image + // + GuiSFX::SlideY( m_cardImage, + m_elapsedTime, + CARD_TRANSITION_OUT_TIME, + false, + GuiSFX::SLIDE_BORDER_TOP ); + + // slide out card count + // + GuiSFX::SlideY( m_itemsCount, + m_elapsedTime, + CARD_TRANSITION_OUT_TIME, + false, + GuiSFX::SLIDE_BORDER_TOP, + 100 ); + + // fade out card text (and scale up) + // + rAssert( m_cardText != NULL ); + m_cardText->SetAlpha( 1.0f - percentageDone ); + + m_cardText->ResetTransformation(); + m_cardText->ScaleAboutCenter( 1.0f + percentageDone * 0.5f ); + +#ifdef RAD_WIN32 + m_cardImage->ScaleAboutCenter( HUDCARD_THUMBNAIL_SCALE ); +#endif + + if( m_isCardDeckComplete ) + { + m_itemsComplete->SetVisible( true ); + + // scale up card deck complete text + // + m_itemsComplete->ScaleAboutCenter( percentageDone ); + + // apply projectile motion effect to card deck complete text + // + const float TEXT_GRAVITY = 0.005f; + GuiSFX::Projectile( m_itemsComplete, + m_elapsedTime, + CARD_TRANSITION_OUT_TIME, + rmt::Vector( 0.0f, 0.0f, 0.0f ), + rmt::Vector( 0.0f, 0.0f, 0.0f ), + false, + TEXT_GRAVITY ); + } + } + else + { + m_cardText->SetAlpha( 0.0f ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + + if( !m_isCardDeckComplete ) + { + // skip to final sub state + // + m_currentSubState = NUM_SUB_STATES; + } + } + + break; + } + case STATE_CARD_DECK_COMPLETE_DISPLAY_HOLD: + { + const float CARD_DISPLAY_HOLD_TIME = 2000.0f; + + if( m_elapsedTime < CARD_DISPLAY_HOLD_TIME ) + { + // do nothing + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_CARD_DECK_COMPLETE_TRANSITION_OUT: + { + const float CARD_TRANSITION_OUT_TIME = 300.0f; + + if( m_elapsedTime < CARD_TRANSITION_OUT_TIME ) + { + float percentageDone = m_elapsedTime / CARD_TRANSITION_OUT_TIME; + + // fade out card text (and scale up) + // + rAssert( m_itemsComplete != NULL ); + m_itemsComplete->SetAlpha( 1.0f - percentageDone ); + + m_itemsComplete->ResetTransformation(); + m_itemsComplete->ScaleAboutCenter( 1.0f + percentageDone * 0.5f ); + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case NUM_SUB_STATES: + { + // ok, we're done + // + this->Stop(); + + break; + } + default: + { + rAssertMsg( false, "Unhandled sub-state!" ); + break; + } + } + } +} + +void +HudCardCollected::SetCurrentCard( unsigned int cardID ) +{ + rAssert( m_cardImage != NULL ); + m_cardImage->SetIndex( cardID ); + + rAssert( m_cardTitle != NULL ); + m_cardTitle->SetIndex( cardID ); +} + +void +HudCardCollected::SetCardCount( unsigned int numCollected, + unsigned int numCollectibles ) +{ + char buffer[ BITMAP_TEXT_BUFFER_SIZE ]; + sprintf( buffer, "%d/%d", numCollected, numCollectibles ); + + rAssert( m_numCards != NULL ); + m_numCards->SetBitmapText( buffer ); + +#ifndef RAD_DEMO + // set card deck complete flag + // + m_isCardDeckComplete = (numCollected == numCollectibles); + + if( m_isCardDeckComplete && + GetCardGallery()->GetNumCardDecksCompleted() == RenderEnums::numLevels ) + { + // all card decks completed + // + rAssert( m_cardDeckComplete != NULL ); + m_cardDeckComplete->SetIndex( CARD_DECK_COMPLETE ); + + rAssert( m_itemsUnlocked != NULL ); + m_itemsUnlocked->SetIndex( UNLOCKED_IS_MOVIE ); + } +#endif // !RAD_DEMO +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudcardcollected.h b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.h new file mode 100644 index 0000000..619af5c --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.h @@ -0,0 +1,100 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudCardCollected +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDCARDCOLLECTED_H +#define HUDCARDCOLLECTED_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Page; + class Group; + class Sprite; + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudCardCollected : public HudEventHandler +{ +public: + HudCardCollected( Scrooby::Page* pPage ); + virtual ~HudCardCollected(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + + void SetCurrentCard( unsigned int cardID ); + +private: + void SetCardCount( unsigned int numCollected, unsigned int numCollectibles ); + + static const unsigned int BITMAP_TEXT_BUFFER_SIZE = 8; + + enum eSubState + { + STATE_CARD_TRANSITION_IN, + STATE_CARD_DISPLAY_HOLD, + STATE_CARD_TRANSITION_OUT, + + // extra state when last card per level is collected + // + STATE_CARD_DECK_COMPLETE_DISPLAY_HOLD, + STATE_CARD_DECK_COMPLETE_TRANSITION_OUT, + + NUM_SUB_STATES + }; + + unsigned int m_currentSubState; + + Scrooby::Sprite* m_cardImage; + + Scrooby::Group* m_cardText; + Scrooby::Text* m_cardGet; + Scrooby::Text* m_cardTitle; + + Scrooby::Group* m_itemsCount; + Scrooby::Sprite* m_numCards; + + Scrooby::Group* m_itemsComplete; + + enum eCardDeckCompleteMessage + { + LEVEL_CARDS_COMPLETE, + CARD_DECK_COMPLETE + }; + + Scrooby::Text* m_cardDeckComplete; + bool m_isCardDeckComplete : 1; + + enum eItemUnlockedMessage + { + UNLOCKED_MINI_GAME_TRACK, + UNLOCKED_IS_MOVIE + }; + + Scrooby::Text* m_itemsUnlocked; + +}; + +#endif // HUDCARDCOLLECTED_H diff --git a/game/code/presentation/gui/ingame/hudevents/hudcoincollected.cpp b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.cpp new file mode 100644 index 0000000..0728a36 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.cpp @@ -0,0 +1,324 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudCoinCollected +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudcoincollected.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guiscreen.h> + +#include <worldsim/coins/coinmanager.h> + +// Scrooby +#include <app.h> +#include <page.h> +#include <group.h> +#include <sprite.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const short NUMERIC_TEXT_SPACING = -12; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudCoinCollected::HudCoinCollected( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "ItemCollected" ) ), + m_currentSubState( 0 ), + m_cardImage( NULL ), + m_cardText( NULL ), + m_itemsCount( NULL ), + m_numCoins( NULL ), + m_currentItemCount( 0 ), + m_itemsComplete( NULL ), + m_isFullCount( false ), + m_elapsedCoinDecrementTime( 0.0f ) +{ + rAssert( pPage != NULL ); + + m_itemsCount = pPage->GetGroup( "ItemsCount" ); + rAssert( m_itemsCount != NULL ); + + m_numCoins = m_itemsCount->GetSprite( "ItemsCount" ); + rAssert( m_numCoins != NULL ); + m_numCoins->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_numCoins->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE ); + m_numCoins->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING ); +#ifdef RAD_WIN32 + m_numCoins->Translate( 70, 0 ); + m_numCoins->ScaleAboutCenter( 0.5f ); +#endif + + m_itemsComplete = pPage->GetGroup( "ItemsComplete" ); + + Scrooby::Group* itemCollected = pPage->GetGroup( "ItemCollected" ); + rAssert( itemCollected != NULL ); + + m_cardImage = itemCollected->GetSprite( "CardCollected" ); + rAssert( m_cardImage != NULL ); + + m_cardText = itemCollected->GetGroup( "CardText" ); + rAssert( m_cardText != NULL ); + + m_currentItemCount = GetCoinManager()->GetBankValue(); +} + +HudCoinCollected::~HudCoinCollected() +{ +} + +void +HudCoinCollected::Start() +{ + if( m_currentState == STATE_RUNNING ) + { + if( m_currentSubState > STATE_COIN_TRANSITION_IN ) + { + // return to beginning of display hold state + // + m_currentSubState = STATE_COIN_DISPLAY_HOLD; + m_elapsedTime = 0.0f; + m_elapsedCoinDecrementTime = 0.0f; + + // restore drawable properties + // + rAssert( m_itemsCount != NULL ); + m_itemsCount->ResetTransformation(); + m_itemsCount->SetAlpha( 1.0f ); + } + } + else + { + m_currentSubState = STATE_COIN_TRANSITION_IN; + m_elapsedCoinDecrementTime = 0.0f; + + rAssert( m_numCoins != NULL ); + m_numCoins->SetColour( tColour( 255, 255, 255 ) ); + + // restore drawable properties + // + rAssert( m_itemsCount != NULL ); + m_itemsCount->ResetTransformation(); + m_itemsCount->SetAlpha( 0.0f ); + + rAssert( m_itemsComplete != NULL ); + m_itemsComplete->SetVisible( false ); + + // hide all the cards sub-groups + // + m_cardImage->SetVisible( false ); + m_cardText->SetVisible( false ); + } + + this->OnStart(); + + // update coin count + // + this->SetItemCount( static_cast<unsigned int>( m_currentItemCount ), 0 ); +} + +void +HudCoinCollected::Stop() +{ + GetCoinManager()->SetHUDCoin( 0, 0, false ); + + this->OnStop(); +} + +void +HudCoinCollected::Update( float elapsedTime ) +{ + if( m_currentState == STATE_RUNNING ) + { + m_elapsedTime += elapsedTime; + + switch( m_currentSubState ) + { + case STATE_COIN_TRANSITION_IN: + { + const float COIN_TRANSITION_IN_TIME = 200.0f; + + rAssert( m_itemsCount != NULL ); + + if( m_elapsedTime < COIN_TRANSITION_IN_TIME ) + { + float percentageDone = m_elapsedTime / COIN_TRANSITION_IN_TIME; + + // slide in coin count + // + GuiSFX::SlideY( m_itemsCount, + m_elapsedTime, + COIN_TRANSITION_IN_TIME, + true, + GuiSFX::SLIDE_BORDER_TOP, + 100 ); + + // fade in coin coint + // + m_itemsCount->SetAlpha( percentageDone ); + } + else + { + m_itemsCount->ResetTransformation(); + m_itemsCount->SetAlpha( 1.0f ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_COIN_DISPLAY_HOLD: + { + const float COIN_DISPLAY_HOLD_TIME = 2000.0f; + const float COIN_UPDATE_PERIOD = 40.0f; + + if( m_elapsedTime < COIN_DISPLAY_HOLD_TIME ) + { + static int coinPosX = CGuiScreen::IsWideScreenDisplay() ? 500 : 555; + static int coinPosY = 422; + GetCoinManager()->SetHUDCoin( coinPosX, coinPosY, true ); + + int currentBankValue = GetCoinManager()->GetBankValue(); + + rAssert( m_numCoins != NULL ); + if( m_currentItemCount > currentBankValue ) + { + // coin loss + // + m_elapsedCoinDecrementTime += elapsedTime; + + tColour coinColour; + GuiSFX::ModulateColour( &coinColour, + m_elapsedCoinDecrementTime, + COIN_UPDATE_PERIOD * 2, + tColour( 255, 255, 255 ), + tColour( 255, 0, 0 ) ); + + m_numCoins->SetColour( coinColour ); + } + else + { + m_numCoins->SetColour( tColour( 255, 255, 255 ) ); + } + + // update coin change progressively + // + if( m_elapsedTime > COIN_UPDATE_PERIOD ) + { + if( m_currentItemCount < currentBankValue ) + { + m_currentItemCount++; + this->SetItemCount( static_cast<unsigned int>( m_currentItemCount ), 0 ); + + m_elapsedTime -= COIN_UPDATE_PERIOD; + } + else if( m_currentItemCount > currentBankValue ) + { + m_currentItemCount--; + this->SetItemCount( static_cast<unsigned int>( m_currentItemCount ), 0 ); + + GetCoinManager()->AddFlyDownCoin(); + + m_elapsedTime -= COIN_UPDATE_PERIOD; + } + } + } + else + { + GetCoinManager()->SetHUDCoin( 0, 0, false ); + + rAssert( m_numCoins != NULL ); + m_numCoins->SetColour( tColour( 255, 255, 255 ) ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_COIN_TRANSITION_OUT: + { + const float COIN_TRANSITION_OUT_TIME = 200.0f; + + if( m_elapsedTime < COIN_TRANSITION_OUT_TIME ) + { + float percentageDone = m_elapsedTime / COIN_TRANSITION_OUT_TIME; + + // slide out coin count + // + GuiSFX::SlideY( m_itemsCount, + m_elapsedTime, + COIN_TRANSITION_OUT_TIME, + false, + GuiSFX::SLIDE_BORDER_TOP, + 100 ); + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + + if( !m_isFullCount ) + { + // skip to final sub state + // + m_currentSubState = NUM_SUB_STATES; + + } + } + + break; + } + case NUM_SUB_STATES: + { + // ok, we're done + // + this->Stop(); + + break; + } + default: + { + rAssertMsg( false, "Unhandled sub-state!" ); + break; + } + } + } +} + +void +HudCoinCollected::SetItemCount( unsigned int numCollected, + unsigned int numCollectibles ) +{ + char buffer[ BITMAP_TEXT_BUFFER_SIZE ]; + sprintf( buffer, "%d", numCollected ); + + rAssert( m_numCoins != NULL ); + m_numCoins->SetBitmapText( buffer ); + + // set card deck complete flag + // + m_isFullCount = (numCollected == numCollectibles); +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudcoincollected.h b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.h new file mode 100644 index 0000000..08f93bb --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.h @@ -0,0 +1,84 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudCoinCollected +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDCOINCOLLECTED_H +#define HUDCOINCOLLECTED_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Page; + class Group; + class Sprite; + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudCoinCollected : public HudEventHandler +{ +public: + HudCoinCollected( Scrooby::Page* pPage ); + virtual ~HudCoinCollected(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + + void SetCurrentItemCount( int itemCount ); + +private: + void SetItemCount( unsigned int numCollected, unsigned int numCollectibles ); + + static const unsigned int BITMAP_TEXT_BUFFER_SIZE = 8; + + enum eSubState + { + STATE_COIN_TRANSITION_IN, + STATE_COIN_DISPLAY_HOLD, + STATE_COIN_TRANSITION_OUT, + + NUM_SUB_STATES + }; + + unsigned int m_currentSubState; + + Scrooby::Sprite* m_cardImage; + Scrooby::Group* m_cardText; + + Scrooby::Group* m_itemsCount; + Scrooby::Sprite* m_numCoins; + int m_currentItemCount; + + Scrooby::Group* m_itemsComplete; + bool m_isFullCount : 1; + + float m_elapsedCoinDecrementTime; + +}; + +inline void HudCoinCollected::SetCurrentItemCount( int itemCount ) +{ + m_currentItemCount = itemCount; +} + +#endif // HUDCOINCOLLECTED_H diff --git a/game/code/presentation/gui/ingame/hudevents/hudcountdown.cpp b/game/code/presentation/gui/ingame/hudevents/hudcountdown.cpp new file mode 100644 index 0000000..b8fc05f --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudcountdown.cpp @@ -0,0 +1,233 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudCountDown +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudcountdown.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guitextbible.h> + +#include <events/eventmanager.h> +#include <input/controller.h> +#include <input/inputmanager.h> +#include <mission/gameplaymanager.h> +#include <gameflow/gameflow.h> +#include <worldsim/character/charactermanager.h> + +// Scrooby +#include <group.h> +#include <page.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudCountDown::HudCountDown( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "CountDown" ) ), + m_countDownMessage( NULL ), + m_missionStage( NULL ), + m_currentSequenceUnit( NULL ), + m_nextSequenceIndex( 0 ), + m_InputDisablePending( false ), + m_isDialogTriggerPending( false ) +{ +// const float BITMAP_TEXT_SPACING = 0.8f; + + rAssert( pPage != NULL ); + m_countDownMessage = pPage->GetSprite( "CountDown" ); + rAssert( m_countDownMessage != NULL ); + m_countDownMessage->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT ); + m_countDownMessage->CreateBitmapTextBuffer( 32 ); +// m_countDownMessage->SetBitmapTextSpacing( BITMAP_TEXT_SPACING ); +} + +HudCountDown::~HudCountDown() +{ +} + +//============================================================================= +// HudCountDown::OnStart +//============================================================================= +// Description: Called when the HudCountDown starts +// +// Parameters: NONE +// +// Return: void +// +//============================================================================= +void HudCountDown::OnStart() +{ + Parent::OnStart(); +} + +//============================================================================= +// HudCountDown::QueueDisableInput +//============================================================================= +// Description: tells the object that the next time update is called, we need +// to disable the input system +// +// Parameters: NONE +// +// Return: void +// +//============================================================================= +void HudCountDown::QueueDisableInput() +{ + m_InputDisablePending = true; +} + +void +HudCountDown::Start() +{ + Character* npcPtr; + const char* modelName; + + this->OnStart(); + + m_missionStage = GetGameplayManager()->GetCurrentMission()->GetCurrentStage(); + + m_nextSequenceIndex = 0; + this->GetNextSequenceUnit(); + + // get dialog event data and queue it up for triggering on the next update + // + BonusMissionInfo* bonusMissionInfo = const_cast<BonusMissionInfo*>( GetGameplayManager()->GetCurrentBonusMissionInfo() ); + if( bonusMissionInfo != NULL ) + { + npcPtr = bonusMissionInfo->GetNPC(); + rAssert( npcPtr != NULL ); + modelName = GetCharacterManager()->GetModelName( npcPtr ); + + m_dialogData.charUID1 = tEntity::MakeUID( modelName ); + m_dialogData.charUID2 = m_missionStage->GetCountdownSecondSpeakerUID(); + m_dialogData.dialogName = m_missionStage->GetCountdownDialogID(); + + m_isDialogTriggerPending = true; + } + + QueueDisableInput(); +} + +void +HudCountDown::Stop() +{ + m_missionStage = NULL; + m_currentSequenceUnit = NULL; + + // enable the controller - yes i know this is not an animated cam + // + if( GetInputManager()->GetGameState() == Input::ACTIVE_ANIM_CAM ) + { + InputManager::GetInstance()->SetGameState( Input::DEACTIVE_ANIM_CAM ); + } + + this->OnStop(); +} + +void +HudCountDown::Update( float elapsedTime ) +{ + if( m_InputDisablePending ) + { + // disable the controller - yes i know this is not an animated cam + // + InputManager::GetInstance()->SetGameState( Input::ACTIVE_ANIM_CAM ); + m_InputDisablePending = false; + } + + if( m_currentState == STATE_RUNNING ) + { + if( m_isDialogTriggerPending ) + { + m_isDialogTriggerPending = false; + + GetEventManager()->TriggerEvent( EVENT_IN_GAMEPLAY_CONVERSATION, static_cast<void*>( &m_dialogData ) ); + } + +#ifdef RAD_WIN32 + static float COUNT_DOWN_MAX_SCALE = 1.5f; +#else + static float COUNT_DOWN_MAX_SCALE = 3.0f; +#endif + static float COUNT_DOWN_THRESHOLD_SCALE = 2.5f; + static int COUNT_DOWN_ZOOM_RATE = 2; + + if( m_currentSequenceUnit != NULL ) + { + bool done = GuiSFX::Flash( m_countDownMessage, + m_elapsedTime, + (float)m_currentSequenceUnit->durationTime, + COUNT_DOWN_ZOOM_RATE, + COUNT_DOWN_MAX_SCALE, + COUNT_DOWN_THRESHOLD_SCALE ); + if( done ) + { + m_elapsedTime = 0; + + this->GetNextSequenceUnit(); + } + } + else + { + // countdown finished + // + this->Stop(); + + // start the mission! + // + GetEventManager()->TriggerEvent( EVENT_GUI_MISSION_START ); + + // + // Take all the AI cars out of the limbo state + // + MissionStage* stage = GetGameplayManager()->GetCurrentMission()->GetCurrentStage(); + rAssert( stage != NULL ); + stage->PutAllAisInLimbo( false ); + } + + m_elapsedTime += elapsedTime; + } +} + +void +HudCountDown::GetNextSequenceUnit() +{ + rAssert( m_missionStage != NULL ); + m_currentSequenceUnit = m_missionStage->GetCountdownSequenceUnit( m_nextSequenceIndex ); + + if( m_currentSequenceUnit != NULL ) + { + // set text message + // + rAssert( m_countDownMessage != NULL ); + m_countDownMessage->SetAlpha( 0.0f ); + + P3D_UNICODE* text = GetTextBibleString( m_currentSequenceUnit->textID ); + if( text != NULL ) + { + m_countDownMessage->SetBitmapText( text ); + } + else + { + m_countDownMessage->SetBitmapText( "" ); + } + } + + m_nextSequenceIndex++; +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudcountdown.h b/game/code/presentation/gui/ingame/hudevents/hudcountdown.h new file mode 100644 index 0000000..4ea50b0 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudcountdown.h @@ -0,0 +1,69 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudCountDown +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDCOUNTDOWN_H +#define HUDCOUNTDOWN_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> +#include <mission/missionstage.h> +#include <events/eventdata.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Page; + class Sprite; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudCountDown : public HudEventHandler +{ +private: + typedef HudEventHandler Parent; + +public: + HudCountDown( Scrooby::Page* pPage ); + virtual ~HudCountDown(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + +protected: + void OnStart(); + void QueueDisableInput(); + +private: + void GetNextSequenceUnit(); + + Scrooby::Sprite* m_countDownMessage; + + MissionStage* m_missionStage; + MissionStage::CountdownSequenceUnit* m_currentSequenceUnit; + int m_nextSequenceIndex; + bool m_InputDisablePending; + + bool m_isDialogTriggerPending; + DialogEventData m_dialogData; + +}; + +#endif // HUDCOUNTDOWN_H diff --git a/game/code/presentation/gui/ingame/hudevents/hudeventhandler.cpp b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.cpp new file mode 100644 index 0000000..378401e --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.cpp @@ -0,0 +1,77 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudEventHandler +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> + +// Scrooby +#include <group.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudEventHandler::HudEventHandler( Scrooby::Group* drawableGroup ) +: m_drawableGroup( drawableGroup ), + m_elapsedTime( 0.0f ), + m_currentState( STATE_IDLE ) +{ + rAssert( drawableGroup != NULL ); + drawableGroup->SetVisible( false ); +} + +HudEventHandler::~HudEventHandler() +{ +} + +void +HudEventHandler::OnStart() +{ + if( m_currentState != STATE_RUNNING ) + { + // show all drawable elements in group + // + rAssert( m_drawableGroup != NULL ); + m_drawableGroup->SetVisible( true ); + + // reset elapsed time + // + m_elapsedTime = 0.0; + + // update current state + // + m_currentState = STATE_RUNNING; + } +} + +void +HudEventHandler::OnStop() +{ + if( m_currentState != STATE_IDLE ) + { + // hide all drawable elements in group + // + rAssert( m_drawableGroup != NULL ); + m_drawableGroup->SetVisible( false ); + + // update current state + // + m_currentState = STATE_IDLE; + } +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudeventhandler.h b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.h new file mode 100644 index 0000000..fcb931d --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.h @@ -0,0 +1,69 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudEventHandler +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDEVENTHANDLER_H +#define HUDEVENTHANDLER_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Group; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudEventHandler +{ +public: + HudEventHandler( Scrooby::Group* drawableGroup ); + virtual ~HudEventHandler(); + + virtual void Start() = 0; + virtual void Stop() = 0; + virtual void Update( float elapsedTime ) = 0; + + bool IsActive() const; + +protected: + void OnStart(); + void OnStop(); + + Scrooby::Group* m_drawableGroup; + float m_elapsedTime; + + enum eState + { + STATE_IDLE, + STATE_RUNNING, + + NUM_STATES + }; + + eState m_currentState; + +}; + +inline bool HudEventHandler::IsActive() const +{ + return( m_currentState != STATE_IDLE ); +} + +#endif // HUDEVENTHANDLER_H diff --git a/game/code/presentation/gui/ingame/hudevents/hudhitnrun.cpp b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.cpp new file mode 100644 index 0000000..17c1da3 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.cpp @@ -0,0 +1,297 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudHitNRun +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudhitnrun.h> +#include <presentation/gui/utility/specialfx.h> + +// Scrooby +#include <app.h> +#include <group.h> +#include <page.h> +#include <text.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#ifdef RAD_WIN32 +const float HNR_MESSAGE_SCALE = 1.75f; +const float HNR_MESSAGE_BUSTED_SCALE = 2.0f; +const float HNR_TICKET_SCALE = 1.0f; +const float HNR_MESSAGE_BUSTED_TILT_ANGLE = -10.0f; // in degrees +const tColour HNR_MESSAGE_BUSTED_COLOUR( 43, 89, 249 ); +#else +const float HNR_MESSAGE_SCALE = 1.75f; +const float HNR_MESSAGE_BUSTED_SCALE = 2.0f; +const float HNR_TICKET_SCALE = 2.0f; +const float HNR_MESSAGE_BUSTED_TILT_ANGLE = -10.0f; // in degrees +const tColour HNR_MESSAGE_BUSTED_COLOUR( 43, 89, 249 ); +#endif + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudHitNRun::HudHitNRun( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "HitNRun" ) ), + m_currentSubState( 0 ), + m_currentMessage( MSG_HIT_N_RUN ), + m_hnrMessage( NULL ), + m_hnrTicket( NULL ), + m_messageTranslateX( 0 ), + m_messageTranslateY( 0 ), + m_defaultMessageColour( 100, 0, 0 ) +{ + rAssert( pPage != NULL ); + + Scrooby::Group* pGroup = pPage->GetGroup( "HitNRun" ); + rAssert( pGroup != NULL ); + + m_hnrMessage = pGroup->GetText( "HitNRun" ); + rAssert( m_hnrMessage != NULL ); + m_hnrMessage->SetTextMode( Scrooby::TEXT_WRAP ); + m_hnrMessage->SetDisplayOutline( true ); + +// m_defaultMessageColour = m_hnrMessage->GetColour(); + + m_hnrTicket = pGroup->GetSprite( "HitNRunTicket" ); + + int messageCenterX = 0; + int messageCenterY = 0; + m_hnrMessage->GetBoundingBoxCenter( messageCenterX, messageCenterY ); + + Scrooby::Sprite* radar = pPage->GetSprite( "Radar0" ); + rAssert( radar != NULL ); + radar->GetBoundingBoxCenter( m_messageTranslateX, m_messageTranslateY ); + + m_messageTranslateX -= messageCenterX; + m_messageTranslateY -= messageCenterY; +} + +HudHitNRun::~HudHitNRun() +{ +} + +void +HudHitNRun::Start() +{ + if( m_currentState != STATE_RUNNING ) + { + m_currentSubState = STATE_MESSAGE_TRANSITION_IN; + + rAssert( m_hnrMessage != NULL ); + m_hnrMessage->SetIndex( m_currentMessage ); + m_hnrMessage->SetAlpha( 0.0f ); + m_hnrMessage->SetColour( m_currentMessage == MSG_BUSTED ? + HNR_MESSAGE_BUSTED_COLOUR : + m_defaultMessageColour ); // restore default colour + + rAssert( m_hnrTicket != NULL ); + m_hnrTicket->SetAlpha( 0.0f ); + m_hnrTicket->SetVisible( m_currentMessage == MSG_BUSTED ); + } + + this->OnStart(); +} + +void +HudHitNRun::Stop() +{ + this->OnStop(); +} + +void +HudHitNRun::Update( float elapsedTime ) +{ + if( m_currentState == STATE_RUNNING ) + { + m_elapsedTime += elapsedTime; + + switch( m_currentSubState ) + { + case STATE_MESSAGE_TRANSITION_IN: + { + const float MESSAGE_TRANSITION_TIME = 200.0f; + + rAssert( m_hnrMessage != NULL ); + m_hnrMessage->ResetTransformation(); + + rAssert( m_hnrTicket != NULL ); + m_hnrTicket->ResetTransformation(); + + if( m_elapsedTime < MESSAGE_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / MESSAGE_TRANSITION_TIME; + + m_hnrMessage->SetAlpha( percentageDone ); + + if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN ) + { + m_hnrMessage->ScaleAboutCenter( percentageDone * HNR_MESSAGE_SCALE ); + } + else + { + m_hnrMessage->ScaleAboutCenter( percentageDone * HNR_MESSAGE_BUSTED_SCALE ); + m_hnrMessage->RotateAboutCenter( percentageDone * HNR_MESSAGE_BUSTED_TILT_ANGLE ); + + m_hnrTicket->SetAlpha( percentageDone ); + m_hnrTicket->ScaleAboutCenter( percentageDone * HNR_TICKET_SCALE ); + + GuiSFX::Projectile( m_hnrTicket, + m_elapsedTime, + MESSAGE_TRANSITION_TIME, + rmt::Vector( 0, 0, 0 ), + rmt::Vector( (float)m_messageTranslateX, (float)m_messageTranslateY, 0 ), + true, + 0.0f ); + } + + GuiSFX::Projectile( m_hnrMessage, + m_elapsedTime, + MESSAGE_TRANSITION_TIME, + rmt::Vector( 0, 0, 0 ), + rmt::Vector( (float)m_messageTranslateX, (float)m_messageTranslateY, 0 ), + true, + 0.0f ); + } + else + { + m_hnrMessage->SetAlpha( 1.0f ); + + if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN ) + { + m_hnrMessage->ScaleAboutCenter( HNR_MESSAGE_SCALE ); + } + else + { + m_hnrMessage->ScaleAboutCenter( HNR_MESSAGE_BUSTED_SCALE ); + m_hnrMessage->RotateAboutCenter( HNR_MESSAGE_BUSTED_TILT_ANGLE ); + + m_hnrTicket->SetAlpha( 1.0f ); + m_hnrTicket->ScaleAboutCenter( HNR_TICKET_SCALE ); + } + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_MESSAGE_DISPLAY_HOLD: + { + const float MESSAGE_DISPLAY_HOLD_TIME = 1200.0f; + + rAssert( m_hnrMessage != NULL ); + if( m_elapsedTime < MESSAGE_DISPLAY_HOLD_TIME ) + { + if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN ) + { + static tColour MESSAGE_OTHER_COLOUR( 240, 8, 8 ); + + tColour currentColour; + GuiSFX::ModulateColour( ¤tColour, + m_elapsedTime, + 333.3f, + m_defaultMessageColour, + MESSAGE_OTHER_COLOUR, + rmt::PI_BY2 ); + + m_hnrMessage->SetColour( currentColour ); + } + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_MESSAGE_TRANSITION_OUT: + { + const float MESSAGE_TRANSITION_TIME = 200.0f; + + rAssert( m_hnrMessage != NULL ); + m_hnrMessage->ResetTransformation(); + + rAssert( m_hnrTicket != NULL ); + m_hnrTicket->ResetTransformation(); + + if( m_elapsedTime < MESSAGE_TRANSITION_TIME ) + { + float percentageDone = m_elapsedTime / MESSAGE_TRANSITION_TIME; + + if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN ) + { + m_hnrMessage->SetAlpha( 1.0f - percentageDone ); + m_hnrMessage->ScaleAboutCenter( (1.0f - percentageDone) * HNR_MESSAGE_SCALE ); + + GuiSFX::Projectile( m_hnrMessage, + m_elapsedTime, + MESSAGE_TRANSITION_TIME, + rmt::Vector( 0, 0, 0 ), + rmt::Vector( (float)m_messageTranslateX, (float)m_messageTranslateY, 0 ), + false, + 0.0f ); + } + else + { + m_hnrMessage->SetAlpha( 0.0f ); + + m_hnrTicket->ScaleAboutCenter( (percentageDone * 3 + 1.0f) * HNR_TICKET_SCALE ); + m_hnrTicket->SetAlpha( 1.0f - percentageDone ); + } + } + else + { + m_hnrMessage->SetAlpha( 0.0f ); + m_hnrTicket->SetAlpha( 0.0f ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case NUM_SUB_STATES: + { + // ok, we're done + // + this->Stop(); + + break; + } + default: + { + rAssertMsg( false, "Unhandled sub-state!" ); + break; + } + } + } +} + +void +HudHitNRun::SetMessage( eMessage message ) +{ + m_currentMessage = message; +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudhitnrun.h b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.h new file mode 100644 index 0000000..778a867 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.h @@ -0,0 +1,81 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudHitNRun +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDHITNRUN_H +#define HUDHITNRUN_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> + +#include <p3d/p3dtypes.hpp> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Page; + class Text; + class Sprite; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudHitNRun : public HudEventHandler +{ +public: + HudHitNRun( Scrooby::Page* pPage ); + virtual ~HudHitNRun(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + + enum eMessage + { + MSG_HIT_N_RUN, + MSG_BUSTED, + + NUM_MESSAGES + }; + + void SetMessage( eMessage message ); + +private: + enum eSubState + { + STATE_MESSAGE_TRANSITION_IN, + STATE_MESSAGE_DISPLAY_HOLD, + STATE_MESSAGE_TRANSITION_OUT, + + NUM_SUB_STATES + }; + + unsigned int m_currentSubState; + + eMessage m_currentMessage; + Scrooby::Text* m_hnrMessage; + Scrooby::Sprite* m_hnrTicket; + + int m_messageTranslateX; + int m_messageTranslateY; + + tColour m_defaultMessageColour; + +}; + +#endif // HUDHITNRUN_H diff --git a/game/code/presentation/gui/ingame/hudevents/huditemdropped.cpp b/game/code/presentation/gui/ingame/hudevents/huditemdropped.cpp new file mode 100644 index 0000000..38eb6f7 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/huditemdropped.cpp @@ -0,0 +1,217 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudItemDropped +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/huditemdropped.h> +#include <presentation/gui/utility/specialfx.h> + +// Scrooby +#include <page.h> +#include <group.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudItemDropped::HudItemDropped( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "ItemDropped" ) ), + m_currentSubState( 0 ), + m_itemDropped( NULL ) +{ + m_itemDropped = m_drawableGroup->GetText( "ItemDropped" ); + rAssert( m_itemDropped != NULL ); + m_itemDropped->SetTextMode( Scrooby::TEXT_WRAP ); +} + +HudItemDropped::~HudItemDropped() +{ +} + +void +HudItemDropped::Start() +{ + this->OnStart(); + + m_currentSubState = STATE_TRANSITION_IN; + + rAssert( m_itemDropped != NULL ); + m_itemDropped->ResetTransformation(); + m_itemDropped->SetAlpha( 0.0f ); + m_itemDropped->SetVisible( true ); +} + +void +HudItemDropped::Stop() +{ + this->OnStop(); +} + +void +HudItemDropped::Update( float elapsedTime ) +{ + if( m_currentState == STATE_RUNNING ) + { + m_elapsedTime += elapsedTime; + + switch( m_currentSubState ) + { + case STATE_TRANSITION_IN: + { + const float TRANSITION_IN_TIME = 200.0f; + + rAssert( m_itemDropped != NULL ); + m_itemDropped->ResetTransformation(); + + if( m_elapsedTime < TRANSITION_IN_TIME ) + { + float percentageDone = m_elapsedTime / TRANSITION_IN_TIME; + + // slide in from HUD icon + // + m_itemDropped->Translate( 0, static_cast<int>( (1.0f - percentageDone) * 100 ) ); + + // fade in coin coint + // + m_itemDropped->SetAlpha( percentageDone ); + } + else + { + m_itemDropped->ResetTransformation(); + m_itemDropped->SetAlpha( 1.0f ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_DISPLAY_HOLD: + { + const float BLINKING_PERIOD = 250.0f; + + bool isBlinked = GuiSFX::Blink( m_itemDropped, + m_elapsedTime, + BLINKING_PERIOD ); + + if( isBlinked ) + { + m_elapsedTime = static_cast<float>( static_cast<int>( m_elapsedTime ) % + static_cast<int>( BLINKING_PERIOD ) ); + } +/* + const float DISPLAY_HOLD_TIME = 2000.0f; + + if( m_elapsedTime < DISPLAY_HOLD_TIME ) + { + static int coinPosX = CGuiScreen::IsWideScreenDisplay() ? 500 : 555; + static int coinPosY = 422; + GetCoinManager()->SetHUDCoin( coinPosX, coinPosY, true ); + + int currentBankValue = GetCoinManager()->GetBankValue(); + + rAssert( m_numCoins != NULL ); + if( m_currentItemCount > currentBankValue ) + { + // coin loss + // + m_elapsedCoinDecrementTime += elapsedTime; + + tColour coinColour; + GuiSFX::ModulateColour( &coinColour, + m_elapsedCoinDecrementTime, + UPDATE_PERIOD * 2, + tColour( 255, 255, 255 ), + tColour( 255, 0, 0 ) ); + + m_numCoins->SetColour( coinColour ); + } + else + { + m_numCoins->SetColour( tColour( 255, 255, 255 ) ); + } + } + else + { + GetCoinManager()->SetHUDCoin( 0, 0, false ); + + rAssert( m_numCoins != NULL ); + m_numCoins->SetColour( tColour( 255, 255, 255 ) ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } +*/ + break; + } + case STATE_TRANSITION_OUT: + { + const float TRANSITION_OUT_TIME = 200.0f; +/* + if( m_elapsedTime < TRANSITION_OUT_TIME ) + { + float percentageDone = m_elapsedTime / TRANSITION_OUT_TIME; + + // slide out coin count + // + GuiSFX::SlideY( m_itemsCount, + m_elapsedTime, + TRANSITION_OUT_TIME, + false, + GuiSFX::SLIDE_BORDER_TOP, + 100 ); + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + + if( !m_isFullCount ) + { + // skip to final sub state + // + m_currentSubState = NUM_SUB_STATES; + + } + } +*/ + break; + } + case NUM_SUB_STATES: + { + // ok, we're done + // + this->Stop(); + + break; + } + default: + { + rAssertMsg( false, "Unhandled sub-state!" ); + break; + } + } + } +} + diff --git a/game/code/presentation/gui/ingame/hudevents/huditemdropped.h b/game/code/presentation/gui/ingame/hudevents/huditemdropped.h new file mode 100644 index 0000000..824c001 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/huditemdropped.h @@ -0,0 +1,61 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudItemDropped +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDITEMDROPPED_H +#define HUDITEMDROPPED_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Page; + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudItemDropped : public HudEventHandler +{ +public: + HudItemDropped( Scrooby::Page* pPage ); + virtual ~HudItemDropped(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + +private: + enum eSubState + { + STATE_TRANSITION_IN, + STATE_DISPLAY_HOLD, + STATE_TRANSITION_OUT, + + NUM_SUB_STATES + }; + + unsigned int m_currentSubState; + + Scrooby::Text* m_itemDropped; + +}; + +#endif // HUDITEMDROPPED_H diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.cpp b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.cpp new file mode 100644 index 0000000..a6b2e05 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.cpp @@ -0,0 +1,255 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudMissionObjective +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudmissionobjective.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/utility/specialfx.h> + +#include <mission/gameplaymanager.h> +#include <mission/mission.h> +#include <mission/missionstage.h> + +// Scrooby +#include <group.h> +#include <page.h> +#include <sprite.h> + +// Pure3D +#include <p3d/utility.hpp> +#include <p3d/sprite.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const int HUD_ICON_SLIDE_DISTANCE = 310; // vertical distance in pixels + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudMissionObjective::HudMissionObjective( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "MissionObjective" ) ), + m_currentSubState( STATE_ICON_POP_UP ), + m_missionIcon( NULL ), + m_missionIconImage( NULL ), + m_messageID( 0 ) +{ + rAssert( pPage != NULL ); + + m_missionIcon = pPage->GetSprite( "ObjectiveIcon" ); + rAssert( m_missionIcon != NULL ); + + m_iconTranslator.SetDrawable( m_missionIcon ); + m_iconTranslator.SetStartOffscreenBottom( m_missionIcon ); + m_iconTranslator.SetFrequency( 5.0f ); + m_iconTranslator.SetTimeInterval( 500.0f ); + + bool isIconFound = this->UpdateIcon(); + if( isIconFound ) + { + this->OnStart(); + + m_missionIcon->ResetTransformation(); + m_missionIcon->ScaleAboutCenter( MISSION_ICON_SCALE ); + m_missionIcon->Translate( 0, HUD_ICON_SLIDE_DISTANCE ); + + m_currentSubState = STATE_IDLE; + } +} + +HudMissionObjective::~HudMissionObjective() +{ + if( m_missionIconImage != NULL ) + { + m_missionIconImage->Release(); + m_missionIconImage = NULL; + } +} + +void +HudMissionObjective::Start() +{ + this->OnStart(); + + m_currentSubState = STATE_ICON_POP_UP; + + bool isIconFound = this->UpdateIcon(); + if( isIconFound ) + { + m_iconTranslator.Reset(); + m_iconTranslator.Activate(); + } + else + { + m_iconTranslator.Deactivate(); + } +} + +void +HudMissionObjective::Stop() +{ + CGuiScreenHud* currentHud = GetCurrentHud(); + if( currentHud != NULL ) + { + currentHud->DisplayMessage( false ); + } + + rAssert( m_missionIcon != NULL ); + m_missionIcon->SetRawSprite( NULL ); + m_missionIcon->SetVisible( false ); + + if( m_missionIconImage != NULL ) + { + m_missionIconImage->Release(); + m_missionIconImage = NULL; + } + + this->OnStop(); +} + +void +HudMissionObjective::Update( float elapsedTime ) +{ + if( m_currentState == STATE_RUNNING ) + { + m_elapsedTime += elapsedTime; + + switch( m_currentSubState ) + { + case STATE_ICON_POP_UP: + { + rAssert( m_missionIcon != NULL ); + m_missionIcon->ResetTransformation(); + m_missionIcon->ScaleAboutCenter( MISSION_ICON_SCALE ); + + if( !m_iconTranslator.IsDone() ) + { + m_iconTranslator.Update( elapsedTime ); + } + else + { + m_iconTranslator.Deactivate(); + + CGuiScreenHud* currentHud = GetCurrentHud(); + rAssert( currentHud != NULL ); + currentHud->DisplayMessage( true, m_messageID ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_ICON_DISPLAY_HOLD: + { + const float DISPLAY_HOLD_TIME = 3000.0f; + + if( m_elapsedTime < DISPLAY_HOLD_TIME ) + { + // do nothing + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_ICON_SLIDE_UP: + { + const float SLIDE_UP_TIME = 200.0f; + + rAssert( m_missionIcon != NULL ); + m_missionIcon->ResetTransformation(); + m_missionIcon->ScaleAboutCenter( MISSION_ICON_SCALE ); + + if( m_elapsedTime < SLIDE_UP_TIME ) + { + int translateY = (int)( (m_elapsedTime / SLIDE_UP_TIME) * HUD_ICON_SLIDE_DISTANCE ); + m_missionIcon->Translate( 0, translateY ); + } + else + { + m_missionIcon->Translate( 0, HUD_ICON_SLIDE_DISTANCE ); + + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_IDLE: + { + // do nothing + // + break; + } + case NUM_SUB_STATES: + { + rAssertMsg( false, "We shouldn't be here; last sub-state should be IDLE." ); + + break; + } + default: + { + rAssertMsg( false, "Unhandled sub-state!" ); + + break; + } + } + } +} + +bool +HudMissionObjective::UpdateIcon() +{ + tSprite* pSprite = NULL; + + Mission* currentMission = GetGameplayManager()->GetCurrentMission(); + if( currentMission != NULL ) + { + MissionStage* currentStage = currentMission->GetCurrentStage(); + if( currentStage != NULL ) + { + const char* iconName = currentStage->GetHUDIcon(); + if( iconName[ 0 ] != '\0' ) + { + pSprite = p3d::find<tSprite>( iconName ); + rTuneWarningMsg( pSprite != NULL, "Can't find HUD icon for mission presentation!" ); + } + } + } + + rAssert( m_missionIcon != NULL ); + m_missionIcon->SetVisible( pSprite != NULL ); + m_missionIcon->SetRawSprite( pSprite, true ); + + if( pSprite != NULL ) + { + tRefCounted::Assign( m_missionIconImage, pSprite ); + } + + return (pSprite != NULL); +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.h b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.h new file mode 100644 index 0000000..7e9c217 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.h @@ -0,0 +1,84 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudMissionObjective +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDMISSIONOBJECTIVE_H +#define HUDMISSIONOBJECTIVE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> +#include <presentation/gui/utility/transitions.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +#ifdef RAD_WIN32 // temporary.. for art testing. +const float MISSION_ICON_SCALE = 0.78f; +#else +const float MISSION_ICON_SCALE = 1.5f; +#endif + +namespace Scrooby +{ + class Page; + class Sprite; +} + +class tSprite; + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudMissionObjective : public HudEventHandler +{ +public: + HudMissionObjective( Scrooby::Page* pPage ); + virtual ~HudMissionObjective(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + + void SetMessageID( unsigned int messageID ); + bool UpdateIcon(); + +private: + enum eSubState + { + STATE_ICON_POP_UP, + STATE_ICON_DISPLAY_HOLD, + STATE_ICON_SLIDE_UP, + STATE_IDLE, + + NUM_SUB_STATES + }; + + unsigned int m_currentSubState; + + Scrooby::Sprite* m_missionIcon; + tSprite* m_missionIconImage; + unsigned int m_messageID; + + GuiSFX::UnderdampedTranslator m_iconTranslator; + +}; + +inline void +HudMissionObjective::SetMessageID( unsigned int messageID ) +{ + m_messageID = messageID; +} + +#endif // HUDMISSIONOBJECTIVE_H diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.cpp b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.cpp new file mode 100644 index 0000000..be85e76 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.cpp @@ -0,0 +1,83 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudMissionProgress +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudmissionprogress.h> +#include <presentation/gui/utility/specialfx.h> + +// Scrooby +#include <group.h> +#include <page.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudMissionProgress::HudMissionProgress( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "MissionProgress" ) ), + m_stageComplete( NULL ) +{ + rAssert( pPage != NULL ); + + Scrooby::Group* missionProgress = pPage->GetGroup( "MissionProgress" ); + rAssert( missionProgress != NULL ); + + m_stageComplete = missionProgress->GetText( "StageComplete" ); + rAssert( m_stageComplete != NULL ); + m_stageComplete->SetTextMode( Scrooby::TEXT_WRAP ); +} + +HudMissionProgress::~HudMissionProgress() +{ +} + +void +HudMissionProgress::Start() +{ + this->OnStart(); +} + +void +HudMissionProgress::Stop() +{ + this->OnStop(); +} + +void +HudMissionProgress::Update( float elapsedTime ) +{ + if( m_currentState == STATE_RUNNING ) + { + m_elapsedTime += elapsedTime; + + static float DURATION_TIME = 1000.0f; + + bool isDone = GuiSFX::Flash( m_stageComplete, + m_elapsedTime, + DURATION_TIME, + 1, + 1.25f, + 1.0f ); + if( isDone ) + { + this->Stop(); + } + } +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.h b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.h new file mode 100644 index 0000000..11623f2 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.h @@ -0,0 +1,50 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudMissionProgress +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDMISSIONPROGRESS_H +#define HUDMISSIONPROGRESS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Page; + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudMissionProgress : public HudEventHandler +{ +public: + HudMissionProgress( Scrooby::Page* pPage ); + virtual ~HudMissionProgress(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + +private: + Scrooby::Text* m_stageComplete; + +}; + +#endif // HUDMISSIONPROGRESS_H diff --git a/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp new file mode 100644 index 0000000..3c3a879 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp @@ -0,0 +1,184 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudWaspDestroyed +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudwaspdestroyed.h> +#include <presentation/gui/utility/specialfx.h> + +#include <mission/gameplaymanager.h> +#include <mission/charactersheet/charactersheetmanager.h> +#include <mission/rewards/rewardsmanager.h> + +// Scrooby +#include <page.h> +#include <group.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudWaspDestroyed::HudWaspDestroyed( Scrooby::Page* pPage ) +: HudEventHandler( pPage->GetGroup( "WaspsDestroyed" ) ), + m_currentSubState( 0 ), + m_itemsComplete( NULL ), + m_isGagInsteadOfWasp( false ) +{ + m_itemsComplete = m_drawableGroup->GetText( "WaspsComplete" ); + rAssert( m_itemsComplete != NULL ); +} + +HudWaspDestroyed::~HudWaspDestroyed() +{ +} + +void +HudWaspDestroyed::Start() +{ + RenderEnums::LevelEnum currentLevel = GetGameplayManager()->GetCurrentLevelIndex(); + + bool isComplete = m_isGagInsteadOfWasp ? + GetCharacterSheetManager()->QueryNumGagsViewed( currentLevel ) == GetRewardsManager()->GetTotalGags( currentLevel ) : + GetCharacterSheetManager()->QueryNumWaspsDestroyed( currentLevel ) == GetRewardsManager()->GetTotalWasps( currentLevel ); + + if( isComplete ) + { + this->OnStart(); + + m_currentSubState = STATE_WASP_TRANSITION_IN; + + // restore drawable properties + // + rAssert( m_itemsComplete != NULL ); + m_itemsComplete->ResetTransformation(); + m_itemsComplete->SetAlpha( 1.0f ); + m_itemsComplete->SetIndex( m_isGagInsteadOfWasp ? 1 : 0 ); + } +} + +void +HudWaspDestroyed::Stop() +{ + this->OnStop(); +} + +void +HudWaspDestroyed::Update( float elapsedTime ) +{ + if( m_currentState == STATE_RUNNING ) + { + m_elapsedTime += elapsedTime; + + switch( m_currentSubState ) + { + case STATE_WASP_TRANSITION_IN: + { + const float CARD_TRANSITION_IN_TIME = 300.0f; + + m_itemsComplete->ResetTransformation(); + + if( m_elapsedTime < CARD_TRANSITION_IN_TIME ) + { + float percentageDone = m_elapsedTime / CARD_TRANSITION_IN_TIME; + + // scale up card deck complete text + // + m_itemsComplete->ScaleAboutCenter( percentageDone ); + + // apply projectile motion effect to card deck complete text + // + const float TEXT_GRAVITY = 0.005f; + GuiSFX::Projectile( m_itemsComplete, + m_elapsedTime, + CARD_TRANSITION_IN_TIME, + rmt::Vector( 0.0f, 0.0f, 0.0f ), + rmt::Vector( 0.0f, 0.0f, 0.0f ), + false, + TEXT_GRAVITY ); + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_WASP_DISPLAY_HOLD: + { + const float CARD_DISPLAY_HOLD_TIME = 2000.0f; + + if( m_elapsedTime < CARD_DISPLAY_HOLD_TIME ) + { + // do nothing + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case STATE_WASP_TRANSITION_OUT: + { + const float CARD_TRANSITION_OUT_TIME = 300.0f; + + if( m_elapsedTime < CARD_TRANSITION_OUT_TIME ) + { + float percentageDone = m_elapsedTime / CARD_TRANSITION_OUT_TIME; + + // fade out card text (and scale up) + // + rAssert( m_itemsComplete != NULL ); + m_itemsComplete->SetAlpha( 1.0f - percentageDone ); + + m_itemsComplete->ResetTransformation(); + m_itemsComplete->ScaleAboutCenter( 1.0f + percentageDone * 0.5f ); + } + else + { + // advance to next sub state + // + m_elapsedTime = 0.0f; + m_currentSubState++; + } + + break; + } + case NUM_SUB_STATES: + { + // ok, we're done + // + this->Stop(); + + break; + } + default: + { + rAssertMsg( false, "Unhandled sub-state!" ); + break; + } + } + } +} + diff --git a/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.h b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.h new file mode 100644 index 0000000..9d50b96 --- /dev/null +++ b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.h @@ -0,0 +1,72 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudWaspDestroyed +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/02/05 TChu Created +// +//=========================================================================== + +#ifndef HUDWASPDESTROYED_H +#define HUDWASPDESTROYED_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/ingame/hudevents/hudeventhandler.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Page; + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +class HudWaspDestroyed : public HudEventHandler +{ +public: + HudWaspDestroyed( Scrooby::Page* pPage ); + virtual ~HudWaspDestroyed(); + + virtual void Start(); + virtual void Stop(); + virtual void Update( float elapsedTime ); + + void SetGagInsteadOfWasp( bool isGagInsteadOfWasp ); + +private: + enum eSubState + { + STATE_WASP_TRANSITION_IN, + STATE_WASP_DISPLAY_HOLD, + STATE_WASP_TRANSITION_OUT, + + NUM_SUB_STATES + }; + + unsigned int m_currentSubState; + + Scrooby::Text* m_itemsComplete; + + // re-use this event handler for gags + // + bool m_isGagInsteadOfWasp : 1; + +}; + +inline void HudWaspDestroyed::SetGagInsteadOfWasp( bool isGagInsteadOfWasp ) +{ + m_isGagInsteadOfWasp = isGagInsteadOfWasp; +} + +#endif // HUDWASPDESTROYED_H diff --git a/game/code/presentation/gui/minigame/allminigame.cpp b/game/code/presentation/gui/minigame/allminigame.cpp new file mode 100644 index 0000000..b727b65 --- /dev/null +++ b/game/code/presentation/gui/minigame/allminigame.cpp @@ -0,0 +1,5 @@ +#include <presentation/gui/minigame/guimanagerminigame.cpp> +#include <presentation/gui/minigame/guiscreenminimenu.cpp> +#include <presentation/gui/minigame/guiscreenminihud.cpp> +#include <presentation/gui/minigame/guiscreenminipause.cpp> +#include <presentation/gui/minigame/guiscreenminisummary.cpp> diff --git a/game/code/presentation/gui/minigame/guimanagerminigame.cpp b/game/code/presentation/gui/minigame/guimanagerminigame.cpp new file mode 100644 index 0000000..0392273 --- /dev/null +++ b/game/code/presentation/gui/minigame/guimanagerminigame.cpp @@ -0,0 +1,491 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerMiniGame +// +// Description: Implementation of the CGuiManagerMiniGame class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/minigame/guimanagerminigame.h> +#include <presentation/gui/guiwindow.h> // for window IDs + +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/minigame/guiscreenminimenu.h> +#include <presentation/gui/minigame/guiscreenminihud.h> +#include <presentation/gui/minigame/guiscreenminipause.h> +#include <presentation/gui/minigame/guiscreenminisummary.h> +#include <presentation/gui/guiscreenmessage.h> + +#include <gameflow/gameflow.h> +#include <memory/srrmemory.h> +#include <loading/loadingmanager.h> + +#include <p3d/utility.hpp> +#include <p3d/inventory.hpp> +#include <raddebug.hpp> // Foundation + +#include <input/inputmanager.h> + +#include <main/platform.h> +#include <main/game.h> +#include <contexts/supersprint/supersprintcontext.h> +#include <supersprint/supersprintmanager.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const char* MINIGAME_CHARACTERS_INVENTORY = "FE_MiniGameCharacters"; + +const char* CHARACTER_FILES[] = +{ + "art\\chars\\homer_m.p3d", + "art\\chars\\bart_m.p3d", + "art\\chars\\lisa_m.p3d", + "art\\chars\\marge_m.p3d", + "art\\chars\\apu_m.p3d", + + "" +}; + +const int NUM_CHARACTER_FILES = sizeof( CHARACTER_FILES ) / sizeof( CHARACTER_FILES[ 0 ] ) - 1; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiManagerMiniGame::CGuiManagerMiniGame +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerMiniGame::CGuiManagerMiniGame( Scrooby::Project* pProject, + CGuiEntity* pParent ) +: CGuiManager( pProject, pParent ), + m_isQuittingToSupersprint( false ), + m_controllerPromptShown( false ), + m_isControllerReconnected( false ), + m_lastControllerDisconnectedId( -1 ) +{ + p3d::inventory->AddSection( MINIGAME_CHARACTERS_INVENTORY ); +} + +//=========================================================================== +// CGuiManagerMiniGame::~CGuiManagerMiniGame +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiManagerMiniGame::~CGuiManagerMiniGame() +{ + p3d::inventory->DeleteSection( MINIGAME_CHARACTERS_INVENTORY ); +} + +//=========================================================================== +// CGuiManagerMiniGame::Populate +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerMiniGame::Populate() +{ +MEMTRACK_PUSH_GROUP( "CGuiManagerMiniGame" ); + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + Scrooby::Screen* pScroobyScreen = NULL; + + pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt" ); + if( pScroobyScreen != NULL ) + { + CGuiScreen* pScreen = new CGuiScreenPrompt( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MiniMenu" ); + if( pScroobyScreen != NULL ) + { + CGuiScreen* pScreen = new CGuiScreenMiniMenu( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_MENU, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MiniHud" ); + if( pScroobyScreen != NULL ) + { + CGuiScreen* pScreen = new CGuiScreenMiniHud( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_HUD, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MiniPause" ); + if( pScroobyScreen != NULL ) + { + CGuiScreen* pScreen = new CGuiScreenMiniPause( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_PAUSE, pScreen ); + } + + pScroobyScreen = m_pScroobyProject->GetScreen( "MiniSummary" ); + if( pScroobyScreen != NULL ) + { + CGuiScreen* pScreen = new CGuiScreenMiniSummary( pScroobyScreen, this ); + this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_SUMMARY, pScreen ); + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); +MEMTRACK_POP_GROUP("CGuiManagerMiniGame"); +} + +void +CGuiManagerMiniGame::Start( CGuiWindow::eGuiWindowID initialWindow ) +{ + rAssert( GUI_FE_UNINITIALIZED == m_state ); + + m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ? + initialWindow : + CGuiWindow::GUI_SCREEN_ID_MINI_MENU; + + m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen() + + CGuiScreen* nextScreen = static_cast<CGuiScreen*>( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); +} + +//=========================================================================== +// CGuiManagerMiniGame::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CGuiManagerMiniGame::HandleMessage( eGuiMessage message, + unsigned int param1, + unsigned int param2 ) +{ + switch( message ) + { + case GUI_MSG_WINDOW_FINISHED: + { + if( GUI_FE_CHANGING_SCREENS == m_state ) + { + m_currentScreen = m_nextScreen; + + CGuiScreen* nextScreen = static_cast<CGuiScreen*>( this->FindWindowByID( m_nextScreen ) ); + rAssert( nextScreen != NULL ); + m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this ); + } + else if( GUI_FE_SHUTTING_DOWN == m_state ) + { + if( m_isQuittingToSupersprint ) + { + // quit and start loading supersprint mini-game + // + GetGameFlow()->SetContext( CONTEXT_LOADING_SUPERSPRINT ); + + m_state = GUI_FE_UNINITIALIZED; + } + else + { + // quit mini-game mode and return to front-end + // + GetGameFlow()->SetContext( CONTEXT_FRONTEND ); + + m_state = GUI_FE_TERMINATED; + } + } + + break; + } + case GUI_MSG_QUIT_MINIGAME: + { + rAssert( GUI_FE_SCREEN_RUNNING == m_state ); + + m_state = GUI_FE_SHUTTING_DOWN; + + m_isQuittingToSupersprint = (param1 > 0 ); + + // Tell the current screen to shut down. + // + this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT ); + + break; + } + + case GUI_MSG_CONTROLLER_DISCONNECT: +#ifndef RAD_GAMECUBE + this->OnControllerDisconnected( static_cast<int>( param1 ) ); +#endif // !RAD_GAMECUBE + break; + + case GUI_MSG_CONTROLLER_CONNECT: +#ifndef RAD_GAMECUBE + m_oldControllerState = InputManager::GetInstance()->GetGameState(); + if( m_oldControllerState == Input::ACTIVE_ANIM_CAM ) + { + // deactivate anim cam state first, since the input manager + // won't let us set the game state to anything else prior + // to that + // + GetInputManager()->SetGameState( Input::DEACTIVE_ANIM_CAM ); + } + GetInputManager()->SetGameState( Input::ACTIVE_FRONTEND ); +#endif // !RAD_GAMECUBE + break; + default: + { + if( message == GUI_MSG_UPDATE && m_isControllerReconnected ) + { + m_isControllerReconnected = false; + m_controllerPromptShown = false; + } + + if (m_controllerPromptShown) // don't pass event if controller error + { + if (message==GUI_MSG_CONTROLLER_START) // start trigger reconnection + { + this->OnControllerConnected( static_cast<int>( param1 ) ); + } + + break; + } + + if( m_state != GUI_FE_UNINITIALIZED && + m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) + { + // Send the messages down to the current screen. + // + CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen ); + rAssert( pScreen != NULL ); + pScreen->HandleMessage( message, param1, param2 ); + } +#ifndef RAD_GAMECUBE + if ( message == GUI_MSG_UPDATE) + PollControllers(); +#endif + break; + } + } + + // propogate message up the hierarchy + // + CGuiManager::HandleMessage( message, param1, param2 ); +} + +void +CGuiManagerMiniGame::OnControllerDisconnected( int controllerID, bool force_display ) +{ + if (force_display) // update message + { + m_lastControllerDisconnectedId = controllerID; + char str_buffer[256]; + CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255); + GetGame()->GetPlatform()->OnControllerError(str_buffer); + m_controllerPromptShown = true; + } + else if (m_controllerPromptShown) // check if this disconnection id is for the player already registered + { + for (int i = 0; i < SuperSprintData::NUM_PLAYERS; i++) + { + int player_controllerID = GetInputManager()->GetControllerIDforPlayer( i ); + if (controllerID == player_controllerID) + { + m_lastControllerDisconnectedId = controllerID; + char str_buffer[256]; + CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255); + GetGame()->GetPlatform()->OnControllerError(str_buffer); + m_controllerPromptShown = true; + } + } + } + +} +bool +CGuiManagerMiniGame::PollControllers() +{ + bool all_ok = true; + bool has_registered = false; + + if ( GetGameFlow()->GetCurrentContext()==CONTEXT_SUPERSPRINT + && GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->IsSuspended() ) // minigame pause menu + { + int controllerID = CGuiScreenMiniHud::s_pausedControllerID; + if (controllerID >= 0) + { + has_registered = true; + if( !GetInputManager()->GetController( controllerID )->IsConnected() ) + { + OnControllerDisconnected(controllerID, true); + all_ok = false; + } + } + } + else + { // minigame game, or minigame menu + for (int i = 0; i < SuperSprintData::NUM_PLAYERS; i++) + { + int controllerID = GetInputManager()->GetControllerIDforPlayer( i ); + if (controllerID >= 0) + { + has_registered = true; + if( !GetInputManager()->GetController( controllerID )->IsConnected() ) + { + OnControllerDisconnected(controllerID, true); + all_ok = false; + break; + } + } + } + } + if (all_ok) { + if (has_registered == false) // minigame menu but no one registered yet + { + int controllerID = GetGuiSystem()->GetPrimaryController( ); + if (controllerID >= 0) + { + if( !GetInputManager()->GetController( controllerID )->IsConnected() ) + { + OnControllerDisconnected(controllerID, true); + all_ok = false; + } + } + } + } + + if (all_ok) + { + m_isControllerReconnected = true; +// m_controllerPromptShown = false; + } + return all_ok; + +} + +void +CGuiManagerMiniGame::OnControllerConnected( int controllerID ) +{ + if (controllerID==m_lastControllerDisconnectedId) + { // poll + bool all_ok = PollControllers(); + if (all_ok) + { + GetGame()->GetPlatform()->ClearControllerError(); + GetSSM()->RestoreControllerState(); + + if ( GetGameFlow()->GetCurrentContext()==CONTEXT_SUPERSPRINT ) + { +#ifdef RAD_XBOX + CGuiScreenMiniHud::s_pausedControllerID = controllerID; + + if( GetSSM()->GetState() != SuperSprintManager::IDLE ) + { + this->HandleMessage( GUI_MSG_GOTO_SCREEN, CGuiWindow::GUI_SCREEN_ID_MINI_PAUSE ); + } + + GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Suspend(); + + if (GetSSM()->GetState()==SuperSprintManager::COUNT_DOWN) + { + InputManager::GetInstance()->SetGameState( Input::DEACTIVE_ANIM_CAM ); + InputManager::GetInstance()->SetGameState( Input::ACTIVE_FRONTEND ); + } + else + { + InputManager::GetInstance()->SetGameState( Input::DEACTIVE_ANIM_CAM ); + InputManager::GetInstance()->SetGameState( Input::ACTIVE_ALL ); + } +#endif + } + + m_isControllerReconnected = true; +// m_controllerPromptShown = false; + m_lastControllerDisconnectedId = -1; + } + } +} + +//=========================================================================== +// CGuiManagerMiniGame::LoadCharacters +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CGuiManagerMiniGame::LoadCharacters() +{ + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + "art\\chars\\global.p3d", + GMA_LEVEL_HUD, + MINIGAME_CHARACTERS_INVENTORY, + MINIGAME_CHARACTERS_INVENTORY ); + + for( int i = 0; i < NUM_CHARACTER_FILES; i++ ) + { + GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D, + CHARACTER_FILES[ i ], + GMA_LEVEL_HUD, + MINIGAME_CHARACTERS_INVENTORY, + MINIGAME_CHARACTERS_INVENTORY ); + } +} + +//=========================================================================== +// CGuiManagerMiniGame::UnloadCharacters +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CGuiManagerMiniGame::UnloadCharacters() +{ + p3d::pddi->DrawSync(); + p3d::inventory->RemoveSectionElements( MINIGAME_CHARACTERS_INVENTORY ); +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + diff --git a/game/code/presentation/gui/minigame/guimanagerminigame.h b/game/code/presentation/gui/minigame/guimanagerminigame.h new file mode 100644 index 0000000..b4534e2 --- /dev/null +++ b/game/code/presentation/gui/minigame/guimanagerminigame.h @@ -0,0 +1,71 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiManagerMiniGame +// +// Description: Interface for the CGuiManagerMiniGame class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created +// +//=========================================================================== + +#ifndef GUIMANAGERMINIGAME_H +#define GUIMANAGERMINIGAME_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guimanager.h> +#include <input/inputmanager.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiManagerMiniGame : public CGuiManager +{ +public: + CGuiManagerMiniGame( Scrooby::Project* pProject, CGuiEntity* pParent ); + virtual ~CGuiManagerMiniGame(); + + virtual void Populate(); + virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + static void LoadCharacters(); + static void UnloadCharacters(); + +private: + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or assignment. Declare but don't define. + // + CGuiManagerMiniGame( const CGuiManagerMiniGame& ); + CGuiManagerMiniGame& operator= ( const CGuiManagerMiniGame& ); + + void OnControllerDisconnected( int controllerID, bool force_display = false ); + void OnControllerConnected( int controllerID ); + bool PollControllers(); + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + bool m_isQuittingToSupersprint : 1; + bool m_controllerPromptShown : 1; + bool m_isControllerReconnected : 1; + int m_lastControllerDisconnectedId; + Input::ActiveState m_oldControllerState; + +}; + +#endif // GUIMANAGERMINIGAME_H diff --git a/game/code/presentation/gui/minigame/guiscreenminihud.cpp b/game/code/presentation/gui/minigame/guiscreenminihud.cpp new file mode 100644 index 0000000..88a9904 --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminihud.cpp @@ -0,0 +1,217 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniHud +// +// Description: Implementation of the CGuiScreenMiniHud class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/minigame/guiscreenminihud.h> +#include <presentation/gui/guimanager.h> + +#include <contexts/supersprint/supersprintcontext.h> +#include <gameflow/gameflow.h> + +#ifdef RAD_WIN32 +#include <input/inputmanager.h> +#endif + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +int CGuiScreenMiniHud::s_pausedControllerID = -1; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMiniHud::CGuiScreenMiniHud +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniHud::CGuiScreenMiniHud +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_HUD ) +{ +} + + +//=========================================================================== +// CGuiScreenMiniHud::~CGuiScreenMiniHud +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniHud::~CGuiScreenMiniHud() +{ +} + + +//=========================================================================== +// CGuiScreenMiniHud::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniHud::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { +#ifdef RAD_WIN32 + case GUI_MSG_CONTROLLER_BACK: + { + if( GetInputManager()->GetValue( 0, InputManager::KeyboardEsc ) > 0.0f ) + { + //GOOD! Fall through. + } + else + { + break; + } + } +#endif + case GUI_MSG_CONTROLLER_START: + { + // pause mini-game + // + GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Suspend(); + + // go to pause menu + // + s_pausedControllerID = static_cast<int>( param1 ); + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MINI_PAUSE ); + + break; + } +/* + // TC: *** for testing only *** + // + case GUI_MSG_CONTROLLER_AUX_X: + case GUI_MSG_CONTROLLER_AUX_Y: + { + // go to Race Summary screen + // + GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Suspend(); + + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MINI_SUMMARY ); + + break; + } +*/ + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMiniHud::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniHud::InitIntro() +{ +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetInGameMode( true ); +#endif +} + + +//=========================================================================== +// CGuiScreenMiniHud::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniHud::InitRunning() +{ + if( GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->IsSuspended() ) + { + // resume mini-game + // + GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Resume(); + } +} + + +//=========================================================================== +// CGuiScreenMiniHud::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniHud::InitOutro() +{ +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + diff --git a/game/code/presentation/gui/minigame/guiscreenminihud.h b/game/code/presentation/gui/minigame/guiscreenminihud.h new file mode 100644 index 0000000..b36c436 --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminihud.h @@ -0,0 +1,52 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniHud +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMINIHUD_H +#define GUISCREENMINIHUD_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMiniHud : public CGuiScreen +{ +public: + CGuiScreenMiniHud( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMiniHud(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + // controller ID of user that paused mini-game + // + static int s_pausedControllerID; + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +}; + +#endif // GUISCREENMINIHUD_H diff --git a/game/code/presentation/gui/minigame/guiscreenminimenu.cpp b/game/code/presentation/gui/minigame/guiscreenminimenu.cpp new file mode 100644 index 0000000..69e5db0 --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminimenu.cpp @@ -0,0 +1,1633 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniMenu +// +// Description: Implementation of the CGuiScreenMiniMenu class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/minigame/guiscreenminimenu.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guimenu.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiuserinputhandler.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/guiscreenprompt.h> + +#include <cards/cardgallery.h> +#include <events/eventmanager.h> +#include <input/inputmanager.h> +#include <memory/srrmemory.h> +#include <mission/gameplaymanager.h> +#include <mission/rewards/rewardsmanager.h> +#include <mission/rewards/reward.h> +#include <render/enums/renderenums.h> +#include <supersprint/supersprintmanager.h> +#include <supersprint/supersprintdata.h> + +// Scrooby +// +#include <screen.h> +#include <page.h> +#include <layer.h> +#include <group.h> +#include <sprite.h> +#include <text.h> +#include <pure3dobject.h> +#include <polygon.h> + +// ATG +// +#include <p3d/camera.hpp> +#include <p3d/utility.hpp> +#include <raddebug.hpp> + +#include <string.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float NUM_LAPS_ARROW_ROTATION = 90.0f; // in degrees +const float NUM_LAPS_ARROW_GREY_OUT_ALPHA = 0.5f; + +#ifdef RAD_WIN32 +const float CHARACTER_SCALE = 0.67f; +const float VEHICLE_SCALE = 0.5f; +const float CHARACTER_ARROW_SCALE = 0.45f; +const float VEHICLE_ARROW_SCALE = 0.85f; +const float NUM_LAPS_ARROW_SCALE = 0.375f; // scale arrows down a bit +#else +const float NUM_LAPS_ARROW_SCALE = 0.75f; // scale arrows down a bit +#endif + +PlayerMenu::PlayerMenu() +: m_currentSubMenu( 0 ), + m_controllerID( -1 ), + m_pressStart( NULL ), + m_vehicleRating( NULL ), + m_characterSelectedIcon( NULL ), + m_vehicleSelectedIcon( NULL ) +{ + memset( m_pMenu, 0, sizeof( m_pMenu ) ); +} + +void +PlayerMenu::HandleMessage( eGuiMessage message, unsigned int param1, + unsigned int param2 ) +{ + if( m_currentSubMenu < NUM_SUB_MENUS ) + { + rAssert( m_currentSubMenu >= 0 ); + m_pMenu[ m_currentSubMenu ]->HandleMessage( message, param1, param2 ); + } +} + +CGuiMenu* +PlayerMenu::GetCurrentSubMenu() const +{ + if( m_currentSubMenu < NUM_SUB_MENUS ) + { + rAssert( m_currentSubMenu >= 0 ); + return m_pMenu[ m_currentSubMenu ]; + } + + return NULL; +} + +void +PlayerMenu::SetActive( bool isActive, int controllerID ) +{ + m_controllerID = isActive ? controllerID : -1; + + // hide/show press start text + // + rAssert( m_pressStart != NULL ); + m_pressStart->SetVisible( !isActive ); + + // show/hide player cursor + // + rAssert( m_pMenu[ MENU_CHARACTERS ] != NULL ); + m_pMenu[ MENU_CHARACTERS ]->GetCursor()->SetVisible( isActive ); + + // show/hide vehicle rating + // + if( m_vehicleRating != NULL ) + { + m_vehicleRating->SetVisible( isActive ); + } + + // reset vehicle selection + // + rAssert( m_pMenu[ MENU_VEHICLES ] != NULL ); + m_pMenu[ MENU_VEHICLES ]->SetSelectionValue( 0, 0 ); + m_pMenu[ MENU_VEHICLES ]->SetMenuItemEnabled( 0, isActive, true ); + + // turn off selected icons + // + rAssert( m_characterSelectedIcon != NULL ); + m_characterSelectedIcon->SetAlpha( 0.0f ); + + rAssert( m_vehicleSelectedIcon != NULL ); + m_vehicleSelectedIcon->SetAlpha( 0.0f ); + + // set controller ID for vehicle selection menu + // + m_pMenu[ MENU_VEHICLES ]->SetControllerID( controllerID ); + + // reset current sub-menu + // + m_currentSubMenu = 0; + + +} + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMiniMenu::CGuiScreenMiniMenu +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniMenu::CGuiScreenMiniMenu +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_MENU ), +// m_screenState( SCREEN_STATE_NORMAL ), + m_pTrackMenu( NULL ), + m_trackDirection( NULL ), + m_trackNumLaps( NULL ), + m_trackNumLapsArrowU( NULL ), + m_trackNumLapsArrowD( NULL ), + m_trackCursorBgd( NULL ), + m_elapsedTime( 0 ), + m_backLabel( NULL ), + m_numActivePlayers( 0 ), + m_numActivePlayersDone( 0 ), + m_characterSlots( 0 ), + m_numUnlockedVehicles( 0 ), + m_optionsButton( NULL ), +#ifdef RAD_WIN32 + m_currentTrack(0), + m_bTrackSelected(false), +#endif +// m_optionsOverlay( NULL ), +// m_optionsMenu( NULL ), + m_characterSelectInfo( NULL ), + m_timerOverlay( NULL ), + m_remainingTime( TIMER_WAIT_TIME ) +{ + memset( m_unlockedVehicles, 0, sizeof( m_unlockedVehicles ) ); + +#ifdef MINI_MENU_SHOW_3D_CHARACTERS + memset( m_3dCharacters, 0, sizeof( m_3dCharacters ) ); +#endif + + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MiniMenu" ); + rAssert( pPage != NULL ); + + int i = 0; + char name[ 32 ]; + Scrooby::Group* pGroup = NULL; + + // create sub menu for tracks (only one needed for all players) + // + m_pTrackMenu = new CGuiMenu2D( this, NUM_TRACKS, NUM_TRACKS, GUI_SPRITE_MENU, MENU_SFX_NONE ); + rAssert( m_pTrackMenu != NULL ); + + // add tracks to menu + // + pGroup = pPage->GetGroup( "Tracks" ); + rAssert( pGroup != NULL ); + for( i = 0; i < NUM_TRACKS; i++ ) + { + sprintf( name, "Track%d", i ); + m_pTrackMenu->AddMenuItem( pGroup->GetSprite( name ) ); + } + + if( this->IsWideScreenDisplay() ) + { + ApplyWideScreenCorrectionScale( pGroup ); + } + + // add track cursor + // + Scrooby::Group* pGroupCursor = pGroup->GetGroup( "TrackCursor" ); + rAssert( pGroupCursor != NULL ); + m_pTrackMenu->SetCursor( pGroupCursor ); + + // get track cursor background + // + m_trackCursorBgd = pGroup->GetPolygon( "TrackBgd" ); + + // get track num laps and direction + // + m_trackNumLaps = pGroupCursor->GetText( "NumLaps" ); + m_trackDirection = pGroupCursor->GetSprite( "Direction" ); + + rAssert( m_trackNumLaps != NULL ); + m_trackNumLaps->SetIndex( SuperSprintData::DEFAULT_NUM_LAPS ); + + // rotate num laps arrows (90 deg CW) so they point up and down, respectively + // + m_trackNumLapsArrowU = pGroupCursor->GetSprite( "NumLaps_LArrow" ); + if( m_trackNumLapsArrowU != NULL ) + { + m_trackNumLapsArrowU->ResetTransformation(); + m_trackNumLapsArrowU->ScaleAboutCenter( NUM_LAPS_ARROW_SCALE ); + m_trackNumLapsArrowU->RotateAboutCenter( NUM_LAPS_ARROW_ROTATION ); + } + + m_trackNumLapsArrowD = pGroupCursor->GetSprite( "NumLaps_RArrow" ); + if( m_trackNumLapsArrowD != NULL ) + { + m_trackNumLapsArrowD->ResetTransformation(); + m_trackNumLapsArrowD->ScaleAboutCenter( NUM_LAPS_ARROW_SCALE ); + m_trackNumLapsArrowD->RotateAboutCenter( NUM_LAPS_ARROW_ROTATION ); + } + + // prepare vehicle selections (only unlocked vehicles are selectable by players) + // + this->PrepareVehicleSelections(); + + // if no vehicles are unlocked, just add the L1 default vehicle so there's at least one vehicle + // to choose from + // + if( m_numUnlockedVehicles == 0 ) + { + m_unlockedVehicles[ 0 ] = GetRewardsManager()->GetReward( RenderEnums::L1, Reward::eDefaultCar ); + m_numUnlockedVehicles++; + } + + rAssertMsg( m_numUnlockedVehicles > 0, "There aren't any unlocked vehicles to choose from!" ); + + // get back label + // + rAssert( m_buttonIcons[ BUTTON_ICON_BACK ] != NULL ); + m_backLabel = m_buttonIcons[ BUTTON_ICON_BACK ]->GetText( "Back" ); + rAssert( m_backLabel != NULL ); + + // create player-specific menus + // + for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + // create sub menu for characters + // + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] = new CGuiMenu2D( this, + NUM_CHARACTERS, + NUM_CHARACTERS, + GUI_SPRITE_MENU, + MENU_SFX_NONE ); + + rAssert( m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] != NULL ); + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetGreyOutEnabled( false ); + + // add character slots to menu + // + pGroup = pPage->GetGroup( "Characters" ); + rAssert( pGroup != NULL ); + for( i = 0; i < NUM_CHARACTERS; i++ ) + { + sprintf( name, "Character%d", i ); + Scrooby::Sprite* characterImage = pGroup->GetSprite( name ); +#ifdef RAD_WIN32 + characterImage->ResetTransformation(); + characterImage->ScaleAboutCenter( CHARACTER_SCALE ); +#endif + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->AddMenuItem( characterImage, + characterImage ); + } + + // get player cursor + // + sprintf( name, "Player%d", p ); + pGroupCursor = pGroup->GetGroup( name ); + rAssert( pGroupCursor != NULL ); + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetCursor( pGroupCursor ); + + // set player-specific colour to cursor + // + pGroupCursor->GetText( name )->SetColour( SuperSprintData::PLAYER_COLOURS[ p ] ); + + // get character selected icon + // + sprintf( name, "Player%d_Selected", p ); + m_playerMenus[ p ].m_characterSelectedIcon = pGroupCursor->GetSprite( name ); + + // create sub menu for vehicles + // + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ] = new CGuiMenu( this, + 1, + GUI_SPRITE_MENU, + MENU_SFX_NONE ); + + rAssert( m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ] != NULL ); + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetHighlightColour( false, tColour( 0, 0, 0 ) ); +// m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetSelectionMadeOutlineColour( tColour( 0, 0, 0, 192 ) ); + + // add vehicle selections to menu + // + pGroup = pPage->GetGroup( "Vehicles" ); + rAssert( pGroup != NULL ); + + // get press start text + // + sprintf( name, "PressStart%d", p ); + m_playerMenus[ p ].m_pressStart = pGroup->GetText( name ); + rAssert( m_playerMenus[ p ].m_pressStart != NULL ); + m_playerMenus[ p ].m_pressStart->SetTextMode( Scrooby::TEXT_WRAP ); + m_playerMenus[ p ].m_pressStart->ScaleAboutCenter( 0.9f ); + m_playerMenus[ p ].m_pressStart->SetVisible( false ); // hide by default + + sprintf( name, "Vehicle%d_Value", p ); + Scrooby::Sprite* vehicleImage = pGroup->GetSprite( name ); + sprintf( name, "Vehicle%d_LArrow", p ); + Scrooby::Sprite* vehicleImageLArrow = pGroup->GetSprite( name ); + sprintf( name, "Vehicle%d_RArrow", p ); + Scrooby::Sprite* vehicleImageRArrow = pGroup->GetSprite( name ); + +#ifdef RAD_WIN32 + vehicleImage->ScaleAboutCenter( VEHICLE_SCALE ); + vehicleImageLArrow->ResetTransformation(); + vehicleImageRArrow->ResetTransformation(); + vehicleImageLArrow->ScaleAboutCenter( VEHICLE_ARROW_SCALE ); + vehicleImageRArrow->ScaleAboutCenter( VEHICLE_ARROW_SCALE ); +#endif + + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->AddMenuItem( vehicleImage, + vehicleImage, + NULL, + NULL, + vehicleImageLArrow, + vehicleImageRArrow ); + + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetSelectionValueCount( 0, m_numUnlockedVehicles ); + + // get vehicle cursor + // + sprintf( name, "Vehicle%d", p ); + pGroupCursor = pGroup->GetGroup( name ); + rAssert( pGroupCursor != NULL ); + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetCursor( pGroupCursor ); + + // set player-specific colour to cursor + // + pGroupCursor->GetText( name )->SetColour( SuperSprintData::PLAYER_COLOURS[ p ] ); + + // get vehicle selected icon + // + sprintf( name, "Vehicle%d_Selected", p ); + m_playerMenus[ p ].m_vehicleSelectedIcon = pGroupCursor->GetSprite( name ); + + // get vehicle rating + // + sprintf( name, "Vehicle%d_Rating", p ); + m_playerMenus[ p ].m_vehicleRating = pGroup->GetSprite( name ); + +#ifdef RAD_WIN32 + m_playerMenus[ p ].m_vehicleRating->ScaleAboutCenter( 0.5f ); +#endif + + this->UpdateVehicleDisplayImages( p, vehicleImage ); + } + + // get 3D character models + // +#ifdef MINI_MENU_SHOW_3D_CHARACTERS + pGroup = pPage->GetGroup( "Characters" ); + rAssert( pGroup != NULL ); + for( i = 0; i < NUM_CHARACTERS; i++ ) + { + sprintf( name, "Character%d", i ); + m_3dCharacters[ i ] = pGroup->GetPure3dObject( name ); + rAssert( m_3dCharacters[ i ] != NULL ); + m_3dCharacters[ i ]->SetClearDepthBuffer( true ); + } +#endif // MINI_MENU_SHOW_3D_CHARACTERS + + // get options overlay stuff + // + m_optionsButton = pPage->GetGroup( "Options" ); + rAssert( m_optionsButton != NULL ); + + Scrooby::Text* optionsText = m_optionsButton->GetText( "Options" ); + if( optionsText != NULL ) + { + optionsText->SetTextMode( Scrooby::TEXT_WRAP ); + } + + if( this->IsWideScreenDisplay() ) + { + ApplyWideScreenCorrectionScale( m_optionsButton ); + } +/* + m_optionsOverlay = pPage->GetLayer( "Options" ); + rAssert( m_optionsOverlay != NULL ); + + // create options menu + // + m_optionsMenu = new CGuiMenu( this, NUM_OPTIONS_MENU_ITEMS ); + rAssert( m_optionsMenu != NULL ); + + // add menu items to options menu + // + pGroup = pPage->GetGroup( "OptionsMenu" ); + rAssert( pGroup != NULL ); + + m_optionsMenu->AddMenuItem( pGroup->GetText( "NumLaps" ), + pGroup->GetText( "NumLaps_Value" ), + NULL, + NULL, + pGroup->GetSprite( "NumLaps_ArrowL" ), + pGroup->GetSprite( "NumLaps_ArrowR" ), + SELECTION_ENABLED | TEXT_OUTLINE_ENABLED ); + + m_optionsMenu->AddMenuItem( pGroup->GetText( "ReverseDirection" ), + pGroup->GetText( "ReverseDirection_Value" ), + NULL, + NULL, + pGroup->GetSprite( "ReverseDirection_ArrowL" ), + pGroup->GetSprite( "ReverseDirection_ArrowR" ), + SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED ); +*/ + + // get character select info + // + m_characterSelectInfo = pPage->GetGroup( "CharacterSelectInfo" ); + if( m_characterSelectInfo != NULL ) + { + m_characterSelectInfo->SetVisible( false ); // hide by default + } + +#ifdef RAD_WIN32 + Scrooby::Sprite* arrow = m_characterSelectInfo->GetSprite( "CharacterLArrow" ); + arrow->ResetTransformation(); + arrow->ScaleAboutCenter( CHARACTER_ARROW_SCALE ); + arrow = m_characterSelectInfo->GetSprite( "CharacterRArrow" ); + arrow->ResetTransformation(); + arrow->ScaleAboutCenter( CHARACTER_ARROW_SCALE ); +#endif + + // get timer overlay stuff + // + m_timerOverlay = pPage->GetGroup( "Timer" ); + rAssert( m_timerOverlay != NULL ); + m_timerOverlay->SetVisible( false ); // hide by default + + Scrooby::Text* waitingForOtherPlayers = m_timerOverlay->GetText( "WaitingForOtherPlayers" ); + if( waitingForOtherPlayers != NULL ) + { + waitingForOtherPlayers->SetTextMode( Scrooby::TEXT_WRAP ); + } + + m_timer.SetScroobyText( m_timerOverlay, "Timer" ); + m_timer.m_digits[ 0 ]->ResetTransformation(); + m_timer.m_digits[ 0 ]->ScaleAboutPoint( 1.5f, 0, 0 ); +} + +//=========================================================================== +// CGuiScreenMiniMenu::~CGuiScreenMiniMenu +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniMenu::~CGuiScreenMiniMenu() +{ +#ifdef MINI_MENU_SHOW_3D_CHARACTERS + // release drawables for 3D characters + // + for( int c = 0; c < NUM_CHARACTERS; c++ ) + { + if( m_3dCharacters[ c ] != NULL ) + { + m_3dCharacters[ c ]->SetDrawable( NULL ); + } + } +#endif // MINI_MENU_SHOW_3D_CHARACTERS + + // destroy track menu + // + if( m_pTrackMenu != NULL ) + { + delete m_pTrackMenu; + m_pTrackMenu = NULL; + } + + // destroy all player sub-menus + // + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { + for( int j = 0; j < PlayerMenu::NUM_SUB_MENUS; j++ ) + { + if( m_playerMenus[ i ].m_pMenu[ j ] != NULL ) + { + delete m_playerMenus[ i ].m_pMenu[ j ]; + m_playerMenus[ i ].m_pMenu[ j ] = NULL; + } + } + } + +/* + // destroy options menu + // + if( m_optionsMenu != NULL ) + { + delete m_optionsMenu; + m_optionsMenu = NULL; + } +*/ +} + +//=========================================================================== +// CGuiScreenMiniMenu::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniMenu::HandleMessage( eGuiMessage message, + unsigned int param1, + unsigned int param2 ) +{ + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + rAssert( param1 == PROMPT_CONFIRM_QUIT ); + + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + m_pParent->HandleMessage( GUI_MSG_QUIT_MINIGAME ); + + break; + } + case (CGuiMenuPrompt::RESPONSE_NO): + { + this->ReloadScreen(); + + break; + } + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + int controllerID = -1; + int playerMenuID = -1; + + if( this->IsControllerMessage( message ) ) + { + controllerID = static_cast<int>( param1 ); + playerMenuID = this->GetPlayerMenuID( controllerID ); + + this->UpdateCharacterSlots(); + } + + if( m_numActivePlayers == 0 ) + { + // relay message to track menu + // + rAssert( m_pTrackMenu != NULL ); + m_pTrackMenu->HandleMessage( message, param1, param2 ); + } + else + { + if( this->IsControllerMessage( message ) ) + { + // relay message ONLY to associated player's current sub-menu + // + if( playerMenuID != -1 ) + { + m_playerMenus[ playerMenuID ].HandleMessage( message, param1, param2 ); + + if( m_playerMenus[ playerMenuID ].m_currentSubMenu == PlayerMenu::MENU_VEHICLES ) + { + this->UpdateVehicleRating( playerMenuID ); + } + } + } + else + { + // relay message to all players' current sub-menu + // + for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + m_playerMenus[ p ].HandleMessage( message, param1, param2 ); + } + } + } + + switch( message ) + { + case GUI_MSG_UPDATE: + { + this->UpdateCharacterSlots(); + + const unsigned int PULSE_PERIOD = 500; + + float alpha = GuiSFX::Pulse( (float)m_elapsedTime, + (float)PULSE_PERIOD, + 0.6f, + 0.4f, + -rmt::PI_BY2 ); + + if( m_numActivePlayers == 0 ) // track selection state + { + // pulse cursor bgd alpha + // + if( m_trackCursorBgd != NULL ) + { + m_trackCursorBgd->SetAlpha( alpha ); + } + + // update U/D arrows on num laps + // + if( m_trackNumLapsArrowU != NULL && m_trackNumLapsArrowD != NULL ) + { + m_trackNumLapsArrowU->SetIndex( 0 ); + m_trackNumLapsArrowD->SetIndex( 0 ); + + int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers(); + for( int i = 0; i < numUserInputHandlers; i++ ) + { + CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i ); + if( userInputHandler != NULL ) + { +#ifdef RAD_WIN32 + if( userInputHandler->IsYAxisOnUp() || + GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWUP ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Up ) || + userInputHandler->IsYAxisOnUp() ) +#endif + { + rAssert( m_trackNumLapsArrowU->GetNumOfImages() > 1 ); + m_trackNumLapsArrowU->SetIndex( 1 ); + } + +#ifdef RAD_WIN32 + if( userInputHandler->IsYAxisOnDown() || + GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWDOWN ) +#else + if( userInputHandler->IsButtonDown( GuiInput::Down ) || + userInputHandler->IsYAxisOnDown() ) +#endif + { + rAssert( m_trackNumLapsArrowD->GetNumOfImages() > 1 ); + m_trackNumLapsArrowD->SetIndex( 1 ); + } + } + } + } + } + else // not in track selection state + { +#ifdef RAD_XBOX + // re-enable Start-to-Select button mapping + // + for( int i = 0; i < GetGuiSystem()->GetNumUserInputHandlers(); i++ ) + { + GetGuiSystem()->GetUserInputHandler( i )->EnableStartToSelectMapping( true ); + } +#endif // RAD_XBOX + + for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + // pulse player's current sub-menu cursor + // + CGuiMenu* currentSubMenu = m_playerMenus[ p ].GetCurrentSubMenu(); + if( currentSubMenu != NULL ) + { + Scrooby::Drawable* pCursor = currentSubMenu->GetCursor(); + rAssert( pCursor != NULL ); + pCursor->SetAlpha( alpha ); + } + } + } + + m_elapsedTime += param1; + m_elapsedTime %= PULSE_PERIOD; + + rAssert( m_timerOverlay != NULL ); + if( m_timerOverlay->IsVisible() ) + { + // update timer + // + m_remainingTime -= static_cast<int>( param1 ); + if( m_remainingTime > 0 ) + + { + m_timer.SetValue( static_cast<unsigned int>( m_remainingTime ) / 1000 ); + } + else + { + this->SetTimerEnabled( false ); + + // timer expired, letz start the mini-game! + // + m_pParent->HandleMessage( GUI_MSG_QUIT_MINIGAME, m_numActivePlayersDone ); + } + } + + break; + } + case GUI_MSG_MENU_SELECTION_CHANGED: // param1 = old, param2 = new + { + if( m_numActivePlayers == 0 ) // track selection state + { + this->MoveTrackCursor( static_cast<int>( param2 ), static_cast<int>( param1 ) ); + } + + break; + } + case GUI_MSG_CONTROLLER_UP: + { + if( m_numActivePlayers == 0 ) // track selection state + { + // increment number of laps + // + rAssert( m_trackNumLaps != NULL ); + int currentNumLaps = m_trackNumLaps->GetIndex(); + if( currentNumLaps < SuperSprintData::MAX_NUM_LAPS ) + { + currentNumLaps++; + m_trackNumLaps->SetIndex( currentNumLaps ); + + if( currentNumLaps == SuperSprintData::MAX_NUM_LAPS && + m_trackNumLapsArrowU != NULL ) + { + m_trackNumLapsArrowU->SetAlpha( NUM_LAPS_ARROW_GREY_OUT_ALPHA ); // grey out arrow + } + + if( m_trackNumLapsArrowD != NULL ) + { + m_trackNumLapsArrowD->SetAlpha( 1.0f ); // restore normal arrow + } + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + } + + break; + } + case GUI_MSG_CONTROLLER_DOWN: + { + if( m_numActivePlayers == 0 ) // track selection state + { + // decrement number of laps + // + rAssert( m_trackNumLaps != NULL ); + int currentNumLaps = m_trackNumLaps->GetIndex(); + if( currentNumLaps > SuperSprintData::MIN_NUM_LAPS ) + { + currentNumLaps--; + m_trackNumLaps->SetIndex( currentNumLaps ); + + if( currentNumLaps == SuperSprintData::MIN_NUM_LAPS && + m_trackNumLapsArrowD != NULL ) + { + m_trackNumLapsArrowD->SetAlpha( NUM_LAPS_ARROW_GREY_OUT_ALPHA ); // grey out arrow + } + + if( m_trackNumLapsArrowU != NULL ) + { + m_trackNumLapsArrowU->SetAlpha( 1.0f ); // restore normal arrow + } + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); + } + } + + break; + } + case GUI_MSG_CONTROLLER_START: + { + if( m_numActivePlayers == 0 ) + { + this->OnTrackSelected(); + } + + // active new player menu + // + if( playerMenuID == -1 ) // means this player's not active yet + { +#ifdef RAD_XBOX + // disable Start-to-Select button mapping to prevent duplicate SELECT inputs; + // it will be re-enabled in the next update + // + GetGuiSystem()->GetUserInputHandler( controllerID )->EnableStartToSelectMapping( false ); +#endif // RAD_XBOX + + this->ActivateNewPlayer( controllerID ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); + } + + break; + } + case GUI_MSG_CONTROLLER_SELECT: + { + if( m_numActivePlayers == 0 ) + { + this->OnTrackSelected(); + + // track selected, activate the first player + // + this->ActivateNewPlayer( controllerID ); + } + else + { + if( playerMenuID != -1 && !m_playerMenus[ playerMenuID ].IsDone() ) + { + Scrooby::Drawable* pCursor = m_playerMenus[ playerMenuID ].GetCurrentSubMenu()->GetCursor(); + rAssert( pCursor != NULL ); + pCursor->SetAlpha( 1.0f ); // restore cursor alpha + + m_playerMenus[ playerMenuID ].m_currentSubMenu++; + + if( m_playerMenus[ playerMenuID ].IsDone() ) + { + // player is done selecting from all sub-menus + // + m_numActivePlayersDone++; + + this->SetTimerEnabled( true ); + + this->OnVehicleSelected( playerMenuID, true ); + } + else + { + this->OnCharacterSelected( playerMenuID, true ); + } + + // if everyone's done selecting, start the game! + // + if( m_numActivePlayersDone == SuperSprintData::NUM_PLAYERS ) + { + this->SetTimerEnabled( false ); + + m_pParent->HandleMessage( GUI_MSG_QUIT_MINIGAME, m_numActivePlayersDone ); + } + } + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { + if( m_numActivePlayers == 0 ) + { + // display quit confirmation screen + // + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT, this ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); + } + else + { + if( playerMenuID != -1 ) + { + if( m_playerMenus[ playerMenuID ].m_currentSubMenu > 0 ) + { + if( !m_playerMenus[ playerMenuID ].IsDone() ) + { + Scrooby::Drawable* pCursor = m_playerMenus[ playerMenuID ].GetCurrentSubMenu()->GetCursor(); + rAssert( pCursor != NULL ); + pCursor->SetAlpha( 1.0f ); // restore cursor alpha + + this->OnCharacterSelected( playerMenuID, false ); + } + else + { + this->OnVehicleSelected( playerMenuID, false ); + + m_numActivePlayersDone--; + + // if no one's done selecting all their sub-menus, disable timer + // + if( m_numActivePlayersDone == 0 ) + { + this->SetTimerEnabled( false ); + } + } + + m_playerMenus[ playerMenuID ].m_currentSubMenu--; + } + else + { + // de-activate player menu + // + m_playerMenus[ playerMenuID ].SetActive( false ); + GetInputManager()->UnregisterControllerID( playerMenuID ); + + m_numActivePlayers--; + + if( m_numActivePlayers == 0 ) + { + // re-enable track selection + // + this->SetTrackSelectionEnabled( true ); + } + } + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); + } + } + + break; + } + case GUI_MSG_CONTROLLER_AUX_X: + { + if( m_numActivePlayers == 0 ) // track selection state + { + // toggle track direction + // + rAssert( m_trackDirection != NULL ); + m_trackDirection->SetIndex( 1 - m_trackDirection->GetIndex() ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN ); +/* + // show options overlay + // + rAssert( m_optionsOverlay != NULL ); + m_optionsOverlay->SetVisible( true ); + + // hide buttons + // + rAssert( m_optionsButton != NULL ); + m_optionsButton->SetVisible( false ); + this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); + + // reset options menu + // + rAssert( m_optionsMenu != NULL ); + m_optionsMenu->Reset(); + + m_screenState = SCREEN_STATE_OPTIONS; +*/ + } + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + +#ifdef RAD_WIN32 +//=========================================================================== +// CGuiScreenMiniMenu::CheckCursorAgainstHotspots +//=========================================================================== +// Description: Checks cursor position against its list of hotspots. +// +// Constraints: None. +// +// Parameters: float x - The x position of cursor in P3D coordinates. +// float y - The y position of cursor in P3D coordinates. +// +// Return: N/A. +// +//=========================================================================== +eFEHotspotType CGuiScreenMiniMenu::CheckCursorAgainstHotspots( float x, float y ) +{ + if( m_bTrackSelected ) return HOTSPOT_NONE; + eFEHotspotType hotSpotType = HOTSPOT_NONE; + CGuiMenu* pCurrentMenu = HasMenu(); + int numMenuItems = 0; + GuiMenuItem* pMenuItem = NULL; + + + if( pCurrentMenu ) + { + numMenuItems = pCurrentMenu->GetNumItems(); + for( int i = 0; i < numMenuItems; i++ ) + { + pMenuItem = pCurrentMenu->GetMenuItem( i ); + + if( pMenuItem ) + { + if( pMenuItem->GetItem()->IsVisible() ) + { + // Just tests if the point is in the bounding rect of the sprite. + if( pMenuItem->GetItem()->IsPointInBoundingRect( x, y ) ) + { + //rDebugPrintf( "Cursor is inside Sprite %d rectangle!\n", i ); + pCurrentMenu->HandleMessage( GUI_MSG_MOUSE_OVER, i ); + m_currentTrack = i; + hotSpotType = HOTSPOT_BUTTON; + + //After taking care of all the events for this menu item, just bail out. + break; + } + } + } + } + } + + if( hotSpotType == HOTSPOT_NONE ) + { + // Since there's only one set of up and down arrows, when they get translated, + // their bounding box info doesn't change.. so I just offset it depending on + // their current selection. + float xOffset = 0.25f * m_currentTrack; + x -= xOffset; + + if( m_trackNumLapsArrowU ) + { + if( m_trackNumLapsArrowU->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWUP; + } + } + if( m_trackNumLapsArrowD ) + { + if( m_trackNumLapsArrowD->IsPointInBoundingRect( x, y ) ) + { + hotSpotType = HOTSPOT_ARROWDOWN; + } + } + } + + return hotSpotType; +} +#endif + +//=========================================================================== +// CGuiScreenMiniMenu::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniMenu::InitIntro() +{ + // disable track(s) that are not unlocked + // + rAssert( m_pTrackMenu != NULL ); + if( !CommandLineOptions::Get( CLO_SKIP_FE ) ) + { + for( int i = 0; i < NUM_TRACKS; i++ ) + { + bool isTrackUnlocked = GetCardGallery()->IsCardDeckComplete( static_cast<unsigned int>( i ) ); + m_pTrackMenu->SetMenuItemEnabled( i, isTrackUnlocked ); + } + } + + rAssertMsg( m_pTrackMenu->GetSelection() != -1, "Why isn't there at least one track enabled??" ); + + if( m_firstTimeEntered ) + { + this->MoveTrackCursor( 0, m_pTrackMenu->GetSelection() ); + } + + // set default track direction + // + rAssert( m_trackDirection != NULL ); + m_trackDirection->SetIndex( GetSSM()->IsTrackReversed() ? 0 : 1 ); + + // de-activate all player menus + // + for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + m_playerMenus[ p ].SetActive( false ); + GetInputManager()->UnregisterControllerID( p ); + } + + // restore all normal character bitmaps + // + for( int j = 0; j < NUM_CHARACTERS; j++ ) + { + rAssert( m_playerMenus[ 0 ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] != NULL ); + m_playerMenus[ 0 ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetSelectionValue( j, 0 ); + } + + m_numActivePlayers = 0; + m_numActivePlayersDone = 0; + + this->SetTrackSelectionEnabled( true ); +} + +//=========================================================================== +// CGuiScreenMiniMenu::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniMenu::InitRunning() +{ +#ifdef MINI_MENU_SHOW_3D_CHARACTERS + // set drawables for 3D characters + // + tDrawable* pDrawable = NULL; + + pDrawable = p3d::find<tDrawable>( "homer_h" ); + if( pDrawable != NULL ) + { + m_3dCharacters[ CHARACTER_HOMER ]->SetDrawable( pDrawable ); + } + + pDrawable = p3d::find<tDrawable>( "bart_h" ); + if( pDrawable != NULL ) + { + m_3dCharacters[ CHARACTER_BART ]->SetDrawable( pDrawable ); + } + + pDrawable = p3d::find<tDrawable>( "lisa_h" ); + if( pDrawable != NULL ) + { + m_3dCharacters[ CHARACTER_LISA ]->SetDrawable( pDrawable ); + } + + pDrawable = p3d::find<tDrawable>( "marge_h" ); + if( pDrawable != NULL ) + { + m_3dCharacters[ CHARACTER_MARGE ]->SetDrawable( pDrawable ); + } + + pDrawable = p3d::find<tDrawable>( "apu_h" ); + if( pDrawable != NULL ) + { + m_3dCharacters[ CHARACTER_APU ]->SetDrawable( pDrawable ); + } + + // adjust camera aspect ratio to match viewport dimensions + // + for( int i = 0; i < NUM_CHARACTERS; i++ ) + { + rAssert( m_3dCharacters[ i ] != NULL ); + + int width = 0; + int height = 0; + m_3dCharacters[ i ]->GetBoundingBoxSize( width, height ); + + tCamera* pCamera = m_3dCharacters[ i ]->GetCamera(); + rAssert( pCamera != NULL ); + pCamera->SetFOV( pCamera->GetFieldOfView(), (float)width / (float)height ); + + // show 3D characters + // + m_3dCharacters[ i ]->SetVisible( false ); // true ); + } +#endif // MINI_MENU_SHOW_3D_CHARACTERS +} + +//=========================================================================== +// CGuiScreenMiniMenu::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniMenu::InitOutro() +{ +#ifdef MINI_MENU_SHOW_3D_CHARACTERS + // hide 3D characters + // + for( int i = 0; i < NUM_CHARACTERS; i++ ) + { + rAssert( m_3dCharacters[ i ] != NULL ); + m_3dCharacters[ i ]->SetVisible( false ); + } +#endif // MINI_MENU_SHOW_3D_CHARACTERS + + // setup supersprint stuff + // + for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + if( m_playerMenus[ p ].IsActive() ) + { + + int character = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection(); + GetSSM()->SetCharacter( p, character ); + + int vehicle = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->GetSelectionValue( 0 ); + rAssert( m_unlockedVehicles[ vehicle ] != NULL ); + GetSSM()->SetVehicle( p, m_unlockedVehicles[ vehicle ]->GetName() ); + } + } +} + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMiniMenu::UpdateCharacterSlots() +{ + // update character slots availability + // + int p = 0; + + m_characterSlots = 0; + for( p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + if( m_playerMenus[ p ].IsActive() ) + { + int currentSelection = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection(); + m_characterSlots |= (1 << currentSelection ); + } + } + + // enable/disable character selections for all player menus + // + for( p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + if( m_playerMenus[ p ].IsActive() ) + { + for( int i = 0; i < NUM_CHARACTERS; i++ ) + { + int currentSelection = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection(); + if( i != currentSelection ) + { + bool isEnabled = ( ((1 << i) & m_characterSlots) == 0 ); + m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetMenuItemEnabled( i, isEnabled ); + } + } + } + } +} + +void +CGuiScreenMiniMenu::SetTrackSelectionEnabled( bool enable ) +{ + // show/hide options button + // + rAssert( m_optionsButton != NULL ); + m_optionsButton->SetVisible( enable ); + + // set back label to "quit" if enabled + // + rAssert( m_backLabel != NULL ); + m_backLabel->SetIndex( enable ? 1 : 0 ); + + // hide/show all players' "press start" + // + for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ ) + { + rAssert( m_playerMenus[ p ].m_pressStart != NULL ); + m_playerMenus[ p ].m_pressStart->SetVisible( !enable ); + } + + // hide/show character select info + // + if( m_characterSelectInfo != NULL ) + { + m_characterSelectInfo->SetVisible( !enable ); + } +#ifdef RAD_WIN32 + m_bTrackSelected = !enable; +#endif +} + +void +CGuiScreenMiniMenu::MoveTrackCursor( int previousIndex, int nextIndex ) +{ + // if cursor exists + // + if( m_trackCursorBgd != NULL ) + { + Scrooby::BoundedDrawable* item = NULL; + int x1, y1, x2, y2; + + rAssert( m_pTrackMenu != NULL ); + + // get location of previous item + item = m_pTrackMenu->GetMenuItem( previousIndex )->GetItem(); + rAssert( item != NULL ); + item->GetOriginPosition( x1, y1 ); + + // get location of next item + item = m_pTrackMenu->GetMenuItem( nextIndex )->GetItem(); + rAssert( item != NULL ); + item->GetOriginPosition( x2, y2 ); + + // translate cursor + m_trackCursorBgd->Translate( x2 - x1, y2 - y1 ); + } +} + +void +CGuiScreenMiniMenu::OnTrackSelected() +{ + this->SetTrackSelectionEnabled( false ); + + // highlight track cursor bgd + // + if( m_trackCursorBgd != NULL ) + { + m_trackCursorBgd->SetAlpha( 1.0f ); + } + + // restore U/D num laps arrows + // + if( m_trackNumLapsArrowU != NULL && m_trackNumLapsArrowD != NULL ) + { + m_trackNumLapsArrowU->SetIndex( 0 ); + m_trackNumLapsArrowD->SetIndex( 0 ); + } + + // get current track selection + // + rAssert( m_pTrackMenu != NULL ); + int currentTrack = m_pTrackMenu->GetSelection(); + + // disable selection made delay + // + m_pTrackMenu->MakeSelection( false ); + + // tell gameplay manager which track to load + // + RenderEnums::LevelEnum levelIndex = static_cast<RenderEnums::LevelEnum>( RenderEnums::B01 + currentTrack ); + GetGameplayManager()->SetLevelIndex( levelIndex ); + + // set track options + // + rAssert( m_trackNumLaps != NULL ); + GetSSM()->SetNumLaps( m_trackNumLaps->GetIndex() ); + + rAssert( m_trackDirection != NULL ); + GetSSM()->SetTrackDirection( m_trackDirection->GetIndex() == 0 ); +} + +void +CGuiScreenMiniMenu::ActivateNewPlayer( int controllerID ) +{ + if( m_numActivePlayers >= SuperSprintData::NUM_PLAYERS ) + { + // can't activate anymore new players + // + return; + } + + int player_slot = 0; +#ifdef RAD_XBOX + player_slot = controllerID; +#elif defined ( RAD_WIN32 ) + player_slot = controllerID; +#else + // look for non empty slot + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { + // find first non-active menu to activate + // + if( !m_playerMenus[ i ].IsActive() ) + { + player_slot = i; + break; + } + } +#endif + + // ok, found it! + // + m_playerMenus[ player_slot ].SetActive( true, controllerID ); + GetInputManager()->RegisterControllerID( player_slot , controllerID); + + m_numActivePlayers++; + + // default character selection to first empty slot + // + for( int s = 0; s < NUM_CHARACTERS; s++ ) + { + if( ((1 << s) & m_characterSlots) == 0 ) + { + m_playerMenus[ player_slot ].GetCurrentSubMenu()->Reset( s ); + + break; + } + } + + // update vehicle rating + // + this->UpdateVehicleRating( player_slot ); +} + +void +CGuiScreenMiniMenu::OnCharacterSelected( int playerID, bool isSelected ) +{ + rAssert( playerID != -1 ); + rAssert( m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] != NULL ); + + // show/hide character selection done indicator + // + rAssert( m_playerMenus[ playerID ].m_characterSelectedIcon != NULL ); + m_playerMenus[ playerID ].m_characterSelectedIcon->SetAlpha( isSelected ? 1.0f : 0.0f ); + + // swap selected character bitmap + // + int characterIndex = m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection(); + m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetSelectionValue( characterIndex, isSelected ? CHARACTER_SELECTED : CHARACTER_NOT_SELECTED ); + + // disable selection made delay + // + if( isSelected ) + { + m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->MakeSelection( false ); + } +} + +void +CGuiScreenMiniMenu::OnVehicleSelected( int playerID, bool isSelected ) +{ + rAssert( playerID != -1 ); + rAssert( m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_VEHICLES ] != NULL ); + + // show/hide vehicle selection done indicator + // + rAssert( m_playerMenus[ playerID ].m_vehicleSelectedIcon != NULL ); + m_playerMenus[ playerID ].m_vehicleSelectedIcon->SetAlpha( isSelected ? 1.0f : 0.0f ); + + // disable selection made delay + // + if( isSelected ) + { + m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->MakeSelection( false ); + } +} + +void +CGuiScreenMiniMenu::AddRewardVehicle( Reward* pReward ) +{ + rAssert( pReward != NULL ); + if( pReward->RewardStatus() || // if reward is unlocked + CommandLineOptions::Get( CLO_SKIP_FE ) || +// GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_CARDS ) || + GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) ) + { + rAssert( m_numUnlockedVehicles < MAX_NUM_VEHICLES ); + + m_unlockedVehicles[ m_numUnlockedVehicles ] = pReward; + m_numUnlockedVehicles++; + } +} + +void +CGuiScreenMiniMenu::PrepareVehicleSelections() +{ + for( int level = 0; level < RenderEnums::numLevels; level++ ) + { + Reward* pReward = NULL; + + for( int i = Reward::eBlank + 1; i < Reward::NUM_QUESTS; i++ ) + { + pReward = GetRewardsManager()->GetReward( level, static_cast<Reward::eQuestType>( i ) ); + if( pReward != NULL ) + { + if( pReward->GetRewardType() == Reward::ALT_PLAYERCAR ) + { + this->AddRewardVehicle( pReward ); + } + } + } + + for( pReward = GetRewardsManager()->FindFirstMerchandise( level, Merchandise::SELLER_GIL ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( level, Merchandise::SELLER_GIL ) ) + { + this->AddRewardVehicle( pReward ); + } + + for( pReward = GetRewardsManager()->FindFirstMerchandise( level, Merchandise::SELLER_SIMPSON ); + pReward != NULL; + pReward = GetRewardsManager()->FindNextMerchandise( level, Merchandise::SELLER_SIMPSON ) ) + { + this->AddRewardVehicle( pReward ); + } + } +} + +void +CGuiScreenMiniMenu::UpdateVehicleDisplayImages( int playerID, Scrooby::Sprite* vehicleImage ) +{ + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + rAssert( vehicleImage != NULL ); + for( int i = 0; i < m_numUnlockedVehicles; i++ ) + { + rAssert( m_unlockedVehicles[ i ] != NULL ); + vehicleImage->SetImage( i, m_unlockedVehicles[ i ]->GetName() ); + } + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); +} + +void +CGuiScreenMiniMenu::UpdateVehicleRating( int playerID ) +{ + if( m_playerMenus[ playerID ].m_vehicleRating != NULL ) + { + int vehicleIndex = m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->GetSelectionValue( 0 ); + + rAssert( m_unlockedVehicles[ vehicleIndex ] != NULL ); + CarAttributeRecord* carStats = GetRewardsManager()->GetCarAttributeRecord( m_unlockedVehicles[ vehicleIndex ]->GetName() ); + if( carStats != NULL ) + { + int rating = (int)( GetRewardsManager()->ComputeOverallCarRating( carStats ) ); + + rAssertMsg( rating >= 0 && rating < m_playerMenus[ playerID ].m_vehicleRating->GetNumOfImages(), + "Invalid vehicle rating (either negative or too high)!" ); + + m_playerMenus[ playerID ].m_vehicleRating->SetIndex( rating ); + } + } +} + +void +CGuiScreenMiniMenu::SetTimerEnabled( bool enable ) +{ + // show/hide timer overlay + // + rAssert( m_timerOverlay != NULL ); + m_timerOverlay->SetVisible( enable ); + + if( !enable ) + { + // reset timer + // + m_remainingTime = TIMER_WAIT_TIME; + } +} + +int +CGuiScreenMiniMenu::GetPlayerMenuID( int controllerID ) const +{ + // search for player menu w/ associated controller ID + // + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { + if( m_playerMenus[ i ].m_controllerID == controllerID ) + { + // found it! return player menu ID + // + return i; + } + } + + // player menu not found, return -1 + // + return -1; +} + diff --git a/game/code/presentation/gui/minigame/guiscreenminimenu.h b/game/code/presentation/gui/minigame/guiscreenminimenu.h new file mode 100644 index 0000000..356233a --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminimenu.h @@ -0,0 +1,210 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniMenu +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMINIMENU_H +#define GUISCREENMINIMENU_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> +#include <presentation/gui/utility/numerictext.h> + +#include <supersprint/supersprintdata.h> + +//#define MINI_MENU_SHOW_3D_CHARACTERS + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu; +class Reward; + +struct PlayerMenu +{ + enum eSubMenu + { + MENU_CHARACTERS, + MENU_VEHICLES, + + NUM_SUB_MENUS + }; + + CGuiMenu* m_pMenu[ NUM_SUB_MENUS ]; + int m_currentSubMenu; + int m_controllerID; + + Scrooby::Text* m_pressStart; + Scrooby::Sprite* m_vehicleRating; + Scrooby::Drawable* m_characterSelectedIcon; + Scrooby::Drawable* m_vehicleSelectedIcon; + + PlayerMenu(); + + void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + CGuiMenu* GetCurrentSubMenu() const; + void SetActive( bool isActive, int controllerID = -1 ); + bool IsActive() const; + bool IsDone() const; + +}; + +inline bool PlayerMenu::IsActive() const +{ + return( m_controllerID != -1 ); +} + +inline bool PlayerMenu::IsDone() const +{ + return( m_currentSubMenu >= NUM_SUB_MENUS ); +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMiniMenu : public CGuiScreen +{ +public: + CGuiScreenMiniMenu( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMiniMenu(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + virtual CGuiMenu* HasMenu() { return m_pTrackMenu; } +#ifdef RAD_WIN32 + virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y ); +#endif + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void UpdateCharacterSlots(); + + void SetTrackSelectionEnabled( bool enable ); + void MoveTrackCursor( int previousIndex, int nextIndex ); + void OnTrackSelected(); + + void ActivateNewPlayer( int controllerID ); + + void OnCharacterSelected( int playerID, bool isSelected ); + void OnVehicleSelected( int playerID, bool isSelected ); + + void AddRewardVehicle( Reward* pReward ); + void PrepareVehicleSelections(); + void UpdateVehicleDisplayImages( int playerID, Scrooby::Sprite* vehicleImage ); + void UpdateVehicleRating( int playerID ); + + void SetTimerEnabled( bool enable ); + + int GetPlayerMenuID( int controllerID ) const; + + static const int NUM_TRACKS = 7; + static const int MAX_NUM_VEHICLES = 64; + +#ifdef RAD_DEBUG + static const int TIMER_WAIT_TIME = 5000; // in msec +#else + static const int TIMER_WAIT_TIME = 10000; // in msec +#endif + + enum eScreenState + { + SCREEN_STATE_NORMAL, + SCREEN_STATE_OPTIONS, + + NUM_SCREEN_STATES + }; + + enum eCharacter + { + CHARACTER_LISA, + CHARACTER_BART, + CHARACTER_HOMER, + CHARACTER_MARGE, + CHARACTER_APU, + + NUM_CHARACTERS + }; + + enum eCharacterSelectionState + { + CHARACTER_NOT_SELECTED = 0, + CHARACTER_SELECTED = 1, + + NUM_CHARACTER_SELECTION_STATES + }; + +/* + enum eOptionsMenuItem + { + MENU_ITEM_NUM_LAPS, + MENU_ITEM_REVERSE_DIRECTION, + + NUM_OPTIONS_MENU_ITEMS + }; + + eScreenState m_screenState; +*/ + + CGuiMenu* m_pTrackMenu; + Scrooby::Sprite* m_trackDirection; + Scrooby::Text* m_trackNumLaps; + Scrooby::Sprite* m_trackNumLapsArrowU; + Scrooby::Sprite* m_trackNumLapsArrowD; + Scrooby::Polygon* m_trackCursorBgd; + unsigned int m_elapsedTime; + + Scrooby::Text* m_backLabel; + + PlayerMenu m_playerMenus[ SuperSprintData::NUM_PLAYERS ]; + int m_numActivePlayers; + int m_numActivePlayersDone; + short m_characterSlots; // bit-mask + +#ifdef MINI_MENU_SHOW_3D_CHARACTERS + Scrooby::Pure3dObject* m_3dCharacters[ NUM_CHARACTERS ]; +#endif + +#ifdef RAD_WIN32 + int m_currentTrack; + bool m_bTrackSelected; +#endif + + Reward* m_unlockedVehicles[ MAX_NUM_VEHICLES ]; + int m_numUnlockedVehicles; + + Scrooby::Group* m_optionsButton; +/* + Scrooby::Layer* m_optionsOverlay; + CGuiMenu* m_optionsMenu; +*/ + + Scrooby::Group* m_characterSelectInfo; + + Scrooby::Group* m_timerOverlay; + NumericText<Scrooby::Text> m_timer; + int m_remainingTime; + +}; + +#endif // GUISCREENMINIMENU_H diff --git a/game/code/presentation/gui/minigame/guiscreenminipause.cpp b/game/code/presentation/gui/minigame/guiscreenminipause.cpp new file mode 100644 index 0000000..db37e0c --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminipause.cpp @@ -0,0 +1,297 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniPause +// +// Description: Implementation of the CGuiScreenMiniPause class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/minigame/guiscreenminipause.h> +#include <presentation/gui/minigame/guiscreenminihud.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guimenu.h> + +#include <contexts/supersprint/supersprintcontext.h> +#include <gameflow/gameflow.h> +#include <input/inputmanager.h> +#include <sound/soundmanager.h> + +#include <screen.h> +#include <page.h> +#include <group.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMiniPause::CGuiScreenMiniPause +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniPause::CGuiScreenMiniPause +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_PAUSE ), + m_pMenu( NULL ) +{ + // Retrieve the Scrooby drawing elements (from MiniPause page). + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MiniPause" ); + rAssert( pPage != NULL ); + + // create menu + // + m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS ); + rAssert( m_pMenu != NULL ); + + Scrooby::Group* pGroup = pPage->GetGroup( "Menu" ); + rAssert( pGroup != NULL ); + m_pMenu->AddMenuItem( pGroup->GetText( "Continue" ) ); + m_pMenu->AddMenuItem( pGroup->GetText( "Quit" ) ); + + // Retrieve the Scrooby drawing elements (from PauseFgd page). + // + pPage = m_pScroobyScreen->GetPage( "PauseFgd" ); + if( pPage != NULL ) + { + // Wrap "Press Start" help text + // + Scrooby::Text* pressStart = pPage->GetText( "PressStartResumePlay" ); + if( pressStart != NULL ) + { + pressStart->SetTextMode( Scrooby::TEXT_WRAP ); + + // add text outline + // + pressStart->SetDisplayOutline( true ); + + // set platform-specific text + // + pressStart->SetIndex( PLATFORM_TEXT_INDEX ); + } + } + + this->AutoScaleFrame( m_pScroobyScreen->GetPage( "XSmallBoard" ) ); + + this->SetZoomingEnabled( true ); +} + + +//=========================================================================== +// CGuiScreenMiniPause::~CGuiScreenMiniPause +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniPause::~CGuiScreenMiniPause() +{ + if( m_pMenu != NULL ) + { + delete m_pMenu; + m_pMenu = NULL; + } +} + + +//=========================================================================== +// CGuiScreenMiniPause::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniPause::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + if( this->IsControllerMessage( message ) && + static_cast<int>( param1 ) != CGuiScreenMiniHud::s_pausedControllerID ) + { + // ignore controller messages if not from user who paused mini-game + // + return; + } + + switch( message ) + { + case GUI_MSG_CONTROLLER_START: + { + if( !m_pMenu->HasSelectionBeenMade() ) + { + this->ResumeGame(); + } + + break; + } + case GUI_MSG_CONTROLLER_BACK: + { +#ifdef RAD_WIN32 + this->ResumeGame(); + break; +#else + // don't allow user to back out of pause menu + // + return; +#endif + } + case GUI_MSG_MENU_SELECTION_MADE: + { + if( param1 == MENU_ITEM_CONTINUE ) + { + this->ResumeGame(); + } + else if( param1 == MENU_ITEM_QUIT ) + { + this->QuitGame(); + } + else + { + rAssertMsg( false, "Invalid menu selection!" ); + } + + break; + } + default: + { + break; + } + } + + // relay message to menu + // + rAssert( m_pMenu != NULL ); + m_pMenu->HandleMessage( message, param1, param2 ); + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMiniPause::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniPause::InitIntro() +{ + rAssert( m_pMenu != NULL ); + m_pMenu->Reset(); // default to 'Continue' + + GetSoundManager()->OnPauseStart(); + +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetInGameMode( false ); +#endif +} + + +//=========================================================================== +// CGuiScreenMiniPause::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniPause::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenMiniPause::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniPause::InitOutro() +{ + GetSoundManager()->OnPauseEnd(); + +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetInGameMode( true ); +#endif +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMiniPause::ResumeGame() +{ + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MINI_HUD, CLEAR_WINDOW_HISTORY ); +} + +void +CGuiScreenMiniPause::QuitGame() +{ + // quit mini-game and return to mini-game FE + // + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_MINI_MENU, + CLEAR_WINDOW_HISTORY ); + + GetGameFlow()->SetContext( CONTEXT_SUPERSPRINT_FE ); +} + diff --git a/game/code/presentation/gui/minigame/guiscreenminipause.h b/game/code/presentation/gui/minigame/guiscreenminipause.h new file mode 100644 index 0000000..543ab36 --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminipause.h @@ -0,0 +1,66 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniPause +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMINIPAUSE_H +#define GUISCREENMINIPAUSE_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +class CGuiMenu; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMiniPause : public CGuiScreen +{ +public: + CGuiScreenMiniPause( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMiniPause(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + + virtual CGuiMenu* HasMenu() { return m_pMenu; } + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void ResumeGame(); + void QuitGame(); + + enum eMenuItem + { + MENU_ITEM_CONTINUE, + MENU_ITEM_QUIT, + + NUM_MENU_ITEMS + }; + + CGuiMenu* m_pMenu; + +}; + +#endif // GUISCREENMINIPAUSE_H diff --git a/game/code/presentation/gui/minigame/guiscreenminisummary.cpp b/game/code/presentation/gui/minigame/guiscreenminisummary.cpp new file mode 100644 index 0000000..4841d93 --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminisummary.cpp @@ -0,0 +1,539 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniSummary +// +// Description: Implementation of the CGuiScreenMiniSummary class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/minigame/guiscreenminisummary.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guiscreenprompt.h> +#include <presentation/gui/guitextbible.h> + +#include <contexts/supersprint/supersprintcontext.h> +#include <events/eventmanager.h> +#include <gameflow/gameflow.h> +#include <input/inputmanager.h> +#include <sound/soundmanager.h> + +#include <screen.h> +#include <page.h> +#include <group.h> +#include <sprite.h> +#include <text.h> +#include <polygon.h> + +#include <supersprint/supersprintmanager.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +const float MINI_SUMMARY_CHARACTER_SCALE_BIG = 0.9f; +const float MINI_SUMMARY_CHARACTER_SCALE_SMALL = 0.7f; +const float MINI_SUMMARY_KING_ICON_SCALE = 0.75f; + +void +CGuiScreenMiniSummary::PlayerDisplayInfo::SetVisible( bool isVisible ) +{ + rAssert( m_face != NULL ); + m_face->SetVisible( isVisible ); + rAssert( m_ranking != NULL ); + m_ranking->SetVisible( isVisible ); + rAssert( m_numWins != NULL ); + m_numWins->SetVisible( isVisible ); + rAssert( m_numPoints != NULL ); + m_numPoints->SetVisible( isVisible ); + rAssert( m_totalTime != NULL ); + m_totalTime->SetVisible( isVisible ); + rAssert( m_bestLap != NULL ); + m_bestLap->SetVisible( isVisible ); + rAssert( m_rowBgd != NULL ); + m_rowBgd->SetVisible( isVisible ); +} + +int +CGuiScreenMiniSummary::PlayerRanking::CompareScores( int points1, int wins1, + int points2, int wins2 ) +{ + if( points1 > points2 ) + { + return 1; + } + else if( points1 == points2 ) + { + if( wins1 > wins2 ) + { + return 1; + } + else if( wins1 == wins2 ) + { + return 0; + } + else + { + return -1; + } + } + else + { + return -1; + } +} + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CGuiScreenMiniSummary::CGuiScreenMiniSummary +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniSummary::CGuiScreenMiniSummary +( + Scrooby::Screen* pScreen, + CGuiEntity* pParent +) +: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_SUMMARY ), + m_totalTimeKingIcon( NULL ), + m_bestLapKingIcon( NULL ) +{ + // Retrieve the Scrooby drawing elements. + // + Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MiniSummary" ); + rAssert( pPage != NULL ); + + Scrooby::Text* raceSummary = pPage->GetText( "RaceSummary" ); + if( raceSummary != NULL ) + { + raceSummary->SetTextMode( Scrooby::TEXT_WRAP ); + } + + Scrooby::Group* pGroupFaces = pPage->GetGroup( "Faces" ); + rAssert( pGroupFaces != NULL ); + Scrooby::Group* pGroupRanks = pPage->GetGroup( "Ranks" ); + rAssert( pGroupRanks != NULL ); + Scrooby::Group* pGroupPlayers = pPage->GetGroup( "Players" ); + rAssert( pGroupPlayers != NULL ); + Scrooby::Group* pGroupWins = pPage->GetGroup( "Wins" ); + rAssert( pGroupWins != NULL ); + Scrooby::Group* pGroupPoints = pPage->GetGroup( "Points" ); + rAssert( pGroupPoints != NULL ); + Scrooby::Group* pGroupTotalTime = pPage->GetGroup( "TotalTime" ); + rAssert( pGroupTotalTime != NULL ); + Scrooby::Group* pGroupBestLap = pPage->GetGroup( "BestLap" ); + rAssert( pGroupBestLap != NULL ); + Scrooby::Group* pGroupRows = pPage->GetGroup( "Rows" ); + rAssert( pGroupRows != NULL ); + + char name[ 32 ]; + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { + sprintf( name, "Face%d", i ); + m_displayInfo[ i ].m_face = pGroupFaces->GetSprite( name ); + + sprintf( name, "Rank%d", i ); + m_displayInfo[ i ].m_ranking = pGroupRanks->GetText( name ); + + sprintf( name, "Player%d", i ); + m_displayInfo[ i ].m_playerIndicator = pGroupPlayers->GetText( name ); + + sprintf( name, "NumWins%d", i ); + m_displayInfo[ i ].m_numWins = pGroupWins->GetText( name ); + + sprintf( name, "NumPoints%d", i ); + m_displayInfo[ i ].m_numPoints = pGroupPoints->GetText( name ); + + sprintf( name, "TotalTime%d", i ); + m_displayInfo[ i ].m_totalTime = pGroupTotalTime->GetText( name ); + + sprintf( name, "BestLap%d", i ); + m_displayInfo[ i ].m_bestLap = pGroupBestLap->GetText( name ); + + sprintf( name, "Row%d", i ); + m_displayInfo[ i ].m_rowBgd = pGroupRows->GetPolygon( name ); + } + + // text wrap "Total Time" and "Best Lap" + // + Scrooby::Text* pText = pGroupTotalTime->GetText( "TotalTime" ); + rAssert( pText != NULL ); + pText->SetTextMode( Scrooby::TEXT_WRAP ); + + pText = pGroupBestLap->GetText( "BestLap" ); + rAssert( pText != NULL ); + pText->SetTextMode( Scrooby::TEXT_WRAP ); + + // get king icons + // + m_totalTimeKingIcon = pGroupTotalTime->GetSprite( "TotalTimeKingIcon" ); + m_bestLapKingIcon = pGroupBestLap->GetSprite( "BestLapKingIcon" ); + +#ifdef RAD_WIN32 + m_totalTimeKingIcon->ScaleAboutCenter( 0.5f ); + m_bestLapKingIcon->ScaleAboutCenter( 0.5f ); + pGroupRanks->GetSprite( "RankKingIcon" )->ScaleAboutCenter( 0.5f ); +#endif + + // TC: [TEMP] hide these for now until I have time to implement the + // functionality + // + rAssert( m_totalTimeKingIcon != NULL ); + m_totalTimeKingIcon->SetVisible( false ); + rAssert( m_bestLapKingIcon != NULL ); + m_bestLapKingIcon->SetVisible( false ); + + this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) ); +} + + +//=========================================================================== +// CGuiScreenMiniSummary::~CGuiScreenMiniSummary +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CGuiScreenMiniSummary::~CGuiScreenMiniSummary() +{ +} + + +//=========================================================================== +// CGuiScreenMiniSummary::HandleMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniSummary::HandleMessage +( + eGuiMessage message, + unsigned int param1, + unsigned int param2 +) +{ + if( message == GUI_MSG_MENU_PROMPT_RESPONSE ) + { + rAssert( param1 == PROMPT_CONFIRM_RACE_AGAIN ); + + switch( param2 ) + { + case (CGuiMenuPrompt::RESPONSE_YES): + { + // ok, letz start another race + // + GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Resume(); + + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_MINI_HUD, + CLEAR_WINDOW_HISTORY ); + + GetSSM()->Reset(); + + GetSoundManager()->RestartSupersprintMusic(); + + break; + } + case (CGuiMenuPrompt::RESPONSE_NO): + { + // quit mini-game and return to mini-game FE + // + m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, + GUI_SCREEN_ID_MINI_MENU, + CLEAR_WINDOW_HISTORY ); + + GetGameFlow()->SetContext( CONTEXT_SUPERSPRINT_FE ); + + break; + } + default: + { + rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" ); + + break; + } + } + + GetSoundManager()->OnStoreScreenEnd(); + } + + if( m_state == GUI_WINDOW_STATE_RUNNING ) + { + switch( message ) + { + case GUI_MSG_CONTROLLER_SELECT: + { + // display 'race again' prompt + // + m_guiManager->DisplayPrompt( PROMPT_CONFIRM_RACE_AGAIN, + this, + PROMPT_TYPE_YES_NO, + false ); + + GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); + + break; + } + default: + { + break; + } + } + } + + // Propogate the message up the hierarchy. + // + CGuiScreen::HandleMessage( message, param1, param2 ); +} + + +//=========================================================================== +// CGuiScreenMiniSummary::InitIntro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniSummary::InitIntro() +{ + this->ResetCurrentRankings(); + + // rank players by points and wins + // + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { +// if( GetSSM()->GetVehicleData( i )->mIsHuman ) + { + this->InsertPlayerRanking( i ); + } + } + + // update display info + // + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { + this->UpdateDisplayInfo( i, m_currentRankings[ i ].m_playerID ); + } + + // + // This isn't a store, but it's a handy set of ducking values + // + GetSoundManager()->OnStoreScreenStart( false ); +} + + +//=========================================================================== +// CGuiScreenMiniSummary::InitRunning +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniSummary::InitRunning() +{ +} + + +//=========================================================================== +// CGuiScreenMiniSummary::InitOutro +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +void CGuiScreenMiniSummary::InitOutro() +{ +#ifdef RAD_WIN32 + GetInputManager()->GetFEMouse()->SetInGameMode( false ); +#endif +} + + +//--------------------------------------------------------------------- +// Private Functions +//--------------------------------------------------------------------- + +void +CGuiScreenMiniSummary::UpdateDisplayInfo( int rankIndex, int playerID ) +{ + rAssert( rankIndex >= 0 && rankIndex < SuperSprintData::NUM_PLAYERS ); + + if( playerID != -1 ) + { + m_displayInfo[ rankIndex ].SetVisible( true ); + + const SuperSprintData::PlayerData* playerData = GetSSM()->GetPlayerData( playerID ); + rAssert( playerData != NULL ); + + HeapMgr()->PushHeap( GMA_LEVEL_HUD ); + + // set character face + // + rAssert( m_displayInfo[ rankIndex ].m_face != NULL ); + m_displayInfo[ rankIndex ].m_face->SetIndex( playerData->mCharacterIndex ); + m_displayInfo[ rankIndex ].m_face->ResetTransformation(); + if( rankIndex == 0 ) + { + m_displayInfo[ rankIndex ].m_face->ScaleAboutCenter( MINI_SUMMARY_CHARACTER_SCALE_BIG ); + } + else + { + m_displayInfo[ rankIndex ].m_face->ScaleAboutCenter( MINI_SUMMARY_CHARACTER_SCALE_SMALL ); + } + + // set ranking colour + // + rAssert( m_displayInfo[ rankIndex ].m_ranking != NULL ); + m_displayInfo[ rankIndex ].m_ranking->SetColour( SuperSprintData::PLAYER_COLOURS[ playerID ] ); + + // set player ID indicator and colour + // + rAssert( m_displayInfo[ rankIndex ].m_playerIndicator != NULL ); + if( GetSSM()->GetVehicleData( playerID )->mIsHuman ) + { + m_displayInfo[ rankIndex ].m_playerIndicator->SetVisible( true ); + m_displayInfo[ rankIndex ].m_playerIndicator->SetIndex( playerID ); + m_displayInfo[ rankIndex ].m_playerIndicator->SetColour( SuperSprintData::PLAYER_COLOURS[ playerID ] ); + } + else + { + m_displayInfo[ rankIndex ].m_playerIndicator->SetVisible( false ); + } + + char buffer[ 16 ]; + UnicodeString unicodeString; + + // set num wins + // + sprintf( buffer, "%d", playerData->mWins ); + rAssert( m_displayInfo[ rankIndex ].m_numWins != NULL ); + m_displayInfo[ rankIndex ].m_numWins->SetString( 0, buffer ); + + // set num points + // + sprintf( buffer, "%d", playerData->mPoints ); + rAssert( m_displayInfo[ rankIndex ].m_numPoints != NULL ); + m_displayInfo[ rankIndex ].m_numPoints->SetString( 0, buffer ); + + // set total time + // + if( playerData->mPosition > 0 ) + { + sprintf( buffer, "%.2f", playerData->mRaceTime / 1000000.0f ); + unicodeString.ReadAscii( buffer ); + } + else + { + unicodeString.ReadUnicode( GetTextBibleString( "DNF" ) ); + } + rAssert( m_displayInfo[ rankIndex ].m_totalTime != NULL ); + m_displayInfo[ rankIndex ].m_totalTime->SetString( 0, unicodeString ); + + // set best lap + // + if( playerData->mRaceTime > 0 ) + { + sprintf( buffer, "%.2f", playerData->mBestLap / 1000000.0f ); + unicodeString.ReadAscii( buffer ); + } + else + { + unicodeString.ReadUnicode( GetTextBibleString( "DNF" ) ); + } + rAssert( m_displayInfo[ rankIndex ].m_bestLap != NULL ); + m_displayInfo[ rankIndex ].m_bestLap->SetString( 0, unicodeString ); + + HeapMgr()->PopHeap( GMA_LEVEL_HUD ); + } + else + { + m_displayInfo[ rankIndex ].SetVisible( false ); + } +} + +void +CGuiScreenMiniSummary::ResetCurrentRankings() +{ + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { + m_currentRankings[ i ].m_playerID = -1; + m_currentRankings[ i ].m_playerPoints = -1; + m_currentRankings[ i ].m_playerWins = -1; + } +} + +void +CGuiScreenMiniSummary::InsertPlayerRanking( int playerID ) +{ + const SuperSprintData::PlayerData* playerData = GetSSM()->GetPlayerData( playerID ); + rAssert( playerData != NULL ); + + for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ ) + { + if( PlayerRanking::CompareScores( playerData->mPoints, playerData->mWins, + m_currentRankings[ i ].m_playerPoints, m_currentRankings[ i ].m_playerWins ) > 0 ) + { + // move everyone else down a spot + // + for( int j = SuperSprintData::NUM_PLAYERS - 1; j > i; j-- ) + { + m_currentRankings[ j ].m_playerID = m_currentRankings[ j - 1 ].m_playerID; + m_currentRankings[ j ].m_playerPoints = m_currentRankings[ j - 1 ].m_playerPoints; + m_currentRankings[ j ].m_playerWins = m_currentRankings[ j - 1 ].m_playerWins; + } + + // insert here + // + m_currentRankings[ i ].m_playerID = playerID; + m_currentRankings[ i ].m_playerPoints = playerData->mPoints; + m_currentRankings[ i ].m_playerWins = playerData->mWins; + + break; + } + } +} + diff --git a/game/code/presentation/gui/minigame/guiscreenminisummary.h b/game/code/presentation/gui/minigame/guiscreenminisummary.h new file mode 100644 index 0000000..231fcf9 --- /dev/null +++ b/game/code/presentation/gui/minigame/guiscreenminisummary.h @@ -0,0 +1,87 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: CGuiScreenMiniSummary +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/24 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef GUISCREENMINISUMMARY_H +#define GUISCREENMINISUMMARY_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <presentation/gui/guiscreen.h> + +#include <supersprint/supersprintdata.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CGuiScreenMiniSummary : public CGuiScreen +{ +public: + CGuiScreenMiniSummary( Scrooby::Screen* pScreen, CGuiEntity* pParent ); + virtual ~CGuiScreenMiniSummary(); + + virtual void HandleMessage( eGuiMessage message, + unsigned int param1 = 0, + unsigned int param2 = 0 ); + +protected: + void InitIntro(); + void InitRunning(); + void InitOutro(); + +private: + void UpdateDisplayInfo( int rankIndex, int playerID ); + + void ResetCurrentRankings(); + void InsertPlayerRanking( int playerID ); + + struct PlayerDisplayInfo + { + Scrooby::Sprite* m_face; + Scrooby::Text* m_ranking; + Scrooby::Text* m_playerIndicator; + Scrooby::Text* m_numWins; + Scrooby::Text* m_numPoints; + Scrooby::Text* m_totalTime; + Scrooby::Text* m_bestLap; + Scrooby::Polygon* m_rowBgd; + + void SetVisible( bool isVisible ); + }; + + PlayerDisplayInfo m_displayInfo[ SuperSprintData::NUM_PLAYERS ]; + + struct PlayerRanking + { + int m_playerID; + int m_playerPoints; + int m_playerWins; + + static int CompareScores( int points1, int wins1, + int points2, int wins2 ); + }; + + PlayerRanking m_currentRankings[ SuperSprintData::NUM_PLAYERS ]; + + Scrooby::Sprite* m_totalTimeKingIcon; + Scrooby::Sprite* m_bestLapKingIcon; + +}; + +#endif // GUISCREENMINISUMMARY_H diff --git a/game/code/presentation/gui/utility/allutility.cpp b/game/code/presentation/gui/utility/allutility.cpp new file mode 100644 index 0000000..f9cbf09 --- /dev/null +++ b/game/code/presentation/gui/utility/allutility.cpp @@ -0,0 +1,8 @@ +#include <presentation/gui/utility/hudmapcam.cpp> +#include <presentation/gui/utility/hudmap.cpp> +#include <presentation/gui/utility/numerictext.cpp> +#include <presentation/gui/utility/slider.cpp> +#include <presentation/gui/utility/specialfx.cpp> +#include <presentation/gui/utility/teletypetext.cpp> +#include <presentation/gui/utility/transitions.cpp> +#include <presentation/gui/utility/scrollingtext.cpp> diff --git a/game/code/presentation/gui/utility/colourutility.h b/game/code/presentation/gui/utility/colourutility.h new file mode 100644 index 0000000..af8a24f --- /dev/null +++ b/game/code/presentation/gui/utility/colourutility.h @@ -0,0 +1,63 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: this file contains some operators for colors *, +, -, etc +// +// History: 29/01/2003 + Created -- Ian Gipson +// +//============================================================================= + +#ifndef _COLOURUTILITY_H_ +#define _COLOURUTILITY_H_ + +#include <p3d/p3dtypes.hpp> + +//============================================================================== +// operator+ +//============================================================================== +// Description: addition of two colors +// +// Parameters: a, b, the two colors to add +// +// Return: the added version of the two colors +// +//============================================================================== +inline tColour operator+( const tColour a, const tColour b ) +{ + int rr = a.Red() + b.Red(); + int gg = a.Green() + b.Green(); + int bb = a.Blue() + b.Blue(); + int aa = a.Alpha() + b.Alpha(); + return( tColour( rr, gg, bb, aa ) ); +} + +//============================================================================== +// operator* +//============================================================================== +// Description: multiplication of a color by a constant +// +// Parameters: a, the color +// f, the float +// +// Return: the scaled version of the colour +// +//============================================================================== +inline tColour operator*( const tColour a, const float f ) +{ + int rr = static_cast< int >( a.Red() * f ); + int gg = static_cast< int >( a.Green() * f ); + int bb = static_cast< int >( a.Blue() * f ); + int aa = static_cast< int >( a.Alpha() * f ); + return tColour( rr, gg, bb, aa ); +} + +inline tColour operator*( const float f, const tColour a ) +{ + return operator*( a, f); +} + +#endif + + diff --git a/game/code/presentation/gui/utility/hudmap.cpp b/game/code/presentation/gui/utility/hudmap.cpp new file mode 100644 index 0000000..dcd4a07 --- /dev/null +++ b/game/code/presentation/gui/utility/hudmap.cpp @@ -0,0 +1,1914 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CHudMap +// +// Description: Implementation of the CHudMap class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/01 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/utility/hudmap.h> +#include <presentation/gui/utility/hudmapcam.h> +#include <presentation/gui/utility/specialfx.h> +#include <presentation/gui/guiscreen.h> + +#include <ai/vehicle/vehicleai.h> +#include <interiors/interiormanager.h> +#include <memory/srrmemory.h> +#include <meta/zoneeventlocator.h> +#include <mission/gameplaymanager.h> +#include <render/intersectmanager/intersectmanager.h> +#include <roads/geometry.h> +#include <roads/road.h> +#include <roads/intersection.h> +#include <roads/roadmanager.h> +#include <worldsim/avatarmanager.h> +#include <worldsim/avatar.h> +#include <worldsim/hitnrunmanager.h> +#include <worldsim/redbrick/vehicle.h> + +#include <p3d/utility.hpp> + +#include <raddebug.hpp> // Foundation + +#include <page.h> +#include <group.h> +#include <pure3dobject.h> +#include <sprite.h> +#include <polygon.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +#define SHOW_HUD_MAP +#define CIRCULAR_HUD_MAP + +#ifdef CIRCULAR_HUD_MAP + #define SMARTER_ICON_LOCATIONS // only works for circular hud map +#endif + +// This is for smooth camera height transitions, to prevent any sudden +// camera cuts. +// +#define SMOOTH_CAMERA_HEIGHT_TRANSITIONS + +const int NUM_AMORTIZED_UPDATE_FRAMES = 5; // for DetermineOnRoadLocation() + +#ifdef DEBUGWATCH + #include <raddebugwatch.hpp> + + static const char* WATCHER_NAMESPACE = "GUI System - HUD Map"; + + float MIN_CAMERA_HEIGHT = 50.0f; + float MAX_CAMERA_HEIGHT = 150.0f; + + float MAX_CAMERA_HEIGHT_TRANSITION = 10.0f; + + float CHASE_FLASH_DISTANCE_THRESHOLD = 0.5f; + float CHASE_FADE_DISTANCE_THRESHOLD = 0.75f; + float RADAR_VISIBLE_RADIUS = 150.0f; // in metres +#else + const float MIN_CAMERA_HEIGHT = 50.0f; + const float MAX_CAMERA_HEIGHT = 150.0f; + + const float MAX_CAMERA_HEIGHT_TRANSITION = 10.0f; + + const float CHASE_FLASH_DISTANCE_THRESHOLD = 0.5f; + const float CHASE_FADE_DISTANCE_THRESHOLD = 0.75f; + const float RADAR_VISIBLE_RADIUS = 150.0f; // in metres +#endif + +const float DEFAULT_CAMERA_HEIGHT = 150.0f; // in metres + +const float MAX_RADAR_CONE_ALPHA = 0.35f; + +enum eVisibilityMode +{ + VISIBLE_IN_SUNDAY_DRIVE = 1, + VISIBLE_IN_MISSION = 2, + + NUM_VISIBILITY_MODES +}; + +const tColour HIT_N_RUN_COLOUR_RED( 255, 0, 0 ); +const tColour HIT_N_RUN_COLOUR_BLUE( 0, 0, 255 ); + +HudMapIcon CHudMap::s_registeredIcons[ MAX_NUM_REGISTERED_ICONS ]; +int CHudMap::s_numRegisteredIcons = 0; +int CHudMap::s_fpIconID = -1; + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +void +HudMapIcon::ApplyAICarIconColour() +{ + rAssert( m_iconImage != NULL ); + + switch( m_type ) + { + case ICON_AI_HIT_N_RUN: + { + m_iconImage->SetColour( HIT_N_RUN_COLOUR_RED ); + + break; + } + case ICON_AI_CHASE: + { + m_iconImage->SetColour( tColour( 255, 128, 0 ) ); + + break; + } + case ICON_AI_RACE: + { + m_iconImage->SetColour( tColour( 255, 255, 0 ) ); + + break; + } + case ICON_AI_EVADE: + { + m_iconImage->SetColour( tColour( 255, 255, 0 ) ); + + break; + } + case ICON_AI_TARGET: + { + m_iconImage->SetColour( tColour( 255, 0, 0 ) ); + + break; + } + default: + { + rAssertMsg( false, "Invalid AI car icon type!" ); + + break; + } + } +} + +//=========================================================================== +// CHudMap::CHudMap +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CHudMap::CHudMap( Scrooby::Page* pPage, int playerID, const char* p3dFile ) +: m_playerID( playerID ), + m_p3dMap( NULL ), + m_p3dHole( NULL ), + m_originalPosX( 0 ), + m_originalPosY( 0 ), + m_originalWidth( 0 ), + m_originalHeight( 0 ), + m_isVisible( false ), + m_radar( NULL ), + m_radarCone( NULL ), + m_iconsGroup( NULL ), + m_hudMapCam( NULL ), + m_currentCameraHeight( DEFAULT_CAMERA_HEIGHT ), + m_fixedCameraHeight( 0.0f ), + m_currentAICarDistance( 0.0f ), + m_maxAICarDistance( 0.0f ), + m_elapsedTime( 0 ), + m_lastRoadSeg( NULL ), + m_lastOnRoadLocation( 0.0f, 0.0f, 0.0f ), + m_frameCount( -1 ) +{ +MEMTRACK_PUSH_GROUP( "CHudMap" ); + memset( m_icons, 0, sizeof( m_icons ) ); + + m_hudMapCam = new HudMapCam( m_playerID ); + rAssert( m_hudMapCam ); + m_hudMapCam->AddRef(); + + m_currentCameraHeight = this->CalculateCameraHeight( RADAR_VISIBLE_RADIUS ); + + char name[ 16 ]; + rAssert( pPage != NULL ); + + // get 3D HUD map + // + sprintf( name, "Map%d", playerID ); + m_p3dMap = pPage->GetPure3dObject( name ); + rAssert( m_p3dMap != NULL ); + m_p3dMap->SetCamera( m_hudMapCam->GetCamera() ); + + // store original hud map position and size + // + m_p3dMap->GetOriginPosition( m_originalPosX, m_originalPosY ); + m_p3dMap->GetBoundingBoxSize( m_originalWidth, m_originalHeight ); + +#ifdef SHOW_HUD_MAP + if( p3dFile != NULL ) + { + // set pure3d file for hud map + // + m_p3dMap->Add3dModel( p3dFile ); + } + + // get 3D HUD hole + // + sprintf( name, "Hole%d", playerID ); + m_p3dHole = pPage->GetPure3dObject( name ); + rAssert( m_p3dHole != NULL ); + m_p3dHole->SetCamera( m_hudMapCam->GetCamera() ); + m_p3dHole->SetColourWrite( false ); + + if( CGuiScreen::IsWideScreenDisplay() ) + { + m_p3dMap->SetWideScreenCorrectionEnabled( true ); + m_p3dHole->SetWideScreenCorrectionEnabled( true ); + } +#else + m_p3dMap->SetVisible( false ); +#endif + +/* + sprintf( name, "RadarLight%d", playerID ); + m_radarLight = pPage->GetSprite( name ); + rAssert( m_radarLight != NULL ); + + // hide radar light temporarily + // + m_radarLight->SetVisible( false ); +*/ + + // get radar & radar cone + // + sprintf( name, "Radar%d", playerID ); + m_radar = pPage->GetGroup( name ); + rAssert( m_radar != NULL ); + + sprintf( name, "RadarCone%d", playerID ); + m_radarCone = pPage->GetGroup( name ); + rAssert( m_radarCone != NULL ); + + Scrooby::Polygon* radarConePolygon = m_radarCone->GetPolygon( name ); + rAssert( radarConePolygon != NULL ); + radarConePolygon->SetAlpha( MAX_RADAR_CONE_ALPHA ); + + // get icons group + // + sprintf( name, "Icons%d", playerID ); + m_iconsGroup = pPage->GetGroup( name ); + rAssert( m_iconsGroup != NULL ); + +#ifdef DEBUGWATCH + ::radDbgWatchAddFloat( &MIN_CAMERA_HEIGHT, + "Mininum Camera Height", + WATCHER_NAMESPACE, + NULL, NULL, 30.0f, 90.0f ); + + ::radDbgWatchAddFloat( &MAX_CAMERA_HEIGHT, + "Maximum Camera Height", + WATCHER_NAMESPACE, + NULL, NULL, 100.0f, 1000.0f ); + + ::radDbgWatchAddFloat( &MAX_CAMERA_HEIGHT_TRANSITION, + "Maximum Camera Height Change", + WATCHER_NAMESPACE, + NULL, NULL, 1.0f, 50.0f ); + + ::radDbgWatchAddFloat( &RADAR_VISIBLE_RADIUS, + "Radar Visible Radius", + WATCHER_NAMESPACE, + NULL, NULL, 0.0f, 1000.0f ); + + ::radDbgWatchAddFloat( &CHASE_FLASH_DISTANCE_THRESHOLD, + "Chase Flash Distance (%)", + WATCHER_NAMESPACE ); + + ::radDbgWatchAddFloat( &CHASE_FADE_DISTANCE_THRESHOLD, + "Chase Fade Distance (%)", + WATCHER_NAMESPACE ); +#endif +MEMTRACK_POP_GROUP("CHudMap"); +} + +//=========================================================================== +// CHudMap::~CHudMap +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CHudMap::~CHudMap() +{ +#ifdef DEBUGWATCH + ::radDbgWatchDelete( &MIN_CAMERA_HEIGHT ); + ::radDbgWatchDelete( &MAX_CAMERA_HEIGHT ); + ::radDbgWatchDelete( &MAX_CAMERA_HEIGHT_TRANSITION ); + ::radDbgWatchDelete( &RADAR_VISIBLE_RADIUS ); + ::radDbgWatchDelete( &CHASE_FLASH_DISTANCE_THRESHOLD ); + ::radDbgWatchDelete( &CHASE_FADE_DISTANCE_THRESHOLD ); +#endif + + if( m_hudMapCam != NULL ) + { + m_hudMapCam->Release(); + m_hudMapCam = NULL; + } +} + +//=========================================================================== +// CHudMap::SetCameraTarget +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CHudMap::SetCameraTarget( ISuperCamTarget* target ) +{ + rAssert( m_hudMapCam ); + m_hudMapCam->SetTarget( target ); +} + +void +CHudMap::EnableFixedCameraHeight( bool enable, float visibleRadius ) +{ +/* + if( !enable ) + { + rWarningMsg( false, "Can't disable fixed camera height in new radar implementation!" ); + + // ignore request to disable fixed camera height + // + return; + } +*/ + m_fixedCameraHeight = enable ? + visibleRadius / rmt::Tan( m_hudMapCam->GetFOV() / 2.0f ) : + 0.0f; +} + +//=========================================================================== +// CHudMap::Update +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CHudMap::Update( unsigned int elapsedTime ) +{ + if( GetInteriorManager()->IsInside() ) + { + this->SetVisible( false ); + } + + if( !m_isVisible ) + { + // no need to update if not visible + // + return; + } + +/* + // update radar light (just rotate about radar center point) + // + static float RADAR_ROTATION_PERIOD = 2000.0f; // in msec + float rotation = (elapsedTime / RADAR_ROTATION_PERIOD) * 360.0f; + rAssert( m_radarLight != NULL ); + m_radarLight->RotateAboutCenter( rotation ); +*/ + + // get current hud map position and size + // + int mapX = 0; + int mapY = 0; + int mapWidth = 0; + int mapHeight = 0; + + rAssert( m_p3dMap != NULL ); + m_p3dMap->GetOriginPosition( mapX, mapY ); + m_p3dMap->GetBoundingBoxSize( mapWidth, mapHeight ); + + float newCameraHeight = DEFAULT_CAMERA_HEIGHT; + if( m_fixedCameraHeight != 0.0f ) // fixed camera height enabled + { + newCameraHeight = m_fixedCameraHeight; + } + else + { + if( s_fpIconID != -1 ) + { + HudMapIcon* focalPointIcon = &(s_registeredIcons[ s_fpIconID ]); + rAssert( focalPointIcon->m_iconImage ); + + if( focalPointIcon->m_dynamicLocator != NULL ) + { + focalPointIcon->m_dynamicLocator->GetPosition( &(focalPointIcon->m_location) ); + } + + newCameraHeight = this->CalculateCameraHeight( s_registeredIcons[ 0 ].m_location, + focalPointIcon->m_location ); + } + } + +#ifdef SMOOTH_CAMERA_HEIGHT_TRANSITIONS + // for smoother camera height transitions + // + float cameraHeightChange = newCameraHeight - m_currentCameraHeight; + if( rmt::Abs( cameraHeightChange ) > MAX_CAMERA_HEIGHT_TRANSITION ) + { + m_currentCameraHeight += rmt::Sign( cameraHeightChange ) * MAX_CAMERA_HEIGHT_TRANSITION; +// rTunePrintf( "Current camera height = %f m\n", m_currentCameraHeight ); + } + else +#endif + { + m_currentCameraHeight = newCameraHeight; + } + + // update hud map camera + // + rAssert( m_hudMapCam != NULL ); + m_hudMapCam->SetHeight( m_currentCameraHeight ); + m_hudMapCam->SetAspect( (float)mapWidth / (float)mapHeight ); + m_hudMapCam->Update( elapsedTime ); + + rmt::Vector hudMapCenter; + m_hudMapCam->GetPosition( &hudMapCenter ); + +#ifdef CIRCULAR_HUD_MAP + // update hud hole + // + if( m_p3dHole != NULL ) + { + static float awayFromCam = 4.5f; + m_p3dHole->SetDrawableTranslation( hudMapCenter.x, + hudMapCenter.y - awayFromCam, + hudMapCenter.z ); + } +#endif + + // update registered icons + // + int iconPosX = 0; + int iconPosY = 0; + int iconWidth = 0; + int iconHeight = 0; + + const unsigned int PULSE_PERIOD = 500; +// bool iconBlinked = false; + +// rWarningMsg( s_fpIconID != -1, "No active focal point icon on hud map!" ); + + for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ ) + { + if( s_registeredIcons[ i ].m_iconImage != NULL ) + { + // check if visible in current gameplay mode + // + if( GetGameplayManager()->IsSundayDrive() ) + { + if( (s_registeredIcons[ i ].m_visibilityMask & VISIBLE_IN_SUNDAY_DRIVE) == 0 ) + { + s_registeredIcons[ i ].m_iconImage->SetVisible( false ); + continue; + } + } + else + { + if( (s_registeredIcons[ i ].m_visibilityMask & VISIBLE_IN_MISSION) == 0 ) + { + s_registeredIcons[ i ].m_iconImage->SetVisible( false ); + continue; + } + } + + // hide icons that are not visible when player is in car + // + if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PHONE_BOOTH || + s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PLAYER_CAR ) + { + Avatar* player = GetAvatarManager()->GetAvatarForPlayer( m_playerID ); + rAssert( player != NULL ); + if( player->IsInCar() ) + { + s_registeredIcons[ i ].m_iconImage->SetVisible( false ); + continue; + } + } + +// s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f ); + + // center icon in hud map first + // + s_registeredIcons[ i ].m_iconImage->GetBoundingBoxSize( iconWidth, iconHeight ); + iconPosX = (mapX + mapWidth / 2) - (iconWidth / 2); + iconPosY = (mapY + mapHeight / 2) - (iconHeight / 2); + s_registeredIcons[ i ].m_iconImage->SetPosition( iconPosX, iconPosY ); + + s_registeredIcons[ i ].m_iconImage->ResetTransformation(); + + // update current location for dynamic icons + if( s_registeredIcons[ i ].m_dynamicLocator != NULL ) + { + s_registeredIcons[ i ].m_dynamicLocator->GetPosition( &s_registeredIcons[ i ].m_location ); + + // place icon object at sea level + s_registeredIcons[ i ].m_location.y = 0; + + if( s_registeredIcons[ i ].IsAICarIcon() || + s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PLAYER || + s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PLAYER_CAR ) + { + rmt::Vector heading( 0, 0, 0 ); + s_registeredIcons[ i ].m_dynamicLocator->GetHeading( &heading ); + + this->UpdateIconHeading( s_registeredIcons[ i ].m_iconImage, &heading ); + } + } + + rmt::Vector iconLocInWorld = s_registeredIcons[ i ].m_location; + +#ifdef SMARTER_ICON_LOCATIONS + if( static_cast< int >( i ) == s_fpIconID ) + { + // TC: [TODO] need to determine this from the maximum camera height and the + // clipping boundary value + // + static float visibleRadius = 120.0f; + + this->DetermineOnRoadLocation( hudMapCenter, + iconLocInWorld, + visibleRadius ); + } +#endif + + rmt::Vector iconLoc( 0, 0, 0 ); + rAssert( m_p3dMap->GetCamera() ); + m_p3dMap->GetCamera()->WorldToView( iconLocInWorld, &iconLoc ); + iconLoc.z = 0.0f; + + static float CLIPPING_BOUNDARY = 0.40f; + float iconScale = 1.0f; + +#ifdef CIRCULAR_HUD_MAP + // apply view clipping (for circular view) + // + float iconLength = iconLoc.Magnitude(); + if( iconLength > CLIPPING_BOUNDARY ) + { + iconScale = CLIPPING_BOUNDARY / iconLength; + iconLoc.Scale( iconScale ); + } +#else + // apply view clipping (for rectangular view) + // + + // x-clipping + float xScale = 1.0f; + if( iconLoc.x > CLIPPING_BOUNDARY ) + { + xScale = CLIPPING_BOUNDARY / iconLoc.x; + iconLoc.Scale( xScale, xScale, 1 ); + } + else if( iconLoc.x < -CLIPPING_BOUNDARY ) + { + xScale = -CLIPPING_BOUNDARY / iconLoc.x; + iconLoc.Scale( xScale, xScale, 1 ); + } + + // y-clipping + float yScale = 1.0f; + if( iconLoc.y > CLIPPING_BOUNDARY ) + { + yScale = CLIPPING_BOUNDARY / iconLoc.y; + iconLoc.Scale( yScale, yScale, 1 ); + } + else if( iconLoc.y < -CLIPPING_BOUNDARY ) + { + yScale = -CLIPPING_BOUNDARY / iconLoc.y; + iconLoc.Scale( yScale, yScale, 1 ); + } + + iconScale = xScale * yScale; +#endif + + bool isIconClipped = (iconScale < 1.0f); + + rAssert( m_radarCone != NULL ); + m_radarCone->SetVisible( s_fpIconID != -1 ); + + if( static_cast< int >( i ) == s_fpIconID ) // for focal point icon ... + { + // update radar cone direction + // + m_radarCone->ResetTransformation(); + m_radarCone->RotateAboutCenter( rmt::RadianToDeg( this->CalculatRadarConeAngle( iconLoc ) ) ); + + if( !isIconClipped || s_registeredIcons[ i ].IsAICarIcon() ) + { + m_radarCone->SetAlpha( iconScale ); + } + else + { + const float MINIMUM_ICON_SCALE = 0.75f; + float alpha = (iconScale - MINIMUM_ICON_SCALE) / (1.0f - MINIMUM_ICON_SCALE); + m_radarCone->SetAlpha( alpha > 0.0f ? alpha : 0.0f ); + } +/* + // apply alpha if focal point icon is clipped on boundary + // + if( iconScale < 1.0f ) + { + if( iconScale < 0.3f ) + { + s_registeredIcons[ i ].m_iconImage->SetAlpha( 0.3f ); + } + else + { + s_registeredIcons[ i ].m_iconImage->SetAlpha( iconScale ); + } + } + else + { + s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f ); + } +*/ + +#ifdef SMARTER_ICON_LOCATIONS + s_registeredIcons[ i ].m_iconImage->SetVisible( true ); +#else + if( !s_registeredIcons[ i ].IsAICarIcon() ) + { + // hide non-AI car icons if clipped on boundary + // + s_registeredIcons[ i ].m_iconImage->SetVisible( !isIconClipped ); + } +#endif + + // special cases + // + if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_MISSION ) + { + static float SCALE_AMPLITUDE = 0.25f; + + float scale = GuiSFX::Pulse( (float)m_elapsedTime, + (float)PULSE_PERIOD, + 1.0f + SCALE_AMPLITUDE, + SCALE_AMPLITUDE ); + +/* + float scale = 1.0f + (float)m_elapsedTime / PULSE_PERIOD * SCALE_AMPLITUDE; + float alpha = 1.0f - (float)m_elapsedTime / PULSE_PERIOD * ALPHA_AMPLITUDE; + + s_registeredIcons[ i ].m_iconImage->SetAlpha( alpha ); +*/ + s_registeredIcons[ i ].m_iconImage->ScaleAboutCenter( scale ); + } +/* + else if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_AI_CAR ) + { + // if focal point is AI car icon, fade out when near + // distance limit + // + if( m_maxAICarDistance > 0.0f ) + { + float distanceRatio = m_currentAICarDistance / m_maxAICarDistance; + rAssert( distanceRatio <= 1.0f ); + + if( distanceRatio > CHASE_FLASH_DISTANCE_THRESHOLD ) + { + // blink icon + // + iconBlinked = GuiSFX::Blink( s_registeredIcons[ i ].m_iconImage, + (float)m_elapsedTime, + (float)BLINKING_PERIOD ); + + if( distanceRatio > CHASE_FADE_DISTANCE_THRESHOLD ) + { + float iconAlpha = (1.0f - distanceRatio) / + (1.0f - CHASE_FADE_DISTANCE_THRESHOLD); + + s_registeredIcons[ i ].m_iconImage->SetAlpha( iconAlpha ); + } + else + { + s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f ); + } + } + else + { + s_registeredIcons[ i ].m_iconImage->SetVisible( true ); + } + } + } +*/ + } + else // for non-focal point icons ... + { + if( !s_registeredIcons[ i ].IsAICarIcon() ) + { + // hide non-AI car icons if clipped on boundary + // + s_registeredIcons[ i ].m_iconImage->SetVisible( !isIconClipped ); + } +/* + // for phone booth icons + // + if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PHONE_BOOTH ) + { + // only show if within visible radius + // + rmt::Vector playerToPhone; + playerToPhone.Sub( s_registeredIcons[ i ].m_location, + s_registeredIcons[ 0 ].m_location ); + + float distanceRatio = playerToPhone.Magnitude() / PHONE_BOOTH_VISIBLE_RADIUS; + bool isWithinRadius = (distanceRatio < 1.0f); + + // fade out nicely to prevent popping + // + const float FADE_OUT_THRESHOLD = 0.9f; + if( !isIconClipped && isWithinRadius ) + { + if( distanceRatio > FADE_OUT_THRESHOLD ) + { + float iconAlpha = (1.0f - distanceRatio) / (1.0f - FADE_OUT_THRESHOLD); + s_registeredIcons[ i ].m_iconImage->SetAlpha( iconAlpha ); + } + else + { + s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f ); + } + } + else + { + s_registeredIcons[ i ].m_iconImage->SetAlpha( 0.0f ); + } + } +*/ + } + + if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_AI_HIT_N_RUN ) + { + if( GetHitnRunManager()->IsHitnRunActive() ) + { + s_registeredIcons[ i ].m_iconImage->SetVisible( true ); + + // modulate icon colour + // + tColour iconColour; + GuiSFX::ModulateColour( &iconColour, + (float)m_elapsedTime, + (float)PULSE_PERIOD, + HIT_N_RUN_COLOUR_RED, + HIT_N_RUN_COLOUR_BLUE ); + + s_registeredIcons[ i ].m_iconImage->SetColour( iconColour ); + } + else + { + // hide icon if H&R is not active + // + s_registeredIcons[ i ].m_iconImage->SetVisible( false ); + } + } + + // translate the icon (in screen space wrt. hud map center) + // + int iconX = static_cast<int>( iconLoc.x * mapWidth ); + int iconY = static_cast<int>( iconLoc.y * mapHeight ); + + s_registeredIcons[ i ].m_iconImage->Translate( iconX, iconY ); + } + } +/* + if( iconBlinked ) + { + m_elapsedTime %= PULSE_PERIOD; + } +*/ + m_elapsedTime = (m_elapsedTime + elapsedTime) % PULSE_PERIOD; +} + +//=========================================================================== +// CHudMap::AddIconToInventory +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CHudMap::AddIconToInventory( HudMapIcon::eIconType type, Scrooby::Sprite* image ) +{ + if( image == NULL ) + { + return; + } + + unsigned int i = 0; + + for( i = 0; i < MAX_NUM_ICONS_PER_TYPE; i++ ) + { + // find first empty slot in inventory to add icon + // + if( m_icons[ type ][ i ] == NULL ) + { + m_icons[ type ][ i ] = image; + + // hide icon image + // + image->SetVisible( false ); + + break; + } + } + + rAssertMsg( i < MAX_NUM_ICONS_PER_TYPE, + "ERROR: *** Exceeded maximum number of icons per type!\n" ); +} + +//=========================================================================== +// CHudMap::RemoveIconFromInventory +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +Scrooby::Sprite* +CHudMap::RemoveIconFromInventory( HudMapIcon::eIconType type ) +{ + Scrooby::Sprite* iconImage = NULL; + + // find an available icon of specified type in inventory + // + for( unsigned int i = 0; i < MAX_NUM_ICONS_PER_TYPE; i++ ) + { + if( m_icons[ type ][ i ] != NULL ) + { + iconImage = m_icons[ type ][ i ]; + iconImage->SetVisible( true ); + + // free up slot in inventory + // + m_icons[ type ][ i ] = NULL; + + break; + } + } + + return iconImage; +} + +//=========================================================================== +// CHudMap::RegisterIcon +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +int +CHudMap::RegisterIcon( HudMapIcon::eIconType type, + rmt::Vector location, + IHudMapIconLocator* hudMapIconLocator, + bool newFocalPoint ) +{ + rAssert( s_numRegisteredIcons < static_cast<int>( MAX_NUM_REGISTERED_ICONS ) ); + + int iconID = -1; + + Scrooby::Sprite* iconImage = this->RemoveIconFromInventory( type ); + if( iconImage == NULL ) + { + rAssertMsg( false, "WARNING: *** No more available icons of this type! Please tell Tony." ); + + return -1; + } + + // convert locations in interiors to world-space location of the interior + // + tName interiorName = GetInteriorManager()->ClassifyPoint( location ); + if( interiorName.GetUID() != static_cast< tUID >( 0 ) ) + { + ZoneEventLocator* locator = p3d::find<ZoneEventLocator>( interiorName.GetUID() ); + locator->GetPosition( &location ); + + if( hudMapIconLocator != NULL ) + { + hudMapIconLocator = locator; + } + } + +#ifdef RAD_DEBUG + // check if there's already a static icon of the same type + // registered at exactly the same location + // + for( unsigned int j = 0; j < MAX_NUM_REGISTERED_ICONS; j++ ) + { + if( s_registeredIcons[ j ].m_iconImage != NULL && + s_registeredIcons[ j ].m_type == type ) + { + rAssertMsg( s_registeredIcons[ j ].m_dynamicLocator != NULL || + s_registeredIcons[ j ].m_location != location, + "WARNING: *** Another icon of this type has already been registered at this location. Is this by design??" ); + } + } +#endif // RAD_DEBUG + + for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ ) + { + if( i == 0 && type != HudMapIcon::ICON_PLAYER ) + { + // icon ID = 0 is reserved for player icon + continue; + } + + // find first empty slot to register icon + if( s_registeredIcons[ i ].m_iconImage == NULL ) + { + iconID = i; + s_numRegisteredIcons++; + + // place icon object at sea level + location.y = 0; + + s_registeredIcons[ iconID ].m_iconImage = iconImage; + s_registeredIcons[ iconID ].m_type = type; + s_registeredIcons[ iconID ].m_location = location; + s_registeredIcons[ iconID ].m_dynamicLocator = hudMapIconLocator; + + // set visible in sunday drive mode for these icon types + // + if( type == HudMapIcon::ICON_PLAYER || + type == HudMapIcon::ICON_PLAYER_CAR || + type == HudMapIcon::ICON_MISSION || + type == HudMapIcon::ICON_BONUS_MISSION || + type == HudMapIcon::ICON_STREET_RACE || + type == HudMapIcon::ICON_WAGER_RACE || + type == HudMapIcon::ICON_PURCHASE_CENTRE || + type == HudMapIcon::ICON_PHONE_BOOTH || + type == HudMapIcon::ICON_AI_HIT_N_RUN ) + { + s_registeredIcons[ i ].m_visibilityMask |= VISIBLE_IN_SUNDAY_DRIVE; + } + + // set visible in mission mode for these icon types + // + if( type == HudMapIcon::ICON_PLAYER || + type == HudMapIcon::ICON_PLAYER_CAR || + type == HudMapIcon::ICON_FLAG_CHECKERED || + type == HudMapIcon::ICON_FLAG_WAYPOINT || + type == HudMapIcon::ICON_COLLECTIBLE || + type == HudMapIcon::ICON_MISSION || + s_registeredIcons[ i ].IsAICarIcon() ) + { + s_registeredIcons[ i ].m_visibilityMask |= VISIBLE_IN_MISSION; + } + + // colour code AI car icons + // + if( s_registeredIcons[ i ].IsAICarIcon() ) + { + s_registeredIcons[ i ].ApplyAICarIconColour(); + } + + break; + } + } + + rAssertMsg( iconID != -1, "ERROR: *** There should have been an empty slot!\n" ); + + if( newFocalPoint ) + { + // set as new focal point icon + // + s_fpIconID = iconID; + + // whenever the target changes, we want to recompute its closest road segment + m_lastRoadSeg = NULL; + + m_frameCount = -1; // reset frame count + } + + + return iconID; +} + +//=========================================================================== +// CHudMap::UnregisterIcon +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CHudMap::UnregisterIcon( int iconID ) +{ + if( iconID != -1 ) + { + rAssert( iconID < static_cast<int>( MAX_NUM_REGISTERED_ICONS ) ); + + if( s_registeredIcons[ iconID ].m_iconImage != NULL ) + { + // return icon to inventory + // + this->AddIconToInventory( s_registeredIcons[ iconID ].m_type, + s_registeredIcons[ iconID ].m_iconImage ); + + s_registeredIcons[ iconID ].m_iconImage = NULL; + s_registeredIcons[ iconID ].m_visibilityMask = 0; + s_numRegisteredIcons--; + + if( s_fpIconID == iconID ) + { + s_fpIconID = -1; + } + } + } + else + { + rAssertMsg( false, "This should only happen if you didn't get a valid icon ID upon registration!" ); + } +} + +//============================================================================= +// CHudMap::ChangeIconType +//============================================================================= +// Description: Comment +// +// Parameters: ( HudMapIcon::eIconType type, int iconID ) +// +// Return: void +// +//============================================================================= +int +CHudMap::ChangeIconType( int iconID, HudMapIcon::eIconType type ) +{ + int newIconID = -1; + + if( iconID != -1 ) + { + bool isFocalPointIcon = (iconID == s_fpIconID); + + // save a copy of old icon + // + HudMapIcon* oldIcon = &s_registeredIcons[ iconID ]; + + // unregister it first + // + this->UnregisterIcon( iconID ); + + // re-registered icon of new type + // + newIconID = this->RegisterIcon( type, oldIcon->m_location, oldIcon->m_dynamicLocator, isFocalPointIcon ); + } + + return newIconID; +} + +//=========================================================================== +// CHudMap::SetFocalPointIcon +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CHudMap::SetFocalPointIcon( int iconID ) +{ + if( iconID != -1 ) + { + rAssert( iconID < static_cast< int >( MAX_NUM_REGISTERED_ICONS ) ); + s_fpIconID = iconID; + + // whenever the target changes, we want to recompute its closest road segment + m_lastRoadSeg = NULL; + + m_frameCount = -1; // reset frame count + } +} + +//=========================================================================== +// CHudMap::FindIcon +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +HudMapIcon* +CHudMap::FindIcon( HudMapIcon::eIconType type ) const +{ + const HudMapIcon* icon = NULL; + + for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ ) + { + if( s_registeredIcons[ i ].m_iconImage != NULL && + s_registeredIcons[ i ].m_type == type ) + { + // found it! + // + icon = &(s_registeredIcons[ i ]); + + break; + } + } + + return const_cast<HudMapIcon*>( icon ); +} + +//=========================================================================== +// CHudMap::Translate +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CHudMap::Translate( int x, int y ) +{ + rAssert( m_p3dMap ); + + m_originalPosX += x; + m_originalPosY += y; + m_p3dMap->SetPosition( m_originalPosX, m_originalPosY ); + if( m_p3dHole != NULL ) + { + m_p3dHole->SetPosition( m_originalPosX, m_originalPosY ); + } + + this->Update( 0 ); +} + +//=========================================================================== +// CHudMap::Reset +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CHudMap::Reset() +{ + rAssert( m_p3dMap != NULL ); + + // restore hud map position and size + // + m_p3dMap->SetPosition( m_originalPosX, m_originalPosY ); + m_p3dMap->SetBoundingBoxSize( m_originalWidth, m_originalHeight ); + + if( m_p3dHole != NULL ) + { + m_p3dHole->SetPosition( m_originalPosX, m_originalPosY ); + m_p3dHole->SetBoundingBoxSize( m_originalWidth, m_originalHeight ); + } + + // restore hud map camera + // + m_p3dMap->SetCamera( m_hudMapCam->GetCamera() ); + + m_elapsedTime = 0; + + this->Update( 0 ); +} + +//=========================================================================== +// CHudMap::SetVisible +//=========================================================================== +// Description: Toggle visibility of 3D map. +// +// Constraints: None. +// +// Parameters: visibility +// +// Return: +// +//=========================================================================== +void CHudMap::SetVisible( bool isVisible ) +{ + m_isVisible = isVisible; + + rAssert( m_p3dMap != NULL ); + m_p3dMap->SetVisible( isVisible ); + + rAssert( m_radar != NULL ); + m_radar->SetVisible( isVisible ); + + rAssert( m_iconsGroup != NULL ); + m_iconsGroup->SetVisible( isVisible ); +} + +void +CHudMap::RestoreAllRegisteredIcons() +{ + if( s_numRegisteredIcons > 0 ) + { + int numIconsRestored = 0; + + for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ ) + { + if( s_registeredIcons[ i ].m_iconImage != NULL ) + { + s_registeredIcons[ i ].m_iconImage = this->RemoveIconFromInventory( s_registeredIcons[ i ].m_type ); + rAssert( s_registeredIcons[ i ].m_iconImage != NULL ); + + if( s_registeredIcons[ i ].IsAICarIcon() ) + { + s_registeredIcons[ i ].ApplyAICarIconColour(); + } + + numIconsRestored++; + } + } + + rAssertMsg( numIconsRestored == s_numRegisteredIcons, "Not all registered icons were restored!" ); + } +} + +void +CHudMap::ClearAllRegisteredIcons() +{ + memset( s_registeredIcons, 0, sizeof( s_registeredIcons ) ); + s_numRegisteredIcons = 0; + s_fpIconID = -1; +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +//=========================================================================== +// CHudMap::CalculateDistanceBetweenPoints +//=========================================================================== +// Description: Calculates the scalar distance between 2 points in 3D-space. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +float +CHudMap::CalculateDistanceBetweenPoints( rmt::Vector& a, rmt::Vector& b ) +{ + rmt::Vector displacement( 0.0f, 0.0f, 0.0f ); + displacement.Sub( a, b ); + + return displacement.Magnitude(); +} + +//=========================================================================== +// CHudMap::UpdateIconHeading +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void +CHudMap::UpdateIconHeading( Scrooby::Sprite* iconImage, rmt::Vector* iconHeading ) +{ + rmt::Vector objectHeading( iconHeading->x, 0, iconHeading->z ); + + rmt::Vector camHeading; + tPointCamera* camera = (tPointCamera*)m_p3dMap->GetCamera(); + rAssert( camera ); + camera->GetVUp( &camHeading ); + camHeading.y = 0.0f; + + if( camHeading.MagnitudeSqr() > 0.0f && objectHeading.MagnitudeSqr() > 0.0f ) + { + float ratio = camHeading.Dot( objectHeading ) / + (camHeading.Magnitude() * objectHeading.Magnitude()); + + float rotation = 0.0f; + + if( ratio > 1.0f ) + { + rotation = 0.0f; + } + else if( ratio < -1.0f ) + { + rotation = rmt::PI; + } + else + { + rotation = rmt::ACos( ratio ); + } + + rAssert( !rmt::IsNan( rotation ) ); + + rmt::Vector normal = camHeading; + normal.CrossProduct( objectHeading ); + if( normal.y < 0 ) + { + rotation = -rotation; + } + + rAssert( iconImage ); + iconImage->RotateAboutCenter( rmt::RadianToDeg( rotation ) ); + } +} + +//=========================================================================== +// CHudMap::CalculateCameraHeight +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +float +CHudMap::CalculateCameraHeight( rmt::Vector& player, rmt::Vector& mission ) const +{ + // fix locations at sea level + // + player.y = 0; + mission.y = 0; + + float distance = CalculateDistanceBetweenPoints( player, mission ); + + // calculate camera height based on distance + // + float cameraHeight = this->CalculateCameraHeight( distance * 1.5f ); + + if( cameraHeight < MIN_CAMERA_HEIGHT ) + { + cameraHeight = MIN_CAMERA_HEIGHT; + } + else if( cameraHeight > MAX_CAMERA_HEIGHT ) + { + cameraHeight = MAX_CAMERA_HEIGHT; + } + + return cameraHeight; +} + +//=========================================================================== +// CHudMap::CalculateCameraHeight +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +float +CHudMap::CalculateCameraHeight( float visibleRadius ) const +{ + float cameraHeight = visibleRadius; + if( rmt::Abs( m_hudMapCam->GetFOV() - rmt::PI_BY2 ) > 0.001f ) + { + cameraHeight = visibleRadius / rmt::Tan( m_hudMapCam->GetFOV() / 2.0f ); + } + + return cameraHeight; +} + +//=========================================================================== +// CHudMap::CalculatRadarConeAngle +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +float +CHudMap::CalculatRadarConeAngle( rmt::Vector& iconLoc ) const +{ + float radarConeAngle = 0.0f; // zero angle by default + + if( iconLoc.y > 0.0f ) // icon is located in either Quadrant I or II + { + radarConeAngle = rmt::ATan( iconLoc.x / iconLoc.y ); + } + else if( iconLoc.y < 0.0f ) // icon is located in either Quadrant III or IV + { + radarConeAngle = rmt::ATan( iconLoc.x / iconLoc.y ) + rmt::PI; + } + else // icon is located somewhere along the X-axis + { + if( iconLoc.x > 0.0f ) + { + radarConeAngle = rmt::PI_BY2; + } + else if( iconLoc.x < 0.0f ) + { + radarConeAngle = -rmt::PI_BY2; + } + } + + return radarConeAngle; +} + +//=========================================================================== +// CHudMap::DetermineOnRoadLocation +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== + +// We return the target vector (where we want to direct the navigation cone) +void +CHudMap::DetermineOnRoadLocation( rmt::Vector& source, rmt::Vector& target, float visibleRadius ) +{ + // place source and target at sea level + // + source.y = 0; + target.y = 0; + + float distance = CalculateDistanceBetweenPoints( source, target ); + if( distance <= visibleRadius ) + { + // no need to do any calculations if target is within 'visibleRadius' from source + // + return; + } + + // check to see if we should skip this update and return cached information instead + // + m_frameCount = (m_frameCount + 1) % NUM_AMORTIZED_UPDATE_FRAMES; + if( m_frameCount != 0 ) + { + target = m_lastOnRoadLocation; + + return; + } + + // get reference to road manager + // + RoadManager* roadManager = RoadManager::GetInstance(); + rAssert( roadManager != NULL ); + + ////////////// + // find path between source and target + // + bool isPathElementFound = false; + float searchRadius = 200.0f; + float dummy; + + // Find source's closest path element + RoadSegment* sourceSeg = NULL; + float sourceSegT = 0.0f; + RoadManager::PathElement sourceElem; + float sourceRoadT = 0.0f; + + isPathElementFound = VehicleAI::FindClosestPathElement( source, + sourceElem, sourceSeg, sourceSegT, sourceRoadT, false ); // don't want shortcuts on hudmap + + if( !isPathElementFound ) + { + GetIntersectManager()->FindClosestRoad( source, searchRadius, sourceSeg, dummy ); // ignore shortcuts + rAssertMsg( sourceSeg, "Should always find a nearby road seg! Increase search radius!" ); + if( !sourceSeg ) + { + return; + } + + sourceElem.type = RoadManager::ET_NORMALROAD; + sourceElem.elem = sourceSeg->GetRoad(); + sourceSegT = roadManager->DetermineSegmentT( source, sourceSeg ); + sourceRoadT = roadManager->DetermineRoadT( sourceSeg, sourceSegT ); + } + rAssert( sourceElem.elem ); + + + // Find target's closest path element + RoadSegment* targetSeg = NULL; + float targetSegT = 0.0f; + RoadManager::PathElement targetElem; + float targetRoadT = 0.0f; + + isPathElementFound = VehicleAI::FindClosestPathElement( target, + targetElem, targetSeg, targetSegT, targetRoadT, false ); // don't want shortcuts on hudmap + + if( !isPathElementFound ) + { + RoadSegment* closestRoadSeg = NULL; + if( m_lastRoadSeg ) + { + closestRoadSeg = m_lastRoadSeg; + } + else + { + GetIntersectManager()->FindClosestRoad( target, searchRadius, closestRoadSeg, dummy ); + rAssertMsg( closestRoadSeg, "Should always find a nearby road seg! Increase search radius!" ); + if( !closestRoadSeg ) + { + return; + } + m_lastRoadSeg = closestRoadSeg; + } + targetElem.type = RoadManager::ET_NORMALROAD; + targetElem.elem = closestRoadSeg->GetRoad(); + targetSeg = closestRoadSeg; + targetSegT = roadManager->DetermineSegmentT( target, targetSeg ); + targetRoadT = roadManager->DetermineRoadT( targetSeg, targetSegT ); + } + else + { + // need to make this check cuz FindClosestPathElement could return an intersection + if( targetSeg ) + { + m_lastRoadSeg = targetSeg; + } + } + rAssert( targetElem.elem ); + + + HeapMgr()->PushHeap( GMA_TEMP ); + + SwapArray<RoadManager::PathElement> pathElements; + pathElements.Allocate( roadManager->GetMaxPathElements() ); + + RoadManager::PathElement tmpSrcElem = sourceElem; + float roadDistance = roadManager->FindPathElementsBetween( false, + tmpSrcElem, sourceRoadT, source, + targetElem, targetRoadT, target, + pathElements ); + + rAssert( pathElements.mUseSize > 0 ); + + // Temp stuff we use over and over again + RoadManager::PathElement* prevElem = &(pathElements[0]); + bool isRoadBackwards = false; + int numIntersects = 0; + rmt::Vector intPts[2]; + + rmt::Sphere visibleSphere( source, visibleRadius ); // this is the hud map circle + + // find closest path element that intersects visible sphere (or circle, really) + // + bool isClosestPathElementFound = false; + + if( pathElements.mUseSize == 1 ) + { + // if only one element returned + if( pathElements[0].type == RoadManager::ET_INTERSECTION ) + { + // if the only elem is an intersection, just point to target + numIntersects = IntersectLineSphere( source, target, visibleSphere, intPts ); + rAssert( numIntersects == 1 ); + target = intPts[0]; + } + else // the only element is a road + { + Road* theRoad = (Road*) targetElem.elem; + + // we know here that one element returned is either cuz: + // A) source and target lie on same road + // or + // B) source and target lie on opposite roads that + // describe the same physical road (target road is returned) + + // case B + if( sourceElem != targetElem ) + { + // iterate through target road's segments to find the closest seg + // to source, the t value of this segment will tell us whether to + // traverse the segments backwards or forwards... + // + rmt::Vector closestPos; + float closestDist; + int closestSegIndex; + + RoadManager::FindClosestPointOnRoad( theRoad, source, closestPos, closestDist, closestSegIndex ); + + rAssert( 0 <= closestSegIndex && closestSegIndex < (int) theRoad->GetNumRoadSegments() ); + RoadSegment* closestSeg = theRoad->GetRoadSegment( (unsigned int) closestSegIndex ); + rAssert( closestSeg ); + + sourceElem.elem = theRoad; + sourceSeg = closestSeg; + sourceSegT = RoadManager::DetermineSegmentT( closestPos, closestSeg ); + sourceRoadT = RoadManager::DetermineRoadT( sourceSeg, sourceSegT ); + } + + rAssert( sourceElem == targetElem ); + + // this should now work for either A or B + if( sourceRoadT > targetRoadT ) + { + isRoadBackwards = true; + } + + unsigned int startIndex = sourceSeg->GetSegmentIndex(); + unsigned int endIndex = targetSeg->GetSegmentIndex(); + + bool foundIntersect = false; + if( !isRoadBackwards ) + { + for( unsigned int i=startIndex; i<=endIndex; i++ ) + { + RoadSegment* seg = theRoad->GetRoadSegment( i ); + + rmt::Vector vec0, vec1, vec2, vec3, start, end; + seg->GetCorner( 0, vec0 ); + seg->GetCorner( 1, vec1 ); + seg->GetCorner( 2, vec2 ); + seg->GetCorner( 3, vec3 ); + + start = (vec0 + vec3) * 0.5f; + start.y = 0.0f; + end = (vec1 + vec2) * 0.5f; + end.y = 0.0f; + + int numIntersects = IntersectLineSphere( start, end, visibleSphere, intPts ); + rAssert( 0 <= numIntersects && numIntersects <= 1 ); + + if( numIntersects == 1 ) + { + target = intPts[0]; + isClosestPathElementFound = true; + + break; + } + } + } + else + { + for( int i=(int)startIndex; i>=(int)endIndex; i-- ) + { + RoadSegment* seg = theRoad->GetRoadSegment( (unsigned int)i ); + + rmt::Vector vec0, vec1, vec2, vec3, start, end; + seg->GetCorner( 0, vec0 ); + seg->GetCorner( 1, vec1 ); + seg->GetCorner( 2, vec2 ); + seg->GetCorner( 3, vec3 ); + + start = (vec0 + vec3) * 0.5f; + start.y = 0.0f; + end = (vec1 + vec2) * 0.5f; + end.y = 0.0f; + + int numIntersects = IntersectLineSphere( start, end, visibleSphere, intPts ); + rAssert( 0 <= numIntersects && numIntersects <= 1 ); + + if( numIntersects == 1 ) + { + target = intPts[0]; + isClosestPathElementFound = true; + + break; + } + } + } + } + } + else + { + // At this point, we're dealing with multiple path elements + // + Intersection* previousIntersection = NULL; + for( int i = 0; i < pathElements.mUseSize; i++ ) + { + if( isClosestPathElementFound ) + { + // we're done! we found the closest path element + // + break; + } + + RoadManager::PathElement* currentPathElement = &( pathElements[ i ] ); + rAssert( currentPathElement != NULL ); + + switch( currentPathElement->type ) + { + case RoadManager::ET_NORMALROAD: + { + Road* road = static_cast<Road*>( currentPathElement->elem ); + rAssert( road != NULL ); + + int numRoadSegments = static_cast<int>( road->GetNumRoadSegments() ); + + // determine which direction to iterate over all road segments + // + bool isRoadBackwards = false; + + if( i == 0 ) // special case if first path element is a road + { + for( int j = 1; j < pathElements.mUseSize; j++ ) + { + RoadManager::PathElement* pathElement = &( pathElements[ j ] ); + rAssert( pathElement != NULL ); + + if( pathElement->type == RoadManager::ET_INTERSECTION ) + { + isRoadBackwards = ( road->GetSourceIntersection() == static_cast<Intersection*>( pathElement->elem ) ); + + break; + } + } + } + else + { + isRoadBackwards = ( road->GetSourceIntersection() != previousIntersection ); + } + + int currentRoadSegmentIndex = isRoadBackwards ? numRoadSegments - 1 : 0; + + while( currentRoadSegmentIndex >= 0 && currentRoadSegmentIndex < numRoadSegments ) + { + RoadSegment* currentRoadSegment = road->GetRoadSegment( currentRoadSegmentIndex ); + rmt::Vector vec0, vec1, vec2, vec3, start, end; + + currentRoadSegment->GetCorner( 0, vec0 ); + currentRoadSegment->GetCorner( 1, vec1 ); + currentRoadSegment->GetCorner( 2, vec2 ); + currentRoadSegment->GetCorner( 3, vec3 ); + + start = (vec0 + vec3) * 0.5f; + start.y = 0.0f; + end = (vec1 + vec2) * 0.5f; + end.y = 0.0f; + + rmt::Vector intersectPoints[ 2 ]; + int numIntersectPoints = IntersectLineSphere( start, end, visibleSphere, intersectPoints ); + if( numIntersectPoints > 0 ) + { + rmt::Vector closestIntersectPoint = intersectPoints[ 0 ]; + + // TC [TODO]: if more than one intersection points, need to determine which + // one is closest to source + // + if( numIntersectPoints > 1 ) + { + rTuneWarningMsg( false, "Multiple intersection points not yet handled properly, but this should not happen here!" ); + } + + // check to make sure that this point is, in fact, closer to the target than the source + // + if( i == 0 ) // only need to check this for the first path element + { + float roadSegT = roadManager->DetermineSegmentT( closestIntersectPoint, const_cast<RoadSegment*>( currentRoadSegment ) ); + float intersectRoadT = roadManager->DetermineRoadT( const_cast<RoadSegment*>( currentRoadSegment ), roadSegT ); + + if( ( isRoadBackwards && intersectRoadT < sourceRoadT) || + (!isRoadBackwards && intersectRoadT > sourceRoadT) ) + { + target = closestIntersectPoint; + isClosestPathElementFound = true; + + break; // stop iterating over road segments + } + else + { + int dummy = 0; + } + } + else + { + target = closestIntersectPoint; + isClosestPathElementFound = true; + + break; // stop iterating over road segments + } + } + + currentRoadSegmentIndex += isRoadBackwards ? -1 : +1; + } + + break; + } + case RoadManager::ET_INTERSECTION: + { + Intersection* intersection = static_cast<Intersection*>( currentPathElement->elem ); + rAssert( intersection != NULL ); + + // keep track of previous intersection + // + previousIntersection = intersection; + + rmt::Vector intersectionLocation; + intersection->GetLocation( intersectionLocation ); + intersectionLocation.y = 0.0f; + float distance = CalculateDistanceBetweenPoints( source, intersectionLocation ); + + if( rmt::Abs( distance - visibleRadius ) <= intersection->GetRadius() ) + { + // project target onto radar edge, on a point that is closest to the + // intersection center point + // + rmt::Vector sourceToIntersection; + sourceToIntersection.Sub( intersectionLocation, source ); + sourceToIntersection.Scale( visibleRadius / distance ); + + target.Add( source, sourceToIntersection ); + + isClosestPathElementFound = true; + } + + break; + } + default: + { + rAssertMsg( false, "Invalid path element type!" ); + + break; + } + } + } + } + + HeapMgr()->PopHeap( GMA_TEMP ); + + target.y = 0.0f; + m_lastOnRoadLocation = target; + +#ifndef RAD_RELEASE + if( !isClosestPathElementFound ) + { + // TC: [INVESTIGATE] if closest path element is not found, there must be some discontinuity + // in the closest path found + // + rTuneWarningMsg( false, "Closest path element not found! Please go tell Tony." ); + } +#endif +} + diff --git a/game/code/presentation/gui/utility/hudmap.h b/game/code/presentation/gui/utility/hudmap.h new file mode 100644 index 0000000..cb8b9ec --- /dev/null +++ b/game/code/presentation/gui/utility/hudmap.h @@ -0,0 +1,240 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CHudMap +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/01 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef HUDMAP_H +#define HUDMAP_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <p3d/p3dtypes.hpp> +#include <radmath/radmath.hpp> + +//=========================================================================== +// Forward References +//=========================================================================== + +#ifndef NULL + #define NULL 0 +#endif + +const unsigned int MAX_NUM_REGISTERED_ICONS = 64; +const unsigned int MAX_NUM_ICONS_PER_TYPE = 32; + +struct HudMapCam; +class ISuperCamTarget; +class tPointCamera; +class RoadSegment; + +namespace Scrooby +{ + class Page; + class Group; + class Pure3dObject; + class Sprite; +} + +// pure virtual interface for dynamic hud map icons +// +struct IHudMapIconLocator +{ + virtual void GetPosition( rmt::Vector* currentLoc ) = 0; + virtual void GetHeading( rmt::Vector* heading ) = 0; +}; + +struct HudMapIcon +{ + enum eIconType + { + UNKNOWN_ICON_TYPE = -1, + + ICON_PLAYER, + ICON_PLAYER_CAR, + + ICON_AI_TYPES_BEGIN = ICON_PLAYER_CAR, // not an icon type + ICON_AI_HIT_N_RUN, + ICON_AI_CHASE, + ICON_AI_RACE, + ICON_AI_EVADE, + ICON_AI_TARGET, + ICON_AI_TYPES_END, // not an icon type + + ICON_FLAG_CHECKERED = ICON_AI_TYPES_END, + ICON_FLAG_WAYPOINT, + ICON_COLLECTIBLE, + ICON_MISSION, + ICON_BONUS_MISSION, + ICON_PHONE_BOOTH, + ICON_PURCHASE_CENTRE, + ICON_STREET_RACE, + ICON_WAGER_RACE, + + NUM_ICON_TYPES + }; + + Scrooby::Sprite* m_iconImage; + eIconType m_type; + rmt::Vector m_location; + IHudMapIconLocator* m_dynamicLocator; + unsigned int m_visibilityMask; + + HudMapIcon() + : m_iconImage( NULL ), + m_type( UNKNOWN_ICON_TYPE ), + m_location( 0, 0, 0 ), + m_dynamicLocator( NULL ), + m_visibilityMask( 0 ) + { + } + + bool IsAICarIcon() const + { + return( static_cast<int>( m_type ) > ICON_AI_TYPES_BEGIN && + static_cast<int>( m_type ) < ICON_AI_TYPES_END ); + } + + void ApplyAICarIconColour(); + +}; + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CHudMap +{ +public: + CHudMap( Scrooby::Page* pPage, int playerID, const char* p3dFile = NULL ); + virtual ~CHudMap(); + + // Camera Target must be set before doing anything else! + // + void SetCameraTarget( ISuperCamTarget* target ); + + // enable/disable fixed camera height (if enabling, the fixed camera + // height will be calculated from the visible radius) + // + void EnableFixedCameraHeight( bool enable, + float visibleRadius = 50.0f ); + + // Update + // + void Update( unsigned int elapsedTime ); + + // for AI Car icons only + // + void UpdateAICarDistance( float currentDistance, float maxDistance ); + + // Map Icons + // + void AddIconToInventory( HudMapIcon::eIconType type, Scrooby::Sprite* image ); + Scrooby::Sprite* RemoveIconFromInventory( HudMapIcon::eIconType type ); + + int RegisterIcon( HudMapIcon::eIconType type, rmt::Vector location, + IHudMapIconLocator* hudMapIconLocator = NULL, + bool newFocalPoint = false ); + + void UnregisterIcon( int iconID ); + + int ChangeIconType( int iconID, HudMapIcon::eIconType type ); + void SetFocalPointIcon( int iconID ); + HudMapIcon* FindIcon( HudMapIcon::eIconType type ) const; + + // Reset position and size to original settings + // + void Translate( int x, int y ); + void Reset(); + + void SetVisible( bool isVisible ); + + // Accessors + // + Scrooby::Pure3dObject* GetMap() const { return m_p3dMap; } + Scrooby::Pure3dObject* GetHole() const { return m_p3dHole; } + HudMapCam* GetHudMapCam() const { return m_hudMapCam; } + + void RestoreAllRegisteredIcons(); + static void ClearAllRegisteredIcons(); + +private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or asignment. Declare but don't define. + // + CHudMap( const CHudMap& ); + CHudMap& operator= ( const CHudMap& ); + + static float CalculateDistanceBetweenPoints( rmt::Vector& a, rmt::Vector& b ); + + void UpdateIconHeading( Scrooby::Sprite* iconImage, rmt::Vector* iconHeading ); + + float CalculateCameraHeight( rmt::Vector& player, rmt::Vector& mission ) const; + float CalculateCameraHeight( float visibleRadius ) const; + float CalculatRadarConeAngle( rmt::Vector& iconLoc ) const; + + void DetermineOnRoadLocation( rmt::Vector& source, rmt::Vector& target, float visibleRadius ); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + int m_playerID; + + Scrooby::Pure3dObject* m_p3dMap; + Scrooby::Pure3dObject* m_p3dHole; + int m_originalPosX; + int m_originalPosY; + int m_originalWidth; + int m_originalHeight; + + bool m_isVisible : 1; + Scrooby::Group* m_radar; + Scrooby::Group* m_radarCone; + Scrooby::Group* m_iconsGroup; + + HudMapCam* m_hudMapCam; + float m_currentCameraHeight; + float m_fixedCameraHeight; + + Scrooby::Sprite* m_icons[ HudMapIcon::NUM_ICON_TYPES ][ MAX_NUM_ICONS_PER_TYPE ]; + + // for AI Car icons only + // + float m_currentAICarDistance; + float m_maxAICarDistance; + + unsigned int m_elapsedTime; + + RoadSegment* m_lastRoadSeg; + rmt::Vector m_lastOnRoadLocation; + int m_frameCount; + + // gameplay-persistent data + // + static HudMapIcon s_registeredIcons[ MAX_NUM_REGISTERED_ICONS ]; + static int s_numRegisteredIcons; + static int s_fpIconID; + +}; + +inline void CHudMap::UpdateAICarDistance( float currentDistance, float maxDistance ) +{ + m_currentAICarDistance = currentDistance; + m_maxAICarDistance = maxDistance; +} + +#endif // HUDMAP_H diff --git a/game/code/presentation/gui/utility/hudmapcam.cpp b/game/code/presentation/gui/utility/hudmapcam.cpp new file mode 100644 index 0000000..b83396b --- /dev/null +++ b/game/code/presentation/gui/utility/hudmapcam.cpp @@ -0,0 +1,113 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudMapCam +// +// Description: Implementation of the CHudMap class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/utility/hudmapcam.h> + +#include <camera/supercammanager.h> +#include <camera/supercamcentral.h> + +#include <raddebug.hpp> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +HudMapCam::HudMapCam( int playerID ) +: KullCam(), + m_camera( NULL ), + m_originalHeading( -1, 0, 0 ) +{ + SetPlayerID( playerID ); + mIgnoreDebugController = true; + + m_camera = new tPointCamera; + m_camera->AddRef(); + SetCamera( m_camera ); + + // override default KullCam parameters + mElevation = 0.0f; + mMagnitude = 150.0f; + + // fix hud map cam FOV + // + this->SetFOV( rmt::PI_BY2 ); +} + +HudMapCam::~HudMapCam() +{ + if( m_camera != NULL ) + { + m_camera->Release(); + m_camera = NULL; + } +} + +void +HudMapCam::Update( unsigned int milliseconds ) +{ + // adjust kull cam rotation to match main camera heading + // + rmt::Vector camHeading; + GetSuperCamManager()->GetSCC( this->GetPlayerID() )->GetActiveSuperCam()->GetHeading( &camHeading ); + camHeading.y = 0; + + if( camHeading.MagnitudeSqr() > 0 ) + { + float ratio = camHeading.DotProduct( m_originalHeading ) / camHeading.Magnitude(); + if( ratio > 1.0f ) + { + mRotation = 0.0f; + } + else if( ratio < -1.0f ) + { + mRotation = rmt::PI; + } + else + { + mRotation = rmt::ACos( ratio ); + } + + rAssert( !rmt::IsNan( mRotation ) ); + + rmt::Vector normal = camHeading; + normal.CrossProduct( m_originalHeading ); + if( normal.y < 0 ) + { + mRotation = -mRotation; + } + } + + KullCam::Update( milliseconds ); + + // fix hud map cam at 'mMagnitude' above sea level + // + rmt::Vector camPosition = m_camera->GetPosition(); + camPosition.y = mMagnitude; + m_camera->SetPosition( camPosition ); +} + +void +HudMapCam::SetHeight( float height ) +{ + rAssert( height > 0.0f ); + mMagnitude = height; +} + diff --git a/game/code/presentation/gui/utility/hudmapcam.h b/game/code/presentation/gui/utility/hudmapcam.h new file mode 100644 index 0000000..21db768 --- /dev/null +++ b/game/code/presentation/gui/utility/hudmapcam.h @@ -0,0 +1,40 @@ +//=========================================================================== +// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved. +// +// Component: HudMapCam +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2003/03/10 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef HUDMAPCAM_H +#define HUDMAPCAM_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <camera/kullcam.h> + +//=========================================================================== +// Interface Definitions +//=========================================================================== +struct HudMapCam : public KullCam +{ + HudMapCam( int playerID ); + virtual ~HudMapCam(); + + void Update( unsigned int milliseconds ); + void SetHeight( float height ); + + tPointCamera* m_camera; + rmt::Vector m_originalHeading; + +}; + +#endif // HUDMAPCAM_H diff --git a/game/code/presentation/gui/utility/numerictext.cpp b/game/code/presentation/gui/utility/numerictext.cpp new file mode 100644 index 0000000..6dafdcc --- /dev/null +++ b/game/code/presentation/gui/utility/numerictext.cpp @@ -0,0 +1,27 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: NumericText +// +// Description: Implementation of the NumericText class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/19 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/utility/numerictext.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + diff --git a/game/code/presentation/gui/utility/numerictext.h b/game/code/presentation/gui/utility/numerictext.h new file mode 100644 index 0000000..04bf24c --- /dev/null +++ b/game/code/presentation/gui/utility/numerictext.h @@ -0,0 +1,197 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: NumericText +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/07 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef NUMERICTEXT_H +#define NUMERICTEXT_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <text.h> + +//=========================================================================== +// Forward References +//=========================================================================== +namespace Scrooby +{ + class Group; + class Page; + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== +template <class Digit> +struct NumericText +{ + enum eDigits + { + DIGIT_ONES, + DIGIT_TENS, + DIGIT_HUNDREDS, + + MAX_NUM_DIGITS + }; + + enum eAlignment + { + ALIGN_RIGHT, + ALIGN_LEFT, + + NUM_ALIGNMENTS + }; + + Digit* m_digits[ MAX_NUM_DIGITS ]; + Scrooby::Group* m_group; + int m_numDigits; + bool m_showLeadingZeros; + eAlignment m_alignment; + + NumericText() + : m_group( NULL ), + m_numDigits( 0 ), + m_showLeadingZeros( false ), + m_alignment( ALIGN_RIGHT ) + { + memset( m_digits, 0, sizeof( m_digits ) ); + } + + void SetScroobyText( Scrooby::Group* pGroup, const char* name ) + { + m_group = pGroup; + m_numDigits = 0; + + char objectName[ 32 ]; + for( int i = 0; i < MAX_NUM_DIGITS; i++ ) + { + sprintf( objectName, "%s_%d", name, i ); + + Digit* pDrawable = dynamic_cast<Digit*>( pGroup->GetText( objectName ) ); + if( pDrawable == NULL ) + { + pDrawable = dynamic_cast<Digit*>( pGroup->GetSprite( objectName ) ); + } + + if( pDrawable != NULL ) + { + m_digits[ i ] = pDrawable; + + // increment number of digits + // + m_numDigits++; + } + else + { + // break, assuming no more digits to follow + // + break; + } + } + + // set value to zero by default + // + this->SetValue( 0 ); + } + + void SetValue( unsigned int value, unsigned int offset = 0 ) + { + for( int i = 0; i < m_numDigits; i++ ) + { + // set current digit value + rAssert( m_digits[ i ] ); + + m_digits[ i ]->SetIndex( value % 10 + offset ); + + // show leading zeros, if enabled + if( m_showLeadingZeros ) + { + m_digits[ i ]->SetVisible( true ); + } + else + { + m_digits[ i ]->SetVisible( value > 0 || i == 0 ); + } + + // shift value one digit to the right + value = value / 10; + } + + if( m_alignment == ALIGN_LEFT ) + { + // align numeric text to the left (TC: Can this be improved??) + for( int j = m_numDigits - 1; j >= 0; j-- ) + { + if( m_digits[ j ]->IsVisible() ) + { + // found leading digit = j, now shift digits to the left + // + for( int k = m_numDigits - 1; k >= 0; k-- ) + { + if( j >= 0 ) + { + m_digits[ k ]->SetIndex( m_digits[ j ]->GetIndex() ); + m_digits[ k ]->SetVisible( true ); + + j--; + } + else + { + m_digits[ k ]->SetVisible( false ); + } + } + + // done, break out of loop + break; + } + } + } + } + + void SetVisible( bool isVisible ) + { + if( m_group != NULL ) + { + m_group->SetVisible( isVisible ); + } + else + { + for( int i = 0; i < MAX_NUM_DIGITS; i++ ) + { + if( m_digits[ i ] != NULL ) + { + m_digits[ i ]->SetVisible( isVisible ); + } + } + } + } + + void SetColour( tColour colour ) + { + for( int i = 0; i < MAX_NUM_DIGITS; i++ ) + { + if( m_digits[ i ] != NULL ) + { + m_digits[ i ]->SetColour( colour ); + } + } + } + +}; + +#endif // NUMERICTEXT_H diff --git a/game/code/presentation/gui/utility/scrollingtext.cpp b/game/code/presentation/gui/utility/scrollingtext.cpp new file mode 100644 index 0000000..3c44e8c --- /dev/null +++ b/game/code/presentation/gui/utility/scrollingtext.cpp @@ -0,0 +1,280 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: ScrollingText +// +// Description: Implementation of the ScrollingText class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/11/21 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <p3d/font.hpp> +#include <presentation/gui/utility/scrollingtext.h> + +#include <raddebug.hpp> // Foundation +#include <app.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// ScrollingText::ScrollingText +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +ScrollingText::ScrollingText( Scrooby::Text* pText ) +: m_pText( pText ), + m_originalString( NULL ), + m_x0( 0 ), + m_y0( 0 ), + m_x1( 0 ), + m_y1( 0 ), + m_currentPos( 0.0f ), + m_state( STATE_IDLE ), + m_numPixelsPerSecond( 90 ), + m_isCyclic( false ) +{ + rAssert( m_pText != NULL ); + + // set text mode to clip on right boundary + // + m_pText->SetTextMode( Scrooby::TEXT_CLIP ); + + // get scroll box boundary + // + m_pText->GetBoundingBox( m_x0, m_y0, m_x1, m_y1 ); + + // hide text until scrolling is started + // + m_pText->SetVisible( false ); + + // save reference to original string buffer + // + m_originalString = m_pText->GetStringBuffer(); + +/* + // save copy of original string + // + P3D_UNICODE* originalString = static_cast<P3D_UNICODE*>( m_pText->GetStringBuffer() ); + rAssert( originalString != NULL ); + p3d::UnicodeStrCpy( originalString, + m_originalString, + p3d::UnicodeStrLen( originalString ) + 1 ); +*/ +} + +//=========================================================================== +// ScrollingText::~ScrollingText +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +ScrollingText::~ScrollingText() +{ +} + +void +ScrollingText::RestoreText() +{ + // restore position and size + // + m_pText->SetPosition( m_x0, m_y0 ); + m_pText->SetBoundingBoxSize( m_x1 - m_x0, m_y1 - m_y0 ); + + // restore original string buffer + // + m_pText->SetStringBuffer( m_originalString ); + + // restore visibility + // + m_pText->SetVisible( true ); +} + +void +ScrollingText::SetTextIndex( int index ) +{ + rAssert( m_state == STATE_IDLE ); + + m_pText->SetIndex( index ); + + // update reference to original string buffer + // + m_originalString = m_pText->GetStringBuffer(); +} + +void +ScrollingText::Start() +{ + m_state = STATE_SCROLLING; + + m_currentPos = (float)m_x1; + this->ClipText( (int)m_currentPos, m_y0 ); + + // show text + // + m_pText->SetVisible( true ); +} + +void +ScrollingText::Stop() +{ + m_state = STATE_IDLE; + + m_pText->SetPosition( m_x0, m_y0 ); + + // restore original string buffer + // + m_pText->SetStringBuffer( m_originalString ); + + // hide text + // + m_pText->SetVisible( false ); + +/* + P3D_UNICODE* originalString = static_cast<P3D_UNICODE*>( m_pText->GetStringBuffer() ); + rAssert( originalString != NULL ); + p3d::UnicodeStrCpy( m_originalString, + originalString, + p3d::UnicodeStrLen( m_originalString ) + 1 ); +*/ +} + +void +ScrollingText::Update( unsigned int elapsedTime ) +{ + if( m_state == STATE_SCROLLING ) + { + // advance text towards the left + // + m_currentPos -= (m_numPixelsPerSecond * elapsedTime) / 1000.0f; + + // apply text clipping for current position + // + this->ClipText( (int)m_currentPos, m_y0 ); + } +} + +//=========================================================================== +// Private Member Functions +//=========================================================================== + +void +ScrollingText::ClipText( int x, int y ) +{ + if( x >= m_x1 ) // *** origin beyond right boundary + { + m_pText->SetPosition( x, y ); + m_pText->SetBoundingBoxSize( 0, m_y1 - y ); + } + else if( x >= m_x0 ) // *** origin within both boundaries + { + m_pText->SetPosition( x, y ); + m_pText->SetBoundingBoxSize( m_x1 - x, m_y1 - y ); + +#ifdef RAD_WIN32 + // TC: for PC sku, the source fonts are actually twice as big (for higher resolution display), + // so we need to stretch the bounding box accordingly for proper text clipping + // + m_pText->StretchBoundingBox( 2.0f, 1.0f ); +#endif + } + else // *** origin beyond left boundary + { + m_pText->SetBoundingBoxSize( m_x1 - m_x0, m_y1 - y ); + +#ifdef RAD_WIN32 + // TC: for PC sku, the source fonts are actually twice as big (for higher resolution display), + // so we need to stretch the bounding box accordingly for proper text clipping + // + m_pText->StretchBoundingBox( 2.0f, 1.0f ); +#endif + + tFont* textFont = m_pText->GetFont(); + if( textFont != NULL ) + { + bool doneClipping = false; + + for( UnicodeChar* currentString = m_pText->GetStringBuffer(); + !doneClipping; + currentString++ ) + { + UnicodeChar tempChar = currentString[ 0 ]; + currentString[ 0 ] = '\0'; + + float clippedTextWidth = textFont->GetTextWidth( static_cast<P3D_UNICODE*>( m_originalString ) ) * + Scrooby::App::GetInstance()->GetScreenWidth() / + Scrooby::App::GetInstance()->GetScreenHeight(); + +#ifdef RAD_WIN32 + // TC: for PC sku, the source fonts are actually twice as big (for higher resolution display), + // so the width of the current text string is only half as wide + // + clippedTextWidth /= 2.0f; +#endif + + currentString[ 0 ] = tempChar; + + int amountClipped = static_cast<int>( clippedTextWidth ) - (m_x0 - x); + if( amountClipped >= 0 ) + { + m_pText->SetPosition( m_x0 + amountClipped, y ); + m_pText->SetStringBuffer( currentString ); + doneClipping = true; + } + + if( currentString[ 0 ] == '\0' ) + { + // done scrolling + // + this->Stop(); + + if( m_isCyclic ) + { + // start over again + // + this->Start(); + } + + // make sure we break out of the loop; otherwise, there's + // a small chance that 'amountClipped' may be slightly less + // than 0 and so we might not be done clipping + // + break; + } + } + } + else + { + rWarningMsg( false, "No font for clipping text!" ); + + this->Stop(); + } + } +} + diff --git a/game/code/presentation/gui/utility/scrollingtext.h b/game/code/presentation/gui/utility/scrollingtext.h new file mode 100644 index 0000000..c1f75c3 --- /dev/null +++ b/game/code/presentation/gui/utility/scrollingtext.h @@ -0,0 +1,110 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: ScrollingText +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/11/21 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef SCROLLINGTEXT_H +#define SCROLLINGTEXT_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <strings/unicodestring.h> + + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Text; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class ScrollingText +{ +public: + ScrollingText( Scrooby::Text* pText ); + virtual ~ScrollingText(); + + void RestoreText(); + void SetTextIndex( int index ); + + void Start(); + void Stop(); + void Pause(); + void Resume(); + + void Update( unsigned int elapsedTime ); + + enum eScrollState + { + STATE_IDLE, + STATE_SCROLLING, + STATE_PAUSED, + + NUM_SCROLL_STATES + }; + + eScrollState GetCurrentState() const { return m_state; } + + void SetSpeed( int numPixelsPerSecond ) { m_numPixelsPerSecond = numPixelsPerSecond; } + + void SetCyclic( bool isCyclic ) { m_isCyclic = isCyclic; } + bool IsCyclic() const { return m_isCyclic; } + +protected: + //--------------------------------------------------------------------- + // Protected Functions + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + // Protected Data + //--------------------------------------------------------------------- + +private: + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or asignment. Declare but don't define. + // + ScrollingText( const ScrollingText& ); + ScrollingText& operator= ( const ScrollingText& ); + + void ClipText( int x, int y ); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + Scrooby::Text* m_pText; + UnicodeChar* m_originalString; + + int m_x0; + int m_y0; + int m_x1; + int m_y1; + float m_currentPos; + + eScrollState m_state; + + int m_numPixelsPerSecond; + bool m_isCyclic; + +}; + +#endif // SCROLLINGTEXT_H diff --git a/game/code/presentation/gui/utility/slider.cpp b/game/code/presentation/gui/utility/slider.cpp new file mode 100644 index 0000000..ac86521 --- /dev/null +++ b/game/code/presentation/gui/utility/slider.cpp @@ -0,0 +1,246 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: Slider +// +// Description: Implementation of the Slider class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/19 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/utility/slider.h> + +#include <raddebug.hpp> // Foundation +#include <polygon.h> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +Slider::Slider( eSliderType type ) +: m_type( type ), + m_pPolygon( NULL ), + m_value( 1 ), + m_pImage( NULL ), + x0( 19820602 ), // some arbitrarily big integer + y0( 19780627 ), // some arbitrarily big integer + x1( 0 ), + y1( 0 ) +{ +} + +void +Slider::SetScroobyPolygon( Scrooby::Polygon* pPolygon, Scrooby::Sprite* pImage ) +{ + rAssert( pPolygon ); + m_pPolygon = pPolygon; + m_pImage = pImage; + + for( int i = 0; i < m_pPolygon->GetNumOfVertexes(); i++ ) + { + int x = 0; + int y = 0; + m_pPolygon->GetVertexLocation( i, x, y ); + + if( x < x0 ) x0 = x; + if( y < y0 ) y0 = y; + if( x > x1 ) x1 = x; + if( y > y1 ) y1 = y; + } + + m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_LEFT, x0, y0 ); + m_pPolygon->SetVertexLocation( VERTEX_TOP_LEFT, x0, y1 ); + m_pPolygon->SetVertexLocation( VERTEX_TOP_RIGHT, x1, y1 ); + m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_RIGHT, x1, y0 ); +} + +void +Slider::SetValue( float value ) +{ + rAssert( value >= 0.0f && value <= 1.0f ); + m_value = value; + + rAssert( m_pPolygon ); + + int x = x0; + int y = y0; + + switch( m_type ) + { + case HORIZONTAL_SLIDER_LEFT: + { + x = x0 + static_cast<int>( (x1 - x0) * value ); + m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_RIGHT, x, y0 ); + m_pPolygon->SetVertexLocation( VERTEX_TOP_RIGHT, x, y1 ); + + if( m_pImage != NULL ) + { + m_pImage->ResetTransformation(); + m_pImage->Translate( x - x1, 0 ); + } + + break; + } + case HORIZONTAL_SLIDER_RIGHT: + { + x = x1 + static_cast<int>( (x0 - x1) * value ); + m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_LEFT, x, y0 ); + m_pPolygon->SetVertexLocation( VERTEX_TOP_LEFT, x, y1 ); + + if( m_pImage != NULL ) + { + m_pImage->ResetTransformation(); + m_pImage->Translate( x - x0, 0 ); + } + + break; + } + case VERTICAL_SLIDER_BOTTOM: + { + y = y0 + static_cast<int>( (y1 - y0) * value ); + m_pPolygon->SetVertexLocation( VERTEX_TOP_LEFT, x0, y ); + m_pPolygon->SetVertexLocation( VERTEX_TOP_RIGHT, x1, y ); + + if( m_pImage != NULL ) + { + m_pImage->ResetTransformation(); + m_pImage->Translate( 0, y - y1 ); + } + + break; + } + case VERTICAL_SLIDER_TOP: + { + y = y1 + static_cast<int>( (y0 - y1) * value ); + m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_LEFT, x0, y ); + m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_RIGHT, x1, y ); + + if( m_pImage != NULL ) + { + m_pImage->ResetTransformation(); + m_pImage->Translate( 0, y - y0 ); + } + + break; + } + default: + { + rAssertMsg( 0, "ERROR: *** Invalid slider type!" ); + + break; + } + } +} + +//=========================================================================== +// Public Member Functions (for ImageSlider) +//=========================================================================== + +ImageSlider::ImageSlider( eSliderType type ) +: Slider( type ) +{ +} + +void +ImageSlider::SetScroobyImage( Scrooby::Sprite* pImage ) +{ + rAssert( pImage ); + m_pImage = pImage; +} + +void +ImageSlider::SetValue( float value, bool resetTransformation ) +{ + rAssert( value >= 0.0f && value <= 1.0f ); + m_value = value; + + rAssert( m_pImage ); + + if( resetTransformation ) + { + m_pImage->ResetTransformation(); + } + + int posX = 0; + int posY = 0; + m_pImage->GetOriginPosition( posX, posY ); + + int width = 0; + int height = 0; + m_pImage->GetBoundingBoxSize( width, height ); + + switch( m_type ) + { + case HORIZONTAL_SLIDER_LEFT: + { + m_pImage->Translate( -posX, 0 ); + m_pImage->Scale( value, 1.0f, 1.0f ); + m_pImage->Translate( posX, 0 ); + + break; + } + case HORIZONTAL_SLIDER_RIGHT: + { + m_pImage->Translate( -posX, 0 ); + m_pImage->Scale( value, 1.0f, 1.0f ); + m_pImage->Translate( posX, 0 ); + + // right align image + // + m_pImage->Translate( (int)( width * (1.0f - value) ), 0 ); + + break; + } + case HORIZONTAL_SLIDER_ABOUT_CENTER: + { + m_pImage->ScaleAboutCenter( value, 1.0f, 1.0f ); + + break; + } + case VERTICAL_SLIDER_BOTTOM: + { + m_pImage->Translate( 0, -posY ); + m_pImage->Scale( 1.0f, value, 1.0f ); + m_pImage->Translate( 0, posY ); + + break; + } + case VERTICAL_SLIDER_TOP: + { + m_pImage->Translate( 0, -posY ); + m_pImage->Scale( 1.0f, value, 1.0f ); + m_pImage->Translate( 0, posY ); + + // top align image + // + m_pImage->Translate( 0, (int)( height * (1.0f - value) ) ); + + break; + } + case VERTICAL_SLIDER_ABOUT_CENTER: + { + m_pImage->ScaleAboutCenter( 1.0f, value, 1.0f ); + + break; + } + default: + { + rAssertMsg( 0, "ERROR: *** Invalid slider type!" ); + + break; + } + } +} + diff --git a/game/code/presentation/gui/utility/slider.h b/game/code/presentation/gui/utility/slider.h new file mode 100644 index 0000000..31df284 --- /dev/null +++ b/game/code/presentation/gui/utility/slider.h @@ -0,0 +1,94 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: Slider +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/07 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef SLIDER_H +#define SLIDER_H + +#ifndef NULL + #define NULL 0 +#endif + +//=========================================================================== +// Nested Includes +//=========================================================================== + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Polygon; + class Sprite; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== +struct Slider +{ + enum eSliderType + { + HORIZONTAL_SLIDER_LEFT, + HORIZONTAL_SLIDER_ABOUT_CENTER, + HORIZONTAL_SLIDER_RIGHT, + + VERTICAL_SLIDER_BOTTOM, + VERTICAL_SLIDER_ABOUT_CENTER, + VERTICAL_SLIDER_TOP, + + NUM_SLIDER_TYPES + }; + + eSliderType m_type; + + enum eVertex + { + VERTEX_BOTTOM_LEFT, + VERTEX_TOP_LEFT, + VERTEX_TOP_RIGHT, + VERTEX_BOTTOM_RIGHT, + + NUM_VERTICES + }; + + Scrooby::Polygon* m_pPolygon; + float m_value; + + // optional image to tag onto the end of the slider + Scrooby::Sprite* m_pImage; + + // bottom-left and top-right vertex co-ordinates + int x0; + int y0; + int x1; + int y1; + + Slider( eSliderType type = HORIZONTAL_SLIDER_LEFT ); + void SetScroobyPolygon( Scrooby::Polygon* pPolygon, Scrooby::Sprite* pImage = NULL ); + virtual void SetValue( float value ); + +}; + +struct ImageSlider : public Slider +{ + ImageSlider( eSliderType type = HORIZONTAL_SLIDER_LEFT ); + + void SetScroobyImage( Scrooby::Sprite* pImage ); + virtual void SetValue( float value, bool resetTransformation = true ); + +}; + +#endif // SLIDER_H diff --git a/game/code/presentation/gui/utility/specialfx.cpp b/game/code/presentation/gui/utility/specialfx.cpp new file mode 100644 index 0000000..b306653 --- /dev/null +++ b/game/code/presentation/gui/utility/specialfx.cpp @@ -0,0 +1,401 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: SpecialFX +// +// Description: Implementation of the SpecialFX class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/30 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/utility/specialfx.h> +#include <boundeddrawable.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +bool GuiSFX::Flash +( + Scrooby::BoundedDrawable* drawable, + float elapsedTime, + float durationTime, + int zoomRate, + float maxScale, + float thresholdScale +) +{ + if( elapsedTime > durationTime ) + { + return true; + } + + rAssert( drawable != NULL ); + rAssert( elapsedTime >= 0 && durationTime > 0 ); + + float scale = (float)elapsedTime / (float)durationTime; + for( int i = 0; i < zoomRate; i++ ) + { + scale = rmt::Sqrt( scale ); + } + + scale *= maxScale; + + drawable->ResetTransformation(); + drawable->ScaleAboutCenter( scale, scale, 1.0f ); + + if( scale > thresholdScale ) + { + drawable->SetAlpha( 1.0f - ((scale - thresholdScale) / + (maxScale - thresholdScale)) ); + } + else + { + drawable->SetAlpha( 1.0f ); + } + + return false; +} + +bool GuiSFX::Blink +( + Scrooby::Drawable* drawable, + float elapsedTime, + float blinkingPeriod, + bool usingAlpha +) +{ + rAssert( drawable ); + + if( elapsedTime > blinkingPeriod ) + { + if( usingAlpha ) + { + // toggle drawable visiblity (using alpha) + // + float newAlpha = (drawable->GetAlpha() > 0.5f) ? 0.0f : 1.0f; + drawable->SetAlpha( newAlpha ); + } + else + { + // toggle drawable visibility + // + drawable->SetVisible( !drawable->IsVisible() ); + } + + return true; + } + + return false; +} + +float GuiSFX::Pulse +( + float elapsedTime, + float period, + float center, + float amplitude, + float thetaOffset +) +{ + float theta = rmt::PI_2 * elapsedTime / period - thetaOffset; + + return( amplitude * rmt::Sin( theta ) + center ); +} + +void GuiSFX::ModulateColour +( + tColour* currentColour, + float elapsedTime, + float period, + tColour startColour, + tColour endColour, + float thetaOffset +) +{ + float modValue = GuiSFX::Pulse( elapsedTime, period, 0.5f, 0.5f, thetaOffset ); + + rAssert( currentColour != NULL ); + + currentColour->SetRed( startColour.Red() + + (int)( modValue * (endColour.Red() - startColour.Red()) ) ); + + currentColour->SetGreen( startColour.Green() + + (int)( modValue * (endColour.Green() - startColour.Green()) ) ); + + currentColour->SetBlue( startColour.Blue() + + (int)( modValue * (endColour.Blue() - startColour.Blue()) ) ); + + currentColour->SetAlpha( startColour.Alpha() + + (int)( modValue * (endColour.Alpha() - startColour.Alpha()) ) ); +} + +float GuiSFX::Pendulum +( + Scrooby::BoundedDrawable* drawable, + float deltaTime, + float length, + float currentAngle, + float initialAngle, + float gravity +) +{ + rAssertMsg( 0, "WARNING: *** Not yet implemented!" ); + + return 0.0f; +/* + rAssert( drawable ); + + float root = (2 * gravity / length) * + (rmt::Cos( initialAngle ) - rmt::Cos( currentAngle )); + + int rootSign = root > 0 ? 1 : -1; + + // update current angle + if( currentAngle > 0.0f ) + { + currentAngle -= rmt::Sqrt( root * rootSign ) + * (deltaTime / 1000.0f); + } + else + { + currentAngle += rmt::Sqrt( root * rootSign ) + * (deltaTime / 1000.0f); + } + + // rotate pendulum arm + drawable->ResetTransformation(); + drawable->RotateAboutCenter( rmt::RadianToDeg( currentAngle ) ); + + return currentAngle; +*/ +} + +bool GuiSFX::Spiral +( + Scrooby::BoundedDrawable* drawable, + float elapsedTime, + float durationTime, + float rotationPeriod, + float startScale, + float endScale, + bool withFading +) +{ + if( elapsedTime > durationTime ) + { + drawable->ResetTransformation(); + drawable->ScaleAboutCenter( endScale ); + + if( withFading ) + { + drawable->SetAlpha( 1.0f ); + } + + return true; + } + + float spiralValue = elapsedTime / durationTime; + + // calculate current scale factor + // + float scale = startScale + + spiralValue * (endScale - startScale); + + // slow down rotation when nearing end of spiral effect + // + rotationPeriod += spiralValue * rotationPeriod; + + // calculate current rotation angle + // + float rotation = elapsedTime / rotationPeriod * rmt::PI_2; + + // scale and rotate drawable + // + rAssert( drawable ); + drawable->ResetTransformation(); + drawable->ScaleAboutCenter( scale ); + drawable->RotateAboutCenter( rmt::RadianToDeg( rotation ) ); + + // if enabled, fade in the drawable as well + if( withFading ) + { + drawable->SetAlpha( spiralValue ); + } + + return false; +} + +bool GuiSFX::SlideX +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + bool slideInwards, + int fromBorder, + int screenWidth +) +{ + rAssert( drawable ); + + if( elapsedTime > durationTime ) + { + drawable->ResetTransformation(); + + return true; + } + + int posX = 0; + int posY = 0; + int width = 0; + int height = 0; + drawable->GetOriginPosition( posX, posY ); + drawable->GetBoundingBoxSize( width, height ); + + int distanceX = (fromBorder > 0) ? (screenWidth - posX) : (posX + width); + + float translationX = slideInwards ? + (1.0f - elapsedTime / durationTime) * distanceX : + (elapsedTime / durationTime) * distanceX; + + drawable->ResetTransformation(); + drawable->Translate( static_cast<int>( translationX ), 0 ); + + return false; +} + +bool GuiSFX::SlideY +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + bool slideInwards, + int fromBorder, + int screenHeight +) +{ + rAssert( drawable ); + + if( elapsedTime > durationTime ) + { + drawable->ResetTransformation(); + + return true; + } + + int posX = 0; + int posY = 0; + int width = 0; + int height = 0; + drawable->GetOriginPosition( posX, posY ); + drawable->GetBoundingBoxSize( width, height ); + + int distanceY = (fromBorder > 0) ? (screenHeight - posY) : (posY + height); + + float translationY = slideInwards ? + (1.0f - elapsedTime / durationTime) * distanceY : + (elapsedTime / durationTime) * distanceY; + + drawable->ResetTransformation(); + drawable->Translate( 0, static_cast<int>( translationY ) ); + + return false; +} + +bool GuiSFX::Flip +( + Scrooby::BoundedDrawable* drawable, + float elapsedTime, + float durationTime, + float startAngle, + float endAngle, + rmt::Vector axis +) +{ + rAssert( drawable ); + drawable->ResetTransformation(); + + if( elapsedTime > durationTime ) + { + return true; + } + + // calculate current rotation angle + float rotation = startAngle + + elapsedTime / durationTime * (endAngle - startAngle); + + // rotate the drawable about specified axis + drawable->RotateAboutCenter( rmt::RadianToDeg( rotation ), axis ); + + return false; +} + +void GuiSFX::Projectile +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + rmt::Vector initVelocity, + bool reverse, + float gravity +) +{ + if( reverse ) + { + // reverse the elapsed time + // + elapsedTime = durationTime - elapsedTime; + } + + // calculate the current trajectory position + // + rmt::Vector currentPos; + currentPos.x = initVelocity.x * elapsedTime; + currentPos.y = initVelocity.y * elapsedTime + + 0.5f * gravity * elapsedTime * elapsedTime; + currentPos.z = 0.0f; + + // translate the drawable + // + rAssert( drawable ); + drawable->Translate( static_cast<int>( currentPos.x ), + static_cast<int>( currentPos.y ) ); +} + +void GuiSFX::Projectile +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + rmt::Vector start, + rmt::Vector end, + bool reverse, + float gravity +) +{ + // calculate the initial velocity + // + rmt::Vector initVelocity; + initVelocity.x = (end.x - start.x) / durationTime; + initVelocity.y = (end.y - start.y - 0.5f * gravity * durationTime * durationTime) / durationTime; + initVelocity.z = 0.0f; + + GuiSFX::Projectile( drawable, + elapsedTime, + durationTime, + initVelocity, + reverse, + gravity ); +} + diff --git a/game/code/presentation/gui/utility/specialfx.h b/game/code/presentation/gui/utility/specialfx.h new file mode 100644 index 0000000..12fc6fe --- /dev/null +++ b/game/code/presentation/gui/utility/specialfx.h @@ -0,0 +1,166 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: SpecialFX +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/30 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef SPECIALFX_H +#define SPECIALFX_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +#include <p3d/p3dtypes.hpp> +#include <radmath/radmath.hpp> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Drawable; + class BoundedDrawable; +} + +//=========================================================================== +// Interface Definitions +//=========================================================================== + +namespace GuiSFX +{ + +bool Flash +( + Scrooby::BoundedDrawable* drawable, + float elapsedTime, + float durationTime, + int zoomRate = 0, // the higher the number, the faster the zoom + float maxScale = 1.5f, + float thresholdScale = 1.0f +); + +bool Blink +( + Scrooby::Drawable* drawable, + float elapsedTime, + float blinkingPeriod = 1000.0f, + bool usingAlpha = false +); + +float Pulse +( + float elapsedTime, + float period, + float center = 0.0f, + float amplitude = 1.0f, + float thetaOffset = 0.0f +); + +void ModulateColour +( + tColour* currentColour, + float elapsedTime, + float period, + tColour startColour, + tColour endColour, + float thetaOffset = 0.0f +); + +float Pendulum +( + Scrooby::BoundedDrawable* drawable, + float deltaTime, + float length, + float currentAngle, + float initialAngle, + float gravity = 9.81f +); + +bool Spiral +( + Scrooby::BoundedDrawable* drawable, + float elapsedTime, + float durationTime, + float rotationPeriod, + float startScale = 0.0f, + float endScale = 1.0f, + bool withFading = true +); + +enum eSlideBorderX +{ + SLIDE_BORDER_LEFT = -1, + SLIDE_BORDER_RIGHT = 1 +}; + +bool SlideX +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + bool slideInwards, + int fromBorder, + int screenWidth = 640 +); + +enum eSlideBorderY +{ + SLIDE_BORDER_BOTTOM = -1, + SLIDE_BORDER_TOP = 1 +}; + +bool SlideY +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + bool slideInwards, + int fromBorder, + int screenHeight = 480 +); + +bool Flip +( + Scrooby::BoundedDrawable* drawable, + float elapsedTime, + float durationTime, + float startAngle = 0.0f, + float endAngle = rmt::PI_2, + rmt::Vector axis = rmt::Vector( 1, 0, 0 ) +); + +void Projectile +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + rmt::Vector initVelocity, + bool reverse = false, + float gravity = 0.005f +); + +void Projectile +( + Scrooby::Drawable* drawable, + float elapsedTime, + float durationTime, + rmt::Vector start, + rmt::Vector end, + bool reverse = false, + float gravity = 0.005f +); + +} // GuiSFX namespace + +#endif // SPECIALFX_H diff --git a/game/code/presentation/gui/utility/teletypetext.cpp b/game/code/presentation/gui/utility/teletypetext.cpp new file mode 100644 index 0000000..fea1dc3 --- /dev/null +++ b/game/code/presentation/gui/utility/teletypetext.cpp @@ -0,0 +1,318 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CTeleTypeText +// +// Description: Implementation of the CTeleTypeText class. +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/19 TChu Created for SRR2 +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <presentation/gui/utility/teletypetext.h> + +#include <raddebug.hpp> // Foundation +#include <group.h> +#include <text.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== + +//=========================================================================== +// Public Member Functions +//=========================================================================== + +//=========================================================================== +// CTeleTypeText::CTeleTypeText +//=========================================================================== +// Description: Constructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CTeleTypeText::CTeleTypeText( Scrooby::Text* pText, + Scrooby::Group* pTextBox, + unsigned int numCharsPerSecond, + unsigned int numSecondsToDisplay ) +: m_state( STATE_INACTIVE ), + m_elapsedTime( 0 ), + m_teletypePeriod( 1000 / numCharsPerSecond ), + m_displayDuration( numSecondsToDisplay * 1000 ), + m_pText( pText ), + m_pTextBox( pTextBox ), + m_charBuffer( NULL ), + m_nextChar( 0 ), + m_currentCharIndex( 0 ) +{ + rAssert( m_pText != NULL ); + + // hide by default + if( m_pTextBox != NULL ) + { + m_pTextBox->SetVisible( false ); + } + else + { + m_pText->SetVisible( false ); + } + + // wrap text by default + m_pText->SetTextMode( Scrooby::TEXT_WRAP ); +} + +//=========================================================================== +// CTeleTypeText::~CTeleTypeText +//=========================================================================== +// Description: Destructor. +// +// Constraints: None. +// +// Parameters: None. +// +// Return: N/A. +// +//=========================================================================== +CTeleTypeText::~CTeleTypeText() +{ +} + +//=========================================================================== +// CTeleTypeText::Update +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CTeleTypeText::Update( unsigned int elapsedTime ) +{ + switch( m_state ) + { + case STATE_TELETYPING: + { + if( m_elapsedTime >= m_teletypePeriod ) + { + this->TypeNextCharacter(); + + m_elapsedTime = m_elapsedTime % m_teletypePeriod; + } + + // update elapsed time + m_elapsedTime += elapsedTime; + + break; + } + case STATE_DISPLAYING: + { + // 0 means display forever, until client hides it + // + if( m_displayDuration > 0 ) + { + if( m_elapsedTime >= m_displayDuration ) + { + this->HideMessage(); + } + + // update elapsed time + m_elapsedTime += elapsedTime; + } + + break; + } + default: + { + break; + } + } +} + +//=========================================================================== +// CTeleTypeText::DisplayMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CTeleTypeText::DisplayMessage() +{ +// rAssertMsg( m_state == STATE_INACTIVE, "ERROR: Teletype message in progress!\n" ); + if( m_state != STATE_INACTIVE ) + { + // ignore request if there's already a message in progress + return; + } + + rAssert( m_pText ); + + // show scrooby text + if( m_pTextBox != NULL ) + { + m_pTextBox->SetVisible( true ); + } + else + { + m_pText->SetVisible( true ); + } + + // get string buffer from text + m_charBuffer = m_pText->GetStringBuffer(); + + rAssert( m_charBuffer ); + + // reset current character index + m_currentCharIndex = 0; + + // save next character and terminate buffer + m_nextChar = m_charBuffer[ m_currentCharIndex + 1 ]; + m_charBuffer[ m_currentCharIndex + 1 ] = '\0'; + + m_state = STATE_TELETYPING; +} + +//=========================================================================== +// CTeleTypeText::DisplayMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CTeleTypeText::DisplayMessage( int index ) +{ + rAssert( m_pText ); + + if( index >= 0 && index < m_pText->GetNumOfStrings() ) + { + m_pText->SetIndex( index ); + + this->DisplayMessage(); + } + else + { + rAssertMsg( 0, "WARNING: Invalid index for teletype message!\n" ); + } +} + +//=========================================================================== +// CTeleTypeText::HideMessage +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CTeleTypeText::HideMessage() +{ + // if stopped during middle of teletyping + if( m_state == STATE_TELETYPING ) + { + // restore character in buffer + m_charBuffer[ m_currentCharIndex + 1 ] = m_nextChar; + } + + // hide scrooby text + if( m_pTextBox != NULL ) + { + m_pTextBox->SetVisible( false ); + } + else + { + m_pText->SetVisible( false ); + } + + // reset elapsed time + m_elapsedTime = 0; + + m_state = STATE_INACTIVE; +} + +void CTeleTypeText::Pause() +{ + if( m_state == STATE_TELETYPING ) + { + // restore character in buffer + m_charBuffer[ m_currentCharIndex + 1 ] = m_nextChar; + + // hide scrooby text + m_pText->SetVisible( false ); + + m_state = STATE_PAUSED; + } +} + +void CTeleTypeText::Resume() +{ + if( m_state == STATE_PAUSED ) + { + // restore character in buffer + m_charBuffer[ m_currentCharIndex + 1 ] = '\0'; + + // show scrooby text + m_pText->SetVisible( true ); + + m_state = STATE_TELETYPING; + } +} + +//=========================================================================== +// CTeleTypeText::TypeNextCharacter +//=========================================================================== +// Description: +// +// Constraints: None. +// +// Parameters: None. +// +// Return: +// +//=========================================================================== +void CTeleTypeText::TypeNextCharacter() +{ + // increment current character index + m_currentCharIndex++; + + // restore character in buffer + m_charBuffer[ m_currentCharIndex ] = m_nextChar; + + // save next character and terminate buffer + m_nextChar = m_charBuffer[ m_currentCharIndex + 1 ]; + m_charBuffer[ m_currentCharIndex + 1 ] = '\0'; + + // if end of buffer reached + if( m_nextChar == '\0' ) + { + m_state = STATE_DISPLAYING; + } +} + +//=========================================================================== +// Protected Member Functions +//=========================================================================== diff --git a/game/code/presentation/gui/utility/teletypetext.h b/game/code/presentation/gui/utility/teletypetext.h new file mode 100644 index 0000000..ebf9eae --- /dev/null +++ b/game/code/presentation/gui/utility/teletypetext.h @@ -0,0 +1,120 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: CTeleTypeText +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/07/19 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef TELETYPETEXT_H +#define TELETYPETEXT_H + +//=========================================================================== +// Nested Includes +//=========================================================================== + +#include <p3d/p3dtypes.hpp> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Text; + class Group; +} + +const unsigned int DEFAULT_TELETYPING_RATE = 8; // in characters/sec + +//=========================================================================== +// Interface Definitions +//=========================================================================== +class CTeleTypeText +{ + public: + + CTeleTypeText( Scrooby::Text* pText, + Scrooby::Group* pTextBox = NULL, + unsigned int numCharsPerSecond = DEFAULT_TELETYPING_RATE, + unsigned int numSecondsToDisplay = 0 ); + virtual ~CTeleTypeText(); + + // update teletype text + void Update( unsigned int elapsedTime ); + + // display message and start teletyping + void DisplayMessage(); + void DisplayMessage( int index ); + + // hide message and stop teletyping if still in progress + void HideMessage(); + + // pause/resume teletyping + void Pause(); + void Resume(); + + // accessor to scrooby text object + Scrooby::Text* GetText() const + { + return m_pText; + } + + protected: + + //--------------------------------------------------------------------- + // Protected Functions + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + // Protected Data + //--------------------------------------------------------------------- + + private: + + //--------------------------------------------------------------------- + // Private Functions + //--------------------------------------------------------------------- + + // No copying or asignment. Declare but don't define. + // + CTeleTypeText( const CTeleTypeText& ); + CTeleTypeText& operator= ( const CTeleTypeText& ); + + void TypeNextCharacter(); + + //--------------------------------------------------------------------- + // Private Data + //--------------------------------------------------------------------- + + enum eTeletypeState + { + STATE_TELETYPING, + STATE_DISPLAYING, + STATE_PAUSED, + + STATE_INACTIVE + }; + + eTeletypeState m_state; + + unsigned int m_elapsedTime; + unsigned int m_teletypePeriod; + unsigned int m_displayDuration; + + Scrooby::Text* m_pText; + Scrooby::Group* m_pTextBox; + P3D_UNICODE* m_charBuffer; + P3D_UNICODE m_nextChar; + int m_currentCharIndex; + +}; + +#endif // TELETYPETEXT_H diff --git a/game/code/presentation/gui/utility/transitions.cpp b/game/code/presentation/gui/utility/transitions.cpp new file mode 100644 index 0000000..aba8d4b --- /dev/null +++ b/game/code/presentation/gui/utility/transitions.cpp @@ -0,0 +1,2911 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: Transitions.cpp +// +// Description: Some transitions for the hud/frontned +// +// Authors: Ian Gipson +// +// +//=========================================================================== + +//=========================================================================== +// Includes +//=========================================================================== +#include <boundeddrawable.h> +#include <contexts/gameplay/gameplaycontext.h> +#include <events/eventmanager.h> +#include <input/inputmanager.h> +#include <memory/classsizetracker.h> +#include <p3d/anim/multicontroller.hpp> +#include <p3d/utility.hpp> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guiwindow.h> +#include <presentation/gui/utility/colourutility.h> +#include <presentation/gui/utility/transitions.h> +#include <radmath/trig.hpp> +#include <sprite.h> + +//=========================================================================== +// Global Data, Local Data, Local Classes +//=========================================================================== +#define WIDESCREEN_EXTRA_PIXELS 107 +//=========================================================================== +// Public Member Functions +//=========================================================================== + +namespace GuiSFX +{ + +#ifdef DEBUGWATCH + void ActivateCallback( void* userData ) + { + Transition* transition = reinterpret_cast< Transition* >( userData ); + Chainable* chainable = dynamic_cast< Chainable* >( transition ); + if( chainable != NULL ) + { + chainable->ResetChain(); + chainable->Activate(); + } + else + { + transition->Reset(); + transition->Activate(); + } + } + + void DeativateCallback( void* userData ) + { + Transition* transition = reinterpret_cast< Transition* >( userData ); + transition->Deactivate(); + } + +#endif + +//============================================================================== +// Chainable::Chainable +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Chainable::Chainable() +{ +} + +//============================================================================== +// Chainable::Chainable +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the transition. +// +// Return: N/A. +// +//============================================================================== +Chainable::Chainable( const tName& name ): + Transition( name ) +{ + //CLASSTRACKER_CREATE( Chainable ); +} + + +//============================================================================== +// Chainable1::Chainable1 +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Chainable1::Chainable1(): + m_NextTransition( NULL ) +{ + //nothing +} + +//============================================================================== +// Chainable1::Chainable1 +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object +// +// Return: N/A. +// +//============================================================================== +Chainable1::Chainable1( const tName& name ) + : Chainable( name ) +{ + //nothing +} + +//============================================================================== +// Chainable1::ContinueChain +//============================================================================== +// Description: moves on to the next transition in the chain +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +void Chainable1::ContinueChain() +{ + Deactivate(); + if( m_NextTransition != NULL ) + { + m_NextTransition->Activate(); + } +} + +//============================================================================== +// Chainable1::DeactivateChain +//============================================================================== +// Description: shuts down the entire chain +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +void Chainable1::DeactivateChain() +{ + Deactivate(); + if( m_NextTransition != NULL ) + { + m_NextTransition->DeactivateChain(); + } +} + +//============================================================================== +// Chainable1::IsChainDone +//============================================================================== +// Description: determines if the entire chain of transitions is done +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +bool Chainable1::IsChainDone() const +{ + if( !IsDone() ) + { + return false; + } + + // + // Yay recursion! + // + if( m_NextTransition != NULL ) + { + return m_NextTransition->IsChainDone(); + } + return true; +} + +//============================================================================== +// Chainable1::operator= +//============================================================================== +// Description: assignment operator +// +// Parameters: right - the one we're assigning from +// +// Return: reference to self +// +//============================================================================== +Chainable1& Chainable1::operator=( const Chainable1& right ) +{ + if( this == &right ) + { + return *this; + } + Transition::operator=( right ); + m_NextTransition = right.m_NextTransition; + return *this; +} + +//============================================================================== +// Chainable1::ResetChain +//============================================================================== +// Description: resets the transition, and all subsequent transitions +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void Chainable1::ResetChain() +{ + Reset(); + if( m_NextTransition != NULL ) + { + return m_NextTransition->ResetChain(); + } + +} + +//============================================================================== +// Chainable1::SetNextTransition +//============================================================================== +// Description: sets the next transition in the chain +// +// Parameters: transition - the next transition to use +// +// Return: N/A. +// +//============================================================================== +void Chainable1::SetNextTransition( Chainable* transition ) +{ + m_NextTransition = transition; +} + +//============================================================================== +// Chainable1::SetNextTransition +//============================================================================== +// Description: sets the next transition in the chain +// +// Parameters: transition - the next transition to use +// +// Return: N/A. +// +//============================================================================== +void Chainable1::SetNextTransition( Chainable& transition ) +{ + m_NextTransition = &transition; +} + +//============================================================================== +// Chainable2::Chainable2() +//============================================================================== +// Description: consturctor +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +Chainable2::Chainable2() +{ + m_NextTransition[ 0 ] = NULL; + m_NextTransition[ 1 ] = NULL; +} + +//============================================================================== +// Chainable2::Chainable2() +//============================================================================== +// Description: consturctor +// +// Parameters: name - the name of the transition +// +// Return: N/A. +// +//============================================================================== +Chainable2::Chainable2( const tName& name ): + Chainable( name ) +{ + m_NextTransition[ 0 ] = NULL; + m_NextTransition[ 1 ] = NULL; +} + +//============================================================================== +// Chainable2::ContinueChain() +//============================================================================== +// Description: continues the chain of transitions +// +// Parameters: name - the name of the transition +// +// Return: N/A. +// +//============================================================================== +void Chainable2::ContinueChain() +{ + Deactivate(); + int i; + for( i = 0; i < 2; ++i ) + { + if( m_NextTransition[ i ] != NULL ) + { + m_NextTransition[ i ]->Activate(); + } + } +} + +//============================================================================== +// Chainable2::DeactivateChain() +//============================================================================== +// Description: shuts down the entire chain +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +void Chainable2::DeactivateChain() +{ + Deactivate(); + int i; + for( i = 0; i < 2; ++i ) + { + if( m_NextTransition[ i ] != NULL ) + { + m_NextTransition[ i ]->DeactivateChain(); + } + } +} + +//============================================================================== +// Chainable2::IsChainDone +//============================================================================== +// Description: determines if the entire chain of transitions is done +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +bool Chainable2::IsChainDone() const +{ + if( !IsDone() ) + { + return false; + } + + // + // Yay recursion! + // + int i; + for( i = 0; i < 2; ++i ) + { + if( m_NextTransition[ i ] != NULL ) + { + bool nextDone = m_NextTransition[ i ]->IsChainDone(); + if( !nextDone ) + { + return false; + } + } + } + return true; +} + +//============================================================================== +// Chainable2::ResetChain +//============================================================================== +// Description: resets the transition, and all subsequent transitions +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void Chainable2::ResetChain() +{ + Reset(); + if( m_NextTransition[ 0 ] != NULL ) + { + m_NextTransition[ 0 ]->ResetChain(); + } + + if( m_NextTransition[ 1 ] != NULL ) + { + m_NextTransition[ 1 ]->ResetChain(); + } +} + +//============================================================================== +// Chainable2::SetNextTransition +//============================================================================== +// Description: sets one of the next transitions triggered by this one +// +// Parameters: index - which one of the next transitions to set +// transition - pointer to the transition +// +// Return: N/A. +// +//============================================================================== +void Chainable2::SetNextTransition( const unsigned int index, Chainable* transition ) +{ + rAssert( index < 2 ); + m_NextTransition[ index ] = transition; +} + +//============================================================================== +// Chainable2::SetNextTransition +//============================================================================== +// Description: sets one of the next transitions triggered by this one +// +// Parameters: index - which one of the next transitions to set +// transition - pointer to the transition +// +// Return: N/A. +// +//============================================================================== +void Chainable2::SetNextTransition( const unsigned int index, Chainable& transition ) +{ + SetNextTransition( index, &transition ); +} + +//============================================================================== +// Chainable3::Chainable3() +//============================================================================== +// Description: consturctor +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +Chainable3::Chainable3() +{ + m_NextTransition[ 0 ] = NULL; + m_NextTransition[ 1 ] = NULL; + m_NextTransition[ 2 ] = NULL; +} + +//============================================================================== +// Chainable3::Chainable3() +//============================================================================== +// Description: consturctor +// +// Parameters: name - the name of the transition +// +// Return: N/A. +// +//============================================================================== +Chainable3::Chainable3( const tName& name ): + Chainable( name ) +{ + m_NextTransition[ 0 ] = NULL; + m_NextTransition[ 1 ] = NULL; + m_NextTransition[ 2 ] = NULL; +} + +//============================================================================== +// Chainable3::ContinueChain() +//============================================================================== +// Description: continues the chain of transitions +// +// Parameters: name - the name of the transition +// +// Return: N/A. +// +//============================================================================== +void Chainable3::ContinueChain() +{ + Deactivate(); + int i; + for( i = 0; i < 3; ++i ) + { + if( m_NextTransition[ i ] != NULL ) + { + m_NextTransition[ i ]->Activate(); + } + } +} + +//============================================================================== +// Chainable3::DeactivateChain() +//============================================================================== +// Description: shuts down the entire chain +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +void Chainable3::DeactivateChain() +{ + Deactivate(); + int i; + for( i = 0; i < 3; ++i ) + { + if( m_NextTransition[ i ] != NULL ) + { + m_NextTransition[ i ]->DeactivateChain(); + } + } +} + + +//============================================================================== +// Chainable3::IsChainDone +//============================================================================== +// Description: determines if the entire chain of transitions is done +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +bool Chainable3::IsChainDone() const +{ + if( !IsDone() ) + { + return false; + } + + // + // Yay recursion! + // + int i; + for( i = 0; i < 3; ++i ) + { + if( m_NextTransition[ i ] != NULL ) + { + bool nextDone = m_NextTransition[ i ]->IsChainDone(); + if( !nextDone ) + { + return false; + } + } + } + return true; +} + +//============================================================================== +// Chainable3::ResetChain +//============================================================================== +// Description: resets the transition, and all subsequent transitions +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void Chainable3::ResetChain() +{ + Reset(); + if( m_NextTransition[ 0 ] != NULL ) + { + m_NextTransition[ 0 ]->ResetChain(); + } + + if( m_NextTransition[ 1 ] != NULL ) + { + m_NextTransition[ 1 ]->ResetChain(); + } + + if( m_NextTransition[ 2 ] != NULL ) + { + m_NextTransition[ 2 ]->ResetChain(); + } +} + +//============================================================================== +// Chainable3::SetNextTransition +//============================================================================== +// Description: sets one of the next transitions triggered by this one +// +// Parameters: index - which one of the next transitions to set +// transition - pointer to the transition +// +// Return: N/A. +// +//============================================================================== +void Chainable3::SetNextTransition( const unsigned int index, Chainable* transition ) +{ + rAssert( index < 3 ); + m_NextTransition[ index ] = transition; +} + +//============================================================================== +// Chainable3::SetNextTransition +//============================================================================== +// Description: sets one of the next transitions triggered by this one +// +// Parameters: index - which one of the next transitions to set +// transition - pointer to the transition +// +// Return: N/A. +// +//============================================================================== +void Chainable3::SetNextTransition( const unsigned int index, Chainable& transition ) +{ + SetNextTransition( index, &transition ); +} + +//============================================================================== +// ColorChange::ColorChange +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +ColorChange::ColorChange() +{ +} + +//============================================================================== +// ColorChange::ColorChange +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object +// +// Return: N/A. +// +//============================================================================== +ColorChange::ColorChange( const tName& name ): + Chainable1( name ) +{ +} + +//============================================================================== +// ColorChange::SetStartColour +//============================================================================== +// Description: sets the starting color for the color transition +// +// Parameters: transition - the next transition to use +// +// Return: N/A. +// +//============================================================================== +void ColorChange::SetStartColour( const tColour c ) +{ + m_StartColor = c; +} + +//============================================================================== +// ColorChange::SetEndColour +//============================================================================== +// Description: sets the end color for the transition +// +// Parameters: transition - the next transition to use +// +// Return: N/A. +// +//============================================================================== +void ColorChange::SetEndColour( const tColour c ) +{ + m_EndColor = c; +} + +//============================================================================== +// ColorChange::Update +//============================================================================== +// Description: updates the color change transition +// +// Parameters: transition - the next transition to use +// +// Return: N/A. +// +//============================================================================== +void ColorChange::Update( const float deltaT ) +{ + if( this->IsActive() ) + { + Transition::Update( deltaT ); + float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f ); + m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval ); + + float percent = m_ElapsedTime / m_TimeInterval; + tColour color = m_StartColor * ( 1.0f - percent ) + m_EndColor * percent; + if( m_Drawable != NULL ) + { + m_Drawable->SetColour( color ); + } + + if( spillover > 0 ) + { + ContinueChain(); + } + } +} + +//============================================================================== +// ColorChange::Watch +//============================================================================== +// Description: Adds this transition to the watcher +// +// Parameters: nameSpace - the name of the group in the watcher +// +// Return: N/A. +// +//============================================================================== +#ifdef DEBUGWATCH +void ColorChange::Watch( const char* nameSpace ) +{ + char output[ 1024 ]; + sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() ); + Parent1::Watch( output ); + Parent2::Watch( output ); +} +#endif + +//============================================================================== +// Dummy::Dummy +//============================================================================== +// Description: Constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +Dummy::Dummy() +{ +} + +//============================================================================== +// Dummy::Dummy +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +Dummy::Dummy( const tName& name ): + Parent( name ) +{ +} + +//============================================================================== +// Dummy::Activate +//============================================================================== +// Description: does nothing, and carrys on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void Dummy::Activate() +{ + Parent::Activate(); + ContinueChain(); +} + +//============================================================================= +// GotoScreen::GotoScreen() +//============================================================================= +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +GotoScreen::GotoScreen(): + mScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ), + mParam1( 0 ), + mParam2( 0 ), + mWindowOptions( 0 ) +{ + //nothing +} + +//============================================================================= +// GotoScreen::GotoScreen() +//============================================================================= +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +GotoScreen::GotoScreen( const tName& name ): + Parent( name ), + mScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ), + mParam1( 0 ), + mParam2( 0 ), + mWindowOptions( 0 ) +{ + //nothing +} + +//============================================================================= +// SendEvent::Activate() +//============================================================================= +// Description: fires off the event that we're supposed to send at this point +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void GotoScreen::Activate() +{ + Transition::Activate(); + rAssert( mScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ); + GetGuiSystem()->GotoScreen( mScreen, mParam1, mParam2, mWindowOptions ); + ContinueChain(); +} + +//============================================================================= +// SendEvent::SetEventData +//============================================================================= +// Description: sets the event data that we're going to fire off later on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void GotoScreen::SetEventData( void* eventData ) +{ + mEventData = eventData; +} + +//============================================================================= +// GotoScreen::SetParam1 +//============================================================================= +// Description: sets the event data that we're going to fire off later on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void GotoScreen::SetParam1( const unsigned int param1 ) +{ + mParam1 = param1; +} + +//============================================================================= +// GotoScreen::SetParam2 +//============================================================================= +// Description: sets the event data that we're going to fire off later on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void GotoScreen::SetParam2( const unsigned int param2 ) +{ + mParam2 = param2; +} + +//============================================================================= +// SendEvent::SetEvent +//============================================================================= +// Description: sets the event that we're going to fire off later on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void GotoScreen::SetScreen( CGuiWindow::eGuiWindowID screen ) +{ + mScreen = screen; +} + +//============================================================================= +// GotoScreen::SetWindowOptions +//============================================================================= +// Description: sets the event data that we're going to fire off later on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void GotoScreen::SetWindowOptions( const unsigned int windowOptions ) +{ + mWindowOptions = windowOptions; +} + +//============================================================================== +// HasMulticontroller::ResetMultiControllerFrames +//============================================================================== +// Description: sometimes you screw up the nubmer of frames in a multicontoller +// calling this function will fix things +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void HasMulticontroller::ResetMultiControllerFrames() +{ + m_MultiController->SetFrameRange( 0.0f, m_NumFrames ); +} + +//============================================================================== +// HasMulticontroller::SetMultiController +//============================================================================== +// Description: sets up the multicontroller that this transition requires +// +// Parameters: multicontroller - the multicontroller to use +// +// Return: N/A. +// +//============================================================================== +void HasMulticontroller::SetMultiController( tMultiController* multicontroller ) +{ + m_MultiController = multicontroller; + m_NumFrames = m_MultiController->GetNumFrames(); +} + +//============================================================================== +// HasTimeInterval::HasTimeInterval +//============================================================================== +// Description: constructor +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +HasTimeInterval::HasTimeInterval(): + m_TimeInterval( 1000.0f ) +{ + //nothing +} + +//============================================================================== +// HasTimeInterval::SetTimeInterval +//============================================================================== +// Description: sets the time interval that this transition should wait +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void HasTimeInterval::SetTimeInterval( const float interval ) +{ + m_TimeInterval = interval; +} + +//============================================================================== +// HasTimeInterval::Watch +//============================================================================== +// Description: Adds this transition to the watcher +// +// Parameters: nameSpace - the name of the group in the watcher +// +// Return: N/A. +// +//============================================================================== +#ifdef DEBUGWATCH +void HasTimeInterval::Watch( const char* nameSpace ) +{ + radDbgWatchDelete( &m_TimeInterval ); + radDbgWatchAddFloat( &m_TimeInterval, "timeInterval", nameSpace, NULL, NULL, 0.0f, 1000.0f ); +} +#endif + +//============================================================================== +// Hide::Hide +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +Hide::Hide() +{ + //nothing +} + +//============================================================================== +// Hide::Hide +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object +// +// Return: N/A. +// +//============================================================================== +Hide::Hide( const tName& name ): + Chainable1( name ) +{ +} + +//============================================================================== +// Hide::Activate +//============================================================================== +// Description: this gets called when a hide transition is triggered +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void Hide::Activate() +{ + Transition::Activate(); + rAssert( m_Drawable != NULL ); + if( m_Drawable != NULL ) + { + m_Drawable->SetVisible( false ); + } + ContinueChain(); +} + +//============================================================================== +// ImageCycler::SetDrawable +//============================================================================== +// Description: set the period for cycling images +// +// Parameters: period - float period in ms +// +// Return: N/A. +// +//============================================================================== +void ImageCycler::SetDrawable( Scrooby::Drawable* drawable ) +{ + Transition::SetDrawable( drawable ); + m_Sprite = dynamic_cast< Scrooby::Sprite* >( m_Drawable ); + rAssert( m_Sprite != NULL ); +} + +//============================================================================== +// ImageCycler::SetDrawable +//============================================================================== +// Description: set the period for cycling images +// +// Parameters: period - float period in ms +// +// Return: N/A. +// +//============================================================================== +void ImageCycler::SetDrawable( Scrooby::Drawable& drawable ) +{ + Transition::SetDrawable( drawable ); + m_Sprite = dynamic_cast< Scrooby::Sprite* >( m_Drawable ); + rAssert( m_Sprite != NULL ); +} + +//============================================================================== +// InputStateChange::InputStateChange +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +InputStateChange::InputStateChange(): + Parent(), + mState( Input::ACTIVE_NONE ) +{ + //nothing +} + +//============================================================================== +// InputStateChange::InputStateChange +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +InputStateChange::InputStateChange( const tName& name ): + Parent( name ), + mState( Input::ACTIVE_NONE ) +{ + //nothing +} + +//============================================================================== +// InputStateChange::Activate +//============================================================================== +// Description: called when this transition is activated +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void InputStateChange::Activate() +{ + Parent::Activate(); + InputManager::GetInstance()->SetGameState( mState ); + ContinueChain(); +} + +//============================================================================== +// InputStateChange::SetState +//============================================================================== +// Description: set the state that this transition will take the input to +// +// Parameters: state - what input state should we go to? +// +// Return: N/A. +// +//============================================================================== +void InputStateChange::SetState( const Input::ActiveState state ) +{ + mState = state; +} + +//============================================================================== +// IrisWipeClose::IrisWipeClose +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +IrisWipeClose::IrisWipeClose() +{ + //none +} + +//============================================================================== +// IrisWipeClose::IrisWipeClose +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object for debugging +// +// Return: N/A. +// +//============================================================================== +IrisWipeClose::IrisWipeClose( const tName& name ): + Chainable1( name ) +{ + //none +} + +//============================================================================== +// IrisWipeClose::Activate +//============================================================================== +// Description: starts the iris wipe transition +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void IrisWipeClose::Activate() +{ + m_MultiController->Reset(); + m_MultiController->SetFrameRange( 0, m_NumFrames * 0.5f ); + m_MultiController->SetFrame( 0 ); + Chainable1::Activate(); +} + +void IrisWipeClose::Deactivate() +{ + Chainable1::Deactivate(); +} + +//============================================================================== +// IrisWipeOpen::Update +//============================================================================== +// Description: needed to check if the irisWipeTransition can move on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void IrisWipeClose::Update( const float deltaT ) +{ + if( IsActive() ) + { + Chainable1::Update( deltaT ); + if( m_MultiController != NULL ) + { + if( m_MultiController->LastFrameReached() ) + { + m_MultiController->SetFrameRange( 0.0f, m_NumFrames ); + ResetMultiControllerFrames(); + ContinueChain(); + } + } + } +} + +//============================================================================== +// IrisWipeOpen::IrisWipeOpen +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +IrisWipeOpen::IrisWipeOpen() +{ + //none +} + +//============================================================================== +// IrisWipeOpen::IrisWipeOpen +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object for debugging +// +// Return: N/A. +// +//============================================================================== +IrisWipeOpen::IrisWipeOpen( const tName& name ): + Chainable1( name ) +{ + //none +} + +//============================================================================== +// IrisWipeOpen::Activate +//============================================================================== +// Description: starts the iris wipe transition +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void IrisWipeOpen::Activate() +{ + tMultiController* multiController = p3d::find< tMultiController >( "IrisController" ); + rAssert( m_MultiController != NULL ); + SetMultiController( multiController ); + + m_MultiController->Reset(); + m_MultiController->SetFrameRange( m_NumFrames * 0.5f, m_NumFrames ); + m_MultiController->SetFrame( m_NumFrames * 0.5f ); + Chainable1::Activate(); +} + +//============================================================================== +// IrisWipeOpen::Update +//============================================================================== +// Description: needed to check if the irisWipeTransition can move on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void IrisWipeOpen::Update( const float deltaT ) +{ + if( IsActive() ) + { + if( m_MultiController->LastFrameReached() ) + { + m_MultiController->SetFrameRange( 0.0f, m_NumFrames ); + ResetMultiControllerFrames(); + ContinueChain(); + } + } +} + +//============================================================================== +// ImageCycler::SetPeriod +//============================================================================== +// Description: set the period for cycling images +// +// Parameters: period - float period in ms +// +// Return: N/A. +// +//============================================================================== +void ImageCycler::SetPeriod( const float period ) +{ + m_Period = period; +} + +//============================================================================== +// ImageCycler::Update +//============================================================================== +// Description: updates the transition animation +// +// Parameters: deltaT - the time elapsed +// +// Return: N/A. +// +//============================================================================== +void ImageCycler::Update( const float deltaT ) +{ + if( IsActive() ) + { + Transition::Update( deltaT ); + if( m_Sprite != NULL ) + { + int nubmerOfStates = m_Sprite->GetNumOfImages(); + int periodsElapsed = static_cast< int >( m_ElapsedTime / m_Period ); + int imageNumber = periodsElapsed % nubmerOfStates; + m_Sprite->SetIndex( imageNumber ); + } + } +} + +//============================================================================== +// Junction2::Activate() +//============================================================================== +// Description: activates all the transitions leaving this junction +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void Junction2::Activate() +{ + ContinueChain(); +} + +//============================================================================== +// Junction3::Activate() +//============================================================================== +// Description: activates all the transitions leaving this junction +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void Junction3::Activate() +{ + ContinueChain(); +} + +//============================================================================== +// Pause::Pause +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Pause::Pause() +{ + //nothing +} + +//============================================================================== +// Pause::Pause +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object +// +// Return: N/A. +// +//============================================================================== +Pause::Pause( const tName& name ): + Chainable1( name ) +{ +} + +//============================================================================== +// Pause::Update +//============================================================================== +// Description: Updates the transition +// +// Parameters: elapsed time - how much time has passed +// +// Return: N/A. +// +//============================================================================== +void Pause::Update( const float deltaT ) +{ + if( IsActive() ) + { + Transition::Update( deltaT ); + float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f ); + m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval ); + if( spillover > 0 ) + { + ContinueChain(); + } + } +} + +//============================================================================= +// Pause::Watch +//============================================================================= +// Description: adds the pause transition object to the watcher +// +// Parameters: deleaT - how much time has passed +// +// Return: N/A. +// +//============================================================================= +#ifdef DEBUGWATCH +void Pause::Watch( const char* nameSpace ) +{ + char output[ 1024 ]; + sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() ); + Parent1::Watch( output ); + Parent2::Watch( output ); +} +#endif + +//============================================================================== +// PauseInFrames::PauseInFrames +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PauseInFrames::PauseInFrames(): + m_FramesToPause( 1 ), + m_FramesElapsed( 0 ) +{ + //nothing +} + +//============================================================================== +// Pause::Pause +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object +// +// Return: N/A. +// +//============================================================================== +PauseInFrames::PauseInFrames( const tName& name ): + Parent( name ), + m_FramesToPause( 1 ), + m_FramesElapsed( 0 ) +{ + //nothing +} + +//============================================================================== +// PauseInFrames::Reset +//============================================================================== +// Description: Resets the transition +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void PauseInFrames::Reset() +{ + Parent::Reset(); + m_FramesElapsed = 0; +} + +//============================================================================== +// PauseInFrames::SetNumberOfFrames +//============================================================================== +// Description: How many frames should this transition pause for? +// +// Parameters: i - thenubmer of fraems to pause +// +// Return: N/A. +// +//============================================================================== +void PauseInFrames::SetNumberOfFrames( const unsigned int i ) +{ + m_FramesToPause = i; +} + +//============================================================================== +// PauseInFrames::Update +//============================================================================== +// Description: Updates the transition +// +// Parameters: elapsed time - how much time has passed +// +// Return: N/A. +// +//============================================================================== +void PauseInFrames::Update( const float deltaT ) +{ + if( IsActive() ) + { + Parent::Update( deltaT ); + + if( deltaT > 0.0f ) + { + ++m_FramesElapsed; + } + + if( m_FramesElapsed == m_FramesToPause ) + { + ContinueChain(); + } + } +} + +//============================================================================== +// PauseGame::Activate +//============================================================================== +// Description: transition that pauses the game +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void PauseGame::Activate() +{ + GameplayContext::GetInstance()->PauseAllButPresentation( true ); + ContinueChain(); +} + +//============================================================================== +// PulseScale::PulseScale +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +PulseScale::PulseScale(): + Transition(), + m_BoundedDrawable( NULL ), + m_Amplitude( 0.25f ), + m_Frequency( 5.0f ) +{ +} + +//============================================================================== +// PulseScale::PulseScale +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +PulseScale::PulseScale( const tName& name ): + Transition( name ), + m_BoundedDrawable( NULL ), + m_Amplitude( 0.25f ), + m_Frequency( 5.0f ) +{ +} + +//============================================================================== +// PulseScale::MovesDrawable +//============================================================================== +// Description: does this transition move a drawable object? +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +bool PulseScale::MovesDrawable() const +{ + return true; +} + +//============================================================================== +// PulseScale::SetAmplitude +//============================================================================== +// Description: sets the amplitude of the pulsing +// +// Parameters: amplitude - the size of the pulsing +// +// Return: N/A. +// +//============================================================================== +void PulseScale::SetAmplitude( const float amplitude ) +{ + m_Amplitude = amplitude; +} + +//============================================================================== +// PulseScale::SetDrawable +//============================================================================== +// Description: sets the drawable that we'll be pulsing +// +// Parameters: drawable +// +// Return: N/A. +// +//============================================================================== +void PulseScale::SetDrawable( Scrooby::Drawable& drawable ) +{ + Transition::SetDrawable( drawable ); + m_BoundedDrawable = dynamic_cast< Scrooby::BoundedDrawable* >( m_Drawable ); + rAssert( m_BoundedDrawable != NULL ); +} + +//============================================================================== +// PulseScale::SetDrawable +//============================================================================== +// Description: sets the drawable that we'll be pulsing +// +// Parameters: drawable +// +// Return: N/A. +// +//============================================================================== +void PulseScale::SetDrawable( Scrooby::Drawable* drawable ) +{ + Transition::SetDrawable( drawable ); + m_BoundedDrawable = dynamic_cast< Scrooby::HasBoundingBox* >( m_Drawable ); + rAssert( m_BoundedDrawable != NULL ); +} + +//============================================================================== +// Pulse::SetFrequency +//============================================================================== +// Description: sets the frequency of the pulse effect (in Hz) +// +// Parameters: frequency - the frequency +// +// Return: N/A. +// +//============================================================================== +void PulseScale::SetFrequency( const float frequency ) +{ + m_Frequency = frequency; +} + +//============================================================================= +// Pulse::Update +//============================================================================= +// Description: causes the bitmap to pulse +// +// Parameters: deleaT - how much time has passed +// +// Return: N/A. +// +//============================================================================= +void PulseScale::Update( const float deltaT ) +{ + if( IsActive() ) + { + Transition::Update( deltaT ); + float period = 1000.0f / m_Frequency; + m_ElapsedTime = fmodf( m_ElapsedTime, period ); + float sin = rmt::Sin( m_ElapsedTime * m_Frequency / 1000.0f * rmt::PI * 2 ); + float scale = sin * m_Amplitude + 1.0f; + m_BoundedDrawable->ScaleAboutCenter( scale ); + } +} + +//============================================================================= +// PulseScale::Watch +//============================================================================= +// Description: adds the pulse transition object to the watcher +// +// Parameters: deleaT - how much time has passed +// +// Return: N/A. +// +//============================================================================= +#ifdef DEBUGWATCH +void PulseScale::Watch( const char* nameSpace ) +{ + Parent::Watch( nameSpace ); + char output[ 1024 ]; + sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() ); + radDbgWatchDelete( &m_Amplitude ); + radDbgWatchDelete( &m_Frequency ); + radDbgWatchAddFloat( &m_Amplitude, "Amplitude", output, NULL, NULL, 0.0f, 1.0f ); + radDbgWatchAddFloat( &m_Frequency, "Frequency", output, NULL, NULL, 0.0f, rmt::PI * 4 ); +} +#endif + + +//============================================================================== +// RecieveEvent::RecieveEvent +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +RecieveEvent::RecieveEvent(): + Chainable1(), + mEvent( NUM_EVENTS ) +{ + //nothing +} + +//============================================================================= +// RecieveEvent::RecieveEvent +//============================================================================= +// Description: constructor +// +// Parameters: name - the name of the object +// +// Return: N/A. +// +//============================================================================= +RecieveEvent::RecieveEvent( const tName& name ): + Chainable1( name ), + mEvent( NUM_EVENTS ) +{ + //nothing +} + +//============================================================================= +// RecieveEvent::Activate +//============================================================================= +// Description: activate makes the object start listening for it's event +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void RecieveEvent::Activate() +{ + rAssertMsg( mEvent != NUM_EVENTS, "you need to set the event to something meaningful before this can be activated" ); + GetEventManager()->AddListener( this, mEvent ); +} + +//============================================================================= +// RecieveEvent::HandleEvent +//============================================================================= +// Description: we've got the message we were listenting for if we get this +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void RecieveEvent::HandleEvent( EventEnum id, void* pEventData ) +{ + GetEventManager()->RemoveListener( this, mEvent ); + ContinueChain(); +} + +//============================================================================= +// RecieveEvent::SetEvent +//============================================================================= +// Description: specify which event we should be listenting for +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void RecieveEvent::SetEvent( const EventEnum event ) +{ + mEvent = event; + //IAN: better ensure that this listener isn't active at the moment +} + +//============================================================================== +// ResumeGame::Activate +//============================================================================== +// Description: transition that resumes a paused game the game +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +ResumeGame::ResumeGame(): + Chainable1() +{ + //nothing +} + +//============================================================================== +// ResumeGame::Activate +//============================================================================== +// Description: transition that resumes a paused game the game +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +ResumeGame::ResumeGame( const tName& name ): + Chainable1( name ) +{ + //nothing +} + +//============================================================================== +// ResumeGame::Activate +//============================================================================== +// Description: transition that resumes a paused game the game +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +void ResumeGame::Activate() +{ + GameplayContext::GetInstance()->PauseAllButPresentation( false ); + ContinueChain(); +} + +//============================================================================= +// SendEvent::SendEvent() +//============================================================================= +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +SendEvent::SendEvent(): + mEvent( NUM_EVENTS ) +{ + //nothing +} + +//============================================================================= +// SendEvent::SendEvent() +//============================================================================= +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +SendEvent::SendEvent( const tName& name ): + Chainable1( name ), + mEvent( NUM_EVENTS ) +{ + //nothing +} + +//============================================================================= +// SendEvent::Activate() +//============================================================================= +// Description: fires off the event that we're supposed to send at this point +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void SendEvent::Activate() +{ + Transition::Activate(); + rAssert( mEvent != NUM_EVENTS ); + GetEventManager()->TriggerEvent( mEvent, mEventData ); + ContinueChain(); +} + +//============================================================================= +// SendEvent::SetEvent +//============================================================================= +// Description: sets the event that we're going to fire off later on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void SendEvent::SetEvent( EventEnum event ) +{ + mEvent = event; +} + +//============================================================================= +// SendEvent::SetEventData +//============================================================================= +// Description: sets the event data that we're going to fire off later on +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void SendEvent::SetEventData( void* eventData ) +{ + mEventData = eventData; +} + +//============================================================================= +// SwitchContext::SwitchContext() +//============================================================================= +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +SwitchContext::SwitchContext(): + mContext( NUM_CONTEXTS ) +{ + //nothing +} + +//============================================================================= +// SwitchContext::SwitchContext() +//============================================================================= +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +SwitchContext::SwitchContext( const tName& name ): + Parent( name ), + mContext( NUM_CONTEXTS ) +{ + //nothing +} + +//============================================================================= +// SwitchContext::Activate() +//============================================================================= +// Description: changes to the context that we want +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void SwitchContext::Activate() +{ + Transition::Activate(); + rAssert( mContext != NUM_CONTEXTS ); + GetGameFlow()->SetContext( mContext ); + ContinueChain(); +} + +//============================================================================= +// SwitchContext::SetContext +//============================================================================= +// Description: sets the context to which we will be going +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================= +void SwitchContext::SetContext( ContextEnum context ) +{ + mContext = context; +} + +//============================================================================== +// Show::Show +//============================================================================== +// Description: constructor +// +// Parameters: NONE +// +// Return: N/A. +// +//============================================================================== +Show::Show() +{ +} +//============================================================================== +// Show::Show +//============================================================================== +// Description: constructor +// +// Parameters: name - the name of the object +// +// Return: N/A. +// +//============================================================================== +Show::Show( const tName& name ): + Chainable1( name ) +{ + //nothing +} + +//============================================================================== +// Show::Activate +//============================================================================== +// Description: this gets called when a show transition is triggered +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void Show::Activate() +{ + Transition::Activate(); + rAssert( m_Drawable != NULL ); + if( m_Drawable != NULL ) + { + m_Drawable->SetVisible( true ); + } + ContinueChain(); +} + + +//============================================================================== +// Spin::Spin +//============================================================================== +// Description: Constructor +// +// Parameters: none +// +// Return: N/A. +// +//============================================================================== +Spin::Spin(): + Transition( "Spin" ), + m_Period( 1.0f ) +{ + //nothing +} + +//============================================================================== +// Spin::MovesDrawable +//============================================================================== +// Description: does this transition move a drawable object? +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +bool Spin::MovesDrawable() const +{ + return true; +} + +//============================================================================== +// Spin::SetPeriod +//============================================================================== +// Description: Sets the period of the spinning object +// +// Parameters: period - float time in seconds for the period +// +// Return: N/A. +// +//============================================================================== +void Spin::SetDrawable( Scrooby::Drawable* drawable ) +{ + Transition::SetDrawable( drawable ); + m_BoundedDrawable = dynamic_cast< Scrooby::BoundedDrawable* >( drawable ); + rAssert( m_BoundedDrawable != NULL ); +} + +//============================================================================== +// Spin::SetPeriod +//============================================================================== +// Description: Sets the period of the spinning object +// +// Parameters: period - float time in seconds for the period +// +// Return: N/A. +// +//============================================================================== +void Spin::SetPeriod( const float period ) +{ + m_Period = period; +} + +//============================================================================== +// Spin::Update +//============================================================================== +// Description: Does the animation +// +// Parameters: deltaT - elapsed time +// +// Return: N/A. +// +//============================================================================== +void Spin::Update( const float deltaT ) +{ + if( IsActive() ) + { + Transition::Update( deltaT ); + m_ElapsedTime = fmodf( m_ElapsedTime, m_Period * 1000.0f ); + float angle = m_ElapsedTime / ( m_Period * 1000 ) * 360.0f; + if( m_BoundedDrawable != NULL ) + { + m_BoundedDrawable->RotateAboutCenter( angle ); + } + } +} + +//============================================================================== +// Transition::Transition +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Transition::Transition(): +#ifdef RAD_DEBUG + m_Name( "NONE" ), +#endif + m_Active( false ), + m_Done( false ), + m_Drawable( NULL ), + m_ElapsedTime( 0.0f ) +{ +#ifdef RAD_DEBUG + static int count = 0; + m_Id = count; + ++count; +#endif +} + +//============================================================================== +// Transition::Transition +//============================================================================== +// Description: constructor +// +// Parameters: name - the name to assign - only in debug builds. +// +// Return: N/A. +// +//============================================================================== +Transition::Transition( const tName& name ): + m_Active( false ), + m_Done( false ), + m_Drawable( NULL ), + m_ElapsedTime( 0.0f ) +{ +#ifdef RAD_DEBUG + m_Name = name; +#endif +} + +//============================================================================== +// Transition::Activate +//============================================================================== +// Description: activates the transition +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void Transition::Activate() +{ + #ifdef RAD_DEBUG + //rAssert( m_Name != "NONE" ); + if( m_Name.GetUID() != static_cast< tUID >( 0 ) ) + { + const char* name = m_Name.GetText(); + rDebugPrintf( "Transition Starting - %s\n", name ); + } + #endif + + m_Active = true; + m_Done = false; + Update( 0.0f ); +} + +//============================================================================== +// Transition::Deactivate +//============================================================================== +// Description: deactivates the transition +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void Transition::Deactivate() +{ + m_Active = false; + m_Done = true; +} + +//============================================================================== +// Transition::GetDrawable +//============================================================================== +// Description: returns the drawable associated with this transition +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Scrooby::Drawable* Transition::GetDrawable() +{ + return m_Drawable; +} + +//============================================================================== +// Transition::IsActive +//============================================================================== +// Description: queries whether or not the transition is active +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +bool Transition::IsActive() const +{ + return m_Active; +} + +//============================================================================== +// Transition::IsDone +//============================================================================== +// Description: queries whether or not the transition is done +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +bool Transition::IsDone() const +{ + return m_Done; +} + +//============================================================================== +// Transition::MovesDrawable +//============================================================================== +// Description: does this transition move a drawable object? +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +bool Transition::MovesDrawable() const +{ + return false; +} + +//============================================================================== +// Transition::operator= +//============================================================================== +// Description: assignment operator +// +// Parameters: right - what we're assigning +// +// Return: N/A. +// +//============================================================================== +Transition& Transition::operator=( const Transition& right ) +{ + if( this == &right) + { + return *this; + } + m_Active = right.m_Active; + m_Drawable = right.m_Drawable; + m_ElapsedTime = right.m_ElapsedTime; + return *this; +} + +//============================================================================== +// Transition::Reset +//============================================================================== +// Description: resets the transition to it's 0 time state +// +// Parameters: None +// +// Return: N/A. +// +//============================================================================== +void Transition::Reset() +{ + m_ElapsedTime = 0; + m_Done = false; +} + +//============================================================================== +// Transition::SetDrawable +//============================================================================== +// Description: sets the drawable that this transition will apply to +// +// Parameters: drawable - the drawable +// +// Return: N/A. +// +//============================================================================== +void Transition::SetDrawable( Scrooby::Drawable* drawable ) +{ + m_Drawable = drawable; +} + +//============================================================================== +// Transition::SetDrawable +//============================================================================== +// Description: sets the drawable that this transition will apply to +// +// Parameters: drawable - the drawable +// +// Return: N/A. +// +//============================================================================== +void Transition::SetDrawable( Scrooby::Drawable& drawable ) +{ + m_Drawable = &drawable; +} + +//============================================================================= +// Transition::Update +//============================================================================= +// Description: applies the transition to the front end element being modified +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================= +void Transition::Update( const float elapsedTime ) +{ + if( !IsActive() ) + { + return; + } + + //rDebugPrintf( "%s\n", m_Name.GetText() ); + + m_ElapsedTime += elapsedTime; +} + +//============================================================================= +// Transition::Watch +//============================================================================= +// Description: adds a function to thw watcher to enable/disable this +// transition +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================= +#ifdef DEBUGWATCH +void Transition::Watch( const char* nameSpace ) +{ + char output[ 1024 ]; + sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() ); + radDbgWatchDelete( &m_DummyVariableForActivate ); + radDbgWatchDelete( &m_DummyVariableForDeactivate ); + radDbgWatchAddBoolean( &m_DummyVariableForActivate, "Activate", output, ActivateCallback, this ); + radDbgWatchAddBoolean( &m_DummyVariableForDeactivate, "Deativate", output, DeativateCallback, this ); +} +#endif + + +//============================================================================== +// Translator::Translator +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Translator::Translator(): + startX( 0 ), + startY( 0 ), + endX( 0 ), + endY( 0 ) +{ + //nothing +} + +//============================================================================== +// Translator::Translator +//============================================================================== +// Description: constructor +// +// Parameters: name - name of the object +// +// Return: N/A. +// +//============================================================================== +Translator::Translator( const tName& name ): + Chainable1( name ), + startX( 0 ), + startY( 0 ), + endX( 0 ), + endY( 0 ) +{ +} + +//============================================================================== +// Translator::~Translator +//============================================================================== +// Description: destructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Translator::~Translator() +{ + //nothing +} + +//============================================================================= +// Translator::MateCoordsEnd +//============================================================================= +// Description: match up the end coordinates of the transition with where the +// scrooby object is supposed to be +// +// Parameters: drawable - the object to match up with +// +// Return: N/A. +// +//============================================================================= +void Translator::MateCoordsEnd( const Scrooby::HasBoundingBox* drawable ) +{ + SetCoordsEnd( 0, 0 ); +} + +//============================================================================= +// Translator::MateCoordsStart +//============================================================================= +// Description: match up the start coordinates of the transition with where the +// scrooby object is supposed to be +// +// Parameters: drawable - the object to match up with +// +// Return: N/A. +// +//============================================================================= +void Translator::MateCoordsStart( const Scrooby::HasBoundingBox* drawable ) +{ + SetCoordsStart( 0, 0 ); +} + +//============================================================================== +// Translator::MovesDrawable +//============================================================================== +// Description: does this transition move a drawable object? +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +bool Translator::MovesDrawable() const +{ + return true; +} + +//============================================================================== +// Translator::operator= +//============================================================================== +// Description: assignment operator +// +// Parameters: right - what we're being assigned +// +// Return: reference to self +// +//============================================================================== +Translator& Translator::operator=( const Translator& right ) +{ + if( this == &right ) + { + return *this; + } + + Chainable1::operator=( right ); + + startX = right.startX; + startY = right.startY; + endX = right.endX; + endY = right.endY; + m_TimeInterval = right.m_TimeInterval; + return *this; +} + +//============================================================================== +// Translator::SetEndCoords +//============================================================================== +// Description: sets the ending position of the object +// +// Parameters: x, y, the coords +// +// Return: N/A. +// +//============================================================================== +void Translator::SetCoordsEnd( const int x, const int y ) +{ + endX = x; + endY = y; +} + +//============================================================================== +// Translator::SetStartCoords +//============================================================================== +// Description: sets the starting position of the object +// +// Parameters: x, y, the coords +// +// Return: N/A. +// +//============================================================================== +void Translator::SetCoordsStart( const int x, const int y ) +{ + startX = x; + startY = y; +} + +//============================================================================== +// Translator::SetEndOffscreenBottom +//============================================================================== +// Description: positions the transition to end the object offscreen to the bottom +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetEndOffscreenBottom( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + #ifdef RAD_PS2 + SetCoordsEnd( 0, -20 -yMax ); + #else + SetCoordsEnd( 0, -yMax ); + #endif +} + +//============================================================================== +// Translator::SetEndOffscreenLeft +//============================================================================== +// Description: positions the transition to end the object offscreen to the left +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetEndOffscreenLeft( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + int width = xMax - xMin; + + if( p3d::display->IsWidescreen() ) + { + SetCoordsEnd( -xMin - width - WIDESCREEN_EXTRA_PIXELS, 0 ); + } + else + { + SetCoordsEnd( -xMin - width, 0 ); + } +} +//============================================================================== +// Translator::SetEndOffscreenRight +//============================================================================== +// Description: positions the transition to end the object offscreen to the right +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetEndOffscreenRight( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + int width = xMax - xMin; + if( p3d::display->IsWidescreen() ) + { + SetCoordsEnd( 640 - xMin + WIDESCREEN_EXTRA_PIXELS, 0 ); + } + else + { + SetCoordsEnd( 640 - xMin, 0 ); + } +} + +//============================================================================== +// Translator::SetEndOffscreenTop +//============================================================================== +// Description: positions the transition to end the object offscreen to the left +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetEndOffscreenTop( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + #ifdef RAD_PS2 + SetCoordsEnd( 0, 480 + 20 - yMin ); + #else + SetCoordsEnd( 0, 480 - yMin ); + #endif +} + +//============================================================================== +// Translator::SetStartOffscreenBottom +//============================================================================== +// Description: positions the transition to start the object offscreen to the bottom +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetStartOffscreenBottom ( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + + #ifdef RAD_PS2 + SetCoordsStart( 0, -20 -yMax ); + #else + SetCoordsStart( 0, -yMax ); + #endif + +} + +//============================================================================== +// Translator::SetTimeInterval +//============================================================================== +// Description: positions the transition to start the object offscreen to the left +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetStartOffscreenLeft( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + int width = xMax - xMin; + + if( p3d::display->IsWidescreen() ) + { + SetCoordsStart( -xMin - width - WIDESCREEN_EXTRA_PIXELS, 0 ); + } + else + { + SetCoordsStart( -xMin - width, 0 ); + } +} +//============================================================================== +// Translator::SetStartOffscreenRight +//============================================================================== +// Description: positions the transition to start the object offscreen to the right +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetStartOffscreenRight ( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + int width = xMax - xMin; + if( p3d::display->IsWidescreen() ) + { + SetCoordsStart( 640 - xMin + WIDESCREEN_EXTRA_PIXELS, 0 ); + } + else + { + SetCoordsStart( 640 - xMin, 0 ); + } +} + +//============================================================================== +// Translator::SetStartOffscreenTop +//============================================================================== +// Description: positions the transition to start the object offscreen to the top +// +// Parameters: drawable - the drawable to line up offscreen with +// +// Return: N/A. +// +//============================================================================== +void Translator::SetStartOffscreenTop( const Scrooby::Drawable* drawable ) +{ + int xMin; + int xMax; + int yMin; + int yMax; + drawable->GetBoundingBox( xMin, yMin, xMax, yMax ); + SetCoordsStart( 0, 480 - yMin ); + #ifdef RAD_PS2 + SetCoordsStart( 0, 480 + 20 - yMin ); + #else + SetCoordsStart( 0, 480 - yMin ); + #endif + +} + +//============================================================================== +// Translator::Apply +//============================================================================== +// Description: applies the transition to the front end element being modified +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void Translator::Update( const float deltaT ) +{ + if( IsActive() ) + { + Transition::Update( deltaT ); + float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f ); + m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval ); + + float percentDone = rmt::Min( m_ElapsedTime / m_TimeInterval, 1.0f ); + int x = static_cast< int >( ( endX - startX ) * percentDone + startX ); + int y = static_cast< int >( ( endY - startY ) * percentDone + startY ); + if( m_Drawable != NULL ) + { + m_Drawable->Translate( x, y ); + } + + if( spillover > 0 ) + { + ContinueChain(); + } + } +} + +//============================================================================== +// Translator::Watch +//============================================================================== +// Description: Adds this transition to the watcher +// +// Parameters: nameSpace - the name of the group in the watcher +// +// Return: N/A. +// +//============================================================================== +#ifdef DEBUGWATCH +void Translator::Watch( const char* nameSpace ) +{ + char output[ 1024 ]; + sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() ); + Parent1::Watch( nameSpace ); + Parent2::Watch( output ); //HasTimeInterval doesn't know the name. + radDbgWatchDelete( &startX ); + radDbgWatchDelete( &startY ); + radDbgWatchDelete( &endX ); + radDbgWatchDelete( &endY ); + radDbgWatchAddShort( &startX, "startX", output, NULL, NULL, -640, 640 * 2 ); + radDbgWatchAddShort( &startY, "startY", output, NULL, NULL, -640, 640 * 2 ); + radDbgWatchAddShort( &endX, "endX", output, NULL, NULL, -640, 640 * 2 ); + radDbgWatchAddShort( &endY, "endY", output, NULL, NULL, -640, 640 * 2 ); +} +#endif + +//============================================================================== +// UnderdampedTranslator::UnderdampedTranslator +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +UnderdampedTranslator::UnderdampedTranslator(): + Translator() +{ +} + +//============================================================================== +// UnderdampedTranslator::UnderdampedTranslator +//============================================================================== +// Description: constructor +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +UnderdampedTranslator::UnderdampedTranslator( const tName& name ): + Translator( name ) +{ +} + +//============================================================================== +// UnderdampedTranslator::MovesDrawable +//============================================================================== +// Description: does this transition move a drawable object? +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +bool UnderdampedTranslator::MovesDrawable() const +{ + return true; +} + +//============================================================================== +// UnderdampedTranslator::SetFrequency +//============================================================================== +// Description: sets the frequency of oscillation of the underdamped translator +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void UnderdampedTranslator::SetFrequency( const float frequency ) +{ + m_Frequency = frequency; +} + +//============================================================================== +// UnderdampedTranslator::Update +//============================================================================== +// Description: updates the object that we're translating +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +void UnderdampedTranslator::Update( const float deltaT ) +{ + if( IsActive() ) + { + Transition::Update( deltaT ); + float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f ); + m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval ); + float decayRate = logf( 0.01f ) / m_TimeInterval; + float exponentialPart = expf( decayRate * m_ElapsedTime ); + float cosinePart = cosf( 2.0f * rmt::PI * m_Frequency * m_ElapsedTime / 1000.0f ); + float percentage = 1.0f - exponentialPart * cosinePart; + int x = static_cast< int >( ( endX - startX ) * percentage + startX ); + int y = static_cast< int >( ( endY - startY ) * percentage + startY ); + m_Drawable->Translate( x, y ); + + if( spillover > 0 ) + { + ContinueChain(); + } + } +} + +}
\ No newline at end of file diff --git a/game/code/presentation/gui/utility/transitions.h b/game/code/presentation/gui/utility/transitions.h new file mode 100644 index 0000000..f00b1b9 --- /dev/null +++ b/game/code/presentation/gui/utility/transitions.h @@ -0,0 +1,592 @@ +//=========================================================================== +// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved. +// +// Component: SpecialFX +// +// Description: +// +// +// Authors: Tony Chu +// +// Revisions Date Author Revision +// 2002/08/30 TChu Created for SRR2 +// +//=========================================================================== + +#ifndef TRANSITIONS_H +#define TRANSITIONS_H + +//=========================================================================== +// Nested Includes +//=========================================================================== +#include <p3d/entity.hpp> +#include "events/eventenum.h" +#include "events/eventlistener.h" +#include <input/controller.h> +#include <gameflow/gameflow.h> +#include <presentation/gui/guiwindow.h> + +//=========================================================================== +// Forward References +//=========================================================================== + +namespace Scrooby +{ + class Drawable; + class BoundedDrawable; + class HasBoundingBox; + class Sprite; +} + +class tMultiController; +//=========================================================================== +// Interface Definitions +//=========================================================================== + +namespace GuiSFX +{ +#ifdef DEBUGWATCH + #define WATCH( object, nameSpace ) object.Watch( nameSpace ) +#else + #define WATCH( object, nameSpace ) +#endif + +#ifdef DEBUGWATCH + void ActivateCallback ( void* userData ); + void DeactivateCallback( void* userData ); +#endif +//============================================================================== +// Transition +//============================================================================== +class Transition +{ +public: + Transition(); + Transition( const tName& name ); + virtual void Activate(); + virtual void Deactivate(); + Scrooby::Drawable* GetDrawable(); + bool IsActive() const; + bool IsDone() const; + virtual bool MovesDrawable() const; + Transition& operator=( const Transition& right ); + virtual void Reset(); + virtual void SetDrawable( Scrooby::Drawable* drawable ); + virtual void SetDrawable( Scrooby::Drawable& drawable ); + virtual void Update( const float deltaT ); + + #ifdef DEBUGWATCH + virtual void Watch( const char* nameSpace ); + #endif + +protected: +#ifdef DEBUGWATCH + tName m_Name; + int m_Id; + bool m_DummyVariableForActivate; + bool m_DummyVariableForDeactivate; +#endif + bool m_Active : 1; + bool m_Done : 1; + Scrooby::Drawable* m_Drawable; + float m_ElapsedTime; +}; + +//============================================================================== +// Chainable +//============================================================================== +class Chainable : public Transition +{ +public: + Chainable(); + Chainable( const tName& name ); + virtual void ContinueChain() = 0; + virtual void DeactivateChain() = 0; + virtual bool IsChainDone() const = 0; + virtual void ResetChain() = 0; +protected: +}; + +//============================================================================== +// Chainable1 - these transitions can be chained together temporally +//============================================================================== +class Chainable1 : public Chainable +{ +private: + typedef Chainable Parent; +public: + Chainable1(); + Chainable1( const tName& name ); + Chainable1& operator=( const Chainable1& right ); + virtual void ContinueChain(); + virtual void DeactivateChain(); + virtual bool IsChainDone() const; + virtual void ResetChain(); + void SetNextTransition( Chainable* transition ); + void SetNextTransition( Chainable& transition ); +protected: + Chainable* m_NextTransition; +}; + +//============================================================================== +// Chainable2 - one transition that spawns 2 others at the same time +//============================================================================== +class Chainable2 : public Chainable +{ +public: + Chainable2(); + Chainable2( const tName& name ); + virtual void ContinueChain(); + virtual void DeactivateChain(); + virtual bool IsChainDone() const; + virtual void ResetChain(); + void SetNextTransition( const unsigned int index, Chainable* transition ); + void SetNextTransition( const unsigned int index, Chainable& transition ); + +protected: + Chainable* m_NextTransition[ 2 ]; +}; + +//============================================================================== +// Chainable3 - one transition that spawns 3 others at the same time +//============================================================================== +//Ian - this should be a templatized class... +class Chainable3 : public Chainable +{ +public: + Chainable3(); + Chainable3( const tName& name ); + virtual void ContinueChain(); + virtual void DeactivateChain(); + virtual bool IsChainDone() const; + virtual void ResetChain(); + void SetNextTransition( const unsigned int index, Chainable* transition ); + void SetNextTransition( const unsigned int index, Chainable& transition ); + +protected: + Chainable* m_NextTransition[ 3 ]; +}; + +//============================================================================== +// Junction2 +//============================================================================== +class Junction2 : public Chainable2 +{ +public: + void Activate(); +protected: +}; + +//============================================================================== +// Junction3 +//============================================================================== +//IAN - this should be a templatized class too +class Junction3 : public Chainable3 +{ +public: + void Activate(); +protected: +}; + +//============================================================================== +// Dummy - this "transition" does nothing. it's a placeholder +//============================================================================== +class Dummy : public Chainable1 +{ +private: + typedef Chainable1 Parent; +public: + Dummy(); + Dummy( const tName& name ); + void Activate(); +}; + +//============================================================================== +// GotoScreen +//============================================================================== +class GotoScreen : public Chainable1 +{ +private: + typedef Chainable1 Parent; +public: + GotoScreen(); + GotoScreen( const tName& name ); + void Activate(); + void SetEventData( void* eventData ); + void SetParam1( const unsigned int param1 ); + void SetParam2( const unsigned int param2 ); + void SetScreen( CGuiWindow::eGuiWindowID screen ); + void SetWindowOptions( const unsigned int windowOptions ); + +protected: + CGuiWindow::eGuiWindowID mScreen; + unsigned int mParam1; + unsigned int mParam2; + void* mEventData; + unsigned int mWindowOptions; +}; + + +//============================================================================== +// Hide +//============================================================================== +class Hide : public Chainable1 +{ +public: + Hide(); + Hide( const tName& name ); + void Activate(); + +protected: +}; + +//============================================================================== +// InputStateChange +//============================================================================== +class InputStateChange : public Chainable1 +{ +private: + typedef Chainable1 Parent; +public: + InputStateChange(); + InputStateChange( const tName& name ); + void Activate(); + void SetState( const Input::ActiveState state ); +protected: +private: + Input::ActiveState mState; +}; + +//============================================================================== +// RecieveEvent +//============================================================================== +class RecieveEvent : + public Chainable1, + public EventListener +{ +public: + RecieveEvent(); + RecieveEvent( const tName& name ); + void Activate(); + virtual void HandleEvent( EventEnum id, void* pEventData ); + void SetEvent( const EventEnum event ); +protected: +private: + EventEnum mEvent; +}; + +//============================================================================== +// SendEvent +//============================================================================== +class SendEvent : public Chainable1 +{ +public: + SendEvent(); + SendEvent( const tName& name ); + void Activate(); + void SetEvent( EventEnum event ); + void SetEventData( void* eventData ); + +protected: + EventEnum mEvent; + void* mEventData; +}; + +//============================================================================== +// SwitchContext +//============================================================================== +class SwitchContext : public Chainable1 +{ +private: + typedef Chainable1 Parent; +public: + SwitchContext(); + SwitchContext( const tName& name ); + void Activate(); + void SetContext( ContextEnum event ); + +protected: + ContextEnum mContext; +}; + +//============================================================================== +// HasMulticontroller +//============================================================================== +class HasMulticontroller +{ +public: + void SetMultiController( tMultiController* multicontroller ); +protected: + void ResetMultiControllerFrames(); + + tMultiController* m_MultiController; + float m_NumFrames; +}; + +//============================================================================== +// HasMulticontroller +//============================================================================== +class HasTimeInterval +{ +public: + HasTimeInterval(); + void SetTimeInterval( const float interval ); + #ifdef DEBUGWATCH + virtual void Watch( const char* nameSpace ); + #endif + +protected: + float m_TimeInterval; +}; + +//============================================================================== +// ColorChange +//============================================================================== +class ColorChange : + public Chainable1, + public HasTimeInterval +{ +private: + typedef Chainable1 Parent1; + typedef HasTimeInterval Parent2; +public: + ColorChange(); + ColorChange( const tName& name ); + void SetStartColour( const tColour c ); + void SetEndColour( const tColour c ); + void Update( const float deltaT ); + #ifdef DEBUGWATCH + virtual void Watch( const char* nameSpace ); + #endif + +protected: + tColour m_StartColor; + tColour m_EndColor; +}; + +//============================================================================== +// IrisWipeClose +//============================================================================== +class IrisWipeOpen + : public Chainable1, + public HasMulticontroller + +{ + //this class doesn't even need a drawable really +public: + IrisWipeOpen(); + IrisWipeOpen( const tName& name ); + void Activate(); + void Update( const float deltaT ); +protected: +}; + +//============================================================================== +// IrisWipeOpen +//============================================================================== +class IrisWipeClose + : public Chainable1, + public HasMulticontroller +{ + //this class doesn't even need a drawable really +public: + IrisWipeClose(); + IrisWipeClose( const tName& name ); + void Activate(); + void Deactivate(); + void Update( const float deltaT ); +protected: +}; + +//============================================================================== +// Show +//============================================================================== +class Show : public Chainable1 +{ +public: + Show(); + Show( const tName& name ); + void Activate(); + +protected: +}; + +//============================================================================= +// Pause +//============================================================================= +class Pause : + public Chainable1, + public HasTimeInterval +{ +private: + typedef Chainable1 Parent1; + typedef HasTimeInterval Parent2; + +public: + Pause(); + Pause( const tName& name ); + void Update( const float deltaT ); + #ifdef DEBUGWATCH + virtual void Watch( const char* nameSpace ); + #endif +protected: +}; + +//============================================================================= +// PauseInFrames +//============================================================================= +class PauseInFrames : + public Chainable1 +{ +private: + typedef Chainable1 Parent; +public: + PauseInFrames(); + PauseInFrames( const tName& name ); + void Reset(); + void SetNumberOfFrames( const unsigned int i ); + void Update( const float deltaT ); +protected: + unsigned int m_FramesToPause; + unsigned int m_FramesElapsed; +}; + +//============================================================================== +// PauseGame +//============================================================================== +class PauseGame : + public Chainable1 +{ + void Activate(); +}; + +//============================================================================== +// ResumeGame +//============================================================================== +class ResumeGame : + public Chainable1 +{ +public: + ResumeGame(); + ResumeGame( const tName& name ); + void Activate(); +}; + +//============================================================================== +// ImageCycler - causes images to cycle forever +//============================================================================== +class ImageCycler : public Transition +{ +public: + void SetDrawable( Scrooby::Drawable* drawable ); + void SetDrawable( Scrooby::Drawable& drawable ); + void SetPeriod( const float period ); + void Update( const float deltaT ); +protected: + float m_Period; + Scrooby::Sprite* m_Sprite; //this is a waste of memory +}; + +//============================================================================== +// Pulse - pulses the scale of the image about its center +//============================================================================== +class PulseScale : public Transition +{ +private: + typedef Transition Parent; +public: + PulseScale(); + PulseScale( const tName& name ); + virtual bool MovesDrawable() const; + void SetAmplitude( const float amplitude ); + void SetDrawable( Scrooby::Drawable* drawable ); + void SetDrawable( Scrooby::Drawable& drawable ); + void SetFrequency( const float frequency ); + void Update( const float deltaT ); + + #ifdef DEBUGWATCH + virtual void Watch( const char* nameSpace ); + #endif + +protected: + Scrooby::HasBoundingBox* m_BoundedDrawable; + float m_Amplitude; + float m_Frequency; +}; + +//============================================================================== +// Spin - causes the object to spin about its center forever +//============================================================================== +class Spin : public Transition +{ +public: + Spin(); + virtual bool MovesDrawable() const; + void SetDrawable( Scrooby::Drawable* drawable ); + void SetPeriod( const float period ); + void Update( const float deltaT ); +protected: + float m_Period; + Scrooby::BoundedDrawable* m_BoundedDrawable; +}; + +//============================================================================== +// Translator +//============================================================================== +class Translator : + public Chainable1, + public HasTimeInterval +{ +private: + typedef Chainable Parent1; + typedef HasTimeInterval Parent2; + +public: + Translator(); + Translator( const tName& name ); + Translator( const Translator& right ); + ~Translator(); + void MateCoordsEnd( const Scrooby::HasBoundingBox* drawable ); + void MateCoordsStart( const Scrooby::HasBoundingBox* drawable ); + virtual bool MovesDrawable() const; + Translator& operator=( const Translator& right ); + void SetCoordsEnd ( const int x, const int y ); + void SetCoordsStart( const int x, const int y ); + void SetEndOffscreenBottom ( const Scrooby::Drawable* drawable ); + void SetEndOffscreenLeft ( const Scrooby::Drawable* drawable ); + void SetEndOffscreenRight ( const Scrooby::Drawable* drawable ); + void SetEndOffscreenTop ( const Scrooby::Drawable* drawable ); + void SetStartOffscreenBottom ( const Scrooby::Drawable* drawable ); + void SetStartOffscreenLeft ( const Scrooby::Drawable* drawable ); + void SetStartOffscreenRight ( const Scrooby::Drawable* drawable ); + void SetStartOffscreenTop ( const Scrooby::Drawable* drawable ); + void Update( const float deltaT ); + #ifdef DEBUGWATCH + virtual void Watch( const char* nameSpace ); + #endif + +protected: + short int startX; + short int startY; + short int endX; + short int endY; +}; + +//============================================================================== +// Translator - with a springy type of effect. +//============================================================================== +class UnderdampedTranslator : public Translator +{ +public: + UnderdampedTranslator(); + UnderdampedTranslator( const tName& name ); + virtual bool MovesDrawable() const; + void SetFrequency( const float frequency ); + void Update( const float deltaT ); +protected: + float m_Frequency; +}; + +} // GuiSFX namespace + +#endif // TRANSITIONS_H diff --git a/game/code/presentation/language.cpp b/game/code/presentation/language.cpp new file mode 100644 index 0000000..d8eaf00 --- /dev/null +++ b/game/code/presentation/language.cpp @@ -0,0 +1,181 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: language.cpp +// +// Description: contains functions for dealing with language +// +// History: 21/1/2002 + Created -- Ian Gipson +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#ifdef RAD_PS2 + #include <libscf.h> +#endif + +#ifdef RAD_GAMECUBE + #include <dolphin/os.h> +#endif + +#ifdef RAD_XBOX + #include <xtl.h> +#endif +//======================================== +// Project Includes +//======================================== + +#include <presentation/language.h> + +//***************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//***************************************************************************** + +//***************************************************************************** +// +// Public Member Functions +// +//***************************************************************************** +namespace Language{ + +//============================================================================= +// Language::GetHardwareLanguage() +//============================================================================= +// Description: returns the currently set language for the console. +// +// Parameters: None. +// +// Return: Language enum specifying the current language +// +//============================================================================= +Language GetHardwareLanguage() +{ + #ifdef RAD_PS2 + //////////////////////////////////////////////////////////// + // PS2 + //////////////////////////////////////////////////////////// + switch ( sceScfGetLanguage() ) + { + case SCE_DUTCH_LANGUAGE : + { + return DUTCH; + } + case SCE_ENGLISH_LANGUAGE : + { + return ENGLISH; + } + case SCE_FRENCH_LANGUAGE : + { + return FRENCH; + } + case SCE_GERMAN_LANGUAGE : + { + return GERMAN; + } + case SCE_ITALIAN_LANGUAGE : + { + return ITALIAN; + } + case SCE_JAPANESE_LANGUAGE : + { + return JAPANESE; + } + case SCE_PORTUGUESE_LANGUAGE : + { + return PORTUGUESE; + } + case SCE_SPANISH_LANGUAGE : + { + return SPANISH; + } + default : + { + return UNKNOWN; + } + } + #endif + + #ifdef RAD_XBOX + //////////////////////////////////////////////////////////// + // XBOX + //////////////////////////////////////////////////////////// + switch ( XGetLanguage() ) + { + case XC_LANGUAGE_ENGLISH : + { + return ENGLISH; + } + case XC_LANGUAGE_FRENCH : + { + return FRENCH; + } + case XC_LANGUAGE_GERMAN : + { + return GERMAN; + } + case XC_LANGUAGE_ITALIAN : + { + return ITALIAN; + } + case XC_LANGUAGE_JAPANESE : + { + return JAPANESE; + } + case XC_LANGUAGE_SPANISH : + { + return SPANISH; + } + default : + { + return UNKNOWN; + } + } + #endif + + #ifdef RAD_GAMECUBE + switch ( OSGetLanguage() ) + { + case OS_LANG_ENGLISH: + { + return ENGLISH; + } + case OS_LANG_GERMAN: + { + return GERMAN; + } + case OS_LANG_FRENCH: + { + return FRENCH; + } + case OS_LANG_SPANISH: + { + return SPANISH; + } + case OS_LANG_ITALIAN: + { + return ITALIAN; + } + case OS_LANG_DUTCH: + { + return DUTCH; + } + default: + { + return UNKNOWN; + } + } + #endif + + #ifdef RAD_WIN32 + //////////////////////////////////////////////////////////// + // WIN32 + //////////////////////////////////////////////////////////// + return ENGLISH; // to be implemented. + #endif +} + +} //namespace Language
\ No newline at end of file diff --git a/game/code/presentation/language.h b/game/code/presentation/language.h new file mode 100644 index 0000000..e2e1a24 --- /dev/null +++ b/game/code/presentation/language.h @@ -0,0 +1,43 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: language.h +// +// Description: this file contains the prototypes for functions for getting +// access to languages that the console is set to +// +// History: 21/11/2002 + Created -- Ian Gipson +// +//============================================================================= + +#ifndef LANGUAGE_H +#define LANGUAGE_H + +//======================================== +// Nested Includes +//======================================== + + +//======================================== +// Forward References +//======================================== +namespace Language +{ + enum Language + { + ENGLISH, + FRENCH, + GERMAN, + ITALIAN, + SPANISH, + DUTCH, + JAPANESE, + PORTUGUESE, + + UNKNOWN + }; + + Language GetHardwareLanguage(); +} + +#endif // LANGUAGE_H diff --git a/game/code/presentation/mouthflapper.cpp b/game/code/presentation/mouthflapper.cpp new file mode 100644 index 0000000..ea094d2 --- /dev/null +++ b/game/code/presentation/mouthflapper.cpp @@ -0,0 +1,565 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: MouthFlapper.cpp +// +// Description: Implement MouthFlapper +// +// History: 09/09/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <radmath/trig.hpp> +#include <radtime.hpp> +#include <stdlib.h> +#include <p3d/anim/skeleton.hpp> + +//======================================== +// Project Includes +//======================================== + +#include <presentation/mouthflapper.h> + +#include <worldsim/character/character.h> + +#include <choreo/puppet.hpp> + +#include <poser/pose.hpp> +#include <poser/joint.hpp> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +static float MIN_OPEN = -0.10f * rmt::PI; +static float MAX_OPEN = 0.15f * rmt::PI; +static float MAX_DEVIATION = 0.04f * rmt::PI; +static float MIN_SPEED = 1.00f; +static float MAX_SPEED = 4.00f; + +//default settings +MouthFlapperDefaultSetting gDefaultSetting( "default", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ); +MouthFlapperDefaultSetting gDefaultSettings[] = +{ + MouthFlapperDefaultSetting( "apu", -0.314159f, 0.490973f, 0.13f, 2.20f, 3.78f ), //done + MouthFlapperDefaultSetting( "b_cbg", -0.314159f, 0.559204f, 0.13f, 2.44f, 3.88f ), //done + MouthFlapperDefaultSetting( "b_cletus", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "b_frink", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "b_grandpa",-0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done + MouthFlapperDefaultSetting("b_milhouse",-0.314159f, 0.521504f, 0.125664f, 2.22f, 4.00f ), //done + MouthFlapperDefaultSetting( "b_nelson", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "b_ralph", -0.314159f, 0.471504f, 0.125664f, 2.22f, 4.00f ), //done + MouthFlapperDefaultSetting( "b_skinner",-0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "b_smithers", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "b_snake", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "b_zfem1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "b_zmale1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "b_zmale2", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "b_zmale3", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "brn_unf", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "barney", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "bart", -0.314159f, 0.521504f, 0.125664f, 2.50f, 4.00f ), //done + MouthFlapperDefaultSetting( "burns", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "captain", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "carl", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "cbg", -0.314159f, 0.559204f, 0.13f, 2.44f, 3.88f ), //done + MouthFlapperDefaultSetting( "cletus", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "frink", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "gil", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "grandpa", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done + MouthFlapperDefaultSetting( "hibbert", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "homer", -0.314159f, 0.420973f, 0.136640f, 2.00f, 3.44f ), //done + MouthFlapperDefaultSetting( "jimbo", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "joger1", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "kearney", -0.314159f, 0.521504f, 0.125664f, 2.34f, 3.78f ), //done + MouthFlapperDefaultSetting( "krusty", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done + MouthFlapperDefaultSetting( "lenny", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "lisa", -0.314159f, 0.471239f, 0.125664f, 2.5f, 4.00f ), //done + MouthFlapperDefaultSetting( "louie", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "marge", -0.314159f, 0.420973f, 0.13f, 1.66f, 3.44f ), //done + MouthFlapperDefaultSetting( "milhouse", -0.314159f, 0.521504f, 0.125664f, 2.22f, 4.00f ), //done + MouthFlapperDefaultSetting( "moe", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "moleman", -0.314159f, 0.452389f, 0.125664f, 1.56f, 3.54f ), //done + MouthFlapperDefaultSetting( "ned", -0.314159f, 0.490088f, 0.13f, 1.78f, 3.78f ), //done + MouthFlapperDefaultSetting( "nelson", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "nriviera", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "otto", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "patty", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done + MouthFlapperDefaultSetting( "ped0", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "ped1", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "ped2", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "ped3", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "ped4", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "ped5", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "ped6", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ), + MouthFlapperDefaultSetting( "ralph", -0.314159f, 0.471504f, 0.125664f, 2.22f, 4.00f ), //done + MouthFlapperDefaultSetting( "reward_barney", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "reward_homer", -0.314159f, 0.420973f, 0.136640f, 2.00f, 3.44f ), //done + MouthFlapperDefaultSetting( "reward_kearney",-0.314159f, 0.521504f, 0.125664f, 2.34f, 3.78f ), //done + MouthFlapperDefaultSetting( "reward_otto", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), + MouthFlapperDefaultSetting( "reward_willie", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "selma", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done + MouthFlapperDefaultSetting( "skinner", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "smithers", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done + MouthFlapperDefaultSetting( "snake", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "teen", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done + MouthFlapperDefaultSetting( "wiggum", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done + MouthFlapperDefaultSetting( "willie", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "zfem1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "zmale1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "zmale2", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), + MouthFlapperDefaultSetting( "zmale3", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), +}; + +char gWatcherNMnameSpace[ 256 ] = "Presentation\\MouthFlapping\\"; + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// MouthFlapper::MouthFlapper +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +MouthFlapper::MouthFlapper() : + mJointIndex( -1 ), + mJoint( NULL ), + mCharacter( NULL ), + mCurrentdt( 0.0f ), + mDirection( -1.0f ), + mAngle( 0.0f ), + mSpeed( 0.0f ), + mMaxOpen( MAX_OPEN ), + mMinOpen( MIN_OPEN ), + mSetting( gDefaultSetting ), + mGotDefaultSettings( false ) +{ +} + +//============================================================================== +// MouthFlapper::~MouthFlapper +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +MouthFlapper::~MouthFlapper() +{ + mCharacter = NULL; +} + +//============================================================================= +// MouthFlapper::AddVariablesToWatcher +//============================================================================= +// Description: Adds all the global variables controlling mouth flapping to the +// watcher so that they can be tuned +// +// Parameters: none +// +// Return: void +// +//============================================================================= +#ifdef DEBUGWATCH +void MouthFlapper::AddVariablesToWatcher() +{ + int size = GetNumberOfDefaultSettings(); + int i; + for( i = 0; i < size; ++i ) + { + gDefaultSettings[ i ].AddToWatcher(); + } +} +#endif //DEBUGWATCH + +//============================================================================= +// MouthFlapper::GetDefaultSettings +//============================================================================= +// Description: Comment +// +// Parameters: name - the name of the character who's mouth is supposed to +// flap +// +// Return: void +// +//============================================================================= +void MouthFlapper::GetDefaultSettings( const tName& name ) +{ + int size = GetNumberOfDefaultSettings(); + int i; + for( i = 0; i < size; ++i ) + { + MouthFlapperDefaultSetting& setting = gDefaultSettings[ i ]; + tName settingName = setting.GetName(); + if( settingName == name ) + { + // + // Assign the settings + // + mSetting = setting; + return; + } + } + rAssertMsg( false, "A character for whom we have no mouth flapping parameters is talking - please tell Ian which level and mission this was" ); +} + +//============================================================================= +// MouthFlapper::GetNumberOfDefaultSettings +//============================================================================= +// Description: returns the nubmer of characters for which default parameters +// have been hardcoded +// +// Parameters: none +// +// Return: unsigned int - how many parameters are there +// +//============================================================================= +unsigned int MouthFlapper::GetNumberOfDefaultSettings() +{ + size_t totalSize = sizeof( gDefaultSettings ); + size_t sizeOfEach = sizeof( MouthFlapperDefaultSetting ); + return totalSize / sizeOfEach; +} + +//============================================================================= +// MouthFlapper::SetCharacter +//============================================================================= +// Description: Comment +// +// Parameters: ( Character* guy ) +// +// Return: void +// +//============================================================================= +void MouthFlapper::SetCharacter( Character* pCharacter ) +{ + mCharacter = pCharacter; + if( pCharacter != NULL ) + { + choreo::Puppet* pPuppet = pCharacter->GetPuppet( ); + + poser::Pose* pPose = pPuppet->GetPose(); + tSkeleton* skeleton = pPose->GetSkeleton(); + mJointIndex = skeleton->FindJointIndex( "Jaw" ); + + mJoint = pPose->GetJoint( mJointIndex ); + } + else + { + mJointIndex = -1; + mJoint = NULL; + } + + NeuSpeed(); +} + +//============================================================================= +// MouthFlapper::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( int elapsedtime ) +// +// Return: void +// +//============================================================================= +void MouthFlapper::Advance( float deltaTime ) +{ + mCurrentdt += deltaTime; +} + +//============================================================================= +// MouthFlapper::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( Pose* pose ) +// +// Return: void +// +//============================================================================= +void MouthFlapper::Update( poser::Pose* pose ) +{ + // + // make sure that the default settings are properly applied + // + rAssert( mCharacter != NULL ); + const tName& name = mCharacter->GetNameObject(); + GetDefaultSettings( name ); + + if( mCurrentdt <= 0.0f ) + { + return; + } + + rAssert( mJointIndex >= 0 ); + poser::Joint* joint = pose->GetJoint(mJointIndex); + poser::Transform pt = joint->GetObjectTransform(); + rmt::Matrix m = pt.GetMatrix(); + rmt::Matrix r; + r.Identity(); + float dAngle = mSpeed * mCurrentdt * mDirection; + mAngle += dAngle; + if( mAngle > mMaxOpen ) + { + mDirection = -mDirection; + mAngle = mMaxOpen; + NeuSpeed(); + } + + if( mAngle < mMinOpen ) + { + mDirection = -mDirection; + mAngle = mMinOpen; + NeuSpeed(); + } + + r.FillRotateZ( mAngle ); + m.Mult( r ); + pt.SetMatrix(m); + joint->SetObjectTransform(pt); + mCurrentdt = 0.0f; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// MouthFlapper::NeuSpeed +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void MouthFlapper::NeuSpeed() +{ + float defaultMaxDeviation = mSetting.GetMaxDeviation(); + float defaultMaxSpeed = mSetting.GetMaxSpeed(); + float defaultMinSpeed = mSetting.GetMinSpeed(); + float defaultMaxOpen = mSetting.GetMaxOpen(); + float defaultMinOpen = mSetting.GetMinOpen(); + mSpeed = defaultMinSpeed + ( defaultMaxSpeed - defaultMinSpeed ) * rand() / RAND_MAX; + mMaxOpen = defaultMaxOpen - defaultMaxDeviation * rand() / RAND_MAX; + mMinOpen = defaultMinOpen + defaultMaxDeviation * rand() / RAND_MAX; +} + +//============================================================================= +// MouthFlapperDefaultSetting::MouthFlapperDefaultSetting +//============================================================================= +// Description: constructor +// +// Parameters: N/A +// +// Return: N/A +// +//============================================================================= +MouthFlapperDefaultSetting::MouthFlapperDefaultSetting( + const tName& name, + const float minOpen, + const float maxOpen, + const float maxDeviation, + const float minSpeed, + const float maxSpeed ) : + name( name ), + minOpen( minOpen ), + maxOpen( maxOpen ), + maxDeviation( maxDeviation ), + minSpeed( minSpeed ), + maxSpeed( maxSpeed ) +{ +} + +//============================================================================= +// MouthFlapperDefaultSetting::MouthFlapperDefaultSetting +//============================================================================= +// Description: copy constructor +// +// Parameters: N/A +// +// Return: N/A +// +//============================================================================= +MouthFlapperDefaultSetting::MouthFlapperDefaultSetting( const MouthFlapperDefaultSetting& right ) +{ + *this = right; +} + +//============================================================================= +// MouthFlapperDefaultSetting::AddToWatcher +//============================================================================= +// Description: adds this set of mouth flapper parameters to the watcher +// +// Parameters: NONE +// +// Return: NONE +// +//============================================================================= +void MouthFlapperDefaultSetting::AddToWatcher() +{ + char nameSpace[ 256 ] = ""; + const char* nameString = name.GetText(); + sprintf( nameSpace , "%s%s", gWatcherNMnameSpace, nameString ); + radDbgWatchAddFloat( &minOpen, "Min Open", nameSpace, NULL, NULL, -rmt::PI, rmt::PI ); + radDbgWatchAddFloat( &maxOpen, "Max Open", nameSpace, NULL, NULL, -rmt::PI, rmt::PI ); + radDbgWatchAddFloat( &maxDeviation, "Max Deviation", nameSpace, NULL, NULL, 0.0f, 20.0f ); + radDbgWatchAddFloat( &minSpeed, "Min Speed", nameSpace, NULL, NULL, 0.0f, 20.0f ); + radDbgWatchAddFloat( &maxSpeed, "Max Speed", nameSpace, NULL, NULL, 0.0f, 20.0f ); +} + +//============================================================================= +// MouthFlapperDefaultSetting::GetMaxDeviation +//============================================================================= +// Description: allows access to the maximum deviation +// +// Parameters: NONE +// +// Return: the maximum deviation parameter +// +//============================================================================= +const float MouthFlapperDefaultSetting::GetMaxDeviation() const +{ + return maxDeviation; +} + +//============================================================================= +// MouthFlapperDefaultSetting::GetMaxOpen +//============================================================================= +// Description: allows access to the maxopen parameters +// +// Parameters: NONE +// +// Return: the max open parameter +// +//============================================================================= +const float MouthFlapperDefaultSetting::GetMaxOpen() const +{ + return maxOpen; +} + +//============================================================================= +// MouthFlapperDefaultSetting::GetMaxSpeed +//============================================================================= +// Description: GetMaxSpeed +// +// Parameters: NONE +// +// Return: the max speed parameter +// +//============================================================================= +const float MouthFlapperDefaultSetting::GetMaxSpeed() const +{ + return maxSpeed; +} + +//============================================================================= +// MouthFlapperDefaultSetting::GetMinOpen +//============================================================================= +// Description: GetMinOpen +// +// Parameters: NONE +// +// Return: the min open parameter +// +//============================================================================= +const float MouthFlapperDefaultSetting::GetMinOpen() const +{ + return minOpen; +} + +//============================================================================= +// MouthFlapperDefaultSetting::GetMinSpeed +//============================================================================= +// Description: GetMinSpeed +// +// Parameters: NONE +// +// Return: the minSpeed parameter +// +//============================================================================= +const float MouthFlapperDefaultSetting::GetMinSpeed() const +{ + return minSpeed; +} + +//============================================================================= +// MouthFlapperDefaultSetting::GetName +//============================================================================= +// Description: GetName +// +// Parameters: NONE +// +// Return: the name of the object +// +//============================================================================= +const tName& MouthFlapperDefaultSetting::GetName() const +{ + return name; +} + +//============================================================================= +// MouthFlapperDefaultSetting::operator= +//============================================================================= +// Description: assignment operator +// +// Parameters: N/A +// +// Return: N/A +// +//============================================================================= +MouthFlapperDefaultSetting& MouthFlapperDefaultSetting::operator=( const MouthFlapperDefaultSetting& right ) +{ + if( this == &right ) + { + return *this; + } + + name = right.name; + minOpen = right.minOpen; + maxOpen = right.maxOpen; + maxDeviation = right.maxDeviation; + minSpeed = right.minSpeed; + maxSpeed = right.maxSpeed; + return *this; +} + +//============================================================================= +// MouthFlapperDefaultSetting::RemoveFromWatcher +//============================================================================= +// Description: removes this set of mouth flapper parameters to the watcher +// +// Parameters: NONE +// +// Return: NONE +// +//============================================================================= +void MouthFlapperDefaultSetting::RemoveFromWatcher() +{ + radDbgWatchDelete( &minOpen ); + radDbgWatchDelete( &maxOpen ); + radDbgWatchDelete( &maxDeviation ); + radDbgWatchDelete( &minSpeed ); + radDbgWatchDelete( &maxSpeed ); +} diff --git a/game/code/presentation/mouthflapper.h b/game/code/presentation/mouthflapper.h new file mode 100644 index 0000000..0a4e600 --- /dev/null +++ b/game/code/presentation/mouthflapper.h @@ -0,0 +1,107 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: mouthflapper.h +// +// Description: Blahblahblah +// +// History: 09/09/2002 + Created -- NAME +// +//============================================================================= + +#ifndef MOUTHFLAPPER_H +#define MOUTHFLAPPER_H + +//======================================== +// Nested Includes +//======================================== + +#include <poser/joint.hpp> +#include <poser/posedriver.hpp> + +//======================================== +// Forward References +//======================================== + +class poser::Joint; +class poser::Pose; +class Character; + + +//============================================================================= +// +// Synopsis: This class contains all the internal settings for mouth +// flapping +// +//============================================================================= +class MouthFlapperDefaultSetting +{ +public: + MouthFlapperDefaultSetting( const tName& name, const float minOpen, const float maxOpen, const float maxDeviation, const float minSpeed, const float maxSpeed ); + MouthFlapperDefaultSetting( const MouthFlapperDefaultSetting& right ); + MouthFlapperDefaultSetting& operator=( const MouthFlapperDefaultSetting& right ); + void AddToWatcher(); + const float GetMaxDeviation() const; + const float GetMaxOpen() const; + const float GetMaxSpeed() const; + const float GetMinOpen() const; + const float GetMinSpeed() const; + const tName& GetName() const; + void RemoveFromWatcher(); +protected: +private: + tName name; + float minOpen; + float maxOpen; + float maxDeviation; + float minSpeed; + float maxSpeed; +}; + +//============================================================================= +// +// Synopsis: class for mouth flapping +// +//============================================================================= +class MouthFlapper : public poser::PoseDriver +{ +public: + MouthFlapper(); + virtual ~MouthFlapper(); + +#ifdef DEBUGWATCH + static void AddVariablesToWatcher(); +#endif DEBUGWATCH + virtual void Advance( float deltaTime ); + void GetDefaultSettings( const tName& name ); + void SetCharacter( Character* pCharacter ); + virtual void Update( poser::Pose* pose ); + +protected: + static unsigned int GetNumberOfDefaultSettings(); + +private: + + //Prevent wasteful constructor creation. + MouthFlapper( const MouthFlapper& mouthflapper ); + MouthFlapper& operator=( const MouthFlapper& mouthflapper ); + + void NeuSpeed(); + + int mJointIndex; + poser::Joint* mJoint; + Character* mCharacter; + + float mCurrentdt; + float mDirection; + float mAngle; + float mSpeed; + float mMaxOpen; + float mMinOpen; + + MouthFlapperDefaultSetting mSetting; + bool mGotDefaultSettings; +}; + + +#endif //MOUTHFLAPPER_H diff --git a/game/code/presentation/nisplayer.cpp b/game/code/presentation/nisplayer.cpp new file mode 100644 index 0000000..b13a9fb --- /dev/null +++ b/game/code/presentation/nisplayer.cpp @@ -0,0 +1,163 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: nisplayer.cpp +// +// Description: Implement NISPlayer +// +// History: 16/04/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <p3d/anim/compositedrawable.hpp> +#include <p3d/utility.hpp> + +//======================================== +// Project Includes +//======================================== +#include <presentation/nisplayer.h> +#include <loading/filehandlerenum.h> +#include <loading/loadingmanager.h> + +#include <render/rendermanager/rendermanager.h> + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// NISPlayer::NISPlayer +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +NISPlayer::NISPlayer() : + mpSceneGraph( NULL ) +{ + SetExclusive( false ); +} + +//============================================================================== +// NISPlayer::~NISPlayer +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +NISPlayer::~NISPlayer() +{ + +} + + +//============================================================================= +// NISPlayer::ClearData +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISPlayer::ClearData() +{ + SimpleAnimationPlayer::ClearData(); + + if( mpSceneGraph != NULL ) + { + GetRenderManager()->mEntityDeletionList.Add((tRefCounted*&)mpSceneGraph); + mpSceneGraph = NULL; + } +} + + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// NISPlayer::DoLoaded +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISPlayer::DoLoaded() +{ + SimpleAnimationPlayer::DoLoaded(); + + tRefCounted::Release(mpSceneGraph); + tRefCounted::Assign(mpSceneGraph, (tDrawable*)p3d::find<Scenegraph::Scenegraph>( GetAnimationName() )); + if(!mpSceneGraph) + { + tRefCounted::Assign(mpSceneGraph, (tDrawable*)p3d::find<tCompositeDrawable>( GetAnimationName() )); + } +} + +//============================================================================= +// NISPlayer::DoRender +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISPlayer::DoRender() +{ + SimpleAnimationPlayer::DoRender(); + + if(mpSceneGraph) + mpSceneGraph->Display(); +} + +//============================================================================= +// NISPlayer::GetBoundingBox +//============================================================================= +// Description: Comment +// +// Parameters: ( rmt::Box3D* box ) +// +// Return: true if box filled out, false otherwise +// +//============================================================================= +bool NISPlayer::GetBoundingBox( rmt::Box3D* box ) +{ + bool retval = false; + + if( mpSceneGraph ) + { + mpSceneGraph->GetBoundingBox( box ); + retval = true; + } + + return( retval ); +} diff --git a/game/code/presentation/nisplayer.h b/game/code/presentation/nisplayer.h new file mode 100644 index 0000000..430eeb0 --- /dev/null +++ b/game/code/presentation/nisplayer.h @@ -0,0 +1,59 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 16/04/2002 + Created -- NAME +// +//============================================================================= + +#ifndef NISPLAYER_H +#define NISPLAYER_H + +//======================================== +// Nested Includes +//======================================== + +#include <presentation/simpleanimationplayer.h> + +#include <p3d/scenegraph/scenegraph.hpp> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class NISPlayer : public SimpleAnimationPlayer +{ + public: + NISPlayer(); + virtual ~NISPlayer(); + + virtual void ClearData(); + + bool GetBoundingBox( rmt::Box3D* box ); + tDrawable* GetDrawable() { return mpSceneGraph; } + + protected: + virtual void DoLoaded(); + virtual void DoRender(); + + private: + + //Prevent wasteful constructor creation. + NISPlayer( const NISPlayer& nisPlayer ); + NISPlayer& operator=( const NISPlayer& nisPlayer ); + + tDrawable* mpSceneGraph; +}; + + +#endif //NISPLAYER_H + diff --git a/game/code/presentation/playerdrawable.cpp b/game/code/presentation/playerdrawable.cpp new file mode 100644 index 0000000..1f36147 --- /dev/null +++ b/game/code/presentation/playerdrawable.cpp @@ -0,0 +1,90 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: Playerdrawable.cpp +// +// Description: Implement PlayerDrawable +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> + +//======================================== +// Project Includes +//======================================== + +#include <presentation/playerdrawable.h> +#include <presentation/animplayer.h> +#include <render/rendermanager/rendermanager.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// PlayerDrawable::PlayerDrawable +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PlayerDrawable::PlayerDrawable() : + mpPlayer( NULL ) +{ +} + +//============================================================================== +// PlayerDrawable::~PlayerDrawable +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PlayerDrawable::~PlayerDrawable() +{ + +} + +//============================================================================= +// PlayerDrawable::Display +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PlayerDrawable::Display() +{ + if(mpPlayer != NULL) + { + mpPlayer->Render(); + } +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/presentation/playerdrawable.h b/game/code/presentation/playerdrawable.h new file mode 100644 index 0000000..059ee1b --- /dev/null +++ b/game/code/presentation/playerdrawable.h @@ -0,0 +1,58 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +#ifndef PlayerDRAWABLE_H +#define PlayerDRAWABLE_H + +//======================================== +// Nested Includes +//======================================== +#include <p3d/drawable.hpp> +#include <render/enums/renderenums.h> + +//======================================== +// Forward References +//======================================== + +class AnimationPlayer; + +//============================================================================= +// +// Synopsis: The PlayerDrawable is just a temporary thing for the DSG to +// call and get the current presentation player to draw. +// +//============================================================================= + +class PlayerDrawable : public tDrawable +{ + public: + PlayerDrawable(); + virtual ~PlayerDrawable(); + + void SetPlayer( AnimationPlayer* pPlayer ) { mpPlayer = pPlayer; } + virtual void Display(); + + void SetRenderLayer( RenderEnums::LayerEnum layer ) { mRenderLayer = layer; } + RenderEnums::LayerEnum GetRenderLayer() { return mRenderLayer; } + + private: + + //Prevent wasteful constructor creation. + PlayerDrawable( const PlayerDrawable& pPlayerDrawable ); + PlayerDrawable& operator=( const PlayerDrawable& pPlayerDrawable ); + + AnimationPlayer* mpPlayer; + RenderEnums::LayerEnum mRenderLayer; +}; + + +#endif // PlayerDRAWABLE_H + diff --git a/game/code/presentation/presentation.cpp b/game/code/presentation/presentation.cpp new file mode 100644 index 0000000..c67fc91 --- /dev/null +++ b/game/code/presentation/presentation.cpp @@ -0,0 +1,1466 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: presentation.cpp +// +// Description: Implement PresentationManager +// +// History: 16/04/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <raddebugwatch.hpp> +#include <p3d/view.hpp> + +//======================================== +// Project Includes +//======================================== +#include <events/eventmanager.h> +#include <events/eventenum.h> +#include <events/eventdata.h> +#include <memory/srrmemory.h> +#include <contexts/context.h> +#include <contexts/bootupcontext.h> +#include <contexts/gameplay/gameplaycontext.h> +#include <gameflow/gameflow.h> +#include <meta/eventlocator.h> +#include <meta/triggervolume.h> +#include <presentation/playerdrawable.h> +#include <presentation/presentation.h> +#include <presentation/presentationanimator.h> +#include <presentation/nisplayer.h> +#include <presentation/tutorialmanager.h> +#include <presentation/cameraplayer.h> +#include <presentation/transitionplayer.h> +#include <presentation/gui/guimanager.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/guitextbible.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/gui/ingame/guiscreenmissionload.h> +#include <presentation/mouthflapper.h> +#include <presentation/fmvplayer/fmvplayer.h> + +#include <camera/supercammanager.h> +#include <camera/supercamcentral.h> +#include <camera/conversationcam.h> +#include <camera/isupercamtarget.h> + +#include <worldsim/character/character.h> +#include <worldsim/character/charactermanager.h> +#include <worldsim/character/charactertarget.h> +#include <worldsim/avatarmanager.h> +#include <p3d/matrixstack.hpp> + +#include <render/rendermanager/rendermanager.h> +#include <render/RenderManager/RenderLayer.h> +#include <render/enums/renderenums.h> +#include <mission/gameplaymanager.h> +#include <mission/objectives/missionobjective.h> +#include <screen.h> +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +// Static pointer to instance of singleton. +PresentationManager* PresentationManager::spInstance = NULL; +const int PLAYER_ONE = 0; +const int MAX_DIALOG_LINES = 64; +#define MAX_CHARACTERS 64 +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================= +// PresentationManager::CreateInstance +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: PresentationManager +// +//============================================================================= +PresentationManager* PresentationManager::CreateInstance() +{ +MEMTRACK_PUSH_GROUP( "PresentationManager" ); + if( spInstance == NULL ) + { + spInstance = new(GMA_PERSISTENT) PresentationManager; + rAssert( spInstance ); + } +MEMTRACK_POP_GROUP( "PresentationManager" ); + + return spInstance; +} + +//============================================================================= +// PresentationManager::GetInstance +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: PresentationManager +// +//============================================================================= +PresentationManager* PresentationManager::GetInstance() +{ + return spInstance; +} + +//============================================================================= +// PresentationManager::DestroyInstance +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationManager::DestroyInstance() +{ + if( spInstance != NULL ) + { + delete( GMA_PERSISTENT, spInstance ); + spInstance = NULL; + } +} + +//============================================================================== +// PresentationManager::PresentationManager +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PresentationManager::PresentationManager() : + mTransitionPool( NULL ), + mNISPool( NULL ), + mFMVPool( NULL ), + mFIFOBegin( 0 ), + mFIFOEnd( 0 ), + mpCurrent( NULL ), + mpFMVPlayer( NULL ), + mpNISPlayer( NULL ), + mpCameraPlayer( NULL ), + mpTransitionPlayer( NULL ), +// mLanguage( Language::MAX_LANGUAGES ), + mp_PCAnimator( NULL ), + mp_NPCAnimator( NULL ), + mDialogLineNumber( -1 ), + mCameraForLineOfDialog(MAX_DIALOG_LINES), + mpPlayCallback( 0 ), + mWaitingOnFade( false ), + mOverlay( 0 ) +{ + mInConversation = false; + // mOldFOV= 0.0F; + + unsigned int i; + + for( i = 0; i < MAX_EVENT_SIZE; i++ ) + { + mEventFIFO[ i ] = NULL; + } + + // what is the current allocator + radMemoryAllocator current = HeapManager::GetInstance()->GetCurrentAllocator(); + GameMemoryAllocator gmaCurrent = HeapManager::GetInstance()->GetCurrentHeap(); + + mFMVPool = new FMVEventPool( gmaCurrent, 10 ); + mNISPool = new NISEventPool( gmaCurrent, 10 ); + mTransitionPool = new TransitionEventPool( gmaCurrent, 10 ); + mpNISPlayer = new NISPlayer(); + mpCameraPlayer = new CameraPlayer(); + mpTransitionPlayer = new TransitionPlayer(); + mpFMVPlayer = new( current ) FMVPlayer(); + mpPlayerDrawable = new PlayerDrawable(); + mpPlayerDrawable->AddRef(); + mOverlay = new PresentationOverlay(); + mOverlay->AddRef(); + + mp_oldcam = NULL; + mOldCamIndexNum =0; +} + +//============================================================================== +// PresentationManager::~PresentationManager +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PresentationManager::~PresentationManager() +{ + delete mFMVPool; mFMVPool = NULL; + delete mNISPool; mNISPool = NULL; + delete mTransitionPool; mTransitionPool = NULL; + delete mpNISPlayer; mpNISPlayer = NULL; + delete mpCameraPlayer; mpCameraPlayer = NULL; + delete mpTransitionPlayer; mpTransitionPlayer = NULL; + delete mpFMVPlayer; mpFMVPlayer = NULL; + + this->FinalizePlayerDrawable(); + + mpPlayerDrawable->ReleaseVerified(); + mOverlay->Release(); +} + +//============================================================================= +// PresentationManager::Initialize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationManager::Initialize() +{ +MEMTRACK_PUSH_GROUP( "PresentationManager" ); + //Cary: I took this out since it was allocating to the levelslot when + //the level isn't even loaded. No one seems to know what it's for + //so Darryl probably did it and it's not used anymore. Feb 13th 2003 + //pLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot ); + //pLayer->AddGuts( mpPlayerDrawable ); + + GetEventManager()->AddListener( this, EVENT_LOCATOR ); + + //Listen for Conversation + GetEventManager()->AddListener( this, EVENT_CONVERSATION_INIT ); + GetEventManager()->AddListener( this, EVENT_CONVERSATION_SKIP ); + GetEventManager()->AddListener( this, EVENT_CONVERSATION_DONE ); + + //Listen for MouthFlapping Cues + GetEventManager()->AddListener( this, EVENT_PC_TALK ); + GetEventManager()->AddListener( this, EVENT_PC_SHUTUP ); + GetEventManager()->AddListener( this, EVENT_NPC_TALK ); + GetEventManager()->AddListener( this, EVENT_NPC_SHUTUP ); + GetEventManager()->AddListener( this, EVENT_GUI_FADE_OUT_DONE ); + + rAssert( mp_PCAnimator == NULL ); + rAssert( mp_NPCAnimator == NULL ); + HeapMgr()->PushHeap( GMA_LEVEL_OTHER ); + mp_PCAnimator = new PresentationAnimator(); + mp_NPCAnimator = new PresentationAnimator(); + HeapMgr()->PopHeap( GMA_LEVEL_OTHER ); +MEMTRACK_POP_GROUP( "PresentationManager" ); +} + +//============================================================================= +// PresentationManager::Finalize +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationManager::Finalize() +{ + mCameraForLineOfDialog.erase( mCameraForLineOfDialog.begin(), mCameraForLineOfDialog.end() ); + + mp_PCAnimator->SetCharacter( NULL ); + mp_NPCAnimator->SetCharacter( NULL ); + mp_PCAnimator->ClearAmbientAnimations(); + mp_NPCAnimator->ClearAmbientAnimations(); + + //remove for Conversation + GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_INIT ); + GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_SKIP ); + GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_DONE ); + + //remove for MouthFlapping Cues + GetEventManager()->RemoveListener( this, EVENT_PC_TALK ); + GetEventManager()->RemoveListener( this, EVENT_PC_SHUTUP ); + GetEventManager()->RemoveListener( this, EVENT_NPC_TALK ); + GetEventManager()->RemoveListener( this, EVENT_NPC_SHUTUP ); + + delete mp_PCAnimator; mp_PCAnimator = NULL; + delete mp_NPCAnimator; mp_NPCAnimator = NULL; +} + +//============================================================================= +// PresentationManager::InitializePlayerDrawable +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void +PresentationManager::InitializePlayerDrawable() +{ + RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( pLayer != NULL ); + pLayer->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) ); + pLayer->AddGuts( mpPlayerDrawable ); +} + +//============================================================================= +// PresentationManager::FinalizePlayerDrawable +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void +PresentationManager::FinalizePlayerDrawable() +{ + RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( pLayer != NULL ); + pLayer->RemoveGuts( mpPlayerDrawable ); +} + +//============================================================================= +// PresentationManager::GetAnimatorNpc +//============================================================================= +// Description: returns the presentation animator for the NPC +// +// Parameters: NONE +// +// Return: pointer to the presentationanimator +// +//============================================================================= +PresentationAnimator* PresentationManager::GetAnimatorNpc() +{ + return this->mp_NPCAnimator; +} + +//============================================================================= +// PresentationManager::GetAnimatorPc +//============================================================================= +// Description: returns the presentation animator for the PC +// +// Parameters: NONE +// +// Return: pointer to the presentationanimator +// +//============================================================================= +PresentationAnimator* PresentationManager::GetAnimatorPc() +{ + return this->mp_PCAnimator; +} + +/*============================================================================= +Description: You're one stop method for playing an FMV during gameplay. It + unloads the HUD (for memory), plays the FMV, and then + reloads the HUD. Don't use this in the frontend as the + un/reloading of the frontend is a waste. + NOTE that the platform specific path for the movies is prepended + to the filename. So if you pass "fmv2.rmv" you'll get + "d:\movies\fmv2.rmv" on XBox, "movies\fmv2.rmv" on PS2, + "movies/fmv2.rmv" on GC. +=============================================================================*/ +void PresentationManager::PlayFMV( const char* FileName, + PresentationEvent::PresentationEventCallBack* pCallback, + bool IsSkippable, + bool StopMusic, + bool IsLocalized ) +{ + // this puts the FMV player in the "loading" state + // this is needed so that the gag system can tell when a gag has ended + // (without this the state right before and right after the fmc playes is the same + mpFMVPlayer->PreLoad(); + +#ifdef RAD_E3 + // no in-game FMV's for E3 build + // + if( pCallback != NULL ) + { + pCallback->OnPresentationEventEnd( NULL ); + } + + return; +#endif + + if( mOverlay ) + { + // + // Hide the HUD + // + CGuiScreenHud* hud = dynamic_cast< CGuiScreenHud* >( GetGuiSystem()->GetInGameManager()->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_HUD ) ); + rAssert( hud != NULL ); + Scrooby::Screen* screen = hud->GetScroobyScreen(); + screen->SetAlpha( 0.0f ); + + + mOverlay->SetStart( BLACK_TRANSPARENT ); + mOverlay->SetEnd( BLACK ); + mOverlay->SetDuration( 0.5f ); + RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( pLayer ); + if( pLayer->IsDead() ) + { + pLayer->Resurrect(); + } + pLayer->Thaw(); + pLayer->AddGuts( mOverlay ); + } + mWaitingOnFade = true; + FMVEvent* pEvent = 0; + GetPresentationManager()->QueueFMV( &pEvent, this ); +#ifdef RAD_XBOX + strcpy( pEvent->fileName, "D:\\movies\\" ); +#elif RAD_PS2 + strcpy( pEvent->fileName, "movies\\" ); +#elif RAD_WIN32 + strcpy( pEvent->fileName, "movies\\" ); +#else + strcpy( pEvent->fileName, "movies/" ); +#endif + strcat( pEvent->fileName, FileName ); + pEvent->SetRenderLayer( RenderEnums::PresentationSlot ); + pEvent->SetAutoPlay( true ); + +#ifdef PAL + if( IsLocalized ) + { + switch( CGuiTextBible::GetCurrentLanguage() ) + { + case Scrooby::XL_FRENCH: + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_FRENCH ); + + break; + } + case Scrooby::XL_GERMAN: + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_GERMAN ); + + break; + } + case Scrooby::XL_SPANISH: + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_SPANISH ); + + break; + } + default: + { + rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH ); + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH ); + + break; + } + } + } + else +#endif // PAL + { + pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH ); + } + +#ifdef RAD_GAMECUBE + pEvent->SetAllocator( GMA_ANYWHERE_IN_LEVEL ); +#else + pEvent->SetAllocator( GMA_LEVEL_HUD ); +#endif + pEvent->SetClearWhenDone( true ); + pEvent->SetKeepLayersFrozen( true ); + pEvent->SetSkippable(IsSkippable); + if( StopMusic ) + { + pEvent->KillMusic(); + } + mpPlayCallback = pCallback; +} +/*============================================================================= +Description: This is a callback when the event queued by PlayFMV. +=============================================================================*/ +void PresentationManager::OnPresentationEventBegin( PresentationEvent* pEvent ) +{ + Context* context = GetGameFlow()->GetContext( GetGameFlow()->GetCurrentContext() ); + if( dynamic_cast<GameplayContext*>( context ) ) + { + static_cast<GameplayContext*>( context )->PauseAllButPresentation( true ); + } + GetGuiSystem()->HandleMessage( GUI_MSG_RELEASE_INGAME ); + if( mpPlayCallback ) + { + mpPlayCallback->OnPresentationEventBegin( pEvent ); + } + RenderLayer* rl = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( rl ); + rl->RemoveGuts( mOverlay ); +} +/*============================================================================= +Description: This is a callback when the event queued by PlayFMV. +=============================================================================*/ +void PresentationManager::OnPresentationEventLoadComplete( PresentationEvent* pEvent ) +{ + if( mpPlayCallback ) + { + mpPlayCallback->OnPresentationEventLoadComplete( pEvent ); + } +} +/*============================================================================= +Description: This is a callback when the event queued by PlayFMV. +=============================================================================*/ +void PresentationManager::OnPresentationEventEnd( PresentationEvent* pEvent ) +{ + HeapMgr()->PushHeap (GMA_LEVEL_HUD); + GetGuiSystem()->HandleMessage( GUI_MSG_INIT_INGAME ); + HeapMgr()->PopHeap (GMA_LEVEL_HUD); + GetLoadingManager()->AddCallback( this ); + if( mOverlay ) + { + mOverlay->SetStart( BLACK_TRANSPARENT ); + mOverlay->SetEnd( BLACK ); + mOverlay->SetDuration( 0.5f ); + //mOverlay->SetRemoveOnComplete( true ); + RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( pLayer ); + pLayer->AddGuts( mOverlay ); + } +} +/*============================================================================= +Description: +=============================================================================*/ +void PresentationManager::OnProcessRequestsComplete( void* pUserData ) +{ + Context* context = GetGameFlow()->GetContext( GetGameFlow()->GetCurrentContext() ); + if( dynamic_cast<GameplayContext*>( context ) ) + { + static_cast<GameplayContext*>( context )->PauseAllButPresentation( false ); + } + GetRenderManager()->ThawFromPresentation(); + GetGuiSystem()->HandleMessage( GUI_MSG_RUN_INGAME ); + if( mpPlayCallback ) + { + mpPlayCallback->OnPresentationEventEnd( 0 ); + } + mpPlayCallback = 0; + if( mOverlay ) + { + mOverlay->SetEnd( BLACK ); + mOverlay->SetFrames( 10 ); + mOverlay->SetRemoveOnComplete( true ); + RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( pLayer ); + pLayer->AddGuts( mOverlay ); + } +} +//============================================================================= +// PresentationManager::QueueFMV +//============================================================================= +// Description: Comment +// +// Parameters: ( FMVEvent** pFMVEvent, PresentationEvent::PresentationEventCallBack* pCallback ) +// +// Return: void +// +//============================================================================= +void PresentationManager::QueueFMV( FMVEvent** pFMVEvent, PresentationEvent::PresentationEventCallBack* pCallback ) +{ + (*pFMVEvent) = mFMVPool->AllocateFromPool(); + (*pFMVEvent)->Init(); + (*pFMVEvent)->SetAllocator(GMA_LEVEL_MOVIE); + (*pFMVEvent)->pCallback = pCallback; + + AddToQueue( *pFMVEvent ); +} + +//============================================================================= +// PresentationManager::QueueNIS +//============================================================================= +// Description: Comment +// +// Parameters: ( NISEvent** pNISEvent, PresentationEvent::PresentationEventCallBack* pCallback ) +// +// Return: void +// +//============================================================================= +void PresentationManager::QueueNIS( NISEvent** pNISEvent, PresentationEvent::PresentationEventCallBack* pCallback ) +{ + (*pNISEvent) = mNISPool->AllocateFromPool(); + (*pNISEvent)->Init(); + + (*pNISEvent)->pCallback = pCallback; + + AddToQueue( *pNISEvent ); +} + +//============================================================================= +// PresentationManager::QueueTransition +//============================================================================= +// Description: Comment +// +// Parameters: ( TransitionEvent** pTransitionEvent, +// PresentationEvent::PresentationEventCallBack* pCallback ) +// +// Return: void +// +//============================================================================= +void PresentationManager::QueueTransition( TransitionEvent** pTransitionEvent, + PresentationEvent::PresentationEventCallBack* pCallback ) +{ + (*pTransitionEvent) = mTransitionPool->AllocateFromPool(); + (*pTransitionEvent)->Init(); + + (*pTransitionEvent)->pCallback = pCallback; + + AddToQueue( *pTransitionEvent ); +} + +bool PresentationManager::IsBusy(void) const +{ + return (mpCurrent != 0) || mWaitingOnFade; +} + +//============================================================================= +// PresentationManager::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( unsigned int elapsedTime ) +// +// Return: void +// +//============================================================================= +void PresentationManager::Update( unsigned int elapsedTime ) +{ + GetTutorialManager()->Update( static_cast< float >( elapsedTime ) ); + + if( mp_PCAnimator != NULL ) + { + mp_PCAnimator->Update( static_cast<int>( elapsedTime )); + } + + if( mp_NPCAnimator != NULL ) + { + mp_NPCAnimator->Update( static_cast<int>( elapsedTime )); + } + + rAssert( mOverlay != NULL ); + mOverlay->Update( elapsedTime ); + + if( mWaitingOnFade ) + { + if( mOverlay->GetAlpha() == 0.0f ) + { + // get one extra frame of full black. + mWaitingOnFade = false; + } + return; + } + if( mpCurrent == NULL ) + { + mpCurrent = GetFirst(); + + if (mpCurrent != NULL ) + { + if( mpCurrent->pCallback != NULL ) + { + mpCurrent->pCallback->OnPresentationEventBegin( mpCurrent ); + } + mpPlayerDrawable->SetPlayer( mpCurrent->GetPlayer() ); + mpPlayerDrawable->SetRenderLayer( mpCurrent->GetRenderLayer() ); + + mpCurrent->Start(); + mWaitingOnFade = false; + } + } + + if( mpCurrent != NULL ) + { + bool finished = !mpCurrent->Update( elapsedTime ); + + if( finished ) + { + if( mpCurrent->pCallback != NULL ) + { + mpCurrent->pCallback->OnPresentationEventEnd( mpCurrent ); + } + mpCurrent->Stop(); + mpPlayerDrawable->SetPlayer( NULL ); + + ReturnToPool( mpCurrent ); + + mpCurrent = NULL; + } + } +} + +//============================================================================= +// PresentationManager::ClearQueue +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationManager::ClearQueue() +{ + if( mpCurrent == NULL ) + { + mpCurrent = GetFirst(); + } + + while ( mpCurrent != NULL ) + { + if( mpCurrent->pCallback != NULL ) + { + mpCurrent->pCallback->OnPresentationEventEnd( mpCurrent ); + } + + mpCurrent->Stop(); + + ReturnToPool( mpCurrent ); + + mpCurrent = GetFirst(); + }; + + mpPlayerDrawable->SetPlayer( NULL ); +} + +//============================================================================= +// PresentationManager::GetCameraTargetForLineOfDialog +//============================================================================= +// Description: what should the camera look at for this line of dialog +// +// Parameters: lineOfDialog - which line are we on? +// +// Return: CameraTarget - PC, NPC, or Don't Care +// +//============================================================================= +const tName PresentationManager::GetCameraTargetForLineOfDialog( const unsigned int lineOfDialog ) const +{ + size_t size = mCameraForLineOfDialog.size(); + if( lineOfDialog >= size ) + { + return tName( "NONE" ); + } + else + { + const tName& returnMe = mCameraForLineOfDialog[ lineOfDialog ]; + return returnMe; + } +} +//============================================================================= +// PresentationManager::HandleEvent +//============================================================================= +// Description: Comment +// +// Parameters: ( EventEnum id, void* pEventData ) +// +// Return: void +// +//============================================================================= +void PresentationManager::HandleEvent( EventEnum id, void* pEventData ) +{ + switch( id ) + { + case EVENT_GUI_FADE_OUT_DONE: + { + if( mWaitingOnFade ) + { + mWaitingOnFade = false; + } + } + break; + case EVENT_LOCATOR: + { +/* + EventLocator* locator = (EventLocator*)pEventData; + if( locator->GetFlag(Locator::ACTIVE) ) + { + if( strcmp( locator->GetTriggerVolume()->GetName(), "TestTrigger" ) == 0 ) + { + NISEvent* pEvent; + QueueNIS( &pEvent, NULL ); + pEvent->fileName = "art\\camtest.p3d"; + pEvent->type = NISEvent::NIS_CAMERA; + strcpy( pEvent->camera, "cameraShape1" ); + strcpy( pEvent->animation, "CAM_cameraShape1" ); + strcpy( pEvent->controller, "MasterController" ); + pEvent->LoadFromInventory(); + } + } +*/ + break; + } + + case EVENT_CONVERSATION_INIT: + { + DialogEventData* p_dialogstruct = static_cast <DialogEventData*> (pEventData); + + // + // Register the character and the NPC with the conversation camera + // + SuperCam* camera = GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( SuperCam::CONVERSATION_CAM ); + ConversationCam* convCam = dynamic_cast< ConversationCam* >( camera ); + convCam->SetCharacter( 0, p_dialogstruct->char1 ); + convCam->SetCharacter( 1, p_dialogstruct->char2 ); + + rAssert(p_dialogstruct); + rAssert( p_dialogstruct->char1 != NULL ); + rAssert( p_dialogstruct->char2 != NULL ); + + // + // some conversations are special - race missions for example + // require different bitmaps + // + Character* char1 = p_dialogstruct->char1; + Character* char2 = p_dialogstruct->char2; + Character* npc = NULL; + Character* pc = NULL; + + if( char1->IsNPC() ) + { + npc = char1; + pc = char2; + } + else + { + rAssert( char2->IsNPC() ); + npc = char2; + pc = char1; + } + + mp_PCAnimator->SetCharacter(pc); + mp_NPCAnimator->SetCharacter(npc); + + if(pc->GetStateManager()->GetState() == CharacterAi::INCAR) + { + GetAvatarManager()->PutCharacterOnGround(pc, pc->GetTargetVehicle()); + } + + // + // Make the characters face one another + // + + // If we're talking to patty and selma, we need to make selma face the user + GameplayManager* gpm = GetGameplayManager(); + Mission* mission = gpm->GetCurrentMission(); + bool pattyAndSelma = mission->GetCurrentStage()->GetObjective()->IsPattyAndSelmaDialog(); + if( pattyAndSelma ) + { + CharacterManager* cm = GetCharacterManager(); + Character* selma = cm->GetCharacterByName( "selma" ); + if(selma == NULL && GetGameplayManager()->GetCurrentLevelIndex() == RenderEnums::L7) + { + selma = cm->GetMissionCharacter("zmale1"); + rTuneAssert(selma != NULL); + } + MakeCharactersFaceEachOther( selma, pc ); + + } + MakeCharactersFaceEachOther( char1, char2 ); + + mDialogLineNumber = -1; + mOldCamIndexNum= GetSuperCamManager()->GetSCC(PLAYER_ONE)->GetActiveSuperCamIndex(); + + // don't swap to close up camera if we are using a static cam (generally in an interior, + // where the camera movement could screw us up) + if(GetSuperCamManager()->GetSCC(PLAYER_ONE)->AllowCameraToggle()) + { + if ( GetGameplayManager()->GetCurrentMission()->DialogueCharactersTeleported() ) + { + GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(SuperCam::CONVERSATION_CAM, SuperCamCentral::CUT, 0 ); + } + else + { + GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(SuperCam::CONVERSATION_CAM, 0 ); + } + GetSuperCamManager()->GetSCC(PLAYER_ONE)->AddTarget( mp_NPCAnimator->GetCharacter()->GetTarget() ); + } + + //TO DO call Character eye blinking + mInConversation =true; + + + // make the talk-to NPC stand still + rAssert( npc ); + static_cast<NPCController*>(npc->GetController())->TransitToState( NPCController::TALKING_WITH_PLAYER ); + + tName name = npc->GetNameObject(); + ReplaceMissionBriefingBitmap( name ); + break; + } + + case EVENT_PC_TALK: + { + if( InConversation() ) + { + ++mDialogLineNumber; + tName target = GetCameraTargetForLineOfDialog( mDialogLineNumber ); + if( target == tName( "NONE" ) ) + { + ConversationCam::UsePcCam(); + } + else + { + ConversationCam::SetCameraByName( target ); + } + mp_PCAnimator->PlaySpecialAmbientAnimation(); + mp_NPCAnimator->PlaySpecialAmbientAnimation(); + } + else + { + Avatar* av = GetAvatarManager()->GetAvatarForPlayer( 0 ); + Character* character = av->GetCharacter(); + mp_PCAnimator->SetCharacter( character ); + + } + mp_PCAnimator->StartTalking(); + break; + } + case EVENT_PC_SHUTUP: + { + mp_PCAnimator->StopTalking(); + break; + } + case EVENT_NPC_TALK: + { + if( InConversation() ) + { + ++mDialogLineNumber; + const tName& target = GetCameraTargetForLineOfDialog( mDialogLineNumber ); + if( target == tName( "NONE" ) ) + { + ConversationCam::UseNpcCam(); + } + else + { + ConversationCam::SetCameraByName( target ); + } + mp_NPCAnimator->PlaySpecialAmbientAnimation(); + mp_PCAnimator->PlaySpecialAmbientAnimation(); + } + else + { + Character* character = reinterpret_cast< Character* >( pEventData ); + mp_NPCAnimator->SetCharacter( character ); + } + mp_NPCAnimator->StartTalking(); + break; + } + case EVENT_NPC_SHUTUP: + { + mp_NPCAnimator->StopTalking(); + if( !InConversation() ) + { + mp_NPCAnimator->SetCharacter( NULL ); + } + break; + } + + case EVENT_CONVERSATION_SKIP: + { + // + // Eventually this will take us to CONVERSATION_DONE + // + mInConversation = false; + break; + } + case EVENT_CONVERSATION_DONE: + { + //change camera to previous + + if ( GetGameplayManager()->GetCurrentMission()->DialogueCharactersTeleported() ) + { + GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(mOldCamIndexNum, SuperCamCentral::CUT, 0); + } + else + { + GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(mOldCamIndexNum, 0); + } + + // resume walking... + Character* npc = mp_NPCAnimator->GetCharacter(); + if( npc ) + { + static_cast<NPCController*>(npc->GetController())->TransitToState( NPCController::STOPPED ); + } + + //TO DO stop eyeblinking. + + mInConversation = false; + if ( mp_PCAnimator->GetCharacter() != NULL) + { + mp_PCAnimator->StopTalking(); + mp_PCAnimator->SetCharacter(NULL); + } + + if ( mp_NPCAnimator->GetCharacter() != NULL) + { + mp_NPCAnimator->StopTalking(); + mp_NPCAnimator->SetCharacter(NULL); + } + + + + break; + } + default: + { + // don't be lazy! handle the event! + rAssert( false ); + } + } +} + + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// PresentationManager::AddToQueue +//============================================================================= +// Description: Comment +// +// Parameters: ( PresentationEvent* pEvent ) +// +// Return: void +// +//============================================================================= +void PresentationManager::AddToQueue( PresentationEvent* pEvent ) +{ + // if you hit this assert then chances are the presentation queue is full + rAssert( mFIFOEnd < MAX_EVENT_SIZE ); + rAssert( mEventFIFO[ mFIFOEnd ] == NULL ); + + mEventFIFO[ mFIFOEnd ] = pEvent; + + mFIFOEnd++; + if( mFIFOEnd >= MAX_EVENT_SIZE ) + { + mFIFOEnd = 0; + } +} + +//============================================================================= +// PresentationManager::ReturnToPool +//============================================================================= +// Description: Comment +// +// Parameters: ( PresentationEvent* presevent ) +// +// Return: void +// +//============================================================================= +void PresentationManager::ReturnToPool( PresentationEvent* presevent ) +{ + // change to use appropriate pool without doing it the dumb way + mFMVPool->ReturnToPool( (unsigned int)presevent ); + mNISPool->ReturnToPool( (unsigned int)presevent ); + mTransitionPool->ReturnToPool( (unsigned int)presevent ); +} + +//============================================================================= +// PresentationManager::GetFirst +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: PresentationEvent +// +//============================================================================= +PresentationEvent* PresentationManager::GetFirst() +{ + rAssert( mFIFOBegin < MAX_EVENT_SIZE ); + + if( mEventFIFO[ mFIFOBegin ] != NULL ) + { + PresentationEvent* pEvent = mEventFIFO[ mFIFOBegin ]; + + mEventFIFO[ mFIFOBegin ] = NULL; + + mFIFOBegin++; + if( mFIFOBegin >= MAX_EVENT_SIZE ) + { + mFIFOBegin = 0; + } + + return( pEvent ); + } + else + { + return( NULL ); + } +} + + +//Do stuff once we are in the gameplay context +void PresentationManager::OnGameplayStart() +{ + //get ptr to the Players Avatar + mp_PCAnimator->SetCharacter(GetCharacterManager()->GetCharacter(0) ); +} + +void PresentationManager::OnGameplayStop() +{ +} + +//============================================================================= +// PresentationManager::SetCamerasForLineOfDialog +//============================================================================= +// Description: sets the cameras for specific lines of dialog +// +// Parameters: names - a vector of names that represnet cameras for lines of +// dialog +// +// Return: NONE +// +//============================================================================= +void PresentationManager::SetCamerasForLineOfDialog( const TNAMEVECTOR& names ) +{ + #ifdef RAD_DEBUG + size_t size = names.size(); + size_t i; + for( i = 0; i < size; ++i ) + { + tName name = names[ i ]; + } + #endif + mCameraForLineOfDialog.erase( mCameraForLineOfDialog.begin(), mCameraForLineOfDialog.end() ); + mCameraForLineOfDialog.insert( mCameraForLineOfDialog.begin(), names.begin(), names.end() ); +} + +//============================================================================= +// PresentationManager::InConversation() +//============================================================================= +// Description: determines if the game is in a conversation or not +// +// Parameters: NONE +// +// Return: bool - are we in a conversation or not? +// +//============================================================================= +bool PresentationManager::InConversation() const +{ + return mInConversation; +} + +//============================================================================= +// PresentationManager::StopAll +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationManager::StopAll() +{ +#ifdef RAD_WIN32 + mpFMVPlayer->ForceStop(); +#else + mpFMVPlayer->Stop(); +#endif + mpNISPlayer->Stop(); + mpTransitionPlayer->Stop(); + mpCameraPlayer->Stop(); +} + +PresentationOverlay::PresentationOverlay() : +mAlpha( 0.0f ), +mInvDuration( 0.0f ), +mStart( BLACK_TRANSPARENT ), +mEnd( BLACK_TRANSPARENT ), +mFrameCount( -1 ), +mIsAutoRemove( false ) +{} + +void PresentationOverlay::Update( unsigned int ElapsedTime ) +{ + if( mFrameCount == 0 ) + { + mAlpha = 0.0f; + mInvDuration = 0.0f; + mFrameCount = -1; + if( mIsAutoRemove ) + { + RenderLayer* rl = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( rl ); + rl->RemoveGuts( this ); + rl->Freeze(); + mIsAutoRemove = false; + } + } + else if( mAlpha > 0.0f ) + { + mAlpha -= ( (float)ElapsedTime * mInvDuration ); + if( mAlpha < 0.0f ) + { + mAlpha = 0.0f; + mInvDuration = 0.0f; + if( mIsAutoRemove ) + { + RenderLayer* rl = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot ); + rAssert( rl ); + rl->RemoveGuts( this ); + rl->Freeze(); + mIsAutoRemove = false; + } + } + } +} + +void PresentationOverlay::Display( void ) +{ + // First check if anything is visible... + int alpha = 0; + if( mFrameCount == -1 ) + { + alpha = int( ( mStart.Alpha() * mAlpha ) + ( mEnd.Alpha() * ( 1.0f - mAlpha ) ) ); + } + else + { + --mFrameCount; + if( mFrameCount < 0 ) + { + mFrameCount = 0; + } + alpha = mEnd.Alpha(); + } + if( alpha <= 0 ) + { + return; + } + // Now figure out the colour. + tColour c; + if( mFrameCount == -1 ) + { + int red = int( ( mStart.Red() * mAlpha ) + ( mEnd.Red() * ( 1.0f - mAlpha ) ) ); + int green = int( ( mStart.Green() * mAlpha ) + ( mEnd.Green() * ( 1.0f - mAlpha ) ) ); + int blue = int( ( mStart.Blue() * mAlpha ) + ( mEnd.Blue() * ( 1.0f - mAlpha ) ) ); + c.Set( red, green, blue, alpha ); + } + else + { + c.c = mEnd.c; + } + + // Let's draw poly! + p3d::stack->Push(); + bool oldZWrite = p3d::pddi->GetZWrite(); + pddiCompareMode oldZComp = p3d::pddi->GetZCompare(); + if( oldZWrite ) + { + p3d::pddi->SetZWrite( false ); + } + if( oldZComp != PDDI_COMPARE_ALWAYS ) + { + p3d::pddi->SetZCompare( PDDI_COMPARE_ALWAYS ); + } + p3d::stack->LoadIdentity(); + p3d::pddi->SetProjectionMode( PDDI_PROJECTION_ORTHOGRAPHIC ); + pddiColour oldAmbient = p3d::pddi->GetAmbientLight(); + p3d::pddi->SetAmbientLight( pddiColour( 255, 255, 255 ) ); + + pddiPrimStream* overlay = 0; + + pddiShader* overlayShader = BootupContext::GetInstance()->GetSharedShader(); + rAssert( overlayShader ); + + overlayShader->SetInt( PDDI_SP_BLENDMODE, PDDI_BLEND_ALPHA ); + overlayShader->SetInt( PDDI_SP_ISLIT, 0 ); + overlayShader->SetInt( PDDI_SP_SHADEMODE, PDDI_SHADE_FLAT ); + overlayShader->SetInt( PDDI_SP_TWOSIDED, 1 ); + + overlay = p3d::pddi->BeginPrims( overlayShader, PDDI_PRIM_TRISTRIP, PDDI_V_C, 4 ); + + overlay->Colour( c ); + overlay->Coord( 0.5f, -0.5f, 1.0f ); + overlay->Colour( c ); + overlay->Coord( -0.5f, -0.5f, 1.0f ); + overlay->Colour( c ); + overlay->Coord( 0.5f, 0.5f, 1.0f ); + overlay->Colour( c ); + overlay->Coord( -0.5f, 0.5f, 1.0f ); + + p3d::pddi->EndPrims( overlay ); + p3d::pddi->SetProjectionMode(PDDI_PROJECTION_PERSPECTIVE); + p3d::pddi->SetAmbientLight( oldAmbient ); + if( oldZWrite ) + { + p3d::pddi->SetZWrite( true ); + } + if( oldZComp != PDDI_COMPARE_ALWAYS ) + { + p3d::pddi->SetZCompare( oldZComp ); + } + p3d::stack->Pop(); +} + +//============================================================================= +// PresentationManager::CheckRaceMissionBitmaps +//============================================================================= +// Description: updates bitmaps on the mission start screen if we're entering +// a race mission +// +// Parameters: none7 +// +// Return: void +// +//============================================================================= +void PresentationManager::CheckRaceMissionBitmaps() +{ +} + +//============================================================================= +// PresentationManager::ReplaceMissionBriefingBitmap +//============================================================================= +// Description: depending on who we're talking to, we need to replace the +// picture on the mission briefing screen +// +// Parameters: conversationCharacterName - name of the character that led to +// this screen +// +// Return: void +// +//============================================================================= +void PresentationManager::ReplaceMissionBriefingBitmap( const tName& conversationCharacterName ) +{ + const tName& name = conversationCharacterName; + + // + // These are for the race missions + // + if( name == "b_nelson" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_CT.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_milhouse" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_TT.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_ralph" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_CP.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_louie" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_GB.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_witch" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_zfem1" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_zmale1" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_zmale3" ) + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + + // + // these are for the bonus missions + // + else if( name == "b_cletus") + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis01_08.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_grandpa") + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis02_08.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_skinner") + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis03_08.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_cbg") + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis04_08.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_frink") + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis05_08.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_snake") + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis06_08.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else if( name == "b_smithers") + { + CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis07_08.p3d" ); + CGuiScreenMissionLoad::ClearBitmap(); + } + else + { + return; + } + + // + // Trigger an update of the picture via scrooby + // + CGuiScreenMissionLoad::ReplaceBitmap(); +} + +//============================================================================= +// PresentationManager::MakeCharactersFaceEachOther +//============================================================================= +// Description: depending on who we're talking to, we need to replace the +// picture on the mission briefing screen +// +// Parameters: c1, c2 - the two characters that we want to face each other +// +// Return: void +// +//============================================================================= +void PresentationManager::MakeCharactersFaceEachOther( Character* c0, Character* c1 ) +{ + rmt::Vector position0; + rmt::Vector position1; + + c0->GetPosition( &position0 ); + c1->GetPosition( &position1 ); + rmt::Vector offset = position1 - position0; + offset.Normalize(); + float rotation = choreo::GetWorldAngle( offset.x, offset.z ); + c0->RelocateAndReset( position0, rotation, false ); + c1->RelocateAndReset( position1, rotation + rmt::PI, false ); +} diff --git a/game/code/presentation/presentation.h b/game/code/presentation/presentation.h new file mode 100644 index 0000000..659c181 --- /dev/null +++ b/game/code/presentation/presentation.h @@ -0,0 +1,217 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 16/04/2002 + Created -- NAME +// +//============================================================================= + +#ifndef PRESENTATIONMANAGER_H +#define PRESENTATIONMANAGER_H + +//======================================== +// Nested Includes +//======================================== + +#include <radmath/radmath.hpp> +#include <p3d/entity.hpp> +#include <p3d/drawable.hpp> +#include <events/eventlistener.h> + +#include <memory/allocpool.h> +#include <memory/stlallocators.h> +//#include <presentation/language.h> +#include <presentation/presevents/fmvevent.h> +#include <presentation/presevents/nisevent.h> +#include <presentation/presevents/presentationevent.h> +#include <presentation/presevents/transevent.h> + +#include <render/enums/renderenums.h> +#include <vector> + +//======================================== +// Forward References +//======================================== +class Character; +class NISPlayer; +class FMVPlayer; +class CameraPlayer; +class TransitionPlayer; +class PlayerDrawable; +class SuperCam; +class PresentationAnimator; + +//======================================== +// typedefs +//======================================== + +typedef AllocPool< FMVEvent > FMVEventPool; +typedef AllocPool< NISEvent > NISEventPool; +typedef AllocPool< TransitionEvent > TransitionEventPool; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +/*============================================================================= + This drawable is used to a poly over the camera to fade out the scene, etc. +This was being done by the frontend, but it relies on a scrooby project being +loaded and while playing a movie during game play we don't have that. + This could also be used for putting a texture over the screen, but that's not +implemented at this time. +=============================================================================*/ +const tColour BLACK( 0x00, 0x00, 0x00, 0xFF ); +const tColour WHITE( 0xFF, 0xFF, 0xFF, 0xFF ); +const tColour BLACK_TRANSPARENT( 0x00, 0x00, 0x00, 0x00 ); +const tColour WHITE_TRANSPARENT( 0xFF, 0xFF, 0xFF, 0x00 ); +class PresentationOverlay : public tDrawable +{ +public: + PresentationOverlay(); + + virtual void Display(); + void Update( unsigned int ElapsedTime ); + + void SetStart( tColour Colour ) { mStart = Colour; } + void SetEnd( tColour Colour ) { mEnd = Colour; } + // Note setting the duration begins the fading from one colour to another. + void SetDuration( float Duration ) { mInvDuration = 0.001f / Duration; mAlpha = 1.0f; mFrameCount = -1; } + void SetFrames( int FrameCount ) { mFrameCount = FrameCount; } // Hold start colour for this many frames. + float GetAlpha( void ) const { return mAlpha; } + void SetRemoveOnComplete( bool AutoRemove ) { mIsAutoRemove = AutoRemove; } + +protected: + float mAlpha; + float mInvDuration; + tColour mStart; + tColour mEnd; + int mFrameCount; + bool mIsAutoRemove : 1; +}; + +class PresentationManager : public EventListener, + public PresentationEvent::PresentationEventCallBack, + public LoadingManager::ProcessRequestsCallback +{ + public: + // Static Methods for accessing this singleton. + static PresentationManager* CreateInstance(); + static PresentationManager* GetInstance(); + static void DestroyInstance(); + + void Initialize(); + void Finalize(); + void OnGameplayStart(); + void OnGameplayStop(); + + void InitializePlayerDrawable(); + void FinalizePlayerDrawable(); + + // Free frontend, play movie, reload frontend. + void PlayFMV( const char* FileName, PresentationEvent::PresentationEventCallBack* pCallback = 0, + bool IsSkippable = true, + bool StopMusic = false, + bool IsLocalized = true ); + + // Creates an event and passes it back. Adds this event to the queue. + void QueueFMV( FMVEvent** pFMVEvent, + PresentationEvent::PresentationEventCallBack* pCallback ); + + // Creates an event and passes it back. Adds this event to the queue. + void QueueNIS( NISEvent** pNISEvent, + PresentationEvent::PresentationEventCallBack* pCallback ); + + // Creates an event and passes it back. Adds this event to the queue. + void QueueTransition( TransitionEvent** pTransitionEvent, + PresentationEvent::PresentationEventCallBack* pCallback ); + + // Scales the p3d stack by 11.9 + void ClearQueue(); + bool IsQueueEmpty() { return( mEventFIFO[ mFIFOBegin ] == NULL ); } + bool IsBusy(void) const; + + void Update( unsigned int elapsedTime ); + + FMVPlayer* GetFMVPlayer() { return( mpFMVPlayer ); } + NISPlayer* GetNISPlayer() { return( mpNISPlayer ); } + TransitionPlayer* GetTransPlayer() { return( mpTransitionPlayer ); } + CameraPlayer* GetCameraPlayer() {return( mpCameraPlayer ); } + + virtual void HandleEvent( EventEnum id, void* pEventData ); + PresentationAnimator* GetAnimatorNpc(); + PresentationAnimator* GetAnimatorPc(); + typedef std::vector< tName, s2alloc<tName> > TNAMEVECTOR; + void SetCamerasForLineOfDialog( const TNAMEVECTOR& names ); + bool InConversation() const; + void StopAll(); + void CheckRaceMissionBitmaps(); + void ReplaceMissionBriefingBitmap( const tName& conversationCharacterName ); + void MakeCharactersFaceEachOther( Character* c0, Character* c1 ); + + protected: + void AddToQueue( PresentationEvent* pEvent ); + const tName GetCameraTargetForLineOfDialog( const unsigned int lineOfDialog ) const; + void ReturnToPool( PresentationEvent* presevent ); + + virtual void OnPresentationEventBegin( PresentationEvent* pEvent ); + virtual void OnPresentationEventLoadComplete( PresentationEvent* pEvent ); + virtual void OnPresentationEventEnd( PresentationEvent* pEvent ); + virtual void OnProcessRequestsComplete( void* pUserData ); + + // Gets the first event in the queue + PresentationEvent* GetFirst(); + private: + PresentationManager(); + virtual ~PresentationManager(); + + //Prevent wasteful constructor creation. + PresentationManager( const PresentationManager& presentationManager ); + PresentationManager& operator=( const PresentationManager& presentationManager ); + + // Pointer to the one and only instance of this singleton. + static PresentationManager* spInstance; + + TransitionEventPool* mTransitionPool; + NISEventPool* mNISPool; + FMVEventPool* mFMVPool; + + SuperCam* mp_oldcam; + unsigned int mOldCamIndexNum; + + + // Very simple implementation of a queue. I don't actually + // even know if it works. + static const unsigned int MAX_EVENT_SIZE = 10; + PresentationEvent* mEventFIFO[ MAX_EVENT_SIZE ]; + unsigned int mFIFOBegin; + unsigned int mFIFOEnd; + + PresentationEvent* mpCurrent; + + FMVPlayer* mpFMVPlayer; + NISPlayer* mpNISPlayer; + CameraPlayer* mpCameraPlayer; + TransitionPlayer* mpTransitionPlayer; + + PlayerDrawable* mpPlayerDrawable; + PresentationAnimator* mp_PCAnimator; + PresentationAnimator* mp_NPCAnimator; +// Language::Language mLanguage; + int mDialogLineNumber; + TNAMEVECTOR mCameraForLineOfDialog; + PresentationEvent::PresentationEventCallBack* mpPlayCallback; + bool mInConversation : 1; + bool mWaitingOnFade : 1; + PresentationOverlay* mOverlay; +}; + +// A little syntactic sugar for getting at this singleton. +inline PresentationManager* GetPresentationManager() { return( PresentationManager::GetInstance() ); } + +#endif //PRESENTATIONMANAGER_H + diff --git a/game/code/presentation/presentationanimator.cpp b/game/code/presentation/presentationanimator.cpp new file mode 100644 index 0000000..a719030 --- /dev/null +++ b/game/code/presentation/presentationanimator.cpp @@ -0,0 +1,367 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: PresentationAnimator.cpp +// +// Description: Implement PresentationAnimator +// +// History: 9/24/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> + +//======================================== +// Project Includes +//======================================== +#include <ai/sequencer/actioncontroller.h> +#include <ai/sequencer/action.h> +#include <memory/srrmemory.h> + +#include <presentation/blinker.h> +#include <presentation/mouthflapper.h> +#include <presentation/presentationanimator.h> + +#include <worldsim/character/character.h> +#include <vector> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//============================================================================= +// Forward Declarations +//============================================================================= + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// PresentationAnimator::PresentationAnimator +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PresentationAnimator::PresentationAnimator(): + mCharacter( NULL ), + mMouthFlapper( NULL ), + mRandomSelection( true ), + mTalkTime(0) +{ + MEMTRACK_PUSH_GROUP( "PresentationAnimator" ); + mMouthFlapper = new(GMA_LEVEL_OTHER) MouthFlapper(); + mMouthFlapper->AddRef(); + MEMTRACK_POP_GROUP( "PresentationAnimator" ); +} + +//============================================================================== +// PresentationAnimator::~PresentationAnimator +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PresentationAnimator::~PresentationAnimator() +{ + mMouthFlapper->Release(); +} +//============================================================================= +// PresentationAnimator::AddAmbientAnimations +//============================================================================= +// Description: Comment +// +// Parameters: ( Character* pCharacter ) +// +// Return: void +// +//============================================================================= +void PresentationAnimator::AddAmbientAnimations( const TNAMEVECTOR& animations ) +{ + if( !animations.empty() ) + { + mAnimationNames.erase( mAnimationNames.begin(), mAnimationNames.end() ); + mAnimationNames.insert( mAnimationNames.begin(), animations.begin(), animations.end() ); + } +} + +//============================================================================= +// PresentationAnimator::ClearAmbientAnimations +//============================================================================= +// Description: Comment +// +// Parameters: +// +// Return: void +// +//============================================================================= +void PresentationAnimator::ClearAmbientAnimations( void ) +{ + mAnimationNames.erase( mAnimationNames.begin(), mAnimationNames.end() ); +} + + +//============================================================================= +// PresentationAnimator::ChooseNextAnimation +//============================================================================= +// Description: Chooses the next animation from a list of animation names +// +// Parameters: NONE +// +// Return: tName - the name of the animation chosen +// +//============================================================================= +const tName PresentationAnimator::ChooseNextAnimation() +{ + size_t size = mAnimationNames.size(); + if( size == 0 ) + { + return tName( "NONE" ); + } + else + { + tName returnMe = mAnimationNames[ 0 ]; + mAnimationNames.erase( mAnimationNames.begin() ); + return returnMe; + } +} + +//============================================================================= +// PresentationAnimator::ChooseRandomAnimation +//============================================================================= +// Description: Chooses a random animation from the vector of potential +// animation names that have been set in the script +// +// Parameters: NONE +// +// Return: tName - the name of the animation chosen +// +//============================================================================= +const tName PresentationAnimator::ChooseRandomAnimation() const +{ + int size = mAnimationNames.size(); + if( size == 0 ) + { + return tName( "NONE" ); + } + else + { + int randomNumber = rand(); + int selection = randomNumber % size; + return mAnimationNames[ selection ]; + } +} + +//============================================================================= +// PresentationAnimator::SetCharacter +//============================================================================= +// Description: Comment +// +// Parameters: ( Character* pCharacter ) +// +// Return: void +// +//============================================================================= +void PresentationAnimator::SetCharacter( Character* pCharacter ) +{ + mCharacter = pCharacter; + mMouthFlapper->SetCharacter( pCharacter ); +} + +//============================================================================= +// PresentationAnimator::GetCharacter +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: Character +// +//============================================================================= +Character* PresentationAnimator::GetCharacter() +{ + return mCharacter; +} + +//============================================================================= +// PresentationAnimator::PlaySpecialAmbientAnimation +//============================================================================= +// Description: triggers playing of a special ambient animation - ie homer +// scratching himself +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationAnimator::PlaySpecialAmbientAnimation() +{ + tName chosenAnimationName; + if( mRandomSelection ) + { + chosenAnimationName = ChooseRandomAnimation(); + } + else + { + chosenAnimationName = ChooseNextAnimation(); + } + + if( ( chosenAnimationName == "NONE" ) || ( chosenAnimationName == "none" ) ) + { + return; + } + + if( mCharacter == NULL ) + { + return; + } + bool canPlay = mCharacter->CanPlayAnimation( chosenAnimationName ); + if( canPlay ) + { + ActionController* actionController = mCharacter->GetActionController(); + rAssert( actionController != NULL ); + Sequencer* pSeq = actionController->GetNextSequencer(); + rAssert( pSeq != NULL ); + if( !pSeq->IsBusy() ) + { + pSeq->BeginSequence(); + PlayAnimationAction* pAction = 0; + pAction = new PlayAnimationAction( mCharacter, chosenAnimationName ); + pAction->AbortWhenMovementOccurs( true ); + pSeq->AddAction( pAction ); + pSeq->EndSequence(); + } + } + else + { + #ifdef RAD_DEBUG + const char* characterName = mCharacter->GetNameDangerous(); + const char* animationName = chosenAnimationName.GetText(); + rDebugPrintf + ( + "PresentationAnimator::PlaySpecialAmbientAnimation, character'%s' cannont play'%s'\n", + characterName, + animationName + ); + #endif + } +} + +//============================================================================= +// PresentationAnimator::SetRandomSelection +//============================================================================= +// Description: should the animations be chosen in order or randomly from the +// set of animations +// +// Parameters: random - random or not +// +// Return: NONE +// +//============================================================================= +void PresentationAnimator::SetRandomSelection( const bool random ) +{ + mRandomSelection = random; +} + +const bool PresentationAnimator::GetRandomSelection() const +{ + return mRandomSelection; +} + + +//============================================================================= +// PresentationAnimator::StartTalking +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationAnimator::StartTalking() +{ + if( mCharacter != NULL ) + { + mCharacter->GetPuppet()->GetEngine()->GetPoseEngine()->AddPoseDriver( 2, mMouthFlapper ); + } + mMouthFlapper->SetIsEnabled( true ); +} + +//============================================================================= +// PresentationAnimator::StopTalking +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationAnimator::StopTalking() +{ + mMouthFlapper->SetIsEnabled( false ); + if( mCharacter != NULL ) + { + mCharacter->GetPuppet()->GetEngine()->GetPoseEngine()->RemovePoseDriver( 2, mMouthFlapper ); + } +} + +//============================================================================= +// PresentationAnimator::Talkfor +//============================================================================= +void PresentationAnimator::TalkFor(int time) +{ + mTalkTime = time; + StartTalking(); +} + +//============================================================================= +// PresentationAnimator::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( int elapsedTime ) +// +// Return: void +// +//============================================================================= +void PresentationAnimator::Update( int elapsedTime ) +{ + if(mTalkTime > 0) + { + if((mTalkTime - elapsedTime) < 0) + { + mTalkTime = 0; + StopTalking(); + } + else + { + mTalkTime -= elapsedTime; + } + } + + + //mBlinker->Update( elapsedTime ); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/presentation/presentationanimator.h b/game/code/presentation/presentationanimator.h new file mode 100644 index 0000000..b2d455a --- /dev/null +++ b/game/code/presentation/presentationanimator.h @@ -0,0 +1,70 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: presentationanimator.h +// +// Description: Blahblahblah +// +// History: 9/24/2002 + Created -- NAME +// +//============================================================================= + +#ifndef PRESENTATIONANIMATOR_H +#define PRESENTATIONANIMATOR_H + +//======================================== +// Nested Includes +//======================================== +#include <vector> + +#include <memory/stlallocators.h> + + +//======================================== +// Forward References +//======================================== + +class Character; +class MouthFlapper; + +//============================================================================= +// +// Synopsis: PresentationAnimator +// +//============================================================================= + +class PresentationAnimator +{ +public: + PresentationAnimator(); + virtual ~PresentationAnimator(); + + void SetCharacter( Character* pCharacter ); + Character* GetCharacter(); + + typedef std::vector< tName, s2alloc<tName> > TNAMEVECTOR; + void AddAmbientAnimations( const TNAMEVECTOR& animations ); + void ClearAmbientAnimations( void ); + void PlaySpecialAmbientAnimation(); + void SetRandomSelection( const bool random ); + const bool GetRandomSelection() const; + void StartTalking(); + void StopTalking(); + void TalkFor(int time); + void Update( int elapsedTime ); + +private: + const tName ChooseNextAnimation(); + const tName ChooseRandomAnimation() const; + PresentationAnimator( const PresentationAnimator& presentationanimator ); + PresentationAnimator& operator=( const PresentationAnimator& presentationanimator ); + + Character* mCharacter; + MouthFlapper* mMouthFlapper; + TNAMEVECTOR mAnimationNames; + bool mRandomSelection; + int mTalkTime; +}; + + +#endif //PRESENTATIONANIMATOR_H diff --git a/game/code/presentation/presevents/allpresevents.cpp b/game/code/presentation/presevents/allpresevents.cpp new file mode 100644 index 0000000..9182536 --- /dev/null +++ b/game/code/presentation/presevents/allpresevents.cpp @@ -0,0 +1,4 @@ +#include <presentation/presevents/fmvevent.cpp> +#include <presentation/presevents/nisevent.cpp> +#include <presentation/presevents/presentationevent.cpp> +#include <presentation/presevents/transevent.cpp> diff --git a/game/code/presentation/presevents/fmvevent.cpp b/game/code/presentation/presevents/fmvevent.cpp new file mode 100644 index 0000000..70235f0 --- /dev/null +++ b/game/code/presentation/presevents/fmvevent.cpp @@ -0,0 +1,74 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: fmvevent.cpp +// +// Description: Implement FMVEvent +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> + +//======================================== +// Project Includes +//======================================== + +#include <presentation/fmvplayer/fmvplayer.h> +#include <presentation/presentation.h> +#include <presentation/presevents/fmvevent.h> +#include <memory/srrmemory.h> +#include <render/rendermanager/rendermanager.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +FMVEvent::FMVEvent () : PresentationEvent () +{ +} + + +FMVEvent::~FMVEvent () +{ +} + + + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// FMVEvent::GetPlayer +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: AnimationPlayer +// +//============================================================================= +AnimationPlayer* FMVEvent::GetPlayer() +{ + return( GetPresentationManager()->GetFMVPlayer() ); +} + +FMVEvent::FMVEventData::FMVEventData() : AudioIndex( 0 ), Allocator( GMA_LEVEL_MOVIE ), KillMusic( false ) +{ +}
\ No newline at end of file diff --git a/game/code/presentation/presevents/fmvevent.h b/game/code/presentation/presevents/fmvevent.h new file mode 100644 index 0000000..498d0a1 --- /dev/null +++ b/game/code/presentation/presevents/fmvevent.h @@ -0,0 +1,62 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +#ifndef FMVEVENT_H +#define FMVEVENT_H + +//======================================== +// Nested Includes +//======================================== + +#include <presentation/presevents/presentationevent.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class FMVEvent : public PresentationEvent +{ + public: + FMVEvent (); + virtual ~FMVEvent (); + + AnimationPlayer* GetPlayer(); + void SetAudioIndex(unsigned int idx) { mData.AudioIndex = idx; } + void SetAllocator( GameMemoryAllocator Alloc ) { mData.Allocator = Alloc; } + void KillMusic() { mData.KillMusic = true; } + + struct FMVEventData + { + FMVEventData(); + unsigned int AudioIndex; + GameMemoryAllocator Allocator; + bool KillMusic; + }; + + static const unsigned int AUDIO_INDEX_ENGLISH = 0; + static const unsigned int AUDIO_INDEX_FRENCH = 1; + static const unsigned int AUDIO_INDEX_GERMAN = 2; + static const unsigned int AUDIO_INDEX_SPANISH = 3; + + protected: + void* GetUserData () { return reinterpret_cast<void*>(&mData); } + + FMVEventData mData; +}; + +#endif //FMVEVENT_H + diff --git a/game/code/presentation/presevents/nisevent.cpp b/game/code/presentation/presevents/nisevent.cpp new file mode 100644 index 0000000..f549d7e --- /dev/null +++ b/game/code/presentation/presevents/nisevent.cpp @@ -0,0 +1,229 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: NISevent.cpp +// +// Description: Implement NISEvent +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> + +//======================================== +// Project Includes +//======================================== + +#include <presentation/animplayer.h> +#include <presentation/cameraplayer.h> +#include <presentation/nisplayer.h> +#include <presentation/presentation.h> +#include <presentation/presevents/nisevent.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================= +// NISEvent::NISEvent +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: NISEvent +// +//============================================================================= +NISEvent::NISEvent() +{ + type = NIS_SCENEGRAPH; +} + +//============================================================================= +// NISEvent::~NISEvent +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: NISEvent +// +//============================================================================= +NISEvent::~NISEvent() +{ +} + +//============================================================================= +// NISEvent::LoadNow +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISEvent::LoadNow() +{ + AnimationPlayer* player = GetPlayer(); + + SetNames(); + + player->LoadData( fileName, false, GetUserData() ); + + player->SetPlayAfterLoad( false ); + + SetLoaded( true ); +} + +//============================================================================= +// NISEvent::LoadFromInventory +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISEvent::LoadFromInventory() +{ + AnimationPlayer* player = GetPlayer(); + + SetNames(); + + player->LoadData( fileName, true, GetUserData() ); + + SetClearWhenDone( false ); + SetLoaded( true ); +} + +//============================================================================= +// NISEvent::Init +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISEvent::Init() +{ + PresentationEvent::Init(); + + mbHasSetNames = false; +} + +//============================================================================= +// NISEvent::Start +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISEvent::Start() +{ + SetNames(); + + PresentationEvent::Start(); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// NISEvent::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( unsigned int elapsedTime ) +// +// Return: void +// +//============================================================================= +AnimationPlayer* NISEvent::GetPlayer() +{ + AnimationPlayer* player = NULL; + + switch( type ) + { + case NIS_CAMERA: + { + player = GetPresentationManager()->GetCameraPlayer(); + break; + } + case NIS_SCENEGRAPH: + { + player = GetPresentationManager()->GetNISPlayer(); + break; + } + default: + { + // trouble! + rAssert( false ); + break; + } + } + + return( player ); +} + +//============================================================================= +// NISEvent::SetNames +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void NISEvent::SetNames() +{ + if( !mbHasSetNames ) + { + mbHasSetNames = true; + + switch( type ) + { + case NIS_CAMERA: + { + CameraPlayer* player = GetPresentationManager()->GetCameraPlayer(); + player->SetNameData( controller, camera, animation ); + break; + } + case NIS_SCENEGRAPH: + { + NISPlayer* player = GetPresentationManager()->GetNISPlayer(); + player->SetNameData( controller, camera, animation ); + break; + } + default: + { + // trouble! + rAssert( false ); + break; + } + } + } +} diff --git a/game/code/presentation/presevents/nisevent.h b/game/code/presentation/presevents/nisevent.h new file mode 100644 index 0000000..6b1e684 --- /dev/null +++ b/game/code/presentation/presevents/nisevent.h @@ -0,0 +1,66 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +#ifndef NISEVENT_H +#define NISEVENT_H + +//======================================== +// Nested Includes +//======================================== + +#include <presentation/presevents/presentationevent.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class NISEvent : public PresentationEvent +{ + public: + NISEvent(); + ~NISEvent(); + + enum NISType + { + NIS_CAMERA, + NIS_SCENEGRAPH, + NUM_NIS_TYPES + }; + + NISType type; + + char controller[32]; + char camera[32]; + char animation[32]; + + void LoadNow(); + void LoadFromInventory(); + + AnimationPlayer* GetPlayer(); + + virtual void Init(); + + virtual void Start(); + protected: + private: + void SetNames(); + + bool mbHasSetNames; +}; + +#endif //NISEVENT_H + diff --git a/game/code/presentation/presevents/presentationevent.cpp b/game/code/presentation/presevents/presentationevent.cpp new file mode 100644 index 0000000..dd26a66 --- /dev/null +++ b/game/code/presentation/presevents/presentationevent.cpp @@ -0,0 +1,180 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: presentationevent.cpp +// +// Description: Implement PresentationEvent +// +// History: 22/05/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== + +// Foundation Tech +#include <raddebug.hpp> + +//======================================== +// Project Includes +//======================================== + +#include <presentation/animplayer.h> +#include <presentation/presevents/presentationevent.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// PresentationEvent::PresentationEvent +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PresentationEvent::PresentationEvent() +{ + Init(); +} + +//============================================================================== +// PresentationEvent::~PresentationEvent +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PresentationEvent::~PresentationEvent() +{ + +} + + +//============================================================================== +// PresentationEvent::OnLoadDataComplete +//============================================================================== +// +// Description: +// +// Parameters: +// +// Return: +// +//============================================================================== +void PresentationEvent::OnLoadDataComplete() +{ + if( pCallback != NULL ) + { + pCallback->OnPresentationEventLoadComplete( this ); + } +} + +//============================================================================= +// PresentationEvent::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( unsigned int elapsedTime ) +// +// Return: bool +// +//============================================================================= +bool PresentationEvent::Update( unsigned int elapsedTime ) +{ + AnimationPlayer* player = GetPlayer(); + + player->Update( elapsedTime ); + + return( player->IsPlaying() ); +} + +//============================================================================= +// PresentationEvent::Start +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationEvent::Start() +{ + AnimationPlayer* player = GetPlayer(); + + if( !mbLoaded ) + { + player->LoadData( fileName, this, false, GetUserData() ); + + mbLoaded = true; + } + player->SetKeepLayersFrozen( mbKeepLayersFrozen ); + player->SetSkippable(mbIsSkippable); + player->Play(); +} + +//============================================================================= +// PresentationEvent::Stop +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationEvent::Stop() +{ + AnimationPlayer* player = GetPlayer(); + + if( mbClearWhenDone ) + { + player->ClearData(); + } + else + { + player->Reset(); + } +} + +//============================================================================= +// PresentationEvent::Init +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void PresentationEvent::Init() +{ + mbAutoPlay = true; + mbClearWhenDone = true; + mbLoaded = false; + mbKeepLayersFrozen = false; + mbIsSkippable = true; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + diff --git a/game/code/presentation/presevents/presentationevent.h b/game/code/presentation/presevents/presentationevent.h new file mode 100644 index 0000000..ae007c0 --- /dev/null +++ b/game/code/presentation/presevents/presentationevent.h @@ -0,0 +1,107 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 22/05/2002 + Created -- NAME +// +//============================================================================= + +#ifndef PRESENTATIONEVENT_H +#define PRESENTATIONEVENT_H + +//======================================== +// Nested Includes +//======================================== + +#include <events/eventenum.h> + +#include <presentation/animplayer.h> + +#include <render/enums/renderenums.h> + +//======================================== +// Forward References +//======================================== + +class AnimationPlayer; + +//============================================================================= +// +// Synopsis: These classes make it easier for the PresentationManager to +// queue lots of animations for use on the different players. +// Keep in mind that the PresentationManager is keeping a bunch +// of these in a pool so you MUST call Init to reset all the +// members to their default values. +// +//============================================================================= + +class PresentationEvent : public AnimationPlayer::LoadDataCallBack +{ + public: + PresentationEvent(); + virtual ~PresentationEvent(); + + // Implement AnimationPlayer::LoadDataCallBack + // + virtual void OnLoadDataComplete(); + + struct PresentationEventCallBack + { + virtual void OnPresentationEventBegin( PresentationEvent* pEvent ) = 0; + virtual void OnPresentationEventLoadComplete( PresentationEvent* pEvent ) = 0; + virtual void OnPresentationEventEnd( PresentationEvent* pEvent ) = 0; + }; + + PresentationEventCallBack* pCallback; + char fileName[64]; + bool bInInventory; + + // set ClearWhenDone to true to clear all data when this event finishes + // or false to leave stuff (like the MoviePlayer) allocated. Default = true + void SetClearWhenDone( bool bClear ) { mbClearWhenDone = bClear; } + + // set AutoPlay to true to play animation immediately after loading finsihes + // Default = true + void SetAutoPlay( bool bAutoPlay ) { mbAutoPlay = bAutoPlay; } + bool GetAutoPlay() { return mbAutoPlay; } + void SetKeepLayersFrozen( bool IsKeep ) { mbKeepLayersFrozen = IsKeep; } + bool GetKeepLayersFrozen( void ) const { return mbKeepLayersFrozen; } + void SetSkippable(bool IsSkippable) {mbIsSkippable = IsSkippable;} + bool IsSkippable(void) const {return mbIsSkippable;} + + void SetRenderLayer( RenderEnums::LayerEnum layer ) { mRenderLayer = layer; } + RenderEnums::LayerEnum GetRenderLayer() { return mRenderLayer; } + + virtual AnimationPlayer* GetPlayer() = 0; + + bool Update( unsigned int elapsedTime ); + + virtual void Start(); + virtual void Stop(); + + virtual void Init(); + + protected: + void SetLoaded( bool bLoaded ) { mbLoaded = bLoaded; } + + virtual void* GetUserData () { return 0; } + + private: + + //Prevent wasteful constructor creation. + PresentationEvent( const PresentationEvent& presentationEvent ); + PresentationEvent& operator=( const PresentationEvent& presentationEvent ); + + bool mbAutoPlay : 1; + bool mbClearWhenDone : 1; + bool mbLoaded : 1; + bool mbKeepLayersFrozen : 1; + bool mbIsSkippable : 1; + RenderEnums::LayerEnum mRenderLayer; +}; + +#endif // PRESENTATIONEVENT_H + diff --git a/game/code/presentation/presevents/transevent.cpp b/game/code/presentation/presevents/transevent.cpp new file mode 100644 index 0000000..daea4a1 --- /dev/null +++ b/game/code/presentation/presevents/transevent.cpp @@ -0,0 +1,77 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: Transevent.cpp +// +// Description: Implement TransEvent +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> + +//======================================== +// Project Includes +//======================================== + +#include <presentation/presentation.h> +#include <presentation/transitionplayer.h> +#include <presentation/presevents/transevent.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// TransitionEvent::GetPlayer +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: AnimationPlayer +// +//============================================================================= +AnimationPlayer* TransitionEvent::GetPlayer() +{ + return( GetPresentationManager()->GetTransPlayer() ); +} + +//============================================================================= +// TransitionEvent::Start +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TransitionEvent::Start() +{ + TransitionPlayer* player = GetPresentationManager()->GetTransPlayer(); + + player->SetTransition( &transInfo ); + + player->Play(); +} + diff --git a/game/code/presentation/presevents/transevent.h b/game/code/presentation/presevents/transevent.h new file mode 100644 index 0000000..6c921b1 --- /dev/null +++ b/game/code/presentation/presevents/transevent.h @@ -0,0 +1,44 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 23/05/2002 + Created -- NAME +// +//============================================================================= + +#ifndef TRANSEVENT_H +#define TRANSEVENT_H + +//======================================== +// Nested Includes +//======================================== + +#include <presentation/presevents/presentationevent.h> +#include <presentation/transitionplayer.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class TransitionEvent : public PresentationEvent +{ + public: + TransitionPlayer::TransitionInfo transInfo; + + AnimationPlayer* GetPlayer(); + + virtual void Start(); + protected: +}; + +#endif //TRANSEVENT_H + diff --git a/game/code/presentation/simpleanimationplayer.cpp b/game/code/presentation/simpleanimationplayer.cpp new file mode 100644 index 0000000..dc250c8 --- /dev/null +++ b/game/code/presentation/simpleanimationplayer.cpp @@ -0,0 +1,300 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: simpleanimationplayer.cpp +// +// Description: Implement SimpleAnimationPlayer +// +// History: 29/05/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <p3d/anim/multicontroller.hpp> +#include <p3d/camera.hpp> +#include <p3d/utility.hpp> +#include <p3d/view.hpp> + +//======================================== +// Project Includes +//======================================== +#include <presentation/simpleanimationplayer.h> + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// SimpleAnimationPlayer::SimpleAnimationPlayer +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SimpleAnimationPlayer::SimpleAnimationPlayer() : + mpMasterController( NULL ), + mCycleMode( DEFAULT_CYCLE_MODE ), + mpCamera( NULL ), + mpViewCamera( NULL ), + mbSetCamera( false ), + mIntroFrames(0), + mOutroFrames(0), + mInIntro(false) +{ + strcpy( msCamera, "" ); + strcpy( msController, "" ); + strcpy( msAnimation, "" ); +} + +//============================================================================== +// SimpleAnimationPlayer::~SimpleAnimationPlayer +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SimpleAnimationPlayer::~SimpleAnimationPlayer() +{ + tRefCounted::Release( mpViewCamera ); +} + +//============================================================================= +// SimpleAnimationPlayer::Update +//============================================================================= +// Description: Comment +// +// Parameters: ( unsigned int elapsedTime ) +// +// Return: void +// +//============================================================================= +void SimpleAnimationPlayer::Update( unsigned int elapsedTime ) +{ + if ( (GetState() == ANIM_PLAYING) && mpMasterController) + { + if(mOutroFrames && (mpMasterController->GetFrame() > static_cast<float>(mNumFrames - mOutroFrames))) + { + mpMasterController->SetFrameRange(static_cast<float>(mNumFrames - mOutroFrames), static_cast<float>(mNumFrames)); + mpMasterController->SetCycleMode(FORCE_CYCLIC); + } + + mpMasterController->Advance( static_cast<float>(elapsedTime) ); + } +} + + +//============================================================================== +// SimpleAnimationPlayer::Rewind +//============================================================================== +// +// Description: +// +// Parameters: +// +// Return: +// +//============================================================================== +void SimpleAnimationPlayer::Rewind() +{ + if(mpMasterController) + { + mpMasterController->Reset(); + mpMasterController->Advance(0.0f); + + SetState( ANIM_LOADED ); + } +} + +//============================================================================= +// SimpleAnimationPlayer::ClearData +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void SimpleAnimationPlayer::ClearData() +{ + AnimationPlayer::ClearData(); + + if( mpMasterController != NULL ) + { + mpMasterController->Release(); + mpMasterController = NULL; + } + + mCycleMode = DEFAULT_CYCLE_MODE; + + if( mpCamera != NULL ) + { + mpCamera->Release(); + mpCamera = NULL; + mbSetCamera = false; + } +} + +//============================================================================= +// SimpleAnimationPlayer::SetNameData +//============================================================================= +// Description: Comment +// +// Parameters: ( char* controller, char* camera, char* animation ) +// +// Return: void +// +//============================================================================= +void SimpleAnimationPlayer::SetNameData( char* controller, char* camera, char* animation ) +{ + strcpy( msController, controller ); + if( camera != NULL ) + { + strcpy( msCamera, camera ); + } + strcpy( msAnimation, animation ); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// SimpleAnimationPlayer::DoLoaded +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void SimpleAnimationPlayer::DoLoaded() +{ + tRefCounted::Assign(mpMasterController, p3d::find<tMultiController>( msController )); + + if(mpMasterController) + { + // reset to the first frame, and update (so evrything is in the correct + // place if we display before calling update again) + mpMasterController->Reset(); + mpMasterController->SetFrame(0); + mpMasterController->Advance(0.0f); + + mpMasterController->SetCycleMode( mCycleMode ); + + mNumFrames = rmt::FtoL(mpMasterController->GetNumFrames()); + + if(mIntroFrames != 0) + { + mpMasterController->SetFrameRange(0.0f, (float)mIntroFrames); + mpMasterController->SetCycleMode( FORCE_CYCLIC ); + } + } + + if( strlen( msCamera ) > 0 ) + { + tRefCounted::Assign(mpCamera,p3d::find<tCamera>( msCamera )); + } + + mbSetCamera = false; +} + +//============================================================================= +// SimpleAnimationPlayer::DoRender +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void SimpleAnimationPlayer::DoRender() +{ + if(!mpMasterController) + { + Stop(); + return; + } + + if ( !mbSetCamera && mpCamera != NULL ) + { + tView* view = p3d::context->GetView(); + rAssert( view ); + + mpViewCamera = view->GetCamera(); + mpViewCamera->AddRef(); + + view->SetCamera( mpCamera ); + + mbSetCamera = true; + } + + if ( (mpMasterController->GetFrame() >= mpMasterController->GetNumFrames()) && (mOutroFrames == 0)) + { + if ( mbSetCamera ) + { + tView* view = p3d::context->GetView(); + rAssert( view ); + + view->SetCamera( mpViewCamera ); + tRefCounted::Release( mpViewCamera ); + } + + Stop(); + } +} + + +void SimpleAnimationPlayer::SetIntroLoop(unsigned nFrames) +{ + mIntroFrames = nFrames; +} + +void SimpleAnimationPlayer::SetOutroLoop(unsigned nFrames) +{ + mOutroFrames = nFrames; +} + +void SimpleAnimationPlayer::Play(void) +{ + AnimationPlayer::Play(); + + if(mIntroFrames) + { + mInIntro = true; + } +} + +void SimpleAnimationPlayer::DoneIntro(void) +{ + if(mpMasterController) + { + mInIntro = false; + mpMasterController->SetFrameRange(0.0f, static_cast<float>(mNumFrames)); + mpMasterController->SetCycleMode(mCycleMode); + } +} diff --git a/game/code/presentation/simpleanimationplayer.h b/game/code/presentation/simpleanimationplayer.h new file mode 100644 index 0000000..eb39bd8 --- /dev/null +++ b/game/code/presentation/simpleanimationplayer.h @@ -0,0 +1,89 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 29/05/2002 + Created -- NAME +// +//============================================================================= + +#ifndef SIMPLEANIMATIONPLAYER_H +#define SIMPLEANIMATIONPLAYER_H + +//======================================== +// Nested Includes +//======================================== +#include <p3d/anim/animate.hpp> // p3dCycleMode +#include <presentation/animplayer.h> + +//======================================== +// Forward References +//======================================== + +class tMultiController; +class tCamera; + +//============================================================================= +// +// Synopsis: Wraps up the P3D related crap involved with playing an +// animation. +// +//============================================================================= + +class SimpleAnimationPlayer : public AnimationPlayer +{ + public: + SimpleAnimationPlayer(); + virtual ~SimpleAnimationPlayer(); + + virtual void Update( unsigned int elapsedTime ); + + virtual void ClearData(); + + void SetNameData( char* controller, char* camera, char* animation ); + + void SetCycleMode( p3dCycleMode cycleMode ) { mCycleMode = cycleMode; } + void SetIntroLoop(unsigned nFrames); + void SetOutroLoop(unsigned nFrames); + + void Play(void); + void DoneIntro(void); + + void Rewind(); + + protected: + + // These set all the objects needs to play an animation + void SetController(tMultiController* pController ) { mpMasterController = pController; } + void SetCamera( tCamera* pCamera ) { mpCamera = pCamera; } + + virtual void DoLoaded(); + virtual void DoRender(); + + const char* GetAnimationName() { return( &msAnimation[0] ); } + + private: + + //Prevent wasteful constructor creation. + SimpleAnimationPlayer( const SimpleAnimationPlayer& ); + SimpleAnimationPlayer& operator=( const SimpleAnimationPlayer& ); + + char msController[32]; + char msCamera[32]; + char msAnimation[32]; + + tMultiController* mpMasterController; + p3dCycleMode mCycleMode; + tCamera* mpCamera; + tCamera* mpViewCamera; + bool mbSetCamera; + unsigned mIntroFrames; + unsigned mOutroFrames; + bool mInIntro; + unsigned mNumFrames; +}; + + +#endif // SIMPLEANIMATIONPLAYER_H diff --git a/game/code/presentation/transitionplayer.cpp b/game/code/presentation/transitionplayer.cpp new file mode 100644 index 0000000..5d7f3ce --- /dev/null +++ b/game/code/presentation/transitionplayer.cpp @@ -0,0 +1,161 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: transitionplayer.cpp +// +// Description: Implement TransitionPlayer +// +// History: 02/05/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +// Foundation Tech +#include <raddebug.hpp> +#include <p3d/view.hpp> + +//======================================== +// Project Includes +//======================================== +#include <presentation/transitionplayer.h> +#include <render/rendermanager/rendermanager.h> +#include <render/rendermanager/renderlayer.h> + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// TransitionPlayer::TransitionPlayer +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TransitionPlayer::TransitionPlayer() : + mpLayer1( NULL ), + mpLayer2( NULL ), + miIndex( static_cast< unsigned int >( -1 ) ) +{ + //init msInfo? +} + +//============================================================================== +// TransitionPlayer::~TransitionPlayer +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TransitionPlayer::~TransitionPlayer() +{ +} + +void TransitionPlayer::SetTransition( TransitionInfo* info ) +{ + rAssert( GetState() != ANIM_IDLE ); + + msInfo = *info; + + RenderManager* rm = GetRenderManager(); + + mpLayer1 = rm->mpLayer( msInfo.layer1 ); + mpLayer2 = rm->mpLayer( msInfo.layer2 ); + + miIndex = 0; + + rAssert( msInfo.length != 0 ); +} + +void TransitionPlayer::Update( unsigned int elapsedTime ) +{ + if ( GetState() == ANIM_PLAYING ) + { + if (miIndex == 0) + { + if ( mpLayer2->IsFrozen() ) + { + mpLayer2->Thaw(); + } + else if ( mpLayer2->IsDead() ) + { + mpLayer2->Resurrect(); + } + } + + miIndex += elapsedTime; + + if ( miIndex < msInfo.length ) + { + DoUpdate( elapsedTime ); + } + else + { + mpLayer1->Freeze(); + + Stop(); + } + } +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +void TransitionPlayer::DoUpdate( unsigned int elapsedTime ) +{ + switch ( msInfo.type ) + { + case TRANS_WIPE_RIGHT: + { + float f1 = static_cast<float>( miIndex ); + float f2 = static_cast<float>( msInfo.length ); + + float r = f1 / f2; + + tView* view = mpLayer2->pView( 0 ); + view->SetWindow( 0.0f, 0.0f, r, 1.0f ); + + view = mpLayer1->pView( 0 ); + view->SetWindow( r, 0.0f, 1.0f, 1.0f ); + break; + } + default : + { + //nothing + } + } +} + +//============================================================================= +// TransitionPlayer::DoRender +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TransitionPlayer::DoRender() +{ +} diff --git a/game/code/presentation/transitionplayer.h b/game/code/presentation/transitionplayer.h new file mode 100644 index 0000000..3e48fb3 --- /dev/null +++ b/game/code/presentation/transitionplayer.h @@ -0,0 +1,82 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: .h +// +// Description: Blahblahblah +// +// History: 02/05/2002 + Created -- NAME +// +//============================================================================= + +#ifndef TRANSITIONPLAYER_H +#define TRANSITIONPLAYER_H + +//======================================== +// Nested Includes +//======================================== + +#include <presentation/animplayer.h> + +#include <render/enums/renderenums.h> + +//======================================== +// Forward References +//======================================== + +class RenderLayer; + +//============================================================================= +// +// Synopsis: Blahblahblah +// +//============================================================================= + +class TransitionPlayer : public AnimationPlayer +{ + public: + TransitionPlayer(); + virtual ~TransitionPlayer(); + + enum TransitionType + { + TRANS_CROSSFADE, + TRANS_WIPE_RIGHT, + TRANS_TO_BLACK, + TRANS_FROM_BLACK, + NUM_TRANS + }; + + struct TransitionInfo + { + RenderEnums::LayerEnum layer1; + RenderEnums::LayerEnum layer2; + unsigned int length; + TransitionType type; + }; + + void SetTransition( TransitionInfo* info ); + + virtual void Update( unsigned int elapsedTime ); + protected: + virtual void DoUpdate( unsigned int elapsedTime ); + + virtual void DoLoaded() {}; + virtual void DoRender(); + + private: + + //Prevent wasteful constructor creation. + TransitionPlayer( const TransitionPlayer& transitionPlayer ); + TransitionPlayer& operator=( const TransitionPlayer& transitionPlayer ); + + RenderLayer* mpLayer1; + RenderLayer* mpLayer2; + + TransitionInfo msInfo; + unsigned int miIndex; +}; + + +#endif //TRANSITIONPLAYER_H + diff --git a/game/code/presentation/tutorialmanager.cpp b/game/code/presentation/tutorialmanager.cpp new file mode 100644 index 0000000..f78e952 --- /dev/null +++ b/game/code/presentation/tutorialmanager.cpp @@ -0,0 +1,745 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: presentation.cpp +// +// Description: Implement PresentationManager +// +// History: 16/04/2002 + Created -- NAME +// +//============================================================================= + +//======================================== +// System Includes +//======================================== + +//======================================== +// Project Includes +//======================================== +#include <data/gamedatamanager.h> +#include <events/eventmanager.h> +#include <gameflow/gameflow.h> +#include <main/commandlineoptions.h> +#include <memory/srrmemory.h> +#include <meta/locatorevents.h> +#include <mission/mission.h> +#include <mission/missionmanager.h> +#include <mission/gameplaymanager.h> +#include <mission/objectives/missionobjective.h> +#include <presentation/gui/guisystem.h> +#include <presentation/gui/ingame/guimanageringame.h> +#include <presentation/gui/ingame/guiscreenhud.h> +#include <presentation/tutorialmanager.h> +#include <presentation/tutorialmode.h> +#include <worldsim/redbrick/vehicle.h> + +#include <string.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +// Static pointer to instance of singleton. +TutorialManager* TutorialManager::spInstance = NULL; +//#define NUMBER_OF_MISSION_OBJECTIVE_MESSAGES 300 + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================= +// TutorialManager::CreateInstance +//============================================================================= +// Description: creats an instance of the singleton +// +// Parameters: () +// +// Return: TutorialManager +// +//============================================================================= +TutorialManager* TutorialManager::CreateInstance() +{ + MEMTRACK_PUSH_GROUP( "TutorialManager" ); + if( spInstance == NULL ) + { + spInstance = new TutorialManager; + rAssert( spInstance ); + } + size_t size = sizeof( TutorialManager ); + MEMTRACK_POP_GROUP( "TutorialManager" ); + return spInstance; +} + +//============================================================================= +// TutorialManager::GetInstance +//============================================================================= +// Description: gets the instance of the singleton +// +// Parameters: () +// +// Return: TutorialManager +// +//============================================================================= +TutorialManager* TutorialManager::GetInstance() +{ + return spInstance; +} + +//============================================================================= +// TutorialManager::AddToQueue +//============================================================================= +// Description: adds an item to the queue of events to process +// +// Parameters: event - the tutorial event that we want to show as soon as +// possible +// +// Return: void +// +//============================================================================= +void TutorialManager::AddToQueue( TutorialMode event ) +{ + m_Queue.push_back( event ); +} + +//============================================================================= +// TutorialManager::DestroyInstance +//============================================================================= +// Description: destroys the only instance of the singleton +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void TutorialManager::DestroyInstance() +{ + if( spInstance != NULL ) + { + delete spInstance; + spInstance = NULL; + } +} + +//============================================================================== +// TutorialManager::TutorialManager +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TutorialManager::TutorialManager() : + m_EnableTutorialMode( false ), + m_EnableTutorialEvents( true ), + m_DialogCurrentlyPlaying( false ), + m_TimeSinceDialogStart( 0.0f ), + m_tutorialsSeen( 0 ) +{ +#ifndef FINAL + // We're going to be passing enums in void* messages - they'd better be the + // same size or else we're in big trouble + size_t sizeOfEnum = sizeof( TutorialMode ); + size_t sizeOfVoid = sizeof( void* ); + rReleaseAssert( sizeOfEnum == sizeOfVoid ); +#endif + m_Queue.reserve( 16 ); + + GetGameDataManager()->RegisterGameData( this, 1 + sizeof( m_tutorialsSeen ), "Tutorial Manager" ); + + if( CommandLineOptions::Get( CLO_NO_TUTORIAL ) ) + { + m_EnableTutorialEvents = false; + } +} + +//============================================================================== +// TutorialManager::~TutorialManager +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +TutorialManager::~TutorialManager() +{ + GetEventManager()->RemoveAll( this ); +} + +//============================================================================== +// TutorialManager::HandleEvent +//============================================================================== +// Description: Handles events that are passed to this listener +// +// Parameters: id - the event id +// pEventData - any data that tags along for the ride +// +// Return: N/A. +// +//============================================================================== +void TutorialManager::HandleEvent( EventEnum id, void* pEventData ) +{ + if( id == EVENT_TUTORIAL_DIALOG_DONE ) + { + MarkDialogFinished(); + + return; + } + + if( !m_EnableTutorialMode || !m_EnableTutorialEvents ) + { + return; + } + + switch( id ) + { + case EVENT_CARD_COLLECTED: + { + AddToQueue( TUTORIAL_COLLECTOR_CARD ); + GetEventManager()->RemoveListener( this, EVENT_CARD_COLLECTED ); + break; + } + case EVENT_COLLECTED_COINS: + { + AddToQueue( TUTORIAL_COLLECTOR_COIN ); + GetEventManager()->RemoveListener( this, EVENT_COLLECTED_COINS ); + break; + } + case static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::INTERIOR_ENTRANCE ): + { + AddToQueue( TUTORIAL_INTERIOR_ENTERED ); + GetEventManager()->RemoveListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::INTERIOR_ENTRANCE ) ); + break; + } + case static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::CAR_DOOR ): + { + AddToQueue( TUTORIAL_AT_CAR_DOOR ); + GetEventManager()->RemoveListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::CAR_DOOR ) ); + break; + } + case static_cast< EventEnum >( EVENT_INTERACTIVE_GAG ): + { + AddToQueue( TUTORIAL_INTERACTIVE_GAG ); + GetEventManager()->RemoveListener( this, static_cast< EventEnum >( EVENT_INTERACTIVE_GAG ) ); + break; + } + case EVENT_ENTERING_PLAYER_CAR: + { + AddToQueue( TUTORIAL_GETTING_INTO_PLAYER_CAR ); + GetEventManager()->RemoveListener( this, EVENT_ENTERING_PLAYER_CAR ); + break; + } + case EVENT_ENTERING_TRAFFIC_CAR: + { + // + // Have we played the player car tutorial message yet? + // + bool seenDrivingTutorial = QueryTutorialSeen( TUTORIAL_GETTING_INTO_PLAYER_CAR ); + if( seenDrivingTutorial ) + { + AddToQueue( TUTORIAL_GETTING_INTO_TRAFFIC_CAR ); + GetEventManager()->RemoveListener( this, EVENT_ENTERING_TRAFFIC_CAR ); + } + else + { + AddToQueue( TUTORIAL_GETTING_INTO_PLAYER_CAR ); + SetTutorialSeen( TUTORIAL_GETTING_INTO_TRAFFIC_CAR, true ); + GetEventManager()->RemoveListener( this, EVENT_ENTERING_TRAFFIC_CAR ); + GetEventManager()->RemoveListener( this, EVENT_ENTERING_PLAYER_CAR ); + } + break; + } + case EVENT_ANIMATED_CAM_SHUTDOWN: + { + AddToQueue( TUTORIAL_START_GAME ); + GetEventManager()->RemoveListener( this, EVENT_ANIMATED_CAM_SHUTDOWN ); + break; + } + case EVENT_BONUS_MISSION_CHARACTER_APPROACHED: + { + int missionNum = reinterpret_cast< int >( pEventData ); + Mission* mission = GetMissionManager()->GetMission( missionNum ); + bool raceMission = mission->IsRaceMission(); + bool wagerMission = mission->IsWagerMission(); + + if( wagerMission ) + { + AddToQueue( TUTORIAL_WAGER_MISSION ); + } + else if( raceMission ) + { + AddToQueue( TUTORIAL_RACE ); + } + else + { + AddToQueue( TUTORIAL_BONUS_MISSION ); + } + + bool seenRace = QueryTutorialSeen( TUTORIAL_RACE ); + bool seenBonus = QueryTutorialSeen( TUTORIAL_BONUS_MISSION ); + bool seenWager = QueryTutorialSeen( TUTORIAL_WAGER_MISSION ); + if( seenRace && seenBonus && seenWager ) + { + GetEventManager()->RemoveListener( this, EVENT_MISSION_START ); + } + break; + } + case EVENT_HIT_BREAKABLE: + { + AddToQueue( TUTORIAL_BREAKABLE_DESTROYED ); + GetEventManager()->RemoveListener( this, EVENT_HIT_BREAKABLE ); + break; + } + case EVENT_UNLOCKED_CAR: + { + AddToQueue( TUTORIAL_UNLOCKED_CAR ); + GetEventManager()->RemoveListener( this, EVENT_UNLOCKED_CAR ); + break; + } + case EVENT_VEHICLE_DESTROYED: + { + // + // Check if this is a user vehicle + // + Vehicle* vehicle = reinterpret_cast< Vehicle* >( pEventData ); + rAssert( vehicle != NULL ); + if( vehicle->mVehicleType == VT_USER ) + { + AddToQueue( TUTORIAL_VEHICLE_DESTROYED ); + GetEventManager()->RemoveListener( this, EVENT_VEHICLE_DESTROYED ); + } + break; + } + case EVENT_COLLECTED_WRENCH: + { + AddToQueue( TUTORIAL_WRENCH ); + GetEventManager()->RemoveListener( this, EVENT_COLLECTED_WRENCH ); + break; + } + case EVENT_WASP_APPROACHED: + { + AddToQueue( TUTORIAL_BREAK_CAMERA ); + GetEventManager()->RemoveListener( this, EVENT_WASP_APPROACHED ); + break; + } + default: + { + rAssertMsg( false, "TutorialManager: why are we registered for messages we don't care about?" ); + break; + } + } + +// ProcessQueue(); +} + +//============================================================================== +// TutorialManager::Initialize +//============================================================================== +// Description: Initializes this manager as a listener to various event types +// +// Parameters: None +// +// Return: N/A. +// +//============================================================================== +void TutorialManager::Initialize() +{ + while( !m_Queue.empty() ) + { + m_Queue.pop_back(); + } + + GetEventManager()->AddListener( this, EVENT_CARD_COLLECTED ); + GetEventManager()->AddListener( this, EVENT_COLLECTED_COINS ); + GetEventManager()->AddListener( this, EVENT_COLLECTED_WRENCH ); + GetEventManager()->AddListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::INTERIOR_ENTRANCE ) ); + GetEventManager()->AddListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::CAR_DOOR ) ); + GetEventManager()->AddListener( this, EVENT_INTERACTIVE_GAG ); + GetEventManager()->AddListener( this, EVENT_ENTERING_PLAYER_CAR ); + GetEventManager()->AddListener( this, EVENT_ENTERING_TRAFFIC_CAR ); + GetEventManager()->AddListener( this, EVENT_ANIMATED_CAM_SHUTDOWN ); + GetEventManager()->AddListener( this, EVENT_BONUS_MISSION_CHARACTER_APPROACHED ); + GetEventManager()->AddListener( this, EVENT_HIT_BREAKABLE ); + GetEventManager()->AddListener( this, EVENT_TUTORIAL_DIALOG_DONE ); + GetEventManager()->AddListener( this, EVENT_UNLOCKED_CAR ); + GetEventManager()->AddListener( this, EVENT_VEHICLE_DESTROYED ); + GetEventManager()->AddListener( this, EVENT_WASP_APPROACHED ); +} + +//============================================================================== +// TutorialManager::MarkDialogFinished +//============================================================================== +// Description: when a piece of dialog is finished playing, you may need to play +// another +// +// Parameters: None +// +// Return: N/A. +// +//============================================================================== +void TutorialManager::MarkDialogFinished() +{ +/* + CGuiScreenHud* hud = GetCurrentHud(); + if( hud != NULL ) + { + hud->TutorialBitmapInitOutro(); + } +*/ + m_DialogCurrentlyPlaying = false; +// ProcessQueue(); +} + +//============================================================================== +// TutorialManager::ProcessQueue +//============================================================================== +// Description: takes an item out of the queue, and processes it +// +// Parameters: None +// +// Return: N/A. +// +//============================================================================== +void TutorialManager::ProcessQueue() +{ +/* + CGuiScreenHud* hud = GetCurrentHud(); + if( hud == NULL ) + { + return; + } +*/ + if( m_DialogCurrentlyPlaying ) + { + return; + } + + // + // return if there's nothing in the queue + // + size_t size = m_Queue.size(); + if( size <= 0 ) + { + return; + } + + TutorialMode event = m_Queue.front(); + + // + // Check if the event is marked in the character sheet as "already played" + // + bool alreadySeen = this->QueryTutorialSeen( event ); + if( !alreadySeen ) + { + // + // Make sure we never see this message again + // + this->SetTutorialSeen( event, true ); + +#ifndef RAD_WIN32 + switch( event ) + { + case TUTORIAL_BREAK_CAMERA: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_BREAK_CAMERA; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_BONUS_MISSION: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_BONUS_MISSION; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_BREAKABLE_DESTROYED: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_BREAKABLE_DESTROYED; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_COLLECTOR_CARD: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_COLLECTOR_CARD; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_COLLECTOR_COIN: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_COLLECTOR_COIN; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_INTERACTIVE_GAG: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_INTERACTIVE_GAG; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_INTERIOR_ENTERED: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_INTERIOR_ENTERED; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode); + break; + } + case TUTORIAL_GETTING_INTO_PLAYER_CAR: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_GETTING_INTO_PLAYER_CAR; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_GETTING_INTO_TRAFFIC_CAR: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_GETTING_INTO_TRAFFIC_CAR; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_GETTING_OUT_OF_CAR: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_GETTING_OUT_OF_CAR; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_RACE: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_RACE; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_START_GAME: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_START_GAME; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_VEHICLE_DESTROYED: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_VEHICLE_DESTROYED; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_REWARD: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_REWARD; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_UNLOCKED_CAR: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_UNLOCKED_CAR; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_WAGER_MISSION: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_WAGER_MISSION; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_WRENCH: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_WRENCH; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_AT_CAR_DOOR: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_AT_CAR_DOOR; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + case TUTORIAL_INTERACTIVE_GAG_APPROACHED: + { + m_DialogCurrentlyPlaying = true; + m_TimeSinceDialogStart = 0; + TutorialMode mode = TUTORIAL_INTERACTIVE_GAG_APPROACHED; + GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode ); + break; + } + default: + { + rAssertMsg( false, "Why don't we process this message" ); + return; + + break; + } + } +#endif + +// hud->SetTutorialMessage( event ); +// hud->TutorialBitmapShow(); + + GetGuiSystem()->GotoScreen( CGuiWindow::GUI_SCREEN_ID_TUTORIAL, 0, 0, + CLEAR_WINDOW_HISTORY | FORCE_WINDOW_CHANGE_IMMEDIATE ); + +#ifdef RAD_WIN32 + m_DialogCurrentlyPlaying = false; +#endif + GetGameFlow()->SetContext( CONTEXT_PAUSE ); + + } + + // + // Pop an item off the queue + // + m_Queue.erase( m_Queue.begin() ); +} + +//============================================================================== +// TutorialManager::Update +//============================================================================== +// Description: takes an item out of the queue, and processes it +// +// Parameters: None +// +// Return: N/A. +// +//============================================================================== +void TutorialManager::Update( const float deltaT ) +{ + CGuiScreenHud* currentHud = GetCurrentHud(); + if( currentHud != NULL && currentHud->IsActive() ) + { + // only update tutorial manager if the HUD is currently active + // +// m_TimeSinceDialogStart += deltaT; +// if( m_TimeSinceDialogStart > 10000.0f ) + { + m_TimeSinceDialogStart = 0; + m_DialogCurrentlyPlaying = false; +/* + CGuiScreenHud* hud = GetCurrentHud(); + if( hud != NULL ) + { + hud->TutorialBitmapInitOutro(); + } +*/ + } + + ProcessQueue(); + } +} + +void +TutorialManager::LoadData( const GameDataByte* dataBuffer, unsigned int numBytes ) +{ + m_EnableTutorialEvents = ( dataBuffer[ 0 ] != 0 ); + + memcpy( &m_tutorialsSeen, dataBuffer + 1, sizeof( m_tutorialsSeen ) ); +} + +void +TutorialManager::SaveData( GameDataByte* dataBuffer, unsigned int numBytes ) +{ + dataBuffer[ 0 ] = m_EnableTutorialEvents ? ~0 : 0; + + memcpy( dataBuffer + 1, &m_tutorialsSeen, sizeof( m_tutorialsSeen ) ); +} + +void +TutorialManager::ResetData() +{ +#ifdef RAD_WIN32 + + if( !GetInputManager()->GetController(0)->IsTutorialDisabled() ) + { +#endif + m_EnableTutorialEvents = true; + m_tutorialsSeen = 0; +#ifdef RAD_WIN32 + } +#endif + +#ifndef FINAL + if( CommandLineOptions::Get( CLO_NO_TUTORIAL ) ) + { + m_EnableTutorialEvents = false; + } +#endif + + // re-add event listeners + // + GetEventManager()->RemoveAll( this ); + this->Initialize(); +} + +//============================================================================= +// TutorialManager::QueryTutorialSeen +//============================================================================= +// Description: checks to see if a given tutorial has already been played +// +// Parameters: tutorial - enum of the tutorial in question +// +// Return: bool - has the tutorial been shown +// +//============================================================================= +bool TutorialManager::QueryTutorialSeen( const TutorialMode tutorial ) +{ + return (m_tutorialsSeen & (1 << tutorial)) > 0; + +} + +//============================================================================= +// TutorialManager::SetTutorialSeen +//============================================================================= +// Description: sets the status of a specific tutorial +// +// Parameters: tutorial - enum of the tutorial in question +// +// Return: bool - has the tutorial been shown +// +//============================================================================= +void TutorialManager::SetTutorialSeen( const TutorialMode tutorial, const bool seen ) +{ + if ( seen ) + { + m_tutorialsSeen |= (1 << tutorial); + } + else + { + m_tutorialsSeen &= ~(1 << tutorial); + } +} + diff --git a/game/code/presentation/tutorialmanager.h b/game/code/presentation/tutorialmanager.h new file mode 100644 index 0000000..c2a6f81 --- /dev/null +++ b/game/code/presentation/tutorialmanager.h @@ -0,0 +1,127 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: tutorialmanager.h +// +// Description: this system controls the operation of tutorial mode +// +// History: 19/12/2002 + Created -- Ian Gipson +// +//============================================================================= + +#ifndef TUTORIALMANGER_H +#define TUTORIALMANGER_H + +//======================================== +// Nested Includes +//======================================== +#include "events/eventlistener.h" +#include "presentation/tutorialmode.h" +#include <vector> + +#include <data/gamedata.h> +#include <memory/stlallocators.h> + +//======================================== +// Forward References +//======================================== + +//======================================== +// typedefs +//======================================== + + +//============================================================================= +// +// Synopsis: TutorialManager +// +//============================================================================= + +class TutorialManager : public EventListener, + public GameDataHandler +{ + public: + // Static Methods for accessing this singleton. + static TutorialManager* CreateInstance(); + static TutorialManager* GetInstance(); + static void DestroyInstance(); + + void EnableTutorialMode( const bool enabled ); + bool IsTutorialModeEnabled() const; + + void EnableTutorialEvents( const bool enabled ); + bool IsTutorialEventsEnabled() const; + + virtual void HandleEvent( EventEnum id, void* pEventData ); + void Initialize(); + void MarkDialogFinished(); + void Update( const float deltaT ); + + TutorialMode GetCurrentEventID() const; + bool IsDialogPlaying() const; + + // Implements GameDataHandler + // + virtual void LoadData( const GameDataByte* dataBuffer, unsigned int numBytes ); + virtual void SaveData( GameDataByte* dataBuffer, unsigned int numBytes ); + virtual void ResetData(); + + protected: + void AddToQueue( TutorialMode event ); + void ProcessQueue(); + + bool QueryTutorialSeen( const TutorialMode tutorial ); + void SetTutorialSeen( const TutorialMode tutorial, const bool seen ); + + static TutorialManager* spInstance; + private: + TutorialManager(); + virtual ~TutorialManager(); + + std::vector< TutorialMode, s2alloc<TutorialMode> > m_Queue; + + bool m_EnableTutorialMode : 1; // controlled by scripts + bool m_EnableTutorialEvents : 1; // controlled by user (in pause menu settings) + bool m_DialogCurrentlyPlaying : 1; + bool m_RaceMissionPlayed : 1; + bool m_BonusMissionPlayed : 1; + float m_TimeSinceDialogStart; + + int m_tutorialsSeen; // bit field + +}; + +inline TutorialManager* GetTutorialManager() { return( TutorialManager::GetInstance() ); } + +inline void TutorialManager::EnableTutorialMode( const bool enabled ) +{ + m_EnableTutorialMode = enabled; +} + +inline bool TutorialManager::IsTutorialModeEnabled() const +{ + return m_EnableTutorialMode; +} + +inline void TutorialManager::EnableTutorialEvents( const bool enabled ) +{ + m_EnableTutorialEvents = enabled; +} + +inline bool TutorialManager::IsTutorialEventsEnabled() const +{ + return m_EnableTutorialEvents; +} + +inline TutorialMode TutorialManager::GetCurrentEventID() const +{ + return m_Queue.front(); +} + +inline bool TutorialManager::IsDialogPlaying() const +{ + return m_DialogCurrentlyPlaying; +} + +#endif //PRESENTATIONMANAGER_H + diff --git a/game/code/presentation/tutorialmode.h b/game/code/presentation/tutorialmode.h new file mode 100644 index 0000000..80ed292 --- /dev/null +++ b/game/code/presentation/tutorialmode.h @@ -0,0 +1,61 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: tutorialmode.h +// +// Description: this system controls the operation of tutorial mode +// +// History: 19/12/2002 + Created -- Ian Gipson +// +//============================================================================= + +#ifndef TUTORIALMODE_H +#define TUTORIALMODE_H + +//======================================== +// Nested Includes +//======================================== + +//======================================== +// Forward References +//======================================== + +//======================================== +// typedefs +//======================================== +enum TutorialMode +{ + TUTORIAL_BREAK_CAMERA, + TUTORIAL_BONUS_MISSION, + TUTORIAL_START_GAME, + TUTORIAL_GETTING_INTO_PLAYER_CAR, + TUTORIAL_GETTING_INTO_TRAFFIC_CAR, + TUTORIAL_INTERACTIVE_GAG, + TUTORIAL_RACE, + TUTORIAL_COLLECTOR_CARD, + TUTORIAL_COLLECTOR_COIN, + TUTORIAL_REWARD, + TUTORIAL_GETTING_OUT_OF_CAR, + TUTORIAL_BREAKABLE_APPROACHED, + TUTORIAL_BREAKABLE_DESTROYED, + TUTORIAL_INTERIOR_ENTERED, + TUTORIAL_COIN_COLLECTED, //never triggered? + TUTORIAL_VEHICLE_DESTROYED, + TUTORIAL_UNLOCKED_CAR, + TUTORIAL_WRENCH, + TUTORIAL_AT_CAR_DOOR, + TUTORIAL_INTERACTIVE_GAG_APPROACHED, //never triggered + TUTORIAL_WAGER_MISSION, + TUTORIAL_INVALID, + TUTORIAL_MAX = TUTORIAL_INVALID +}; + +//============================================================================= +// +// Synopsis: +// +//============================================================================= + + +#endif //TUTORIALMODE_H + |