#include "pch.h"
TRef<IPopup> CreateInputMapPopup(
Modeler* pmodeler,
InputEngine* pinputEngine,
TrekInput* ptrekInput,
IEngineFont* pfont,
Number* ptime
);
const int countAxis = 6;
const int keyMax = 256;
const int ModifierNone = 0;
const int ModifierShift = 1;
const int ModifierControl = 2;
const int ModifierAlt = 4;
const int ModifierAny = 8;
class TrekInputImpl : public TrekInput {
public:
TRef<InputEngine> m_pinputEngine;
TRef<JoystickImage> m_pjoystickImage;
TArray<TRef<Number>, countAxis> m_ppnumberAxis;
TArray<TRef<Boolean>, TK_Max> m_ppboolTrekKeyButtonDown;
TArray<bool , TK_Max> m_boolTrekKeyButtonDown;
TArray<TRef<ModifiableBoolean>, 4> m_ppboolHatButton;
bool m_bFocus;
TArray<TrekKey, keyMax> m_KeyMap;
TArray<TrekKey, keyMax> m_ShiftKeyMap;
TArray<TrekKey, keyMax> m_ControlKeyMap;
TArray<TrekKey, keyMax> m_AltKeyMap;
TArray<TrekKey, keyMax> m_ControlShiftKeyMap;
TArray<TrekKey, keyMax> m_ShiftAltKeyMap;
TArray<TrekKey, keyMax> m_ControlAltKeyMap;
TArray<TrekKey, keyMax> m_ControlShiftAltKeyMap;
TArray<TRef<ModifiableBoolean>, keyMax> m_pboolKeyDown;
TArray<TRef<Boolean>, TK_Max> m_pboolTrekKeyDown;
TRef<Boolean> m_pboolNone;
TRef<Boolean> m_pboolJustShift;
TRef<Boolean> m_pboolJustControl;
TRef<Boolean> m_pboolJustAlt;
TRef<Boolean> m_pboolJustControlShift;
TRef<Boolean> m_pboolJustShiftAlt;
TRef<Boolean> m_pboolJustControlAlt;
TRef<Boolean> m_pboolJustControlShiftAlt;
TrekInputImpl(
HINSTANCE hInst,
HWND hWnd,
InputEngine* pinputEngine,
JoystickImage* pjoystickImage
) :
m_pinputEngine(pinputEngine),
m_pjoystickImage(pjoystickImage)
{
InitializeCommandsMDL();
for (int index = 0; index < 4; index++) {
m_ppboolHatButton[index] = new ModifiableBoolean(false);
}
ClearButtonStates();
if (!LoadMap(INPUTMAP_FILE)) {
LoadMap(DEFAULTINPUTMAP_FILE);
}
Flush();
}
void Flush(void)
{
for (int x = 0; x < 256; x++) {
GetKeyState(x);
}
}
int normalize (int val, int minval, int maxval);
void InitializeCommandsMDL()
{
TRef<INameSpace> pnsCommands =
GetModeler()->CreateNameSpace(
"commands",
GetModeler()->GetNameSpace("model")
);
pnsCommands->AddMember("CommandHelp" , new Number((float)TK_Help ));
pnsCommands->AddMember("CommandScreenShot" , new Number((float)TK_ScrnShot ));
pnsCommands->AddMember("CommandNextCommMsg" , new Number((float)TK_NextCommMsg ));
pnsCommands->AddMember("CommandPrevCommMsg" , new Number((float)TK_PrevCommMsg ));
pnsCommands->AddMember("CommandPrevWeapon" , new Number((float)TK_PrevWeapon ));
pnsCommands->AddMember("CommandNextWeapon" , new Number((float)TK_NextWeapon ));
pnsCommands->AddMember("CommandToggleGroupFire" , new Number((float)TK_ToggleGroupFire ));
pnsCommands->AddMember("CommandPrevPart" , new Number((float)TK_PrevPart ));
pnsCommands->AddMember("CommandNextPart" , new Number((float)TK_NextPart ));
pnsCommands->AddMember("CommandMountPart" , new Number((float)TK_MountPart ));
pnsCommands->AddMember("CommandReplacePart" , new Number((float)TK_ReplacePart ));
pnsCommands->AddMember("CommandUnmountPart" , new Number((float)TK_UnmountPart ));
pnsCommands->AddMember("CommandDropPart" , new Number((float)TK_DropPart ));
pnsCommands->AddMember("CommandZoomOut" , new Number((float)TK_ZoomOut ));
pnsCommands->AddMember("CommandZoomIn" , new Number((float)TK_ZoomIn ));
pnsCommands->AddMember("CommandPitchUp" , new Number((float)TK_PitchUp ));
pnsCommands->AddMember("CommandPitchDown" , new Number((float)TK_PitchDown ));
pnsCommands->AddMember("CommandYawLeft" , new Number((float)TK_YawLeft ));
pnsCommands->AddMember("CommandYawRight" , new Number((float)TK_YawRight ));
pnsCommands->AddMember("CommandRollModifier" , new Number((float)TK_RollModifier ));
pnsCommands->AddMember("CommandRollLeft" , new Number((float)TK_RollLeft ));
pnsCommands->AddMember("CommandRollRight" , new Number((float)TK_RollRight ));
pnsCommands->AddMember("CommandMainMenu" , new Number((float)TK_MainMenu ));
pnsCommands->AddMember("CommandViewFrontLeft" , new Number((float)TK_ViewFrontLeft ));
pnsCommands->AddMember("CommandViewFrontRight" , new Number((float)TK_ViewFrontRight ));
pnsCommands->AddMember("CommandViewLeft" , new Number((float)TK_ViewLeft ));
pnsCommands->AddMember("CommandViewRight" , new Number((float)TK_ViewRight ));
pnsCommands->AddMember("CommandViewExternal" , new Number((float)TK_ViewExternal ));
pnsCommands->AddMember("CommandViewFlyby" , new Number((float)TK_ViewFlyby ));
pnsCommands->AddMember("CommandViewMissile" , new Number((float)TK_ViewMissile ));
pnsCommands->AddMember("CommandViewTarget" , new Number((float)TK_ViewTarget ));
pnsCommands->AddMember("CommandViewChase" , new Number((float)TK_ViewChase ));
pnsCommands->AddMember("CommandViewBase" , new Number((float)TK_ViewBase ));
pnsCommands->AddMember("CommandViewSector" , new Number((float)TK_ViewSector ));
pnsCommands->AddMember("CommandViewCommand" , new Number((float)TK_ViewCommand ));
pnsCommands->AddMember("CommandCycleChatMsgs" , new Number((float)TK_CycleChatMsgs ));
pnsCommands->AddMember("CommandExecuteCommand" , new Number((float)TK_ExecuteCommand ));
pnsCommands->AddMember("CommandAcceptCommand" , new Number((float)TK_AcceptCommand ));
pnsCommands->AddMember("CommandRejectCommand" , new Number((float)TK_RejectCommand ));
pnsCommands->AddMember("CommandClearCommand" , new Number((float)TK_ClearCommand ));
pnsCommands->AddMember("CommandToggleAutoPilot" , new Number((float)TK_ToggleAutoPilot ));
pnsCommands->AddMember("CommandThrustLeft" , new Number((float)TK_ThrustLeft ));
pnsCommands->AddMember("CommandThrustRight" , new Number((float)TK_ThrustRight ));
pnsCommands->AddMember("CommandThrustUp" , new Number((float)TK_ThrustUp ));
pnsCommands->AddMember("CommandThrustDown" , new Number((float)TK_ThrustDown ));
pnsCommands->AddMember("CommandThrustForward" , new Number((float)TK_ThrustForward ));
pnsCommands->AddMember("CommandThrustBackward" , new Number((float)TK_ThrustBackward ));
pnsCommands->AddMember("CommandFireBooster" , new Number((float)TK_FireBooster ));
pnsCommands->AddMember("CommandFireWeapon" , new Number((float)TK_FireWeapon ));
pnsCommands->AddMember("CommandFireMissile" , new Number((float)TK_FireMissile ));
pnsCommands->AddMember("CommandLockVector" , new Number((float)TK_LockVector ));
pnsCommands->AddMember("CommandThrottleUp" , new Number((float)TK_ThrottleUp ));
pnsCommands->AddMember("CommandThrottleDown" , new Number((float)TK_ThrottleDown ));
pnsCommands->AddMember("CommandThrottleZero" , new Number((float)TK_ThrottleZero ));
pnsCommands->AddMember("CommandThrottle33" , new Number((float)TK_Throttle33 ));
pnsCommands->AddMember("CommandThrottle66" , new Number((float)TK_Throttle66 ));
pnsCommands->AddMember("CommandThrottleFull" , new Number((float)TK_ThrottleFull ));
pnsCommands->AddMember("CommandToggleBooster" , new Number((float)TK_ToggleBooster ));
pnsCommands->AddMember("CommandLODUp" , new Number((float)TK_LODUp ));
pnsCommands->AddMember("CommandLODDown" , new Number((float)TK_LODDown ));
pnsCommands->AddMember("CommandConModeCombat" , new Number((float)TK_ConModeCombat ));
pnsCommands->AddMember("CommandConModeCommand" , new Number((float)TK_ConModeCommand ));
pnsCommands->AddMember("CommandConModeNav" , new Number((float)TK_ConModeNav ));
pnsCommands->AddMember("CommandConModeInventory" , new Number((float)TK_ConModeInventory ));
pnsCommands->AddMember("CommandConModeInvest" , new Number((float)TK_ConModeInvest ));
pnsCommands->AddMember("CommandConModeTeam" , new Number((float)TK_ConModeTeam ));
pnsCommands->AddMember("CommandConModeGameState" , new Number((float)TK_ConModeGameState ));
pnsCommands->AddMember("CommandViewRear" , new Number((float)TK_ViewRear ));
pnsCommands->AddMember("CommandTarget" , new Number((float)TK_Target ));
pnsCommands->AddMember("CommandTargetNearest" , new Number((float)TK_TargetNearest ));
pnsCommands->AddMember("CommandTargetPrev" , new Number((float)TK_TargetPrev ));
pnsCommands->AddMember("CommandTargetFriendly" , new Number((float)TK_TargetFriendly ));
pnsCommands->AddMember("CommandTargetFriendlyNearest" , new Number((float)TK_TargetFriendlyNearest ));
pnsCommands->AddMember("CommandTargetFriendlyPrev" , new Number((float)TK_TargetFriendlyPrev ));
pnsCommands->AddMember("CommandTargetEnemy" , new Number((float)TK_TargetEnemy ));
pnsCommands->AddMember("CommandTargetEnemyNearest" , new Number((float)TK_TargetEnemyNearest ));
pnsCommands->AddMember("CommandTargetEnemyPrev" , new Number((float)TK_TargetEnemyPrev ));
pnsCommands->AddMember("CommandTargetEnemyBase" , new Number((float)TK_TargetEnemyBase ));
pnsCommands->AddMember("CommandTargetEnemyBaseNearest" , new Number((float)TK_TargetEnemyBaseNearest ));
pnsCommands->AddMember("CommandTargetEnemyBasePrev" , new Number((float)TK_TargetEnemyBasePrev ));
pnsCommands->AddMember("CommandTargetFriendlyBase" , new Number((float)TK_TargetFriendlyBase ));
pnsCommands->AddMember("CommandTargetFriendlyBaseNearest", new Number((float)TK_TargetFriendlyBaseNearest));
pnsCommands->AddMember("CommandTargetFriendlyBasePrev" , new Number((float)TK_TargetFriendlyBasePrev ));
pnsCommands->AddMember("CommandTargetCommand" , new Number((float)TK_TargetCommand ));
pnsCommands->AddMember("CommandTargetCenter" , new Number((float)TK_TargetCenter ));
pnsCommands->AddMember("CommandTargetHostile" , new Number((float)TK_TargetHostile ));
pnsCommands->AddMember("CommandSuicide" , new Number((float)TK_Suicide ));
pnsCommands->AddMember("CommandToggleGrid" , new Number((float)TK_ToggleGrid ));
pnsCommands->AddMember("CommandToggleCloak" , new Number((float)TK_ToggleCloak ));
pnsCommands->AddMember("CommandDropMine" , new Number((float)TK_DropMine ));
pnsCommands->AddMember("CommandRipcord" , new Number((float)TK_Ripcord ));
pnsCommands->AddMember("CommandViewRearLeft" , new Number((float)TK_ViewRearLeft ));
pnsCommands->AddMember("CommandViewRearRight" , new Number((float)TK_ViewRearRight ));
pnsCommands->AddMember("CommandTargetSelf" , new Number((float)TK_TargetSelf ));
pnsCommands->AddMember("CommandToggleCollisions" , new Number((float)TK_ToggleCollisions ));
pnsCommands->AddMember("CommandOccupyNextTurret" , new Number((float)TK_OccupyNextTurret ));
pnsCommands->AddMember("CommandTargetNothing" , new Number((float)TK_TargetNothing ));
pnsCommands->AddMember("CommandMatchSpeed" , new Number((float)TK_MatchSpeed ));
pnsCommands->AddMember("CommandChatPageUp" , new Number((float)TK_ChatPageUp ));
pnsCommands->AddMember("CommandChatPageDown" , new Number((float)TK_ChatPageDown ));
pnsCommands->AddMember("CommandViewExternalOrbit" , new Number((float)TK_ViewExternalOrbit ));
pnsCommands->AddMember("CommandViewExternalStation" , new Number((float)TK_ViewExternalStation ));
pnsCommands->AddMember("CommandDropChaff" , new Number((float)TK_DropChaff ));
pnsCommands->AddMember("CommandToggleCommand" , new Number((float)TK_ToggleCommand ));
pnsCommands->AddMember("CommandSwapWeapon1" , new Number((float)TK_SwapWeapon1 ));
pnsCommands->AddMember("CommandSwapWeapon2" , new Number((float)TK_SwapWeapon2 ));
pnsCommands->AddMember("CommandSwapWeapon3" , new Number((float)TK_SwapWeapon3 ));
pnsCommands->AddMember("CommandSwapWeapon4" , new Number((float)TK_SwapWeapon4 ));
pnsCommands->AddMember("CommandSwapTurret1" , new Number((float)TK_SwapTurret1 ));
pnsCommands->AddMember("CommandSwapTurret2" , new Number((float)TK_SwapTurret2 ));
pnsCommands->AddMember("CommandSwapTurret3" , new Number((float)TK_SwapTurret3 ));
pnsCommands->AddMember("CommandSwapTurret4" , new Number((float)TK_SwapTurret4 ));
pnsCommands->AddMember("CommandPromoteTurret1" , new Number((float)TK_PromoteTurret1 ));
pnsCommands->AddMember("CommandPromoteTurret2" , new Number((float)TK_PromoteTurret2 ));
pnsCommands->AddMember("CommandPromoteTurret3" , new Number((float)TK_PromoteTurret3 ));
pnsCommands->AddMember("CommandPromoteTurret4" , new Number((float)TK_PromoteTurret4 ));
pnsCommands->AddMember("CommandSwapMissile" , new Number((float)TK_SwapMissile ));
pnsCommands->AddMember("CommandSwapChaff" , new Number((float)TK_SwapChaff ));
pnsCommands->AddMember("CommandSwapShield" , new Number((float)TK_SwapShield ));
pnsCommands->AddMember("CommandSwapCloak" , new Number((float)TK_SwapCloak ));
pnsCommands->AddMember("CommandSwapAfterburner" , new Number((float)TK_SwapAfterburner ));
pnsCommands->AddMember("CommandSwapMine" , new Number((float)TK_SwapMine ));
pnsCommands->AddMember("CommandNextCargo" , new Number((float)TK_NextCargo ));
pnsCommands->AddMember("CommandToggleWeapon1" , new Number((float)TK_ToggleWeapon1 ));
pnsCommands->AddMember("CommandToggleWeapon2" , new Number((float)TK_ToggleWeapon2 ));
pnsCommands->AddMember("CommandToggleWeapon3" , new Number((float)TK_ToggleWeapon3 ));
pnsCommands->AddMember("CommandToggleWeapon4" , new Number((float)TK_ToggleWeapon4 ));
pnsCommands->AddMember("CommandDropCargo" , new Number((float)TK_DropCargo ));
pnsCommands->AddMember("CommandQuickChatMenu" , new Number((float)TK_QuickChatMenu ));
pnsCommands->AddMember("CommandToggleLODSlider" , new Number((float)TK_ToggleLODSlider ));
pnsCommands->AddMember("CommandStartChat" , new Number((float)TK_StartChat ));
pnsCommands->AddMember("CommandReload" , new Number((float)TK_Reload ));
pnsCommands->AddMember("CommandCycleRadar" , new Number((float)TK_CycleRadar ));
pnsCommands->AddMember("CommandConModeMiniTeam" , new Number((float)TK_ConModeMiniTeam ));
pnsCommands->AddMember("CommandConModeTeleport" , new Number((float)TK_ConModeTeleport ));
pnsCommands->AddMember("CommandTargetEnemyBomber" , new Number((float)TK_TargetEnemyBomber ));
pnsCommands->AddMember("CommandTargetEnemyFighter" , new Number((float)TK_TargetEnemyFighter ));
pnsCommands->AddMember("CommandTargetEnemyConstructor" , new Number((float)TK_TargetEnemyConstructor ));
pnsCommands->AddMember("CommandTargetEnemyMiner" , new Number((float)TK_TargetEnemyMiner ));
pnsCommands->AddMember("CommandTargetEnemyMajorBase" , new Number((float)TK_TargetEnemyMajorBase ));
pnsCommands->AddMember("CommandTargetFriendlyBomber" , new Number((float)TK_TargetFriendlyBomber ));
pnsCommands->AddMember("CommandTargetFriendlyFighter" , new Number((float)TK_TargetFriendlyFighter ));
pnsCommands->AddMember("CommandTargetFriendlyConstructor", new Number((float)TK_TargetFriendlyConstructor));
pnsCommands->AddMember("CommandTargetFriendlyMiner" , new Number((float)TK_TargetFriendlyMiner ));
pnsCommands->AddMember("CommandTargetFriendlyLifepod" , new Number((float)TK_TargetFriendlyLifepod ));
pnsCommands->AddMember("CommandTargetFriendlyMajorBase" , new Number((float)TK_TargetFriendlyMajorBase ));
pnsCommands->AddMember("CommandTargetFlag" , new Number((float)TK_TargetFlag ));
pnsCommands->AddMember("CommandTargetArtifact" , new Number((float)TK_TargetArtifact ));
pnsCommands->AddMember("CommandTargetEnemyBomberNearest" , new Number((float)TK_TargetEnemyBomberNearest ));
pnsCommands->AddMember("CommandTargetEnemyFighterNearest" , new Number((float)TK_TargetEnemyFighterNearest ));
pnsCommands->AddMember("CommandTargetEnemyConstructorNearest" , new Number((float)TK_TargetEnemyConstructorNearest ));
pnsCommands->AddMember("CommandTargetEnemyMinerNearest" , new Number((float)TK_TargetEnemyMinerNearest ));
pnsCommands->AddMember("CommandTargetEnemyMajorBaseNearest" , new Number((float)TK_TargetEnemyMajorBaseNearest ));
pnsCommands->AddMember("CommandTargetFriendlyBomberNearest" , new Number((float)TK_TargetFriendlyBomberNearest ));
pnsCommands->AddMember("CommandTargetFriendlyFighterNearest" , new Number((float)TK_TargetFriendlyFighterNearest ));
pnsCommands->AddMember("CommandTargetFriendlyConstructorNearest", new Number((float)TK_TargetFriendlyConstructorNearest));
pnsCommands->AddMember("CommandTargetFriendlyMinerNearest" , new Number((float)TK_TargetFriendlyMinerNearest ));
pnsCommands->AddMember("CommandTargetFriendlyLifepodNearest" , new Number((float)TK_TargetFriendlyLifepodNearest ));
pnsCommands->AddMember("CommandTargetFriendlyMajorBaseNearest" , new Number((float)TK_TargetFriendlyMajorBaseNearest ));
pnsCommands->AddMember("CommandTargetFlagNearest" , new Number((float)TK_TargetFlagNearest ));
pnsCommands->AddMember("CommandTargetArtifactNearest" , new Number((float)TK_TargetArtifactNearest ));
pnsCommands->AddMember("CommandTargetEnemyBomberPrev" , new Number((float)TK_TargetEnemyBomberPrev ));
pnsCommands->AddMember("CommandTargetEnemyFighterPrev" , new Number((float)TK_TargetEnemyFighterPrev ));
pnsCommands->AddMember("CommandTargetEnemyConstructorPrev" , new Number((float)TK_TargetEnemyConstructorPrev ));
pnsCommands->AddMember("CommandTargetEnemyMinerPrev" , new Number((float)TK_TargetEnemyMinerPrev ));
pnsCommands->AddMember("CommandTargetEnemyMajorBasePrev" , new Number((float)TK_TargetEnemyMajorBasePrev ));
pnsCommands->AddMember("CommandTargetFriendlyBomberPrev" , new Number((float)TK_TargetFriendlyBomberPrev ));
pnsCommands->AddMember("CommandTargetFriendlyFighterPrev" , new Number((float)TK_TargetFriendlyFighterPrev ));
pnsCommands->AddMember("CommandTargetFriendlyConstructorPrev", new Number((float)TK_TargetFriendlyConstructorPrev));
pnsCommands->AddMember("CommandTargetFriendlyMinerPrev" , new Number((float)TK_TargetFriendlyMinerPrev ));
pnsCommands->AddMember("CommandTargetFriendlyLifepodPrev" , new Number((float)TK_TargetFriendlyLifepodPrev ));
pnsCommands->AddMember("CommandTargetFriendlyMajorBasePrev" , new Number((float)TK_TargetFriendlyMajorBasePrev ));
pnsCommands->AddMember("CommandTargetFlagPrev" , new Number((float)TK_TargetFlagPrev ));
pnsCommands->AddMember("CommandTargetArtifactPrev" , new Number((float)TK_TargetArtifactPrev ));
pnsCommands->AddMember("CommandTargetWarp" , new Number((float)TK_TargetWarp ));
pnsCommands->AddMember("CommandTargetWarpNearest" , new Number((float)TK_TargetWarpNearest ));
pnsCommands->AddMember("CommandTargetWarpPrev" , new Number((float)TK_TargetWarpPrev ));
pnsCommands->AddMember("CommandTrackCommandView" , new Number((float)TK_TrackCommandView ));
pnsCommands->AddMember("CommandPauseTM" , new Number((float)TK_PauseTM ));
pnsCommands->AddMember("CommandFinishTM" , new Number((float)TK_CommandFinishTM ));
pnsCommands->AddMember("CommandToggleMouse" , new Number((float)TK_ToggleMouse ));
pnsCommands->AddMember("CommandVoteYes" , new Number((float)TK_VoteYes ));
pnsCommands->AddMember("CommandVoteNo" , new Number((float)TK_VoteNo ));
pnsCommands->AddMember("CommandSkipTMGoal" , new Number((float)TK_SkipTMGoal ));
pnsCommands->AddMember("CommandIncreaseTMClockSpeed" , new Number((float)TK_IncreaseTMClockSpeed ));
pnsCommands->AddMember("CommandDecreaseTMClockSpeed" , new Number((float)TK_DecreaseTMClockSpeed ));
pnsCommands->AddMember("CommandResetTMClockSpeed" , new Number((float)TK_ResetTMClockSpeed ));
pnsCommands->AddMember("None" , new Number((float)ModifierNone ));
pnsCommands->AddMember("Shift" , new Number((float)ModifierShift ));
pnsCommands->AddMember("Control", new Number((float)ModifierControl));
pnsCommands->AddMember("Alt" , new Number((float)ModifierAlt ));
pnsCommands->AddMember("Any" , new Number((float)ModifierAny ));
TRef<Boolean> pboolShift = GetKeyDown(VK_SHIFT );
TRef<Boolean> pboolControl = GetKeyDown(VK_CONTROL);
TRef<Boolean> pboolAlt = GetKeyDown(VK_MENU );
TRef<Boolean> pboolNotShift = Not(pboolShift );
TRef<Boolean> pboolNotControl = Not(pboolControl);
TRef<Boolean> pboolNotAlt = Not(pboolAlt );
TRef<Boolean> pboolNotControlShift = And(pboolNotControl, pboolNotShift);
TRef<Boolean> pboolNotShiftAlt = And(pboolNotShift, pboolNotAlt );
TRef<Boolean> pboolNotControlAlt = And(pboolNotControl, pboolNotAlt );
TRef<Boolean> pboolControlShift = And(pboolControl, pboolShift);
TRef<Boolean> pboolShiftAlt = And(pboolShift, pboolAlt );
TRef<Boolean> pboolControlAlt = And(pboolControl, pboolAlt );
m_pboolNone = And(pboolNotControlShift, pboolNotAlt );
m_pboolJustShift = And(pboolShift, pboolNotControlAlt );
m_pboolJustControl = And(pboolControl, pboolNotShiftAlt );
m_pboolJustAlt = And(pboolAlt, pboolNotControlShift);
m_pboolJustControlShift = And(pboolControlShift, pboolNotAlt );
m_pboolJustShiftAlt = And(pboolShiftAlt, pboolNotControl );
m_pboolJustControlAlt = And(pboolControlAlt, pboolNotShift );
m_pboolJustControlShiftAlt = And(pboolControlShift, pboolAlt );
}
Boolean* GetKeyDown(int vk)
{
if (m_pboolKeyDown[vk] == NULL) {
m_pboolKeyDown[vk] = new ModifiableBoolean(false);
}
return m_pboolKeyDown[vk];
}
ZString GetFPSString()
{
return
ZString(m_pboolNone->GetValue() ? "N " : " " )
+ ZString(m_pboolJustControl->GetValue() ? "C " : " " )
+ ZString(m_pboolJustShift->GetValue() ? "S " : " " )
+ ZString(m_pboolJustAlt->GetValue() ? "A " : " " )
+ ZString(m_pboolJustControlShift->GetValue() ? "CS " : " " )
+ ZString(m_pboolJustShiftAlt->GetValue() ? "SA " : " " )
+ ZString(m_pboolJustControlAlt->GetValue() ? "CA " : " " )
+ ZString(m_pboolJustControlShiftAlt->GetValue() ? "CSA " : " ")
;
}
bool LoadMap(const ZString& str)
{
TRef<INameSpace> pns = GetModeler()->GetNameSpace(str, false);
if (pns == NULL) {
return false;
}
m_pinputEngine->EnumerateJoysticks();
if (
m_pinputEngine->GetJoystick(0)
&& m_pinputEngine->GetJoystick(0)->HasForceFeedback()
) {
m_pinputEngine->GetJoystick(0)->CreateEffects();
}
int index;
for (index = 0; index < keyMax; index++) {
m_KeyMap[index] = -1;
m_ShiftKeyMap[index] = -1;
m_ControlKeyMap[index] = -1;
m_AltKeyMap[index] = -1;
m_ControlShiftKeyMap[index] = -1;
m_ShiftAltKeyMap[index] = -1;
m_ControlAltKeyMap[index] = -1;
m_ControlShiftAltKeyMap[index] = -1;
}
for (index = 0; index < TK_Max; index++) {
m_pboolTrekKeyDown[index] = NULL;
m_ppboolTrekKeyButtonDown[index] = NULL;
}
for (index = 0; index < m_ppnumberAxis.GetCount(); index++) {
m_ppnumberAxis[index] = NULL;
}
{
TRef<IObjectList> plist = pns->FindList("keyCommandMap");
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
int vk = (int)GetNumber(ppair->GetNth(0) );
int modifiers = (int)GetNumber(ppair->GetNth(1) );
int tk = (int)GetNumber(ppair->GetLastNth(2));
TArray<TrekKey, keyMax>* pptk;
if (modifiers & ModifierShift) {
if (modifiers & ModifierControl) {
if (modifiers & ModifierAlt) {
pptk = &m_ControlShiftAltKeyMap;
} else {
pptk = &m_ControlShiftKeyMap;
}
} else {
if (modifiers & ModifierAlt) {
pptk = &m_ShiftAltKeyMap;
} else {
pptk = &m_ShiftKeyMap;
}
}
} else {
if (modifiers & ModifierControl) {
if (modifiers & ModifierAlt) {
pptk = &m_ControlAltKeyMap;
} else {
pptk = &m_ControlKeyMap;
}
} else {
if (modifiers & ModifierAlt) {
pptk = &m_AltKeyMap;
} else {
pptk = &m_KeyMap;
}
}
}
ZAssert((*pptk)[vk] == -1);
(*pptk)[vk] = tk;
TRef<Boolean> pbool = GetKeyDown(vk);
if (modifiers != ModifierAny) {
TRef<Boolean> pboolModifier;
if (modifiers & ModifierShift) {
if (modifiers & ModifierControl) {
if (modifiers & ModifierAlt) {
pboolModifier = m_pboolJustControlShiftAlt;
} else {
pboolModifier = m_pboolJustControlShift;
}
} else {
if (modifiers & ModifierAlt) {
pboolModifier = m_pboolJustShiftAlt;
} else {
pboolModifier = m_pboolJustShift;
}
}
} else {
if (modifiers & ModifierControl) {
if (modifiers & ModifierAlt) {
pboolModifier = m_pboolJustControlAlt;
} else {
pboolModifier = m_pboolJustControl;
}
} else {
if (modifiers & ModifierAlt) {
pboolModifier = m_pboolJustAlt;
} else {
pboolModifier = m_pboolNone;
}
}
}
pbool = And(pbool, pboolModifier);
}
if (m_pboolTrekKeyDown[tk] == NULL) {
m_pboolTrekKeyDown[tk] = pbool;
} else {
m_pboolTrekKeyDown[tk] =
Or(
pbool,
m_pboolTrekKeyDown[tk]
);
}
plist->GetNext();
}
}
{
TRef<IObjectList> plist = pns->FindList("mouseButtonCommandMap");
if (plist) {
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
int index = (int)GetNumber(ppair->GetFirst() );
int tk = (int)GetNumber(ppair->GetSecond());
TRef<Boolean> pboolButton = m_pjoystickImage->IsDown(index);
if (pboolButton) {
if (m_ppboolTrekKeyButtonDown[tk] == NULL) {
m_ppboolTrekKeyButtonDown[tk] = pboolButton;
} else {
m_ppboolTrekKeyButtonDown[tk] =
Or(
pboolButton,
m_ppboolTrekKeyButtonDown[tk]
);
}
}
plist->GetNext();
}
}
}
{
TRef<IObjectList> plist = pns->FindList("buttonCommandMap");
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
int indexJoystick = (int)GetNumber(ppair->GetNth(0) );
int indexButton = (int)GetNumber(ppair->GetNth(1) );
int tk = (int)GetNumber(ppair->GetLastNth(2));
TRef<JoystickInputStream> pjoystick = m_pinputEngine->GetJoystick(indexJoystick);
TRef<Boolean> pboolButton;
if (indexButton < 0) {
pboolButton = m_ppboolHatButton[-indexButton - 1];
} else {
if (pjoystick) {
pboolButton = pjoystick->IsDown(indexButton);
}
}
if (pboolButton) {
if (m_ppboolTrekKeyButtonDown[tk] == NULL) {
m_ppboolTrekKeyButtonDown[tk] = pboolButton;
} else {
m_ppboolTrekKeyButtonDown[tk] =
Or(
pboolButton,
m_ppboolTrekKeyButtonDown[tk]
);
}
}
plist->GetNext();
}
}
{
TRef<IObjectList> plist = pns->FindList("numericValuesNew");
bool bNew = (plist != NULL);
if (!bNew) {
plist = pns->FindList("numericValues");
}
plist->GetFirst();
for (int indexValueOutput = 0; indexValueOutput < m_ppnumberAxis.GetCount(); indexValueOutput++) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
if (ppair) {
int indexJoystick = (int)GetNumber(ppair->GetFirst() );
int indexValueInput = (int)GetNumber(ppair->GetSecond());
if (!bNew) {
if (indexValueInput == 2) {
indexValueInput = 3;
} else if (indexValueInput == 3) {
indexValueInput = 2;
}
}
TRef<JoystickInputStream> pjoystick = m_pinputEngine->GetJoystick(indexJoystick);
TRef<Number> pvalueInput;
if (pjoystick) {
pvalueInput = pjoystick->GetValue(indexValueInput);
}
if (pvalueInput) {
m_ppnumberAxis[indexValueOutput] = pvalueInput;
} else {
m_ppnumberAxis[indexValueOutput] = NULL;
}
}
plist->GetNext();
}
}
GetModeler()->UnloadNameSpace(pns);
return true;
}
void ClearButtonStates()
{
for (int index = 0; index < TK_Max; index++) {
m_boolTrekKeyButtonDown[index] = false;
}
}
bool IsTrekKeyDown(TrekKey tk, bool bCheckKeyboard)
{
bool bDown = false;
Boolean* pbool = m_ppboolTrekKeyButtonDown[tk];
if (pbool) {
bDown = pbool->GetValue();
}
if (bCheckKeyboard) {
Boolean* pbool = m_pboolTrekKeyDown[tk];
if (pbool) {
bDown = bDown || pbool->GetValue();
}
}
return bDown;
}
void SetFocus(bool bFocus)
{
if (m_bFocus != bFocus) {
m_bFocus = bFocus;
if (!m_bFocus) {
for (int index = 0; index < keyMax; index++) {
if (m_pboolKeyDown[index] != NULL) {
m_pboolKeyDown[index]->SetValue(false);
}
}
ClearButtonStates();
}
}
}
TrekKey TranslateKeyMessage(const KeyState& ks)
{
if (ks.bShift) {
if (ks.bControl) {
if (ks.bAlt) {
return m_ControlShiftAltKeyMap[ks.vk];
} else {
return m_ControlShiftKeyMap[ks.vk];
}
} else {
if (ks.bAlt) {
return m_ShiftAltKeyMap[ks.vk];
} else {
return m_ShiftKeyMap[ks.vk];
}
}
} else {
if (ks.bControl) {
if (ks.bAlt) {
return m_ControlAltKeyMap[ks.vk];
} else {
return m_ControlKeyMap[ks.vk];
}
} else {
if (ks.bAlt) {
return m_AltKeyMap[ks.vk];
} else {
return m_KeyMap[ks.vk];
}
}
}
return TK_NoKeyMapping;
}
TrekKey HandleKeyMessage(const KeyState& ks)
{
if (m_bFocus) {
if (m_pboolKeyDown[ks.vk] != NULL) {
m_pboolKeyDown[ks.vk]->SetValue(ks.bDown);
}
return TranslateKeyMessage(ks);
}
return TK_NoKeyMapping;
}
void PlayFFEffect(ForceEffectID effectID, LONG lDirection)
{
if (
m_pinputEngine->GetJoystick(0)
&& m_pinputEngine->GetJoystick(0)->HasForceFeedback()
) {
m_pinputEngine->GetJoystick(0)->PlayFFEffect(effectID, lDirection);
}
}
float GetAxis(int index)
{
if (m_ppnumberAxis[index] != NULL) {
return m_ppnumberAxis[index]->GetValue();
} else {
return 0;
}
}
bool IsAxisValid(int index)
{
return m_ppnumberAxis[index] != NULL;
}
void GetButtonTrekKeys(TrekInputSite* psite)
{
if (m_ppnumberAxis[5] != NULL) {
float value = m_ppnumberAxis[5]->GetValue();
for (int index = 0; index < 4; index++) {
m_ppboolHatButton[index]->SetValue(0);
}
if (value > 0.75f) {
m_ppboolHatButton[2]->SetValue(1);
} else if (value > 0.25f) {
m_ppboolHatButton[1]->SetValue(1);
} else if (value > -0.25f) {
m_ppboolHatButton[0]->SetValue(1);
} else if (value > -0.75f) {
m_ppboolHatButton[3]->SetValue(1);
} else if (value > -1.25f) {
m_ppboolHatButton[2]->SetValue(1);
}
}
for (int index = 0; index < TK_Max; index++) {
if (
m_ppboolTrekKeyButtonDown[index] != NULL
&& m_ppboolTrekKeyButtonDown[index]->GetValue() != m_boolTrekKeyButtonDown[index]
) {
m_boolTrekKeyButtonDown[index] = m_ppboolTrekKeyButtonDown[index]->GetValue();
if (m_boolTrekKeyButtonDown[index]) {
psite->OnTrekKey(index);
}
}
}
}
TRef<IPopup> CreateInputMapPopup(Modeler* pmodeler, IEngineFont* pfont, Number* ptime)
{
return
::CreateInputMapPopup(
pmodeler,
m_pinputEngine,
this,
pfont,
ptime
);
}
};
TRef<TrekInput> CreateTrekInput(HINSTANCE hInst, HWND hwnd, InputEngine* pinputEngine, JoystickImage* pjoystickImage)
{
return new TrekInputImpl(hInst, hwnd, pinputEngine, pjoystickImage);
}
PCC g_ppccAxisDescription[] =
{
"Yaw",
"Pitch",
"Roll",
"Throttle",
"Hat",
"Hat as Buttons"
};
class KeyInfo {
public:
PCC m_pcc;
};
KeyInfo g_pkeyInfo[] =
{
{ NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "Backspace" }, { "Tab" }, { NULL }, { NULL }, { NULL }, { "Enter" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "Pause" }, { "Caps Lock" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "Escape" }, { NULL }, { NULL }, { NULL }, { NULL }, { "Space" }, { "Page Up" }, { "Page Down" }, { "End" }, { "Home" }, { "Left" }, { "Up" }, { "Right" }, { "Down" }, { NULL }, { NULL }, { NULL }, { "PrintScreen" }, { "Insert" }, { "Delete" }, { NULL }, { "0" }, { "1" }, { "2" }, { "3" }, { "4" }, { "5" }, { "6" }, { "7" }, { "8" }, { "9" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "A" }, { "B" }, { "C" }, { "D" }, { "E" }, { "F" }, { "G" }, { "H" }, { "I" }, { "J" }, { "K" }, { "L" }, { "M" }, { "N" }, { "O" }, { "P" }, { "Q" }, { "R" }, { "S" }, { "T" }, { "U" }, { "V" }, { "W" }, { "X" }, { "Y" }, { "Z" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "Num Pad 0" }, { "Num Pad 1" }, { "Num Pad 2" }, { "Num Pad 3" }, { "Num Pad 4" }, { "Num Pad 5" }, { "Num Pad 6" }, { "Num Pad 7" }, { "Num Pad 8" }, { "Num Pad 9" }, { "Num Pad Multiply" }, { "Num Pad Plus" }, { "Num Pad Enter" }, { "Num Pad Minus" }, { "Num Pad Decimal" }, { "Num Pad Divide" }, { "F1" }, { "F2" }, { "F3" }, { "F4" }, { "F5" }, { "F6" }, { "F7" }, { "F8" }, { "F9" }, { "F10" }, { "F11" }, { "F12" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "Num Lock" }, { "Scroll Lock" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "SemiColon" }, { "Equals" }, { "Comma" }, { "Minus" }, { "Period" }, { "Forward Slash" }, { "Tilde" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { "Left Square" }, { "Back Slash" }, { "Right Square" }, { "Quote" }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL } };
class CommandInfo {
public:
int m_tk;
PCC m_pcc;
};
CommandInfo g_pCommandInfo[] =
{
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Chat" },
{ TK_NoKeyMapping , "" },
{ TK_QuickChatMenu , "Quick Chat Menu" },
{ TK_StartChat , "Start Chat" },
{ TK_ChatPageUp , "Chat Page Up" },
{ TK_ChatPageDown , "Chat Page Down" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Commands" },
{ TK_NoKeyMapping , "" },
{ TK_AcceptCommand , "Accept Command" },
{ TK_ClearCommand , "Clear Command" },
{ TK_RejectCommand , "Reject Command" },
{ TK_ExecuteCommand , "Execute Command" },
{ TK_VoteYes , "Vote Yes" },
{ TK_VoteNo , "Vote No" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Weapons" },
{ TK_NoKeyMapping , "" },
{ TK_FireWeapon , "Fire Weapon" },
{ TK_FireMissile , "Fire Missile" },
{ TK_PrevWeapon , "Previous Weapon" },
{ TK_NextWeapon , "Next Weapon" },
{ TK_ToggleGroupFire , "Toggle Group Fire" },
{ TK_Reload , "Reload" },
{ TK_DropMine , "Drop Mine or Probe" }, { TK_DropChaff , "Drop Chaff" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Turning" },
{ TK_NoKeyMapping , "" },
{ TK_PitchUp , "Pitch Up" },
{ TK_PitchDown , "Pitch Down" },
{ TK_YawLeft , "Yaw Left" },
{ TK_YawRight , "Yaw Right" },
{ TK_RollLeft , "Roll Left" },
{ TK_RollRight , "Roll Right" },
{ TK_RollModifier , "Roll Modifier" },
{ TK_ToggleMouse , "Toggle Mouse Control" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Thrust" },
{ TK_NoKeyMapping , "" },
{ TK_ThrustLeft , "Thrust Left" },
{ TK_ThrustRight , "Thrust Right" },
{ TK_ThrustUp , "Thrust Up" },
{ TK_ThrustDown , "Thrust Down" },
{ TK_ThrustForward , "Thrust Forward" },
{ TK_ThrustBackward , "Thrust Backward" },
{ TK_FireBooster , "Fire Booster" },
{ TK_ThrottleUp , "Throttle Up" },
{ TK_ThrottleDown , "Throttle Down" },
{ TK_ThrottleZero , "Throttle Zero" },
{ TK_Throttle33 , "Throttle 33%" },
{ TK_Throttle66 , "Throttle 66%" },
{ TK_ThrottleFull , "Throttle Full" },
{ TK_LockVector , "Lock Vector" },
{ TK_ToggleAutoPilot , "Toggle AutoPilot" },
{ TK_MatchSpeed , "Match Speed" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Camera" },
{ TK_NoKeyMapping , "" },
{ TK_ZoomOut , "Zoom Out" },
{ TK_ZoomIn , "Zoom In" },
{ TK_ViewFrontLeft , "View Front Left" },
{ TK_ViewFrontRight , "View Front Right" },
{ TK_ViewLeft , "View Left" },
{ TK_ViewRight , "View Right" },
{ TK_ViewExternal , "View External" },
{ TK_ViewFlyby , "View Flyby" },
{ TK_ViewMissile , "View Missile" },
{ TK_ViewTarget , "View Target" },
{ TK_ViewChase , "View Chase" },
{ TK_ViewBase , "View Base" },
{ TK_ViewSector , "View Sector" },
{ TK_ViewCommand , "View Command" },
{ TK_ViewRear , "View Rear" },
{ TK_ViewRearLeft , "View Rear Left" },
{ TK_ViewRearRight , "View Rear Right" },
{ TK_ViewExternalOrbit , "View External Orbit" },
{ TK_ViewExternalStation , "View External Target" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "UI Toggles" },
{ TK_NoKeyMapping , "" },
{ TK_ConModeGameState , "Switch To Game State" },
{ TK_ConModeCombat , "Switch To Combat" },
{ TK_ConModeCommand , "Switch To Command" },
{ TK_ConModeInventory , "Switch To Inventory" },
{ TK_ConModeInvest , "Switch To Invest" },
{ TK_ConModeTeam , "Switch To Team" },
{ TK_ConModeNav , "Switch To Nav" },
{ TK_ConModeMiniTeam , "Switch To Mini Team" },
{ TK_ConModeTeleport , "Switch To Teleport" },
{ TK_ToggleGrid , "Toggle Grid" },
{ TK_CycleRadar , "Cycle Radar Modes" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Inventory" },
{ TK_NoKeyMapping , "" },
{ TK_SwapWeapon1 , "Swap Weapon1" },
{ TK_SwapWeapon2 , "Swap Weapon2" },
{ TK_SwapWeapon3 , "Swap Weapon3" },
{ TK_SwapWeapon4 , "Swap Weapon4" },
{ TK_SwapTurret1 , "Swap Turret1" },
{ TK_SwapTurret2 , "Swap Turret2" },
{ TK_SwapTurret3 , "Swap Turret3" },
{ TK_SwapTurret4 , "Swap Turret4" },
{ TK_PromoteTurret1 , "Promote Turret1" },
{ TK_PromoteTurret2 , "Promote Turret2" },
{ TK_PromoteTurret3 , "Promote Turret3" },
{ TK_PromoteTurret4 , "Promote Turret4" },
{ TK_SwapMissile , "Swap Missile" },
{ TK_SwapChaff , "Swap Chaff" },
{ TK_SwapShield , "Swap Shield" },
{ TK_SwapCloak , "Swap Cloak" },
{ TK_SwapAfterburner , "Swap Afterburner" },
{ TK_SwapMine , "Swap Mine" },
{ TK_NextCargo , "Next Cargo" },
{ TK_ToggleWeapon1 , "Toggle Weapon1" },
{ TK_ToggleWeapon2 , "Toggle Weapon2" },
{ TK_ToggleWeapon3 , "Toggle Weapon3" },
{ TK_ToggleWeapon4 , "Toggle Weapon4" },
{ TK_DropCargo , "Drop Cargo" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Targeting" },
{ TK_NoKeyMapping , "" },
{ TK_Target , "Target" },
{ TK_TargetNothing , "Target Nothing" },
{ TK_TargetSelf , "Target Self" },
{ TK_TargetNearest , "Target Nearest" },
{ TK_TargetPrev , "Target Previous" },
{ TK_TargetCommand , "Target Command" },
{ TK_TargetCenter , "Target Center" },
{ TK_NoKeyMapping , "" },
{ TK_TargetFlag , "Target Flag" },
{ TK_TargetFlagNearest , "Target Nearest flag" },
{ TK_TargetFlagPrev , "Target Previous flag" },
{ TK_NoKeyMapping , "" },
{ TK_TargetArtifact , "Target Artifact" },
{ TK_TargetArtifactNearest , "Target Nearest artifact" },
{ TK_TargetArtifactPrev , "Target Previous artifact" },
{ TK_NoKeyMapping , "" },
{ TK_TargetWarp , "Target Aleph" },
{ TK_TargetWarpNearest , "Target Nearest Aleph" },
{ TK_TargetWarpPrev , "Target Previous Alpeh" },
{ TK_NoKeyMapping , "" },
{ TK_TargetHostile , "Target Hostile" },
{ TK_TargetEnemy , "Target Enemy" },
{ TK_TargetEnemyNearest , "Target Enemy Nearest" },
{ TK_TargetEnemyPrev , "Target Enemy Previous" },
{ TK_TargetEnemyBase , "Target Enemy Base" },
{ TK_TargetEnemyBaseNearest , "Target Enemy Base Nearest" },
{ TK_TargetEnemyBasePrev , "Target Enemy Base Previous" },
{ TK_TargetEnemyBomber , "Target Enemy Bomber" },
{ TK_TargetEnemyFighter , "Target Enemy Fighter" },
{ TK_TargetEnemyConstructor , "Target Enemy Constructor" },
{ TK_TargetEnemyMiner , "Target Enemy Miner" },
{ TK_TargetEnemyMajorBase , "Target Enemy Major Base" },
{ TK_TargetEnemyBomberNearest , "Target Nearest Enemy Bomber" },
{ TK_TargetEnemyFighterNearest , "Target Nearest Enemy Fighter" },
{ TK_TargetEnemyConstructorNearest , "Target Nearest Enemy Constructor" },
{ TK_TargetEnemyMinerNearest , "Target Nearest Enemy Miner" },
{ TK_TargetEnemyMajorBaseNearest , "Target Nearest Enemy Major Base" },
{ TK_TargetEnemyBomberPrev , "Target Previous Enemy Bomber" },
{ TK_TargetEnemyFighterPrev , "Target Previous Enemy Fighter" },
{ TK_TargetEnemyConstructorPrev , "Target Previous Enemy Constructor" },
{ TK_TargetEnemyMinerPrev , "Target Previous Enemy Miner" },
{ TK_TargetEnemyMajorBasePrev , "Target Previous Enemy Major Base" },
{ TK_NoKeyMapping , "" },
{ TK_TargetFriendly , "Target Friendly" },
{ TK_TargetFriendlyNearest , "Target Friendly Nearest" },
{ TK_TargetFriendlyPrev , "Target Friendly Previous" },
{ TK_TargetFriendlyBase , "Target Friendly Base" },
{ TK_TargetFriendlyBaseNearest , "Target Friendly Base Nearest" },
{ TK_TargetFriendlyBasePrev , "Target Friendly Base Previous" },
{ TK_TargetFriendlyBomber , "Target Friendly Bomber" },
{ TK_TargetFriendlyFighter , "Target Friendly Fighter" },
{ TK_TargetFriendlyConstructor , "Target Friendly Constructor" },
{ TK_TargetFriendlyMiner , "Target Friendly Miner" },
{ TK_TargetFriendlyLifepod , "Target Friendly Lifepod" },
{ TK_TargetFriendlyMajorBase , "Target Friendly Major Base" },
{ TK_TargetFriendlyBomberNearest , "Target Nearest Friendly Bomber" },
{ TK_TargetFriendlyFighterNearest , "Target Nearest Friendly Fighter" },
{ TK_TargetFriendlyConstructorNearest, "Target Nearest Friendly Constructor" },
{ TK_TargetFriendlyMinerNearest , "Target Nearest Friendly Miner" },
{ TK_TargetFriendlyLifepodNearest , "Target Nearest Friendly Lifepod" },
{ TK_TargetFriendlyMajorBaseNearest , "Target Nearest Friendly Major Base" },
{ TK_TargetFriendlyBomberPrev , "Target Previous Friendly Bomber" },
{ TK_TargetFriendlyFighterPrev , "Target Previous Friendly Fighter" },
{ TK_TargetFriendlyConstructorPrev , "Target Previous Friendly Constructor" },
{ TK_TargetFriendlyMinerPrev , "Target Previous Friendly Miner" },
{ TK_TargetFriendlyLifepodPrev , "Target Previous Friendly Lifepod" },
{ TK_TargetFriendlyMajorBasePrev , "Target Previous Friendly Major Base" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Other" },
{ TK_NoKeyMapping , "" },
{ TK_Suicide , "Eject From Turret (Press 3 times)" },
{ TK_ToggleCloak , "Toggle Cloak" },
{ TK_Ripcord , "Ripcord (teleport)" },
{ TK_PauseTM , "Pause (training mission only)" },
{ TK_CommandFinishTM , "Finish goal (training mission only)" },
{ TK_TrackCommandView , "Toggle command view target tracking" },
{ TK_ScrnShot , "Take a screen shot" },
{ TK_NoKeyMapping , "" },
{ TK_NoKeyMapping , "Joystick" },
{ TK_NoKeyMapping , "" },
};
const int g_nCommandInfo = ArrayCount(g_pCommandInfo);
class InputMapPopup :
public IPopup,
public EventTargetContainer<InputMapPopup>,
public List,
public ItemPainter
{
private:
class KeyMapping {
public:
int m_vk ;
int m_modifiers;
};
class ButtonMapping {
public:
int m_indexJoystick;
int m_indexButton ;
};
class CommandMap {
public:
int indexJoystick;
TList<KeyMapping> m_listKeyMapping;
TList<ButtonMapping> m_listButtonMapping;
void Clear()
{
m_listKeyMapping.SetEmpty();
m_listButtonMapping.SetEmpty();
}
void AddKeyMapping(int vk, int modifiers)
{
m_listKeyMapping.PushFront();
m_listKeyMapping.GetFront().m_vk = vk;
if (modifiers == ModifierAny) {
m_listKeyMapping.GetFront().m_modifiers = ModifierNone;
} else {
m_listKeyMapping.GetFront().m_modifiers = modifiers;
}
}
void AddButtonMapping(int indexJoystick, int indexButton)
{
m_listButtonMapping.PushFront();
m_listButtonMapping.GetFront().m_indexJoystick = indexJoystick;
m_listButtonMapping.GetFront().m_indexButton = indexButton;
}
bool HasKeyMapping(int vk, int modifiers)
{
TList<KeyMapping>::Iterator iter(m_listKeyMapping);
while (!iter.End()) {
KeyMapping& map = iter.Value();
if (
map.m_vk == vk
&& map.m_modifiers == modifiers
) {
return true;
}
iter.Next();
}
return false;
}
void RemoveKeyMapping(int vk, int modifiers)
{
TList<KeyMapping>::Iterator iter(m_listKeyMapping);
while (!iter.End()) {
KeyMapping& map = iter.Value();
if (
map.m_vk == vk
&& map.m_modifiers == modifiers
) {
iter.Remove();
} else {
iter.Next();
}
}
}
bool HasButtonMapping(int indexJoystick, int indexButton)
{
TList<ButtonMapping>::Iterator iter(m_listButtonMapping);
while (!iter.End()) {
ButtonMapping& map = iter.Value();
if (
map.m_indexJoystick == indexJoystick
&& map.m_indexButton == indexButton
) {
return true;
}
iter.Next();
}
return false;
}
void RemoveButtonMapping(int indexJoystick, int indexButton)
{
TList<ButtonMapping>::Iterator iter(m_listButtonMapping);
while (!iter.End()) {
ButtonMapping& map = iter.Value();
if (
map.m_indexJoystick == indexJoystick
&& map.m_indexButton == indexButton
) {
iter.Remove();
} else {
iter.Next();
}
}
}
ZString GetString(InputEngine* pinputEngine, bool bInternational)
{
ZString str;
bool bFirst = true;
{
TList<KeyMapping>::Iterator iter(m_listKeyMapping);
while (!iter.End()) {
KeyMapping& map = iter.Value();
if (bFirst) {
bFirst = false;
} else {
str += ", ";
}
if (map.m_modifiers & ModifierShift) {
str += "Shift+";
}
if (map.m_modifiers & ModifierControl) {
str += "Control+";
}
if (map.m_modifiers & ModifierAlt) {
str += "Alt+";
}
char buf[128];
UINT scan = ::MapVirtualKey(map.m_vk, 0) << 16;
if (scan & (1 << 32)) {
scan |= (1 << 24);
scan &= ~(1 << 23);
}
int length = 0;
if (bInternational) {
length = ::GetKeyNameText(scan, buf, 128);
}
if (length == 0) {
str += g_pkeyInfo[map.m_vk].m_pcc;
} else {
str += ZString(buf, length);
}
iter.Next();
}
}
{
TList<ButtonMapping>::Iterator iter(m_listButtonMapping);
while (!iter.End()) {
ButtonMapping& map = iter.Value();
if (bFirst) {
bFirst = false;
} else {
str += ", ";
}
if (map.m_indexJoystick == -1) {
str += "Mouse Btn " + ZString(map.m_indexButton + 1);
} else {
str += "Joy " + ZString(map.m_indexJoystick);
switch(map.m_indexButton) {
case -1: str += " Hat Forward" ; break;
case -2: str += " Hat Right" ; break;
case -3: str += " Hat Backward" ; break;
case -4: str += " Hat Left " ; break;
default: str += " Btn " + ZString(map.m_indexButton + 1); break;
}
}
iter.Next();
}
}
return str;
}
void FillModifierMap(TArray<bool, 256>& pbNoModifiers)
{
TList<KeyMapping>::Iterator iter(m_listKeyMapping);
while (!iter.End()) {
KeyMapping& map = iter.Value();
if (map.m_modifiers != ModifierNone) {
pbNoModifiers[map.m_vk] = false;
}
iter.Next();
}
}
void WriteKeyboardMapping(ZFile* pfile, int cmd, bool& bFirst, TArray<bool, 256>& pbNoModifiers)
{
{
TList<KeyMapping>::Iterator iter(m_listKeyMapping);
while (!iter.End()) {
KeyMapping& map = iter.Value();
if (bFirst) {
bFirst = false;
} else {
pfile->Write(ZString(",\n"));
}
int modifiers = map.m_modifiers;
if (
modifiers == ModifierNone
&& pbNoModifiers[map.m_vk]
) {
modifiers = ModifierAny;
}
pfile->Write(
" ("
+ ZString(map.m_vk)
+ ", "
+ ZString(modifiers)
+ ", "
+ ZString(cmd)
+ ")"
);
iter.Next();
}
}
}
void WriteMouseButtonMapping(ZFile* pfile, int cmd, bool& bFirst)
{
TList<ButtonMapping>::Iterator iter(m_listButtonMapping);
while (!iter.End()) {
ButtonMapping& map = iter.Value();
if (map.m_indexJoystick == -1) {
if (bFirst) {
bFirst = false;
} else {
pfile->Write(ZString(",\n"));
}
pfile->Write(
" ("
+ ZString(map.m_indexButton)
+ ", "
+ ZString(cmd)
+ ")"
);
}
iter.Next();
}
}
void WriteButtonMapping(ZFile* pfile, int cmd, bool& bFirst)
{
TList<ButtonMapping>::Iterator iter(m_listButtonMapping);
while (!iter.End()) {
ButtonMapping& map = iter.Value();
if (map.m_indexJoystick != -1) {
if (bFirst) {
bFirst = false;
} else {
pfile->Write(ZString(",\n"));
}
pfile->Write(
" ("
+ ZString(map.m_indexJoystick)
+ ", "
+ ZString(map.m_indexButton)
+ ", "
+ ZString(cmd)
+ ")"
);
}
iter.Next();
}
}
};
class Axis {
public:
int m_indexJoystick;
int m_indexValue;
};
class EvaluateImage : public WrapImage {
private:
InputMapPopup* m_ppopup;
public:
EvaluateImage(InputMapPopup* ppopup, Image* pimage, Number* ptime) :
WrapImage(pimage, ptime),
m_ppopup(ppopup)
{
}
void Evaluate()
{
m_ppopup->Evaluate();
}
MouseResult HitTest(IInputProvider* pprovider, const Point& point, bool bCaptured)
{
MouseResult result = WrapImage::HitTest(pprovider, point, bCaptured);
if (m_ppopup->IsEditing()) {
result.Set(MouseResultHit());
}
return result;
}
MouseResult Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown)
{
if (m_ppopup->IsEditing()) {
if (bDown) {
m_ppopup->Button(button);
}
return MouseResult();
}
return WrapImage::Button(pprovider, point, button, bCaptured, bInside, bDown);
}
};
CommandMap m_pcommandMap[TK_Max];
TArray<Axis, countAxis> m_paxis;
TVector<float> m_vvalue;
TArray<bool, 256> m_pbNoModifiers;
TRef<Modeler> m_pmodeler;
TRef<InputEngine> m_pinputEngine;
TRef<TrekInput> m_ptrekInput;
TRef<IEngineFont> m_pfont;
TRef<Number> m_ptime;
TRef<ModifiableString> m_pstringText;
TRef<Pane> m_ppane;
TRef<ButtonPane> m_pbuttonOK;
TRef<ButtonPane> m_pbuttonCancel;
TRef<ButtonPane> m_pbuttonRestore;
TRef<ButtonPane> m_pbuttonClose;
TRef<ListPane> m_plistPane;
TRef<EventSourceImpl> m_peventSource;
int m_column;
Color m_colorSelection;
Color m_colorText;
Color m_colorNoMapping;
bool m_bInternational;
bool m_bEditing;
bool m_bQuestion;
bool m_bButton;
bool m_bAxis;
int m_vkQuestion;
int m_modifiersQuestion;
int m_indexJoystickQuestion;
int m_indexButtonQuestion;
int m_indexAxisQuestion;
public:
bool IsInternationalKeyboard()
{
HKL hkl = ::GetKeyboardLayout(0);
return (hkl != (HKL)0x04090409);
}
InputMapPopup(
Modeler* pmodeler,
InputEngine* pinputEngine,
TrekInput* ptrekInput,
IEngineFont* pfont,
Number* ptime
) :
m_pmodeler(pmodeler),
m_pinputEngine(pinputEngine),
m_ptrekInput(ptrekInput),
m_pfont(pfont),
m_ptime(ptime),
m_peventSource(new EventSourceImpl()),
m_bEditing(false),
m_bQuestion(false),
m_bButton(false),
m_bAxis(false)
{
m_bInternational = IsInternationalKeyboard();
TRef<INameSpace> pnsTeamScreenData = GetModeler()->CreateNameSpace("inputmappanedata");
pnsTeamScreenData->AddMember("text", m_pstringText = new ModifiableString(ZString()));
SetMessage();
TRef<INameSpace> pns = pmodeler->GetNameSpace("inputmappane");
CastTo(m_ppane, pns->FindMember("inputMapPane"));
CastTo(m_pbuttonOK, pns->FindMember("okButton"));
CastTo(m_pbuttonCancel, pns->FindMember("cancelButton"));
CastTo(m_pbuttonRestore, pns->FindMember("restoreButton"));
CastTo(m_pbuttonClose, pns->FindMember("closeButton"));
AddEventTarget(&InputMapPopup::OnButtonOK, m_pbuttonOK->GetEventSource());
AddEventTarget(&InputMapPopup::OnButtonCancel, m_pbuttonCancel->GetEventSource());
AddEventTarget(&InputMapPopup::OnButtonRestore, m_pbuttonRestore->GetEventSource());
m_column = (int)pns->FindNumber("mappingOffset");
m_colorText = pns->FindColor("textColor");
m_colorNoMapping = pns->FindColor("noMappingColor");
m_colorSelection = pns->FindColor("selectionColor");
CastTo(m_plistPane, (Pane*)pns->FindMember("listPane"));
AddEventTarget(&InputMapPopup::OnDoubleClick, m_plistPane->GetDoubleClickEventSource());
m_plistPane->SetItemPainter(this);
m_plistPane->SetList(this);
pmodeler->UnloadNameSpace(pns);
if (!LoadMap(INPUTMAP_FILE)) {
LoadMap(DEFAULTINPUTMAP_FILE);
}
}
void SetMessage(const ZString& str = ZString())
{
if (str.IsEmpty()) {
m_pstringText->SetValue("Press Enter to add a mapping or Delete to remove mapping.");
} else {
m_pstringText->SetValue(str);
}
}
void Changed()
{
m_peventSource->Trigger();
}
bool LoadMap(const ZString& str)
{
TRef<INameSpace> pns = GetModeler()->GetNameSpace(str, false);
if (pns == NULL) {
return false;
}
m_pinputEngine->EnumerateJoysticks();
int index;
for (index = 0; index < TK_Max; index++) {
m_pcommandMap[index].Clear();
}
{
TRef<IObjectList> plist = pns->FindList("keyCommandMap");
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
int vk = (int)GetNumber(ppair->GetNth(0) );
int modifiers = (int)GetNumber(ppair->GetNth(1) );
int tk = (int)GetNumber(ppair->GetLastNth(2));
m_pcommandMap[tk].AddKeyMapping(vk, modifiers);
plist->GetNext();
}
}
{
TRef<IObjectList> plist = pns->FindList("mouseButtonCommandMap");
if (plist) {
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
int index = (int)GetNumber(ppair->GetFirst() );
int tk = (int)GetNumber(ppair->GetSecond());
m_pcommandMap[tk].AddButtonMapping(-1, index);
plist->GetNext();
}
}
}
{
TRef<IObjectList> plist = pns->FindList("buttonCommandMap");
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
int indexJoystick = (int)GetNumber(ppair->GetNth(0) );
int indexButton = (int)GetNumber(ppair->GetNth(1) );
int tk = (int)GetNumber(ppair->GetLastNth(2));
m_pcommandMap[tk].AddButtonMapping(indexJoystick, indexButton);
plist->GetNext();
}
}
{
TRef<IObjectList> plist = pns->FindList("numericValuesNew");
bool bNew = (plist != NULL);
if (!bNew) {
plist = pns->FindList("numericValues");
}
plist->GetFirst();
for (int indexValueOutput = 0; indexValueOutput < m_paxis.GetCount(); indexValueOutput++) {
TRef<IObjectPair> ppair; CastTo(ppair, plist->GetCurrent());
if (ppair) {
m_paxis[indexValueOutput].m_indexJoystick = (int)GetNumber(ppair->GetFirst() );
m_paxis[indexValueOutput].m_indexValue = (int)GetNumber(ppair->GetSecond());
if (!bNew) {
if (m_paxis[indexValueOutput].m_indexValue == 2) {
m_paxis[indexValueOutput].m_indexValue = 3;
} else if (m_paxis[indexValueOutput].m_indexValue == 3) {
m_paxis[indexValueOutput].m_indexValue = 2;
}
}
} else {
m_paxis[indexValueOutput].m_indexJoystick = -1;
m_paxis[indexValueOutput].m_indexValue = 0;
}
plist->GetNext();
}
}
GetModeler()->UnloadNameSpace(pns);
return true;
}
void SaveMap(const ZString& str)
{
TRef<ZFile> pfile = new ZWriteFile(m_pmodeler->GetArtPath() + "/" + str + ".mdl");
pfile->Write(ZString("use \"commands\";\n"));
pfile->Write(ZString("use \"keycode\";\n" ));
int index;
for (index = 0; index < 256; index++) {
m_pbNoModifiers[index] = true;
}
for (index = 0; index < TK_Max; index++) {
m_pcommandMap[index].FillModifierMap(m_pbNoModifiers);
}
pfile->Write(ZString("keyCommandMap =\n" ));
pfile->Write(ZString(" [\n" ));
bool bFirst = true;
for (index = 0; index < TK_Max; index++) {
m_pcommandMap[index].WriteKeyboardMapping(pfile, index, bFirst, m_pbNoModifiers);
}
if (!bFirst) {
pfile->Write(ZString("\n"));
}
pfile->Write(ZString(" ];\n" ));
pfile->Write(ZString("mouseButtonCommandMap =\n"));
pfile->Write(ZString(" [\n" ));
bFirst = true;
for (index = 0; index < TK_Max; index++) {
m_pcommandMap[index].WriteMouseButtonMapping(pfile, index, bFirst);
}
if (!bFirst) {
pfile->Write(ZString("\n"));
}
pfile->Write(ZString(" ];\n" ));
pfile->Write(ZString("buttonCommandMap =\n"));
pfile->Write(ZString(" [\n" ));
bFirst = true;
for (index = 0; index < TK_Max; index++) {
m_pcommandMap[index].WriteButtonMapping(pfile, index, bFirst);
}
if (!bFirst) {
pfile->Write(ZString("\n"));
}
pfile->Write(ZString(" ];\n" ));
pfile->Write(ZString("numericValuesNew =\n"));
pfile->Write(ZString(" [\n" ));
for (index = 0; index < m_paxis.GetCount(); index++) {
pfile->Write(
" ("
+ ZString(m_paxis[index].m_indexJoystick)
+ ", "
+ ZString(m_paxis[index].m_indexValue)
+ ")"
);
if (index != m_paxis.GetCount() - 1) {
pfile->Write(ZString(","));
}
pfile->Write(ZString("\n"));
}
pfile->Write(ZString(" ];\n" ));
}
void Close()
{
if (!m_ptrekInput->LoadMap(INPUTMAP_FILE)) {
m_ptrekInput->LoadMap(DEFAULTINPUTMAP_FILE);
}
m_plistPane->SetList(NULL);
m_plistPane->SetItemPainter(NULL);
ClosePopup(this);
}
bool OnButtonOK()
{
SaveMap(INPUTMAP_FILE);
Close();
return true;
}
bool OnButtonCancel()
{
Close();
return true;
}
bool OnButtonRestore()
{
LoadMap(DEFAULTINPUTMAP_FILE);
Changed();
return true;
}
bool OnDoubleClick()
{
EditSelection();
return true;
}
int GetSelectionIndex()
{
return GetIndex(m_plistPane->GetSelection());
}
bool IsAxisSelection()
{
return GetSelectionIndex() >= g_nCommandInfo;
}
int GetCommandMapIndex()
{
return g_pCommandInfo[GetSelectionIndex()].m_tk;
}
int GetAxisIndex()
{
return GetSelectionIndex() - g_nCommandInfo;
}
void DeleteMapping()
{
if (IsAxisSelection()) {
m_paxis[GetAxisIndex()].m_indexJoystick = -1;
m_paxis[GetAxisIndex()].m_indexValue = 0;
} else {
TrekKey tk = GetCommandMapIndex();
if (tk != TK_NoKeyMapping) {
m_pcommandMap[GetCommandMapIndex()].Clear();
}
}
Changed();
}
bool IsEditing()
{
return m_bEditing;
}
void EditSelection()
{
if (IsAxisSelection()) {
m_vvalue.SetCount(0);
int countJoystick = m_pinputEngine->GetJoystickCount();
for (int indexJoystick = 0; indexJoystick < countJoystick; indexJoystick++) {
JoystickInputStream* pjoystick = m_pinputEngine->GetJoystick(indexJoystick);
int count = pjoystick->GetValueCount();
for (int index = 0; index < count; index++) {
m_vvalue.PushEnd(pjoystick->GetValue(index)->GetValue());
}
}
m_bEditing = true;
SetMessage("Move desired joystick axis.");
} else {
TrekKey tk = GetCommandMapIndex();
m_bEditing = (tk != TK_NoKeyMapping);
if (m_bEditing) {
SetMessage("Type desired key sequence or button. Escape cancels.");
}
}
Changed();
}
void StopEditing()
{
m_bEditing = false;
m_bQuestion = false;
SetMessage();
Changed();
}
void RemoveKeyMappings(int vk, int modifiers)
{
for (int index = 0; index < TK_Max; index++) {
m_pcommandMap[index].RemoveKeyMapping(vk, modifiers);
}
}
bool AddKeyMapping(int vk, int modifiers)
{
for (int index = 0; index < TK_Max; index++) {
if (m_pcommandMap[index].HasKeyMapping(vk, modifiers)) {
if (index == GetCommandMapIndex()) {
return true;
}
m_vkQuestion = vk;
m_modifiersQuestion = modifiers;
m_bQuestion = true;
m_bButton = false;
m_bAxis = false;
SetMessage("Key in use. Press Enter to lose old mapping. Escape cancels");
return false;
}
}
m_pcommandMap[GetCommandMapIndex()].AddKeyMapping(vk, modifiers);
return true;
}
void RemoveButtonMappings(int indexJoystick, int indexButton)
{
for (int index = 0; index < TK_Max; index++) {
m_pcommandMap[index].RemoveButtonMapping(indexJoystick, indexButton);
}
}
bool AddButtonMapping(int indexJoystick, int indexButton)
{
for (int index = 0; index < TK_Max; index++) {
if (m_pcommandMap[index].HasButtonMapping(indexJoystick, indexButton)) {
if (index == GetCommandMapIndex()) {
return true;
}
m_indexJoystickQuestion = indexJoystick;
m_indexButtonQuestion = indexButton;
m_bQuestion = true;
m_bButton = true;
m_bAxis = false;
SetMessage("Button in use. Press Enter to lose old mapping. Escape cancels");
return false;
}
}
m_pcommandMap[GetCommandMapIndex()].AddButtonMapping(indexJoystick, indexButton);
return true;
}
void RemoveAxisMapping(int indexJoystick, int indexValue)
{
for (int index = 0; index < m_paxis.GetCount(); index++) {
if (
m_paxis[index].m_indexJoystick == indexJoystick
&& m_paxis[index].m_indexValue == indexValue
) {
m_paxis[index].m_indexJoystick = -1;
m_paxis[index].m_indexValue = 0;
}
}
}
bool AddAxisMapping(int indexJoystick, int indexValue)
{
for (int index = 0; index < m_paxis.GetCount(); index++) {
if (
(m_paxis[index].m_indexJoystick == indexJoystick)
&& (m_paxis[index].m_indexValue == indexValue)
) {
if (index == GetAxisIndex()) {
return true;
}
m_indexJoystickQuestion = indexJoystick;
m_indexAxisQuestion = indexValue;
m_bQuestion = true;
m_bButton = false;
m_bAxis = true;
SetMessage("Axis in use. Press Enter to lose old mapping. Escape cancels");
return false;
}
}
m_paxis[GetAxisIndex()].m_indexJoystick = indexJoystick;
m_paxis[GetAxisIndex()].m_indexValue = indexValue;
return true;
}
void Button(int index)
{
if (!IsAxisSelection()) {
if (AddButtonMapping(-1, index)) {
StopEditing();
}
}
}
void Evaluate()
{
if (m_bEditing) {
int countJoystick = m_pinputEngine->GetJoystickCount();
int vindex = 0;
int indexJoystick;
for (indexJoystick = 0; indexJoystick < countJoystick; indexJoystick++) {
JoystickInputStream* pjoystick = m_pinputEngine->GetJoystick(indexJoystick);
if (IsAxisSelection()) {
int count = pjoystick->GetValueCount();
for (int index = 0; index < count; index++) {
float dvalue = m_vvalue[vindex] - pjoystick->GetValue(index)->GetValue();
vindex++;
if (dvalue < -0.9 || dvalue > 0.9) {
if (AddAxisMapping(indexJoystick, index)) {
StopEditing();
}
return;
}
}
} else {
int count = pjoystick->GetButtonCount();
for (int index = 0; index < count; index++) {
if (pjoystick->IsDown(index)->GetValue()) {
if (AddButtonMapping(indexJoystick, index)) {
StopEditing();
}
return;
}
}
}
}
if (!IsAxisSelection()) {
JoystickInputStream* pjoystick = m_pinputEngine->GetJoystick(m_paxis[5].m_indexJoystick);
if (pjoystick) {
Number* pvalue = pjoystick->GetValue(m_paxis[5].m_indexValue);
if (pvalue) {
float value = pvalue->GetValue();
if (value > 0.75f) {
if (AddButtonMapping(indexJoystick, -3)) {
StopEditing();
}
return;
} else if (value > 0.25f) {
if (AddButtonMapping(indexJoystick, -2)) {
StopEditing();
}
return;
} else if (value > -0.25f) {
if (AddButtonMapping(indexJoystick, -1)) {
StopEditing();
}
return;
} else if (value > -0.75f) {
if (AddButtonMapping(indexJoystick, -4)) {
StopEditing();
}
return;
} else if (value > -1.25f) {
if (AddButtonMapping(indexJoystick, -3)) {
StopEditing();
}
return;
}
}
}
}
}
}
int GetCount()
{
return g_nCommandInfo + m_paxis.GetCount();
}
ItemID GetItem(int index)
{
return (ItemID)(index + 1);
}
int GetIndex(ItemID pitem)
{
return int(pitem) - 1;
}
ItemID GetNext(ItemID pitem)
{
int index = GetIndex(pitem);
if (index == GetCount() - 1) {
return 0;
} else {
return GetItem(index + 1);
}
}
IEventSource* GetChangedEvent()
{
return m_peventSource;
}
int GetXSize()
{
return m_plistPane->XSize();
}
int GetYSize()
{
return m_pfont->GetHeight();
}
void Paint(ItemID itemID, Surface* psurface, bool bSelected, bool bFocus)
{
ZString strCommand;
ZString strMapping;
int index = GetIndex(itemID);
bool bNoMapping = false;
if (index >= g_nCommandInfo) {
int indexAxis = index - g_nCommandInfo;
strCommand = g_ppccAxisDescription[indexAxis];
if (m_paxis[indexAxis].m_indexJoystick != -1) {
JoystickInputStream* pjoystick = m_pinputEngine->GetJoystick(m_paxis[indexAxis].m_indexJoystick);
TRef<Number> pvalueInput;
if (pjoystick) {
pvalueInput = pjoystick->GetValue(m_paxis[indexAxis].m_indexValue);
}
if (pvalueInput) {
strMapping =
pjoystick->GetShortDescription(m_paxis[indexAxis].m_indexJoystick)
+ " "
+ pjoystick->GetValueDescription(m_paxis[indexAxis].m_indexValue);
} else {
strMapping =
"Joy " + ZString(m_paxis[indexAxis].m_indexJoystick)
+ " Value "
+ ZString(m_paxis[indexAxis].m_indexValue);
}
}
} else {
strCommand = g_pCommandInfo[index].m_pcc;
TrekKey tk = g_pCommandInfo[index].m_tk;
if (tk != TK_NoKeyMapping) {
strMapping = m_pcommandMap[tk].GetString(m_pinputEngine, m_bInternational);
} else {
bNoMapping = true;
}
}
if (m_bEditing && index == GetSelectionIndex()) {
if (m_bQuestion) {
strMapping = "!!!";
} else {
strMapping = "???";
}
}
if (bSelected) {
psurface->FillRect(
WinRect(0, 0, GetXSize(), GetYSize()),
m_colorSelection
);
}
if (bNoMapping) {
psurface->DrawString(m_pfont, m_colorNoMapping, WinPoint(0, 0), strCommand);
} else {
psurface->DrawString(m_pfont, m_colorText, WinPoint(0, 0), strCommand);
}
psurface->DrawString(m_pfont, m_colorText, WinPoint(m_column, 0), strMapping);
}
Pane* GetPane()
{
return m_ppane;
}
TRef<Image> GetImage(Engine* pengine)
{
return
new EvaluateImage(
this,
CreatePaneImage(pengine, SurfaceType3D(), true, GetPane()),
m_ptime
);
}
bool OnKey(IInputProvider* pprovider, const KeyState& ks, bool& fForceTranslate)
{
if (ks.bDown) {
if (m_bQuestion) {
if (ks.vk == VK_ESCAPE) {
StopEditing();
} else if (ks.vk == VK_RETURN) {
if (m_bButton) {
RemoveButtonMappings(m_indexJoystickQuestion, m_indexButtonQuestion);
AddButtonMapping(m_indexJoystickQuestion, m_indexButtonQuestion);
} else if (m_bAxis) {
RemoveAxisMapping(m_indexJoystickQuestion, m_indexAxisQuestion);
AddAxisMapping(m_indexJoystickQuestion, m_indexAxisQuestion);
} else {
RemoveKeyMappings(m_vkQuestion, m_modifiersQuestion);
AddKeyMapping(m_vkQuestion, m_modifiersQuestion);
}
StopEditing();
}
} else if (m_bEditing) {
if (ks.vk == VK_ESCAPE) {
StopEditing();
} else if (
ks.vk != VK_MENU
&& ks.vk != VK_CONTROL
&& ks.vk != VK_SHIFT
) {
if (!IsAxisSelection()) {
int modifiers = 0;
if (ks.bAlt) {
modifiers |= ModifierAlt;
}
if (ks.bShift) {
modifiers |= ModifierShift;
}
if (ks.bControl) {
modifiers |= ModifierControl;
}
if (AddKeyMapping(ks.vk, modifiers)) {
StopEditing();
}
}
}
} else {
switch (ks.vk) {
case VK_ESCAPE:
OnButtonCancel();
break;
case VK_DELETE:
DeleteMapping();
break;
case VK_RETURN:
EditSelection();
break;
case VK_SPACE:
OnButtonOK();
break;
default:
m_plistPane->OnKey(pprovider, ks, fForceTranslate);
break;
}
}
}
return true;
}
};
TRef<IPopup> CreateInputMapPopup(
Modeler* pmodeler,
InputEngine* pinputEngine,
TrekInput* ptrekInput,
IEngineFont* pfont,
Number* ptime
) {
return
new InputMapPopup(
pmodeler,
pinputEngine,
ptrekInput,
pfont,
ptime
);
}