mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-12-11 13:11:47 +00:00
449 lines
11 KiB
C++
449 lines
11 KiB
C++
|
/*
|
||
|
===========================================================================
|
||
|
|
||
|
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 <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
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"
|
||
|
|
||
|
extern idCVar in_useJoystick;
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::~idMenuHandler
|
||
|
================================================
|
||
|
*/
|
||
|
idMenuHandler::idMenuHandler() {
|
||
|
scrollingMenu = false;
|
||
|
scrollCounter = 0;
|
||
|
activeScreen = -1;
|
||
|
nextScreen = -1;
|
||
|
transition = -1;
|
||
|
platform = 0;
|
||
|
gui = NULL;
|
||
|
cmdBar = NULL;
|
||
|
|
||
|
for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) {
|
||
|
menuScreens[ index ] = NULL;
|
||
|
}
|
||
|
|
||
|
sounds.SetNum( NUM_GUI_SOUNDS );
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::~idMenuHandler
|
||
|
================================================
|
||
|
*/
|
||
|
idMenuHandler::~idMenuHandler() {
|
||
|
Cleanup();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::Initialize
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::Initialize( const char * swfFile, idSoundWorld * sw ) {
|
||
|
Cleanup();
|
||
|
gui = new idSWF( swfFile, sw );
|
||
|
|
||
|
platform = 2;
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::AddChild
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::AddChild( idMenuWidget * widget ) {
|
||
|
widget->SetSWFObj( gui );
|
||
|
widget->SetHandlerIsParent( true );
|
||
|
children.Append( widget );
|
||
|
widget->AddRef();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::GetChildFromIndex
|
||
|
================================================
|
||
|
*/
|
||
|
idMenuWidget * idMenuHandler::GetChildFromIndex( int index ) {
|
||
|
|
||
|
if ( children.Num() == 0 ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if ( index > children.Num() ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return children[ index ];
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::GetPlatform
|
||
|
================================================
|
||
|
*/
|
||
|
int idMenuHandler::GetPlatform( bool realPlatform ) {
|
||
|
|
||
|
if ( platform == 2 && in_useJoystick.GetBool() && !realPlatform ) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return platform;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::GetPlatform
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::PlaySound( menuSounds_t type, int channel ) {
|
||
|
|
||
|
if ( gui == NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( type >= sounds.Num() ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( sounds[ type ].IsEmpty() ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int c = SCHANNEL_ANY;
|
||
|
if ( channel != -1 ) {
|
||
|
c = channel;
|
||
|
}
|
||
|
|
||
|
gui->PlaySound( sounds[ type ], c );
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::StopSound
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::StopSound( int channel ) {
|
||
|
gui->StopSound();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::Cleanup
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::Cleanup() {
|
||
|
for ( int index = 0; index < children.Num(); ++index ) {
|
||
|
assert( children[ index ]->GetRefCount() > 0 );
|
||
|
children[ index ]->Release();
|
||
|
}
|
||
|
children.Clear();
|
||
|
|
||
|
for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) {
|
||
|
if ( menuScreens[ index ] != NULL ) {
|
||
|
menuScreens[ index ]->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete gui;
|
||
|
gui = NULL;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::TriggerMenu
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::TriggerMenu() {
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::IsActive
|
||
|
================================================
|
||
|
*/
|
||
|
bool idMenuHandler::IsActive() {
|
||
|
if ( gui == NULL ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return gui->IsActive();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::ActivateMenu
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::ActivateMenu( bool show ) {
|
||
|
|
||
|
if ( gui == NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( !show ) {
|
||
|
gui->Activate( show );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
class idSWFScriptFunction_updateMenuDisplay : public idSWFScriptFunction_RefCounted {
|
||
|
public:
|
||
|
idSWFScriptFunction_updateMenuDisplay( idSWF * _gui, idMenuHandler * _handler ) {
|
||
|
gui = _gui;
|
||
|
handler = _handler;
|
||
|
}
|
||
|
idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
|
||
|
if ( handler != NULL ) {
|
||
|
int screen = parms[0].ToInteger();
|
||
|
handler->UpdateMenuDisplay( screen );
|
||
|
}
|
||
|
|
||
|
return idSWFScriptVar();
|
||
|
}
|
||
|
private:
|
||
|
idSWF * gui;
|
||
|
idMenuHandler * handler;
|
||
|
};
|
||
|
|
||
|
class idSWFScriptFunction_activateMenu : public idSWFScriptFunction_RefCounted {
|
||
|
public:
|
||
|
idSWFScriptFunction_activateMenu( idMenuHandler * _handler ) {
|
||
|
handler = _handler;
|
||
|
}
|
||
|
idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
|
||
|
if ( handler != NULL ) {
|
||
|
handler->TriggerMenu();
|
||
|
}
|
||
|
|
||
|
return idSWFScriptVar();
|
||
|
}
|
||
|
private:
|
||
|
idMenuHandler * handler;
|
||
|
};
|
||
|
|
||
|
gui->SetGlobal( "updateMenuDisplay", new (TAG_SWF) idSWFScriptFunction_updateMenuDisplay( gui, this ) );
|
||
|
gui->SetGlobal( "activateMenus", new (TAG_SWF) idSWFScriptFunction_activateMenu( this ) );
|
||
|
|
||
|
gui->Activate( show );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::Update
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::Update() {
|
||
|
|
||
|
PumpWidgetActionRepeater();
|
||
|
|
||
|
if ( gui != NULL && gui->IsActive() ) {
|
||
|
gui->Render( renderSystem, Sys_Milliseconds() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::UpdateChildren
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::UpdateChildren() {
|
||
|
for ( int index = 0; index < children.Num(); ++index ) {
|
||
|
if ( children[ index ] != NULL ) {
|
||
|
children[index]->Update();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::UpdateMenuDisplay
|
||
|
================================================
|
||
|
*/
|
||
|
void idMenuHandler::UpdateMenuDisplay( int menu ) {
|
||
|
|
||
|
if ( menuScreens[ menu ] != NULL ) {
|
||
|
menuScreens[ menu ]->Update();
|
||
|
}
|
||
|
|
||
|
UpdateChildren();
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::Update
|
||
|
================================================
|
||
|
*/
|
||
|
bool idMenuHandler::HandleGuiEvent( const sysEvent_t * sev ) {
|
||
|
|
||
|
if ( gui != NULL && activeScreen != -1 ) {
|
||
|
return gui->HandleEvent( sev );
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================================================
|
||
|
idMenuHandler::Update
|
||
|
================================================
|
||
|
*/
|
||
|
bool idMenuHandler::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) {
|
||
|
|
||
|
widgetAction_t actionType = action.GetType();
|
||
|
const idSWFParmList & parms = action.GetParms();
|
||
|
|
||
|
switch ( actionType ) {
|
||
|
case WIDGET_ACTION_ADJUST_FIELD: {
|
||
|
if ( widget != NULL && widget->GetDataSource() != NULL ) {
|
||
|
widget->GetDataSource()->AdjustField( widget->GetDataSourceFieldIndex(), parms[ 0 ].ToInteger() );
|
||
|
widget->Update();
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
case WIDGET_ACTION_FUNCTION: {
|
||
|
if ( verify( action.GetScriptFunction() != NULL ) ) {
|
||
|
action.GetScriptFunction()->Call( event.thisObject, event.parms );
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
case WIDGET_ACTION_PRESS_FOCUSED: {
|
||
|
idMenuScreen * const screen = menuScreens[ activeScreen ];
|
||
|
if ( screen != NULL ) {
|
||
|
idWidgetEvent pressEvent( WIDGET_EVENT_PRESS, 0, event.thisObject, idSWFParmList() );
|
||
|
screen->ReceiveEvent( pressEvent );
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
case WIDGET_ACTION_START_REPEATER: {
|
||
|
idWidgetAction repeatAction;
|
||
|
widgetAction_t repeatActionType = static_cast< widgetAction_t >( parms[ 0 ].ToInteger() );
|
||
|
assert( parms.Num() >= 2 );
|
||
|
int repeatDelay = DEFAULT_REPEAT_TIME;
|
||
|
if ( parms.Num() >= 3 ) {
|
||
|
repeatDelay = parms[2].ToInteger();
|
||
|
}
|
||
|
repeatAction.Set( repeatActionType, parms[ 1 ], repeatDelay );
|
||
|
StartWidgetActionRepeater( widget, repeatAction, event );
|
||
|
return true;
|
||
|
}
|
||
|
case WIDGET_ACTION_STOP_REPEATER: {
|
||
|
ClearWidgetActionRepeater();
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !widget->GetHandlerIsParent() ) {
|
||
|
for ( int index = 0; index < children.Num(); ++index ) {
|
||
|
if ( children[index] != NULL ) {
|
||
|
if ( children[index]->HandleAction( action, event, widget, forceHandled ) ) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
========================
|
||
|
idMenuHandler::StartWidgetActionRepeater
|
||
|
========================
|
||
|
*/
|
||
|
void idMenuHandler::StartWidgetActionRepeater( idMenuWidget * widget, const idWidgetAction & action, const idWidgetEvent & event ) {
|
||
|
if ( actionRepeater.isActive && actionRepeater.action == action ) {
|
||
|
return; // don't attempt to reactivate an already active repeater
|
||
|
}
|
||
|
|
||
|
actionRepeater.isActive = true;
|
||
|
actionRepeater.action = action;
|
||
|
actionRepeater.widget = widget;
|
||
|
actionRepeater.event = event;
|
||
|
actionRepeater.numRepetitions = 0;
|
||
|
actionRepeater.nextRepeatTime = 0;
|
||
|
actionRepeater.screenIndex = activeScreen; // repeaters are cleared between screens
|
||
|
|
||
|
if ( action.GetParms().Num() == 2 ) {
|
||
|
actionRepeater.repeatDelay = action.GetParms()[ 1 ].ToInteger();
|
||
|
} else {
|
||
|
actionRepeater.repeatDelay = DEFAULT_REPEAT_TIME;
|
||
|
}
|
||
|
|
||
|
// do the first event immediately
|
||
|
PumpWidgetActionRepeater();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
========================
|
||
|
idMenuHandler::PumpWidgetActionRepeater
|
||
|
========================
|
||
|
*/
|
||
|
void idMenuHandler::PumpWidgetActionRepeater() {
|
||
|
if ( !actionRepeater.isActive ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( activeScreen != actionRepeater.screenIndex || nextScreen != activeScreen ) { // || common->IsDialogActive() ) {
|
||
|
actionRepeater.isActive = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( actionRepeater.nextRepeatTime > Sys_Milliseconds() ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// need to hold down longer on the first iteration before we continue to scroll
|
||
|
if ( actionRepeater.numRepetitions == 0 ) {
|
||
|
actionRepeater.nextRepeatTime = Sys_Milliseconds() + 400;
|
||
|
} else {
|
||
|
actionRepeater.nextRepeatTime = Sys_Milliseconds() + actionRepeater.repeatDelay;
|
||
|
}
|
||
|
|
||
|
if ( verify( actionRepeater.widget != NULL ) ) {
|
||
|
actionRepeater.widget->HandleAction( actionRepeater.action, actionRepeater.event, actionRepeater.widget );
|
||
|
actionRepeater.numRepetitions++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
========================
|
||
|
idMenuHandler::ClearWidgetActionRepeater
|
||
|
========================
|
||
|
*/
|
||
|
void idMenuHandler::ClearWidgetActionRepeater() {
|
||
|
actionRepeater.isActive = false;
|
||
|
}
|