You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1138 lines
42 KiB
1138 lines
42 KiB
4 years ago
|
/*==LICENSE==*
|
||
|
|
||
|
CyanWorlds.com Engine - MMOG client, server and tools
|
||
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
||
|
|
||
|
This program 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.
|
||
|
|
||
|
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
Additional permissions under GNU GPL version 3 section 7
|
||
|
|
||
|
If you modify this Program, or any covered work, by linking or
|
||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||
|
(or a modified version of those libraries),
|
||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||
|
licensors of this Program grant you additional
|
||
|
permission to convey the resulting work. Corresponding Source for a
|
||
|
non-source form of such a combination shall include the source code for
|
||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||
|
work.
|
||
|
|
||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||
|
or by snail mail at:
|
||
|
Cyan Worlds, Inc.
|
||
|
14617 N Newport Hwy
|
||
|
Mead, WA 99021
|
||
|
|
||
|
*==LICENSE==*/
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// //
|
||
|
// plAvatarInputInterface //
|
||
|
// //
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#ifdef PLASMA_EXTERNAL_RELEASE
|
||
|
//#define LIMIT_VOICE_CHAT 1
|
||
|
#endif
|
||
|
|
||
|
#include "hsConfig.h"
|
||
|
#include "hsWindows.h"
|
||
|
#include "hsTypes.h"
|
||
|
#include "plAvatarInputInterface.h"
|
||
|
|
||
|
#include "../pnInputCore/plKeyMap.h"
|
||
|
#include "../plMessage/plInputEventMsg.h"
|
||
|
|
||
|
#include "plInputInterfaceMgr.h"
|
||
|
#include "plInputManager.h"
|
||
|
#include "plInputDevice.h"
|
||
|
|
||
|
#include "../pnKeyedObject/plKey.h"
|
||
|
#include "../pnKeyedObject/plFixedKey.h"
|
||
|
#include "../pnSceneObject/plSceneObject.h"
|
||
|
#include "../pnMessage/plProxyDrawMsg.h"
|
||
|
#include "../pnMessage/plCmdIfaceModMsg.h"
|
||
|
|
||
|
// DEHACK
|
||
|
// used to run debug drawing stuff only; should never be checked in with this enabled
|
||
|
#if 0
|
||
|
#include "../FeatureLib/pfCamera/plVirtualCam.h"
|
||
|
#include "../plDrawable/plDrawableSpans.h"
|
||
|
#endif
|
||
|
|
||
|
#include "../plAudio/plVoiceChat.h"
|
||
|
#include "plInputDevice.h"
|
||
|
#include "plInputManager.h"
|
||
|
#include "hsResMgr.h"
|
||
|
#include "plgDispatch.h"
|
||
|
|
||
|
#include "hsConfig.h"
|
||
|
#include "hsMatrix44.h"
|
||
|
#include "../pnSceneObject/plSceneObject.h"
|
||
|
#include "../pnSceneObject/plCoordinateInterface.h"
|
||
|
|
||
|
#include "../pnNetCommon/plNetApp.h"
|
||
|
|
||
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
||
|
|
||
|
plAvatarInputInterface *plAvatarInputInterface::fInstance = nil;
|
||
|
|
||
|
plAvatarInputInterface::plAvatarInputInterface()
|
||
|
{
|
||
|
fInstance = this;
|
||
|
fMouseDisabled = false;
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
fCursorOpacity = 1.f;
|
||
|
fCursorTimeout = 0;
|
||
|
fCursorFadeDelay = 3.f;
|
||
|
f3rdPerson = true;
|
||
|
fInputMap = nil;
|
||
|
ISetBasicMode(); // Must be after 3rdPerson and fInputMap are set.
|
||
|
SetEnabled( true ); // Always enabled
|
||
|
|
||
|
// Add our control codes to our control map. Do NOT add the key bindings yet.
|
||
|
// Note: HERE is where you specify the actions for each command, i.e. net propagate and so forth.
|
||
|
// This part basically declares us master of the bindings for these commands.
|
||
|
|
||
|
// IF YOU ARE LOOKING TO CHANGE THE DEFAULT KEY BINDINGS, DO NOT LOOK HERE. GO TO
|
||
|
// RestoreDefaultKeyMappings()!!!!
|
||
|
|
||
|
#ifndef LIMIT_VOICE_CHAT
|
||
|
// only allow mapping of 'PushToTalk in online versions'
|
||
|
fControlMap->AddCode( S_PUSH_TO_TALK, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
#endif
|
||
|
fControlMap->AddCode( S_SET_FIRST_PERSON_MODE, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_EXIT_MODE, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
|
||
|
fControlMap->AddCode( B_CAMERA_ZOOM_IN, kControlFlagNormal );
|
||
|
fControlMap->AddCode( B_CAMERA_ZOOM_OUT, kControlFlagNormal );
|
||
|
|
||
|
fControlMap->AddCode( B_CONTROL_MODIFIER_FAST, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_MODIFIER_STRAFE, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_MOVE_FORWARD, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_MOVE_BACKWARD, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_ROTATE_LEFT, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_ROTATE_RIGHT, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_STRAFE_LEFT, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_STRAFE_RIGHT, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
|
||
|
|
||
|
fControlMap->AddCode( B_CONTROL_ALWAYS_RUN, kControlFlagToggle | kControlFlagUpEvent | kControlFlagNoRepeat );
|
||
|
|
||
|
|
||
|
fControlMap->AddCode( B_CONTROL_JUMP, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_DIVE, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_IGNORE_AVATARS, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
|
||
|
fControlMap->AddConsoleCommand( "Game.EnterChatMode" );
|
||
|
fControlMap->AddConsoleCommand( "Game.Emote.wave" );
|
||
|
fControlMap->AddConsoleCommand( "Game.Emote.laugh" );
|
||
|
fControlMap->AddConsoleCommand( "Game.Emote.clap" );
|
||
|
fControlMap->AddConsoleCommand( "Game.Emote.dance" );
|
||
|
fControlMap->AddConsoleCommand( "Game.Emote.talk" );
|
||
|
fControlMap->AddConsoleCommand( "Game.Emote.sneeze" );
|
||
|
fControlMap->AddConsoleCommand( "Game.Emote.sit" );
|
||
|
fControlMap->AddConsoleCommand( "Keyboard.ResetBindings" );
|
||
|
|
||
|
fControlMap->AddConsoleCommand( "Game.KIOpenKI" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIHelp" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KICreateMarker" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KICreateMarkerFolder" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIOpenYeeshaBook" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIToggleMini" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIPutAway" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIChatPageUp" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIChatPageDown" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIChatToStart" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIChatToEnd" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIUpSizeFont" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KIDownSizeFont" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KITakePicture" );
|
||
|
fControlMap->AddConsoleCommand( "Game.KICreateJournal" );
|
||
|
|
||
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||
|
fControlMap->AddCode( B_CONTROL_TOGGLE_PHYSICAL, kControlFlagDownEvent | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_MOVE_UP, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_CONTROL_MOVE_DOWN, kControlFlagNormal | kControlFlagNoRepeat );
|
||
|
fControlMap->AddCode( B_TOGGLE_DRIVE_MODE, kControlFlagDownEvent | kControlFlagNoRepeat );
|
||
|
fControlMap->AddConsoleCommand( "NextStatusLog" );
|
||
|
#endif
|
||
|
|
||
|
// IF YOU ARE LOOKING TO CHANGE THE DEFAULT KEY BINDINGS, DO NOT LOOK HERE. GO TO
|
||
|
// RestoreDefaultKeyMappings()!!!!
|
||
|
}
|
||
|
|
||
|
plAvatarInputInterface::~plAvatarInputInterface()
|
||
|
{
|
||
|
delete fInputMap;
|
||
|
}
|
||
|
|
||
|
//// Init/Shutdown ///////////////////////////////////////////////////////////
|
||
|
|
||
|
void plAvatarInputInterface::Init( plInputInterfaceMgr *manager )
|
||
|
{
|
||
|
plInputInterface::Init( manager );
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::Shutdown( void )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::CameraInThirdPerson(hsBool state)
|
||
|
{
|
||
|
if (state != f3rdPerson)
|
||
|
{
|
||
|
f3rdPerson = state;
|
||
|
|
||
|
if (fInputMap->IsBasic())
|
||
|
{
|
||
|
ISetBasicMode();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::IDeactivateCommand(plMouseInfo *info)
|
||
|
{
|
||
|
if (IHasControlFlag(info->fCode) && !(info->fControlFlags & (kControlFlagNoDeactivate | kControlFlagToggle)))
|
||
|
{
|
||
|
// The mapping is currently on, it's ok to deactivate, and it's not a toggle command
|
||
|
plCtrlCmd* pCmd = TRACKED_NEW plCtrlCmd( this );
|
||
|
pCmd->fNetPropagateToPlayers = info->fControlFlags & kControlFlagNetPropagate;
|
||
|
pCmd->fControlActivated = false;
|
||
|
pCmd->fControlCode = info->fCode;
|
||
|
IClearControlFlag(pCmd->fControlCode);
|
||
|
fMessageQueue->Append(pCmd);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//// IChangeInputMaps ////////////////////////////////////////////////////////
|
||
|
|
||
|
void plAvatarInputInterface::IChangeInputMaps( plAvatarInputMap *newMap )
|
||
|
{
|
||
|
newMap->fButtonState = fInputMap ? fInputMap->fButtonState : 0;
|
||
|
|
||
|
if (fInputMap)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < fInputMap->fMouseMap->fMap.GetCount(); i++)
|
||
|
{
|
||
|
plMouseInfo *info = fInputMap->fMouseMap->fMap[i];
|
||
|
IDeactivateCommand(info);
|
||
|
}
|
||
|
delete fInputMap;
|
||
|
}
|
||
|
|
||
|
fInputMap = newMap;
|
||
|
// fInputMap->fButtonState = 0;
|
||
|
// Reset();
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ISetSuspendMovementMode()
|
||
|
{
|
||
|
IChangeInputMaps(TRACKED_NEW plSuspendedMovementMap());
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ISetLadderMap()
|
||
|
{
|
||
|
IChangeInputMaps(TRACKED_NEW plLadderControlMap());
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
}
|
||
|
|
||
|
|
||
|
void plAvatarInputInterface::ISetPreLadderMap()
|
||
|
{
|
||
|
IChangeInputMaps(TRACKED_NEW plLadderMountMap());
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ISetPostLadderMap()
|
||
|
{
|
||
|
IChangeInputMaps(TRACKED_NEW plLadderDismountMap());
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ISetBasicMode()
|
||
|
{
|
||
|
plAvatarInputMap *map;
|
||
|
if (!f3rdPerson)
|
||
|
map = TRACKED_NEW plBasicFirstPersonControlMap();
|
||
|
else
|
||
|
map = TRACKED_NEW plBasicThirdPersonControlMap();
|
||
|
|
||
|
IChangeInputMaps(map);
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ISetMouseWalkMode(ControlEventCode code)
|
||
|
{
|
||
|
if (code == S_SET_WALK_BACK_MODE)
|
||
|
IChangeInputMaps(TRACKED_NEW pl3rdWalkBackwardMap());
|
||
|
else if (code == S_SET_WALK_BACK_LB_MODE)
|
||
|
IChangeInputMaps(TRACKED_NEW pl3rdWalkBackwardLBMap());
|
||
|
else
|
||
|
IChangeInputMaps(TRACKED_NEW pl3rdWalkForwardMap());
|
||
|
|
||
|
fCurrentCursor = kCursorHidden;
|
||
|
}
|
||
|
|
||
|
//// ClearKeyMap ///////////////////////////////////////////////
|
||
|
void plAvatarInputInterface::ClearKeyMap()
|
||
|
{
|
||
|
// Note: we might be clearing our key bindings, but we still want to be owners of the commands,
|
||
|
if( fControlMap != nil )
|
||
|
{
|
||
|
fControlMap->UnmapAllBindings();
|
||
|
|
||
|
// Still want this one tho
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlShiftKeyCombo( KEY_0 ), "Keyboard.ResetBindings" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//// RestoreDefaultKeyMappings ///////////////////////////////////////////////
|
||
|
|
||
|
void plAvatarInputInterface::RestoreDefaultKeyMappings( void )
|
||
|
{
|
||
|
if( fControlMap == nil )
|
||
|
return;
|
||
|
|
||
|
fControlMap->UnmapAllBindings();
|
||
|
|
||
|
#ifndef LIMIT_VOICE_CHAT
|
||
|
fControlMap->BindKey( KEY_TAB, S_PUSH_TO_TALK );
|
||
|
#endif
|
||
|
fControlMap->BindKey( KEY_F1, S_SET_FIRST_PERSON_MODE );
|
||
|
fControlMap->BindKey( plCtrlKeyCombo( KEY_F ), S_SET_FIRST_PERSON_MODE );
|
||
|
fControlMap->BindKey( KEY_BACKSPACE, B_CONTROL_EXIT_MODE );
|
||
|
fControlMap->BindKey( KEY_ESCAPE, B_CONTROL_EXIT_MODE );
|
||
|
|
||
|
fControlMap->BindKey( KEY_NUMPAD_ADD, B_CAMERA_ZOOM_IN );
|
||
|
fControlMap->BindKey( KEY_NUMPAD_SUBTRACT, B_CAMERA_ZOOM_OUT );
|
||
|
|
||
|
fControlMap->BindKey( KEY_SHIFT, B_CONTROL_MODIFIER_FAST );
|
||
|
fControlMap->BindKey( KEY_Z, B_CONTROL_MODIFIER_STRAFE );
|
||
|
fControlMap->BindKey( KEY_UP, B_CONTROL_MOVE_FORWARD );
|
||
|
fControlMap->BindKey( KEY_DOWN, B_CONTROL_MOVE_BACKWARD );
|
||
|
fControlMap->BindKey( KEY_LEFT, B_CONTROL_ROTATE_LEFT );
|
||
|
fControlMap->BindKey( KEY_RIGHT, B_CONTROL_ROTATE_RIGHT );
|
||
|
fControlMap->BindKey( KEY_COMMA, B_CONTROL_STRAFE_LEFT );
|
||
|
fControlMap->BindKey( KEY_PERIOD, B_CONTROL_STRAFE_RIGHT );
|
||
|
|
||
|
// This is now hard-coded to capslock
|
||
|
// fControlMap->BindKey( KEY_CAPSLOCK, B_CONTROL_ALWAYS_RUN );
|
||
|
|
||
|
fControlMap->BindKey( KEY_SPACE, B_CONTROL_JUMP );
|
||
|
// fControlMap->BindKey( KEY_D, B_CONTROL_DIVE );
|
||
|
fControlMap->BindKey( KEY_DELETE, B_CONTROL_IGNORE_AVATARS );
|
||
|
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_1 ), "Game.Emote.wave" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_2 ), "Game.Emote.laugh" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_3 ), "Game.Emote.clap" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_4 ), "Game.Emote.dance" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_5 ), "Game.Emote.talk" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_6 ), "Game.Emote.sneeze" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_7 ), "Game.Emote.sit" );
|
||
|
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlShiftKeyCombo( KEY_0 ), "Keyboard.ResetBindings" );
|
||
|
|
||
|
// KI shortcut keyboard commands
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_F2, "Game.KIOpenKI" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_F3, "Game.KIOpenYeeshaBook" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_F4, "Game.KIHelp" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_HOME ), "Game.KIToggleMini" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_END ), "Game.KIPutAway" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_PAGEUP, "Game.KIChatPageUp" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_PAGEDOWN, "Game.KIChatPageDown" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_HOME, "Game.KIChatToStart" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_END, "Game.KIChatToEnd" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_NUMPAD_ADD ), "Game.KIUpSizeFont" );
|
||
|
fControlMap->BindKeyToConsoleCmd( plCtrlKeyCombo( KEY_NUMPAD_SUBTRACT ), "Game.KIDownSizeFont" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_F5, "Game.KITakePicture" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_F6, "Game.KICreateJournal" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_F7, "Game.KICreateMarker" );
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_F8, "Game.KICreateMarkerFolder" );
|
||
|
|
||
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||
|
fControlMap->BindKey( plShiftKeyCombo( KEY_P ), B_CONTROL_TOGGLE_PHYSICAL );
|
||
|
fControlMap->BindKey( KEY_U, B_CONTROL_MOVE_UP );
|
||
|
fControlMap->BindKey( KEY_H, B_CONTROL_MOVE_DOWN );
|
||
|
fControlMap->BindKey( plShiftKeyCombo( KEY_C ), B_TOGGLE_DRIVE_MODE );
|
||
|
|
||
|
fControlMap->BindKeyToConsoleCmd( KEY_L, "NextStatusLog" );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::SetLadderMode()
|
||
|
{
|
||
|
ISetPreLadderMap();
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ClearLadderMode()
|
||
|
{
|
||
|
ISetBasicMode();
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::SuspendMouseMovement()
|
||
|
{
|
||
|
ISetSuspendMovementMode();
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::EnableMouseMovement()
|
||
|
{
|
||
|
ISetBasicMode();
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::EnableJump(hsBool val)
|
||
|
{
|
||
|
EnableControl(val, B_CONTROL_JUMP);
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::EnableForwardMovement(hsBool val)
|
||
|
{
|
||
|
EnableControl(val, B_CONTROL_MOVE_FORWARD);
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::EnableControl(hsBool val, ControlEventCode code)
|
||
|
{
|
||
|
if (val)
|
||
|
IEnableControl(code);
|
||
|
else
|
||
|
IDisableControl(code);
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ForceAlwaysRun(hsBool val)
|
||
|
{
|
||
|
plCtrlCmd *pCmd = TRACKED_NEW plCtrlCmd( this );
|
||
|
pCmd->fControlCode = B_CONTROL_ALWAYS_RUN;
|
||
|
pCmd->fControlActivated = val;
|
||
|
pCmd->fNetPropagateToPlayers = false;
|
||
|
|
||
|
fMessageQueue->Append( pCmd );
|
||
|
}
|
||
|
|
||
|
//// IEval ///////////////////////////////////////////////////////////////////
|
||
|
// Gets called once per IUpdate(), just like normal IEval()s
|
||
|
|
||
|
hsBool plAvatarInputInterface::IEval( double secs, hsScalar del, UInt32 dirty )
|
||
|
{
|
||
|
fCursorTimeout += del;
|
||
|
if( fCursorTimeout > fCursorFadeDelay )
|
||
|
{
|
||
|
if( fCursorTimeout > fCursorFadeDelay + 2.f )
|
||
|
fCursorOpacity = 0.f;
|
||
|
else
|
||
|
fCursorOpacity = 1.f - ( ( fCursorTimeout - fCursorFadeDelay ) / 2.f );
|
||
|
}
|
||
|
else
|
||
|
fCursorOpacity = 1.f;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//// IHandleCtrlCmd //////////////////////////////////////////////////////////
|
||
|
|
||
|
hsBool plAvatarInputInterface::IHandleCtrlCmd( plCtrlCmd *cmd )
|
||
|
{
|
||
|
switch( cmd->fControlCode )
|
||
|
{
|
||
|
case S_SET_CURSOR_UPWARD:
|
||
|
if( cmd->fControlActivated )
|
||
|
fCurrentCursor = kCursorUpward;
|
||
|
return true;
|
||
|
case S_SET_CURSOR_UP:
|
||
|
if( cmd->fControlActivated )
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
return true;
|
||
|
case S_SET_CURSOR_DOWN:
|
||
|
if( cmd->fControlActivated )
|
||
|
fCurrentCursor = kCursorDown;
|
||
|
return true;
|
||
|
case S_SET_CURSOR_RIGHT:
|
||
|
if( cmd->fControlActivated )
|
||
|
fCurrentCursor = kCursorRight;
|
||
|
return true;
|
||
|
case S_SET_CURSOR_LEFT:
|
||
|
if( cmd->fControlActivated )
|
||
|
fCurrentCursor = kCursorLeft;
|
||
|
return true;
|
||
|
case S_SET_CURSOR_HIDDEN:
|
||
|
if( cmd->fControlActivated )
|
||
|
fCurrentCursor = kCursorHidden;
|
||
|
else
|
||
|
fCurrentCursor = kCursorUp;
|
||
|
case S_SET_LADDER_CONTROL:
|
||
|
if( cmd->fControlActivated )
|
||
|
ISetLadderMap();
|
||
|
return true;
|
||
|
#if 0
|
||
|
case S_SET_FIRST_PERSON_MODE:
|
||
|
if( cmd->fControlActivated )
|
||
|
IChangeInputMaps( TRACKED_NEW plFirstPersonControlMap() );
|
||
|
return true;
|
||
|
#endif
|
||
|
case S_SET_BASIC_MODE:
|
||
|
if( cmd->fControlActivated )
|
||
|
{
|
||
|
ISetBasicMode();
|
||
|
#if 0
|
||
|
plProxyDrawMsg* Dmsg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kCamera | plProxyDrawMsg::kDestroy);
|
||
|
plgDispatch::MsgSend(Dmsg);
|
||
|
plVirtualCam::Instance()->GetPipeline()->SetDrawableTypeMask(plVirtualCam::Instance()->GetPipeline()->GetDrawableTypeMask() & ~plDrawableSpans::kCameraProxy);
|
||
|
#endif
|
||
|
}
|
||
|
return true;
|
||
|
|
||
|
|
||
|
case S_SET_WALK_MODE:
|
||
|
|
||
|
if( cmd->fControlActivated )
|
||
|
{
|
||
|
hsBool abort = false;
|
||
|
for (int i = 0; i < fMessageQueue->GetCount(); i++)
|
||
|
{
|
||
|
if ((*fMessageQueue)[i]->fControlCode == S_SET_WALK_MODE && !(*fMessageQueue)[i]->fControlActivated)
|
||
|
{
|
||
|
abort = true;
|
||
|
#if 0
|
||
|
|
||
|
plProxyDrawMsg* Dmsg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kCamera | plProxyDrawMsg::kDestroy);
|
||
|
plgDispatch::MsgSend(Dmsg);
|
||
|
plVirtualCam::Instance()->GetPipeline()->SetDrawableTypeMask(plVirtualCam::Instance()->GetPipeline()->GetDrawableTypeMask() & ~plDrawableSpans::kCameraProxy);
|
||
|
#endif
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (abort)
|
||
|
return true;
|
||
|
ISetMouseWalkMode(S_SET_WALK_MODE);
|
||
|
}
|
||
|
return true;
|
||
|
|
||
|
case S_SET_WALK_BACK_MODE:
|
||
|
|
||
|
if( cmd->fControlActivated )
|
||
|
{
|
||
|
hsBool abort = false;
|
||
|
for (int i = 0; i < fMessageQueue->GetCount(); i++)
|
||
|
{
|
||
|
if ((*fMessageQueue)[i]->fControlCode == S_SET_WALK_BACK_MODE && !(*fMessageQueue)[i]->fControlActivated)
|
||
|
{
|
||
|
abort = true;
|
||
|
#if 0
|
||
|
|
||
|
plProxyDrawMsg* Dmsg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kCamera | plProxyDrawMsg::kDestroy);
|
||
|
plgDispatch::MsgSend(Dmsg);
|
||
|
plVirtualCam::Instance()->GetPipeline()->SetDrawableTypeMask(plVirtualCam::Instance()->GetPipeline()->GetDrawableTypeMask() & ~plDrawableSpans::kCameraProxy);
|
||
|
#endif
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (abort)
|
||
|
return true;
|
||
|
ISetMouseWalkMode(S_SET_WALK_BACK_MODE);
|
||
|
}
|
||
|
return true;
|
||
|
|
||
|
case S_SET_WALK_BACK_LB_MODE:
|
||
|
|
||
|
if( cmd->fControlActivated )
|
||
|
{
|
||
|
hsBool abort = false;
|
||
|
for (int i = 0; i < fMessageQueue->GetCount(); i++)
|
||
|
{
|
||
|
if ((*fMessageQueue)[i]->fControlCode == S_SET_WALK_BACK_MODE && !(*fMessageQueue)[i]->fControlActivated)
|
||
|
{
|
||
|
abort = true;
|
||
|
#if 0
|
||
|
|
||
|
plProxyDrawMsg* Dmsg = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kCamera | plProxyDrawMsg::kDestroy);
|
||
|
plgDispatch::MsgSend(Dmsg);
|
||
|
plVirtualCam::Instance()->GetPipeline()->SetDrawableTypeMask(plVirtualCam::Instance()->GetPipeline()->GetDrawableTypeMask() & ~plDrawableSpans::kCameraProxy);
|
||
|
#endif
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (abort)
|
||
|
return true;
|
||
|
ISetMouseWalkMode(S_SET_WALK_BACK_LB_MODE);
|
||
|
}
|
||
|
return true;
|
||
|
|
||
|
case S_INCREASE_MIC_VOL:
|
||
|
plVoiceRecorder::IncreaseRecordingThreshhold();
|
||
|
return true;
|
||
|
|
||
|
case S_DECREASE_MIC_VOL:
|
||
|
plVoiceRecorder::DecreaseRecordingThreshhold();
|
||
|
return true;
|
||
|
|
||
|
/* case B_CONTROL_ACTION:
|
||
|
{
|
||
|
if (fMessageQueue[i]->fControlActivated)
|
||
|
{
|
||
|
// send a 'picked' message to the picked object
|
||
|
plPickedMsg* pPickedMsg = TRACKED_NEW plPickedMsg;
|
||
|
pPickedMsg->AddReceiver(fCurrentClickable);
|
||
|
plgDispatch::MsgSend(pPickedMsg);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// send an 'unpicked message'
|
||
|
plPickedMsg* pPickedMsg = TRACKED_NEW plPickedMsg;
|
||
|
pPickedMsg->AddReceiver(fCurrentClickable);
|
||
|
pPickedMsg->fPicked = false;
|
||
|
plgDispatch::MsgSend(pPickedMsg);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
hsBool plAvatarInputInterface::CursorInBox(plMouseEventMsg* pMsg, hsPoint4 box)
|
||
|
{
|
||
|
return ( pMsg->GetXPos() >= box.fX && pMsg->GetXPos() <= box.fY && pMsg->GetYPos() >= box.fZ && pMsg->GetYPos() <= box.fW );
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::Reset()
|
||
|
{
|
||
|
fControlFlags.Clear();
|
||
|
fKeyControlFlags.Clear();
|
||
|
fDisabledControls.Clear();
|
||
|
}
|
||
|
|
||
|
void plAvatarInputInterface::ClearMouseCursor()
|
||
|
{
|
||
|
IClearControlFlag(S_SET_CURSOR_UPWARD);
|
||
|
IClearControlFlag(S_SET_CURSOR_UP);
|
||
|
IClearControlFlag(S_SET_CURSOR_DOWN);
|
||
|
IClearControlFlag(S_SET_CURSOR_LEFT);
|
||
|
IClearControlFlag(S_SET_CURSOR_RIGHT);
|
||
|
}
|
||
|
|
||
|
hsBool plAvatarInputInterface::MsgReceive( plMessage *msg )
|
||
|
{
|
||
|
plCmdIfaceModMsg *pCMsg = plCmdIfaceModMsg::ConvertNoRef( msg );
|
||
|
if( pCMsg )
|
||
|
{
|
||
|
if (pCMsg->Cmd(plCmdIfaceModMsg::kDisableControlCode))
|
||
|
{
|
||
|
IDisableControl(pCMsg->fControlCode);
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
if (pCMsg->Cmd(plCmdIfaceModMsg::kEnableControlCode))
|
||
|
{
|
||
|
IEnableControl(pCMsg->fControlCode);
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//// MissedInputEvent ////////////////////////////////////////////////////////
|
||
|
// If we "missed" an input event, then somebody caught it above us, thus we
|
||
|
// have "lost focus" in a way. So we should stop walking/moving/whatever.
|
||
|
// Should this be in the base inputInterface, since it deals with key
|
||
|
// bindings? Perhaps, dunno yet. We'll see...
|
||
|
|
||
|
void plAvatarInputInterface::MissedInputEvent( plInputEventMsg *pMsg )
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
|
||
|
if( plKeyEventMsg::ConvertNoRef( pMsg ) == nil )
|
||
|
{
|
||
|
// We only "lose focus" if someone else grabbed a key message. Don't care about anything else.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Disable all set control flags, EXCEPT autorun. Rrrgh.
|
||
|
for( i = 0; i < fControlMap->GetNumBindings(); i++ )
|
||
|
{
|
||
|
const plKeyBinding &binding = fControlMap->GetBinding( i );
|
||
|
|
||
|
if( IHasKeyControlFlag( binding.GetCode() ) && binding.GetCode() != B_CONTROL_ALWAYS_RUN )
|
||
|
{
|
||
|
plCtrlCmd *pCmd = TRACKED_NEW plCtrlCmd( this );
|
||
|
pCmd->fControlCode = binding.GetCode();
|
||
|
pCmd->fControlActivated = false;
|
||
|
pCmd->SetCmdString( binding.GetExtendedString() );
|
||
|
|
||
|
if( binding.GetCodeFlags() & kControlFlagNetPropagate )
|
||
|
pCmd->fNetPropagateToPlayers = true;
|
||
|
else
|
||
|
pCmd->fNetPropagateToPlayers = false;
|
||
|
|
||
|
fMessageQueue->Append( pCmd );
|
||
|
IClearKeyControlFlag( binding.GetCode() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hsBool plAvatarInputInterface::IsEnterChatModeBound()
|
||
|
{
|
||
|
int i;
|
||
|
for ( i=0; i< fControlMap->GetNumBindings(); i++ )
|
||
|
{
|
||
|
const plKeyBinding &binding = fControlMap->GetBinding( i );
|
||
|
|
||
|
const char* extString = binding.GetExtendedString();
|
||
|
if ( extString && strcmp("Game.EnterChatMode",extString) == 0 )
|
||
|
{
|
||
|
if (binding.GetKey1() != plKeyCombo::kUnmapped )
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//// InterpretInputEvent /////////////////////////////////////////////////////
|
||
|
|
||
|
hsBool plAvatarInputInterface::InterpretInputEvent( plInputEventMsg *pMsg )
|
||
|
{
|
||
|
if( fInputMap == nil )
|
||
|
return false;
|
||
|
|
||
|
plMouseMap *mouseMap = fInputMap->fMouseMap;
|
||
|
|
||
|
|
||
|
plKeyEventMsg* pKeyMsg = plKeyEventMsg::ConvertNoRef(pMsg);
|
||
|
if( pKeyMsg )
|
||
|
{
|
||
|
// Handled by key bindings
|
||
|
}
|
||
|
|
||
|
if (fMouseDisabled)
|
||
|
return false;
|
||
|
|
||
|
plMouseEventMsg* pMouseMsg = plMouseEventMsg::ConvertNoRef(pMsg);
|
||
|
if (pMouseMsg)
|
||
|
{
|
||
|
UInt32 oldButtonState = fInputMap->fButtonState;
|
||
|
|
||
|
// check for button presses...
|
||
|
if (fInputMap->fButtonState & kLeftButtonDown)
|
||
|
{
|
||
|
fInputMap->fButtonState |= kLeftButtonRepeat;
|
||
|
}
|
||
|
if (fInputMap->fButtonState & kRightButtonDown)
|
||
|
{
|
||
|
fInputMap->fButtonState |= kRightButtonRepeat;
|
||
|
}
|
||
|
if (fInputMap->fButtonState & kMiddleButtonDown)
|
||
|
{
|
||
|
fInputMap->fButtonState |= kMiddleButtonRepeat;
|
||
|
}
|
||
|
if (pMouseMsg->GetButton() == kLeftButtonDown)
|
||
|
{
|
||
|
fInputMap->fButtonState |= kLeftButtonDown;
|
||
|
}
|
||
|
if (pMouseMsg->GetButton() == kLeftButtonUp)
|
||
|
{
|
||
|
fInputMap->fButtonState &= ~kLeftButtonDown;
|
||
|
fInputMap->fButtonState &= ~kLeftButtonRepeat;
|
||
|
}
|
||
|
if (pMouseMsg->GetButton() == kRightButtonDown)
|
||
|
{
|
||
|
fInputMap->fButtonState |= kRightButtonDown;
|
||
|
}
|
||
|
if (pMouseMsg->GetButton() == kRightButtonUp)
|
||
|
{
|
||
|
fInputMap->fButtonState &= ~kRightButtonDown;
|
||
|
fInputMap->fButtonState &= ~kRightButtonRepeat;
|
||
|
}
|
||
|
if (pMouseMsg->GetButton() == kMiddleButtonDown)
|
||
|
{
|
||
|
fInputMap->fButtonState |= kMiddleButtonDown;
|
||
|
}
|
||
|
if (pMouseMsg->GetButton() == kMiddleButtonUp)
|
||
|
{
|
||
|
fInputMap->fButtonState &= ~kMiddleButtonDown;
|
||
|
fInputMap->fButtonState &= ~kMiddleButtonRepeat;
|
||
|
}
|
||
|
|
||
|
if( oldButtonState != fInputMap->fButtonState || pMouseMsg->GetDX() != 0.f || pMouseMsg->GetDY() != 0.f )
|
||
|
{
|
||
|
fCursorTimeout = 0.f; // Reset cursor opacity timeout thingy
|
||
|
}
|
||
|
|
||
|
/* NOTE: I see that this interface always returns true for mouse
|
||
|
messages, even if it does nothing with them. It ends up working
|
||
|
because this interface is always last in the stack. Seems like
|
||
|
a bad idea, but it works so far and I'm not going to change it
|
||
|
unless it obviously breaks something.
|
||
|
|
||
|
Still, since we say that we've handled any mouse message, I'm
|
||
|
taking the liberty of making things simple. If a button is down,
|
||
|
we reserve focus. If not, we release it.
|
||
|
|
||
|
If things ever change so that an interface below us expects us
|
||
|
to return false for messages we don't care about, we'll have to
|
||
|
be more careful about reserving focus.
|
||
|
*/
|
||
|
if (fInputMap->fButtonState & kAnyButtonDown)
|
||
|
fManager->SetCurrentFocus(this);
|
||
|
else
|
||
|
fManager->ReleaseCurrentFocus(this);
|
||
|
|
||
|
for (int i=0; i < mouseMap->fMap.Count(); i++)
|
||
|
{
|
||
|
// is this control already set?
|
||
|
if (IHasControlFlag(mouseMap->fMap[i]->fCode))
|
||
|
{
|
||
|
// Control isn't enabled, ignore
|
||
|
if (!IControlCodeEnabled(mouseMap->fMap[i]->fCode))
|
||
|
return true;
|
||
|
|
||
|
// can we disable this control?
|
||
|
hsBool disable = false;
|
||
|
|
||
|
// can we disable this control based on a button?
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButton && !(fInputMap->fButtonState & kLeftButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButton && !(fInputMap->fButtonState & kRightButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButton && !(fInputMap->fButtonState & kMiddleButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && (fInputMap->fButtonState & kLeftButtonRepeat))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && (fInputMap->fButtonState & kRightButtonRepeat))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && (fInputMap->fButtonState & kMiddleButtonRepeat))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && !(fInputMap->fButtonState & kLeftButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && !(fInputMap->fButtonState & kRightButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && !(fInputMap->fButtonState & kMiddleButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonRepeat && !(fInputMap->fButtonState & kLeftButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonRepeat && !(fInputMap->fButtonState & kRightButtonDown))
|
||
|
disable = true;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonRepeat && !(fInputMap->fButtonState & kMiddleButtonDown))
|
||
|
disable = true;
|
||
|
|
||
|
// can we disable this control based on the cursor position?
|
||
|
if (!CursorInBox(pMouseMsg, mouseMap->fMap[i]->fBox) && mouseMap->fMap[i]->fControlFlags & kControlFlagBoxDisable)
|
||
|
disable = true;
|
||
|
|
||
|
if (disable)
|
||
|
{
|
||
|
IDeactivateCommand(mouseMap->fMap[i]);
|
||
|
continue;
|
||
|
}
|
||
|
// is it a range control? If so we need to re-send the command
|
||
|
|
||
|
if ((mouseMap->fMap[i]->fControlFlags & kControlFlagRangePos) || (mouseMap->fMap[i]->fControlFlags & kControlFlagRangeNeg))
|
||
|
{
|
||
|
plCtrlCmd* pCmd = TRACKED_NEW plCtrlCmd( this );
|
||
|
pCmd->fControlActivated = true;
|
||
|
pCmd->fControlCode = mouseMap->fMap[i]->fCode;
|
||
|
hsScalar pct = 0.0f;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangePos)
|
||
|
{
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent)
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fX - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX));
|
||
|
else
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fZ - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ));
|
||
|
}
|
||
|
else
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangeNeg)
|
||
|
{
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent)
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fY - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX));
|
||
|
else
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fW - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ));
|
||
|
}
|
||
|
pCmd->fPct = pct;
|
||
|
if (pct == 1.0f || pct == -1.0f)
|
||
|
{
|
||
|
delete pCmd;
|
||
|
break;
|
||
|
}
|
||
|
pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate;
|
||
|
fMessageQueue->Append(pCmd);
|
||
|
}
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagDelta)
|
||
|
{
|
||
|
plCtrlCmd* pCmd = TRACKED_NEW plCtrlCmd( this );
|
||
|
pCmd->fControlActivated = true;
|
||
|
pCmd->fControlCode = mouseMap->fMap[i]->fCode;
|
||
|
hsScalar pct = 0.0f;
|
||
|
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent)
|
||
|
pct = pMouseMsg->GetDX();
|
||
|
else
|
||
|
pct = pMouseMsg->GetDY();
|
||
|
|
||
|
if (pct == 0.f)
|
||
|
{
|
||
|
delete pCmd;
|
||
|
continue;
|
||
|
}
|
||
|
pCmd->fPct = pct;
|
||
|
pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate;
|
||
|
fMessageQueue->Append(pCmd);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else // if it is an 'always if in box' command see if it's not in the box
|
||
|
if ( (mouseMap->fMap[i]->fControlFlags & kControlFlagInBox) && (!CursorInBox(pMouseMsg, mouseMap->fMap[i]->fBox)) )
|
||
|
{
|
||
|
plCtrlCmd* pCmd = TRACKED_NEW plCtrlCmd( this );
|
||
|
pCmd->fControlActivated = false;
|
||
|
pCmd->fControlCode = mouseMap->fMap[i]->fCode;
|
||
|
pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate;
|
||
|
fMessageQueue->Append(pCmd);
|
||
|
continue;
|
||
|
}
|
||
|
else // the control is not set, see if we should set it.
|
||
|
{
|
||
|
// is the control disabled?
|
||
|
if (fDisabledControls.IsBitSet(mouseMap->fMap[i]->fCode))
|
||
|
continue;
|
||
|
|
||
|
// is the cursor in the appropriate box?
|
||
|
if (CursorInBox(pMouseMsg, mouseMap->fMap[i]->fBox))
|
||
|
{
|
||
|
// do we require a button?
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButton && !(fInputMap->fButtonState & kLeftButtonDown))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButton && !(fInputMap->fButtonState & kRightButtonDown))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButton && !(fInputMap->fButtonState & kMiddleButtonDown))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && (fInputMap->fButtonState & kLeftButtonRepeat))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && (fInputMap->fButtonState & kRightButtonRepeat))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && (fInputMap->fButtonState & kMiddleButtonRepeat))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonRepeat && !(fInputMap->fButtonState & kLeftButtonRepeat))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonRepeat && !(fInputMap->fButtonState & kRightButtonRepeat))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonRepeat && !(fInputMap->fButtonState & kMiddleButtonRepeat))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && !(fInputMap->fButtonState & kLeftButtonDown))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && !(fInputMap->fButtonState & kLeftButtonDown))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && !(fInputMap->fButtonState & kMiddleButtonDown))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonUp && !(pMouseMsg->GetButton() == kLeftButtonUp))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonUp && !(pMouseMsg->GetButton() == kRightButtonUp))
|
||
|
continue;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonUp && !(pMouseMsg->GetButton() == kMiddleButtonUp))
|
||
|
continue;
|
||
|
|
||
|
// okay, we're in the box and either we don't require a button or our button is pressed.
|
||
|
// so set the command as 'enabled'
|
||
|
// UNLESS it has kControlFlagInBox, which means we want it sent every frame it is in the box
|
||
|
if (!(mouseMap->fMap[i]->fControlFlags & kControlFlagInBox))
|
||
|
SetControlFlag(mouseMap->fMap[i]->fCode);
|
||
|
// issue the command
|
||
|
plCtrlCmd* pCmd = TRACKED_NEW plCtrlCmd( this );
|
||
|
pCmd->fControlActivated = true;
|
||
|
pCmd->fControlCode = mouseMap->fMap[i]->fCode;
|
||
|
pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate;
|
||
|
|
||
|
// figure out what percent (if any)
|
||
|
hsScalar pct = 0.0f;
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangePos)
|
||
|
{
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent)
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fX - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX));
|
||
|
else
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fZ - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ));
|
||
|
}
|
||
|
else
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangeNeg)
|
||
|
{
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent)
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fY - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX));
|
||
|
else
|
||
|
pct = hsABS((mouseMap->fMap[i]->fBox.fW - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ));
|
||
|
}
|
||
|
pCmd->fPct = pct;
|
||
|
if (pct == 1.0f || pct == -1.0f)
|
||
|
{
|
||
|
delete pCmd;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagDelta)
|
||
|
{
|
||
|
if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent)
|
||
|
pct = pMouseMsg->GetDX();
|
||
|
else
|
||
|
pct = pMouseMsg->GetDY();
|
||
|
|
||
|
pCmd->fPct = pct;
|
||
|
}
|
||
|
|
||
|
// and add it to the list
|
||
|
fMessageQueue->Append(pCmd);
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//// plAvatarInputMap and derivations ////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
// You really want to think of input maps as various states in a state machine.
|
||
|
// (This is why there are 3 different maps for walking. It all depends on which
|
||
|
// "state" we want to jump to.)
|
||
|
//
|
||
|
// When you pop from one map to the next:
|
||
|
// - All controls in the old map are deactivated
|
||
|
// (except kControlFlagNoDeactivate and kControlFlagToggle)
|
||
|
// - Any controls in the new map that can be activated by the current state
|
||
|
// will be. (i.e. you press a mouse button to switch to walk mode, hold
|
||
|
// hold that button down, and the walk command in the new mode will activate)
|
||
|
|
||
|
plAvatarInputMap::plAvatarInputMap()
|
||
|
{
|
||
|
fMouseMap = TRACKED_NEW plMouseMap;
|
||
|
|
||
|
fButtonState = 0;
|
||
|
fInterface = plAvatarInputInterface::GetInstance();
|
||
|
}
|
||
|
|
||
|
plAvatarInputMap::~plAvatarInputMap()
|
||
|
{
|
||
|
delete fMouseMap;
|
||
|
}
|
||
|
|
||
|
plSuspendedMovementMap::plSuspendedMovementMap() : plAvatarInputMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_ACTION_MOUSE, kControlFlagLeftButtonEx, 0.0f, 1.0f, 0.0f, 1.0f, "The Picked key") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_PICK, kControlFlagLeftButton, 0.0f, 1.0f, 0.0f, 1.0f, "The Picked key") );
|
||
|
}
|
||
|
|
||
|
plBasicControlMap::plBasicControlMap() : plSuspendedMovementMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_ROTATE_RIGHT, kControlFlagLeftButton | kControlFlagBoxDisable, 0.95f, 1.0f, 0.0f, 1.0f, "Rotate Player Right") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_ROTATE_LEFT, kControlFlagLeftButton | kControlFlagBoxDisable, 0.0f, 0.05f, 0.0f, 1.0f, "Rotate Player Left") );
|
||
|
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_TURN_TO, kControlFlagLeftButtonEx, 0.05f, 0.95f, 0.0f, 0.95f, "Turn to") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_WALK_MODE, kControlFlagLeftButton, 0.05f, 0.95f, 0.0f, 0.95f, "Set Walk Mode") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_WALK_BACK_LB_MODE, kControlFlagLeftButton, 0.05f, 0.95f, 0.95f, 1.0f, "Set Walk Back LB Mode") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_WALK_BACK_MODE, kControlFlagMiddleButton, 0.05f, 0.95f, 0.0f, 1.0f, "Set Walk Back Mode") );
|
||
|
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_CURSOR_UP, kControlFlagNormal | kControlFlagInBox, 0.05f, 0.95f, 0.0f, 0.95f, "set cursor up") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_CURSOR_DOWN, kControlFlagNormal | kControlFlagInBox, 0.05f, 0.95f, 0.95f, 1.0f, "set cursor down") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_CURSOR_RIGHT, kControlFlagNormal | kControlFlagInBox, 0.95f, 1.0f, 0.0f, 1.0f, "set cursor right") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_CURSOR_LEFT, kControlFlagNormal | kControlFlagInBox, 0.0f, 0.05f, 0.0f, 1.0f, "set cursor left") );
|
||
|
}
|
||
|
|
||
|
plLadderControlMap::plLadderControlMap() : plSuspendedMovementMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_MOVE_FORWARD, kControlFlagLeftButton | kControlFlagBoxDisable, 0.0f, 1.0f, 0.0f, 0.5f, "Set Walk Mode") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_MOVE_BACKWARD, kControlFlagLeftButton | kControlFlagBoxDisable, 0.0f, 1.0f, 0.5f, 1.0f, "Set Walk Back LB Mode") );
|
||
|
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_CURSOR_UPWARD, kControlFlagNormal | kControlFlagInBox, 0.0f, 1.0f, 0.0f, 0.5f, "set cursor up") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_CURSOR_DOWN, kControlFlagNormal | kControlFlagInBox, 0.0f, 1.0f, 0.5f, 1.0f, "set cursor down") );
|
||
|
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_FREELOOK, kControlFlagRightButton, 0.05f, 0.95f, 0.0f, 0.95f, "Set Camera first-person z-axis panning") );
|
||
|
}
|
||
|
|
||
|
|
||
|
plLadderMountMap::plLadderMountMap() : plSuspendedMovementMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_LADDER_CONTROL, kControlFlagLeftButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Set Ladder Mode") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_LADDER_CONTROL, kControlFlagRightButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Set Ladder Mode") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_LADDER_CONTROL, kControlFlagMiddleButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Set Ladder Mode") );
|
||
|
}
|
||
|
|
||
|
plLadderDismountMap::plLadderDismountMap() : plSuspendedMovementMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_BASIC_MODE, kControlFlagLeftButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Set Basic Mode") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_BASIC_MODE, kControlFlagRightButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Set Basic Mode") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_BASIC_MODE, kControlFlagMiddleButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Set Basic Mode") );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
plBasicThirdPersonControlMap::plBasicThirdPersonControlMap() : plBasicControlMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_FREELOOK, kControlFlagRightButton, 0.0f, 1.0f, 0.0f, 1.0f, "Freelook Mode") );
|
||
|
}
|
||
|
|
||
|
plBasicFirstPersonControlMap::plBasicFirstPersonControlMap() : plBasicControlMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(A_CONTROL_TURN, kControlFlagRightButtonRepeat | kControlFlagXAxisEvent | kControlFlagDelta, 0.0f, 1.0f, 0.0f, 1.0f, "Rotate Player") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_FREELOOK, kControlFlagRightButton, 0.05f, 0.95f, 0.0f, 0.95f, "Set Camera first-person z-axis panning") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_CAMERA_WALK_PAN, kControlFlagRightButton, 0.05f, 0.95f, 0.0f, 0.95f, "Set Camera first-person z-axis panning") );
|
||
|
}
|
||
|
|
||
|
// also used in 1st person walk mode
|
||
|
pl3rdWalkMap::pl3rdWalkMap() : plAvatarInputMap()
|
||
|
{
|
||
|
// control special to this mode.
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_MODIFIER_FAST, kControlFlagRightButton, 0.0f, 1.0f, 0.0f, 1.0f, "Run Modifier" ) );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(A_CONTROL_TURN, kControlFlagXAxisEvent | kControlFlagDelta, 0.0f, 1.0f, 0.0f, 1.0f, "Rotate Player") );
|
||
|
|
||
|
plInputManager::SetRecenterMouse(true);
|
||
|
plMouseDevice::HideCursor();
|
||
|
plInputInterfaceMgr::GetInstance()->ForceCursorHidden(true);
|
||
|
}
|
||
|
|
||
|
pl3rdWalkMap::~pl3rdWalkMap()
|
||
|
{
|
||
|
plInputManager::SetRecenterMouse(false);
|
||
|
plMouseDevice::ShowCursor();
|
||
|
plInputInterfaceMgr::GetInstance()->ForceCursorHidden(false);
|
||
|
}
|
||
|
|
||
|
pl3rdWalkForwardMap::pl3rdWalkForwardMap() : pl3rdWalkMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_BASIC_MODE, kControlFlagLeftButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Third Person") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_MOVE_FORWARD, kControlFlagLeftButton, 0.0f, 1.0f, 0.0f, 1.0f, "Walk forward") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_CAMERA_WALK_PAN, kControlFlagLeftButton, 0.0f, 1.0f, 0.0f, 1.0f, "Set Camera first-person z-axis panning") );
|
||
|
}
|
||
|
|
||
|
pl3rdWalkBackwardMap::pl3rdWalkBackwardMap() : pl3rdWalkMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_BASIC_MODE, kControlFlagMiddleButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Third Person") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_MOVE_BACKWARD, kControlFlagMiddleButton, 0.0f, 1.0f, 0.0f, 1.0f, "Walk backward") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_CAMERA_WALK_PAN, kControlFlagMiddleButton, 0.0f, 1.0f, 0.0f, 1.0f, "Set Camera first-person z-axis panning") );
|
||
|
}
|
||
|
|
||
|
// same as the other backward walk map, but this one is triggered by the left mouse button.
|
||
|
pl3rdWalkBackwardLBMap::pl3rdWalkBackwardLBMap() : pl3rdWalkMap()
|
||
|
{
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(S_SET_BASIC_MODE, kControlFlagLeftButtonUp, 0.0f, 1.0f, 0.0f, 1.0f, "Third Person") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_MOVE_BACKWARD, kControlFlagLeftButton, 0.0f, 1.0f, 0.0f, 1.0f, "Walk backward") );
|
||
|
fMouseMap->AddMapping( TRACKED_NEW plMouseInfo(B_CONTROL_CAMERA_WALK_PAN, kControlFlagLeftButton, 0.0f, 1.0f, 0.0f, 1.0f, "Set Camera first-person z-axis panning") );
|
||
14 years ago
|
}
|