/* =========================================================================== Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Doom 3 BFG Edition Source Code. If not, see . In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #pragma hdrstop #include "../../idLib/precompiled.h" #include "../Game_local.h" static const int MAX_PDA_ITEMS = 15; static const int MAX_NAV_OPTIONS = 4; /* ======================== idMenuHandler_PDA::Update ======================== */ void idMenuHandler_PDA::Update() { if ( gui == NULL || !gui->IsActive() ) { return; } if ( activeScreen != nextScreen ) { if ( nextScreen == PDA_AREA_INVALID ) { menuScreens[ activeScreen ]->HideScreen( static_cast(transition) ); idMenuWidget_CommandBar * cmdBar = dynamic_cast< idMenuWidget_CommandBar * >( GetChildFromIndex( PDA_WIDGET_CMD_BAR ) ); if ( cmdBar != NULL ) { cmdBar->ClearAllButtons(); cmdBar->Update(); } idSWFSpriteInstance * menu = gui->GetRootObject().GetNestedSprite( "navBar" ); idSWFSpriteInstance * bg = gui->GetRootObject().GetNestedSprite( "background" ); idSWFSpriteInstance * edging = gui->GetRootObject().GetNestedSprite( "_fullScreen" ); if ( menu != NULL ) { menu->PlayFrame( "rollOff" ); } if ( bg != NULL ) { bg->PlayFrame( "rollOff" ); } if ( edging != NULL ) { edging->PlayFrame( "rollOff" ); } } else { if ( activeScreen > PDA_AREA_INVALID && activeScreen < PDA_NUM_AREAS && menuScreens[ activeScreen ] != NULL ) { menuScreens[ activeScreen ]->HideScreen( static_cast(transition) ); } if ( nextScreen > PDA_AREA_INVALID && nextScreen < PDA_NUM_AREAS && menuScreens[ nextScreen ] != NULL ) { menuScreens[ nextScreen ]->UpdateCmds(); menuScreens[ nextScreen ]->ShowScreen( static_cast(transition) ); } } transition = MENU_TRANSITION_INVALID; activeScreen = nextScreen; } idPlayer * player = gameLocal.GetLocalPlayer(); if ( player != NULL ) { if ( activeScreen == PDA_AREA_USER_DATA ) { bool isPlaying = player->IsSoundChannelPlaying( SND_CHANNEL_PDA_AUDIO ); UpdateAudioLogPlaying( isPlaying ); } if ( activeScreen == PDA_AREA_VIDEO_DISKS ) { bool isPlaying = player->IsSoundChannelPlaying( SND_CHANNEL_PDA_VIDEO ); UdpateVideoPlaying( isPlaying ); } } idMenuHandler::Update(); } /* ================================================ idMenuHandler::TriggerMenu ================================================ */ void idMenuHandler_PDA::TriggerMenu() { nextScreen = PDA_AREA_USER_DATA; transition = MENU_TRANSITION_FORCE; } /* ======================== idMenuHandler_PDA::ActivateMenu ======================== */ void idMenuHandler_PDA::ActivateMenu( bool show ) { idMenuHandler::ActivateMenu( show ); if ( show ) { // Add names to pda idPlayer * player = gameLocal.GetLocalPlayer(); if ( player == NULL ) { return; } pdaNames.Clear(); for ( int j = 0; j < player->GetInventory().pdas.Num(); j++ ) { const idDeclPDA * pda = player->GetInventory().pdas[ j ]; idList< idStr > names; names.Append( pda->GetPdaName() ); pdaNames.Append( names ); } idMenuWidget_DynamicList * pdaList = dynamic_cast< idMenuWidget_DynamicList * >( GetChildFromIndex( PDA_WIDGET_PDA_LIST ) ); if ( pdaList != NULL ) { pdaList->SetListData( pdaNames ); } navOptions.Clear(); navOptions.Append( idLocalization::GetString( "#str_04190" ) ); navOptions.Append( idLocalization::GetString( "#str_01442" ) ); navOptions.Append( idLocalization::GetString( "#str_01440" ) ); navOptions.Append( idLocalization::GetString( "#str_01414" ) ); idMenuWidget_NavBar * navBar = dynamic_cast< idMenuWidget_NavBar * >( GetChildFromIndex( PDA_WIDGET_NAV_BAR ) ); if ( navBar != NULL ) { navBar->SetListHeadings( navOptions ); navBar->SetFocusIndex( 0 ); navBar->Update(); } idMenuWidget_CommandBar * cmdBar = dynamic_cast< idMenuWidget_CommandBar * >( GetChildFromIndex( PDA_WIDGET_CMD_BAR ) ); if ( cmdBar != NULL ) { cmdBar->ClearAllButtons(); cmdBar->Update(); } } else { nextScreen = PDA_AREA_INVALID; activeScreen = PDA_AREA_INVALID; } } /* ======================== idMenuHandler_PDA::Initialize ======================== */ void idMenuHandler_PDA::Initialize( const char * swfFile, idSoundWorld * sw ) { idMenuHandler::Initialize( swfFile, sw ); //--------------------- // Initialize the menus //--------------------- #define BIND_PDA_SCREEN( screenId, className, menuHandler ) \ menuScreens[ (screenId) ] = new (TAG_SWF) className(); \ menuScreens[ (screenId) ]->Initialize( menuHandler ); \ menuScreens[ (screenId) ]->AddRef(); \ menuScreens[ (screenId) ]->SetNoAutoFree( true ); for ( int i = 0; i < PDA_NUM_AREAS; ++i ) { menuScreens[ i ] = NULL; } BIND_PDA_SCREEN( PDA_AREA_USER_DATA, idMenuScreen_PDA_UserData, this ); BIND_PDA_SCREEN( PDA_AREA_USER_EMAIL, idMenuScreen_PDA_UserEmails, this ); BIND_PDA_SCREEN( PDA_AREA_VIDEO_DISKS, idMenuScreen_PDA_VideoDisks, this ); BIND_PDA_SCREEN( PDA_AREA_INVENTORY, idMenuScreen_PDA_Inventory, this ); pdaScrollBar.SetSpritePath( "pda_persons", "info", "scrollbar" ); pdaScrollBar.Initialize( this ); pdaScrollBar.SetNoAutoFree( true ); pdaList.SetSpritePath( "pda_persons", "info", "list" ); pdaList.SetNumVisibleOptions( MAX_PDA_ITEMS ); pdaList.SetWrappingAllowed( true ); pdaList.SetNoAutoFree( true ); while ( pdaList.GetChildren().Num() < MAX_PDA_ITEMS ) { idMenuWidget_Button * const buttonWidget = new (TAG_SWF) idMenuWidget_Button(); buttonWidget->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_USER, pdaList.GetChildren().Num() ); buttonWidget->Initialize( this ); if ( menuScreens[ PDA_AREA_USER_DATA ] != NULL ) { idMenuScreen_PDA_UserData * userDataScreen = dynamic_cast< idMenuScreen_PDA_UserData * >( menuScreens[ PDA_AREA_USER_DATA ] ); if ( userDataScreen != NULL ) { buttonWidget->RegisterEventObserver( userDataScreen->GetUserData() ); buttonWidget->RegisterEventObserver( userDataScreen->GetObjective() ); buttonWidget->RegisterEventObserver( userDataScreen->GetAudioFiles() ); } } if ( menuScreens[ PDA_AREA_USER_EMAIL ] != NULL ) { idMenuScreen_PDA_UserEmails * userEmailScreen = dynamic_cast< idMenuScreen_PDA_UserEmails * >( menuScreens[ PDA_AREA_USER_EMAIL ] ); if ( userEmailScreen != NULL ) { buttonWidget->RegisterEventObserver( &userEmailScreen->GetInbox() ); buttonWidget->RegisterEventObserver( userEmailScreen ); } } buttonWidget->RegisterEventObserver( &pdaScrollBar ); pdaList.AddChild( buttonWidget ); } pdaList.AddChild( &pdaScrollBar ); pdaList.Initialize( this ); navBar.SetSpritePath( "navBar", "options" ); navBar.Initialize( this ); navBar.SetNumVisibleOptions( MAX_NAV_OPTIONS ); navBar.SetWrappingAllowed( true ); navBar.SetButtonSpacing( 20.0f, 25.0f, 75.0f ); navBar.SetInitialXPos( 40.0f ); navBar.SetNoAutoFree( true ); for ( int count = 0; count < ( MAX_NAV_OPTIONS * 2 - 1 ); ++count ) { idMenuWidget_NavButton * const navButton = new (TAG_SWF) idMenuWidget_NavButton(); if ( count < MAX_NAV_OPTIONS - 1 ) { navButton->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_NAV, count ); } else if ( count < ( ( MAX_NAV_OPTIONS - 1 ) * 2 ) ) { int index = ( count - ( MAX_NAV_OPTIONS - 1 ) ) + 1; navButton->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_NAV, index ); } else { navButton->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_NAV, -1 ); } navBar.AddChild( navButton ); } // // command bar // commandBarWidget.SetAlignment( idMenuWidget_CommandBar::LEFT ); commandBarWidget.SetSpritePath( "prompts" ); commandBarWidget.Initialize( this ); commandBarWidget.SetNoAutoFree( true ); AddChild( &navBar ); AddChild( &pdaList ); AddChild( &pdaScrollBar ); AddChild( &commandBarWidget ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_DOWN_LSTICK ) ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, WIDGET_EVENT_SCROLL_UP_LSTICK ) ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ) ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ) ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_DOWN ) ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, WIDGET_EVENT_SCROLL_UP ) ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_RELEASE ) ); pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_RELEASE ) ); menuScreens[ PDA_AREA_USER_DATA ]->RegisterEventObserver( &pdaList ); menuScreens[ PDA_AREA_USER_EMAIL ]->RegisterEventObserver( &pdaList ); idPlayer * player = gameLocal.GetLocalPlayer(); if ( player != NULL ) { for ( int j = 0; j < MAX_WEAPONS; j++ ) { const char * weaponDefName = va( "def_weapon%d", j ); const char *weap = player->spawnArgs.GetString( weaponDefName ); if ( weap != NULL && *weap != NULL ) { const idDeclEntityDef * weaponDef = gameLocal.FindEntityDef( weap, false ); if ( weaponDef != NULL ) { declManager->FindMaterial( weaponDef->dict.GetString( "pdaIcon" ) ); declManager->FindMaterial( weaponDef->dict.GetString( "hudIcon" ) ); } } } } class idPDAGGUIClose : public idSWFScriptFunction_RefCounted { public: idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) { idPlayer * player = gameLocal.GetLocalPlayer(); if ( player != NULL ) { player->TogglePDA(); } return idSWFScriptVar(); } }; if ( gui != NULL ) { gui->SetGlobal( "closePDA", new idPDAGGUIClose() ); } // precache sounds // don't load gui music for the pause menu to save some memory const idSoundShader * soundShader = NULL; soundShader = declManager->FindSound( "gui/list_scroll", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_SCROLL ] = soundShader->GetName(); } soundShader = declManager->FindSound( "gui/btn_PDA_advance", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_ADVANCE ] = soundShader->GetName(); } soundShader = declManager->FindSound( "gui/btn_PDA_back", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_BACK ] = soundShader->GetName(); } soundShader = declManager->FindSound( "gui/pda_next_tab", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_BUILD_ON ] = soundShader->GetName(); } soundShader = declManager->FindSound( "gui/pda_prev_tab", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_BUILD_OFF ] = soundShader->GetName(); } soundShader = declManager->FindSound( "gui/btn_set_focus", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_FOCUS ] = soundShader->GetName(); } soundShader = declManager->FindSound( "gui/btn_roll_over", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_ROLL_OVER ] = soundShader->GetName(); } soundShader = declManager->FindSound( "gui/btn_roll_out", true ); if ( soundShader != NULL ) { sounds[ GUI_SOUND_ROLL_OUT ] = soundShader->GetName(); } } /* ======================== idMenuHandler_PDA::HandleAction ======================== */ bool idMenuHandler_PDA::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) { if ( activeScreen == PDA_AREA_INVALID ) { return true; } widgetAction_t actionType = action.GetType(); const idSWFParmList & parms = action.GetParms(); if ( event.type == WIDGET_EVENT_COMMAND ) { if ( menuScreens[ activeScreen ] != NULL && !forceHandled ) { if ( menuScreens[ activeScreen ]->HandleAction( action, event, widget, true ) ) { if ( actionType == WIDGET_ACTION_GO_BACK ) { PlaySound( GUI_SOUND_BACK ); } else { PlaySound( GUI_SOUND_ADVANCE ); } return true; } } } switch ( actionType ) { case WIDGET_ACTION_PDA_SELECT_USER: { int index = parms[0].ToInteger(); idMenuWidget_DynamicList * pdaList = dynamic_cast< idMenuWidget_DynamicList * >( GetChildFromIndex( PDA_WIDGET_PDA_LIST ) ); if ( pdaList != NULL ) { pdaList->SetViewIndex( pdaList->GetViewOffset() + index ); pdaList->SetFocusIndex( index ); } return true; } case WIDGET_ACTION_SCROLL_TAB: { if ( transition != MENU_TRANSITION_INVALID ) { return true; } int delta = parms[0].ToInteger(); idMenuWidget_NavBar * navBar = dynamic_cast< idMenuWidget_NavBar * >( GetChildFromIndex( PDA_WIDGET_NAV_BAR ) ); if ( navBar != NULL ) { int focused = navBar->GetFocusIndex(); focused += delta; if ( focused < 0 ) { focused = navBar->GetNumVisibleOptions() - 1; } else if ( focused >= navBar->GetNumVisibleOptions() ) { focused = 0; } navBar->SetViewIndex( focused ); navBar->SetFocusIndex( focused, true ); navBar->Update(); nextScreen = activeScreen + delta; if ( nextScreen < 0 ) { nextScreen = PDA_NUM_AREAS - 1; } else if ( nextScreen == PDA_NUM_AREAS ) { nextScreen = 0; } if ( delta < 0 ) { transition = MENU_TRANSITION_BACK; } else { transition = MENU_TRANSITION_ADVANCE; } } return true; } case WIDGET_ACTION_PDA_SELECT_NAV: { int index = parms[0].ToInteger(); if ( index == -1 && activeScreen == PDA_AREA_USER_EMAIL ) { idMenuScreen_PDA_UserEmails * screen = dynamic_cast< idMenuScreen_PDA_UserEmails * const >( menuScreens[ PDA_AREA_USER_EMAIL ] ); if ( screen ) { screen->ShowEmail( false ); } return true; } // click on the current nav tab if ( index == -1 ) { return true; } idMenuWidget_NavBar * navBar = dynamic_cast< idMenuWidget_NavBar * >( GetChildFromIndex( PDA_WIDGET_NAV_BAR ) ); if ( navBar != NULL ) { navBar->SetViewIndex( navBar->GetViewOffset() + index ); navBar->SetFocusIndex( index, true ); navBar->Update(); if ( index < activeScreen ) { nextScreen = index; transition = MENU_TRANSITION_BACK; } else if ( index > activeScreen ) { nextScreen = index; transition = MENU_TRANSITION_ADVANCE; } } return true; } case WIDGET_ACTION_SELECT_PDA_AUDIO: { if ( activeScreen == PDA_AREA_USER_DATA ) { int index = parms[0].ToInteger(); idMenuWidget_DynamicList * pdaList = dynamic_cast< idMenuWidget_DynamicList * >( GetChildFromIndex( PDA_WIDGET_PDA_LIST ) ); bool change = false; if ( pdaList != NULL ) { int pdaIndex = pdaList->GetViewIndex(); change = PlayPDAAudioLog( pdaIndex, index ); } if ( change ) { if ( widget->GetParent() != NULL ) { idMenuWidget_DynamicList * audioList = dynamic_cast< idMenuWidget_DynamicList * >( widget->GetParent() ); int index = parms[0].ToInteger(); if ( audioList != NULL ) { audioList->SetFocusIndex( index ); } } } } return true; } case WIDGET_ACTION_SELECT_PDA_VIDEO: { if ( activeScreen == PDA_AREA_VIDEO_DISKS ) { int index = parms[0].ToInteger(); if ( menuScreens[ PDA_AREA_VIDEO_DISKS ] != NULL ) { idMenuScreen_PDA_VideoDisks * screen = dynamic_cast< idMenuScreen_PDA_VideoDisks * const >( menuScreens[ PDA_AREA_VIDEO_DISKS ] ); if ( screen != NULL ) { screen->SelectedVideoToPlay( index ); } } } return true; } } return idMenuHandler::HandleAction( action, event, widget, forceHandled ); } /* ======================== idMenuHandler_PDA::PlayPDAAudioLog ======================== */ bool idMenuHandler_PDA::PlayPDAAudioLog( int pdaIndex, int audioIndex ) { idPlayer * player = gameLocal.GetLocalPlayer(); if ( player != NULL ) { const idDeclPDA * pda = player->GetInventory().pdas[ pdaIndex ]; if ( pda != NULL && pda->GetNumAudios() > audioIndex ) { const idDeclAudio *aud = pda->GetAudioByIndex( audioIndex ); if ( audioFile == aud ) { player->EndAudioLog(); return true; } else if ( aud != NULL ) { audioFile = aud; player->EndAudioLog(); player->PlayAudioLog( aud->GetWave() ); return true; } } } return false; } /* ======================== idMenuHandler_PDA::GetMenuScreen ======================== */ idMenuScreen * idMenuHandler_PDA::GetMenuScreen( int index ) { if ( index < 0 || index >= PDA_NUM_AREAS ) { return NULL; } return menuScreens[ index ]; } /* ======================== idMenuHandler_PDA::GetMenuScreen ======================== */ void idMenuHandler_PDA::UpdateAudioLogPlaying( bool playing ) { if ( playing != audioLogPlaying && activeScreen == PDA_AREA_USER_DATA && menuScreens[ activeScreen ] != NULL ) { menuScreens[ activeScreen ]->Update(); } audioLogPlaying = playing; if ( !playing ) { audioFile = NULL; } } /* ======================== idMenuHandler_PDA::GetMenuScreen ======================== */ void idMenuHandler_PDA::UdpateVideoPlaying( bool playing ) { if ( playing != videoPlaying ) { if ( activeScreen == PDA_AREA_VIDEO_DISKS && menuScreens[ activeScreen ] != NULL ) { idPlayer * player = gameLocal.GetLocalPlayer(); if ( !playing ) { player->EndVideoDisk(); } idMenuScreen_PDA_VideoDisks * screen = dynamic_cast< idMenuScreen_PDA_VideoDisks * const >( menuScreens[ PDA_AREA_VIDEO_DISKS ] ); if ( screen != NULL ) { if ( !playing ) { screen->ClearActiveVideo(); } screen->Update(); } } videoPlaying = playing; } } /* ================================================ idMenuHandler_PDA::Cleanup ================================================ */ void idMenuHandler_PDA::Cleanup() { idMenuHandler::Cleanup(); for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) { delete menuScreens[ index ]; menuScreens[ index ] = NULL; } } /* ================================================ idMenuHandler_PDA::~idMenuHandler_PDA ================================================ */ idMenuHandler_PDA::~idMenuHandler_PDA() { pdaScrollBar.Cleanup(); pdaList.Cleanup(); navBar.Cleanup(); commandBarWidget.Cleanup(); Cleanup(); }