//=========================================================================== // 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 #include #include #include #include #include #include #include // Scrooby #include #include #include #include #include #include // ATG #include //=========================================================================== // 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( 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 ); } }