#pragma once #include "..\munga\controls.h" #include "l4rio.h" #include "l4keybd.h" #include "l4mouse.h" #include "l4joystk.h" #include "l4lamp.h" #include "..\munga\time.h" #include "..\munga\entity.h" #include class LBE4ControlsManager; class L4MappableButtonManager; //######################################################################## //############################ Joystick classes ########################## //######################################################################## class Joystick; class OrdinaryJoystick; class FlightStickPro; class ThrustMaster; class Joystick SIGNATURED { friend class LBE4ControlsManager; friend class OrdinaryJoystick; friend class FlightStickPro; friend class ThrustMaster; protected: Joystick(); public: virtual ~Joystick(); virtual void BeginAlignment(); virtual void EndAlignment(); virtual void Update(); void SetDeadBand(Scalar amount_of_deadband); Logical TestInstance() const; protected: virtual void EndAndSaveAlignment(NotationFile *init_file); public: enum ButtonState { NoButton = 0, Trigger = 0x01, Thumb1 = 0x02, Thumb2 = 0x04, Thumb3 = 0x08, HatUp = 0x10, HatDown = 0x20, HatLeft = 0x40, HatRight = 0x80, Throttle = 0x100 }; Vector2DOf Value; Vector2DOf ExtendedValue; Vector2DOf Rotation; int ButtonReleased; int ButtonPressed; protected: FilterChannel *channel[2]; int oldButtons; }; class OrdinaryJoystick: public Joystick { public: OrdinaryJoystick(); ~OrdinaryJoystick(); void Update(); }; class FlightStickPro: public Joystick { public: FlightStickPro(); ~FlightStickPro(); void Update(); void BeginAlignment(); void EndAlignment(); protected: FilterChannel *throttle; }; class ThrustMaster: public Joystick { friend BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext); friend BOOL CALLBACK EnumAxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); public: ThrustMaster(HINSTANCE hInstance, HWND hWnd); ~ThrustMaster(); void Update(); int hatMax, prevHatState; private: bool Poll(); LPDIRECTINPUT8 mDI; LPDIRECTINPUTDEVICE8 mJoystick; DIJOYSTATE2 mJoystate; LONG xAxisMin, xAxisMax; LONG yAxisMin, yAxisMax; LONG zAxisMin, zAxisMax; LONG rzAxisMin, rzAxisMax; }; enum RioStreamEventType { analog, digital }; struct RIOStreamEvent { Time timeStamp; RioStreamEventType eventType; union { struct { Scalar joystickX, joystickY, throttle, pedalLeft, pedalRight; } analog; RIO::RIOEvent rioEvent; } data; }; //######################################################################### //########################## LBE4ControlsManager ########################## //######################################################################### class LBE4ControlsManager: public ControlsManager { friend class L4MappableButtonManager; // allows access to 'groupEnable' //------------------------------------------------------------------- // Shared data support //------------------------------------------------------------------- public: static Derivation *GetClassDerivations(); static SharedData DefaultData; //------------------------------------------------------------------- // Message support //------------------------------------------------------------------- // public: // enum { // BeginCalibrationMessageID=ControlsManager::NextMessageID, // EndCalibrationMessageID, // NextMessageID // }; // private: // static const HandlerEntry MessageHandlerEntries[]; // protected: // static MessageHandlerSet MessageHandlers; //------------------------------------------------------------------- // Construction/destruction/verification //------------------------------------------------------------------- public: LBE4ControlsManager(); ~LBE4ControlsManager(); static Logical TestClass(); Logical TestInstance() const; void LocalShutdown(); void Execute(); //------------------------------------------------------------------- // Message handlers //------------------------------------------------------------------- // void // BeginCalibrationMessageHandler(Receiver::Message *message); // void // EndCalibrationMessageHandler(Receiver::Message *message); // //------------------------------------------------------------------- // Control mapping methods //------------------------------------------------------------------- void Remove(ModeMask mode_mask); static int SetControlMappingID( const char *control_name, ControlsMapping *mapping ); void CreateStreamedMappings( Entity *player, const int *control_mappings ); //------------------------------------------------------------------- // Lamps //------------------------------------------------------------------- // Commonly used combinations enum { LampSolidOff = RIO::solid + RIO::state1Off + RIO::state2Off, LampSolidDim = RIO::solid + RIO::state1Dim + RIO::state2Dim, LampSolidBright = RIO::solid + RIO::state1Bright + RIO::state2Bright }; // This is the order of the mapped lamps // See also "GetLampName" enum { LampAuxLowerRight8=0x00, // Lower left auxiliary panel buttons LampAuxLowerRight7, LampAuxLowerRight6, LampAuxLowerRight5, LampAuxLowerRight4, LampAuxLowerRight3, LampAuxLowerRight2, LampAuxLowerRight1, LampAuxLowerLeft8=0x08, // Lower right auxiliary panel buttons LampAuxLowerLeft7, LampAuxLowerLeft6, LampAuxLowerLeft5, LampAuxLowerLeft4, LampAuxLowerLeft3, LampAuxLowerLeft2, LampAuxLowerLeft1, LampSecondary1=0x10, // Secondary panel buttons LampSecondary2, LampSecondary3, LampSecondary4, LampSecondary5, LampSecondary6, LampTesla1, // top? of three solid-state relays LampTesla2, // middle? of three solid-state relays LampSecondary7=0x18, LampSecondary8, LampSecondary9, LampSecondary10, LampSecondary11, LampSecondary12, LampTesla3, // bottom of three solid-state relays LampAuxUpperCenter8=0x20, // Upper center auxiliary panel buttons LampAuxUpperCenter7, LampAuxUpperCenter6, LampAuxUpperCenter5, LampAuxUpperCenter4, LampAuxUpperCenter3, LampAuxUpperCenter2, LampAuxUpperCenter1, LampAuxUpperLeft8=0x28, // Upper left auxiliary panel buttons LampAuxUpperLeft7, LampAuxUpperLeft6, LampAuxUpperLeft5, LampAuxUpperLeft4, LampAuxUpperLeft3, LampAuxUpperLeft2, LampAuxUpperLeft1, LampAuxUpperRight8=0x30, // Upper right auxiliary panel buttons LampAuxUpperRight7, LampAuxUpperRight6, LampAuxUpperRight5, LampAuxUpperRight4, LampAuxUpperRight3, LampAuxUpperRight2, LampAuxUpperRight1, LampIcomDecRelay = 0x38, LampIcomAmpEnable = 0x39, LampIcomIncRelay = 0x3A, LampIcomPTTRelay = 0x03B, LampPanic=0x3D, LampFloor=0x3E, // floor lamp (entry/exit) LampUnused=0x3F, // unimplemented convenience lamp LampCount // the total number of defined lamps }; Lamp * MakeLinkedLamp( int element, ModeMask mode_mask = ModeManager::ModeAlwaysActive ); void SetLamp( int lamp_number, int state ); static const char* GetLampName(int lamp_number); //------------------------------------------------------------------- // Control groups // Each control belongs to one of several groups (as in the // enum below). //------------------------------------------------------------------- enum { ScalarGroup, JoystickGroup, KeyboardGroup, ButtonGroup, MouseGroup }; //------------------------------------------------------------- // Scalars //------------------------------------------------------------- // This is the order of the mapped scalars enum { ScalarThrottle, ScalarLeftPedal, ScalarRightPedal, ScalarJoystickX, ScalarJoystickY, // 'real' joystick values ScalarMouseX, ScalarMouseY, // 'virtual' joystick values ScalarCount }; ControlsUpdateManager scalarGroup[ScalarCount]; public: void SetThrottleDeadBand(Scalar dead_band); void SetPedalsDeadBand(Scalar dead_band); //------------------------------------------------------------- // Joysticks //------------------------------------------------------------- void BeginAlignJoystick(); void EndAlignJoystick(); void CenterRIOJoystick(); void SetJoystickDeadBand(Scalar dead_band); // This is the order of the mapped joysticks enum { JoystickPhysical, // the 'real' joystick JoystickVirtual, // a 'virtual' joystick driven by the PC mouse JoystickCount }; ControlsUpdateManager joystickGroup[JoystickCount]; enum JoystickType { none, ordinary, flightstickPro, thrustMaster, directInputJoystick }; JoystickType joystickType; protected: Joystick *joystickPointer; int virtualJoystickX, virtualJoystickY; Scalar lastJoystickUpdate; public: //------------------------------------------------------------- // Keyboards //------------------------------------------------------------- // This is the order of the mapped keyboards enum { KeyboardPilot, // internal keypad used by the pilot KeyboardExternal, // external keypad used by an operator KeyboardPC, // PC keyboard KeyboardCount }; ControlsUpdateManager keyboardGroup[KeyboardCount]; //------------------------------------------------------------- // Buttons //------------------------------------------------------------- // This is the order of the buttons enum { ButtonAuxLowerRight8=0x00, // Lower left auxiliary panel buttons ButtonAuxLowerRight7, ButtonAuxLowerRight6, ButtonAuxLowerRight5, ButtonAuxLowerRight4, ButtonAuxLowerRight3, ButtonAuxLowerRight2, ButtonAuxLowerRight1, ButtonAuxLowerLeft8=0x08, // Lower right auxiliary panel buttons ButtonAuxLowerLeft7, ButtonAuxLowerLeft6, ButtonAuxLowerLeft5, ButtonAuxLowerLeft4, ButtonAuxLowerLeft3, ButtonAuxLowerLeft2, ButtonAuxLowerLeft1, ButtonSecondary1=0x10, // Secondary panel buttons ButtonSecondary2, ButtonSecondary3, ButtonSecondary4, ButtonSecondary5, ButtonSecondary6, ButtonSecondary7=0x18, ButtonSecondary8, ButtonSecondary9, ButtonSecondary10, ButtonSecondary11, ButtonSecondary12, ButtonAuxUpperCenter8=0x20,// Upper center auxiliary panel buttons ButtonAuxUpperCenter7, ButtonAuxUpperCenter6, ButtonAuxUpperCenter5, ButtonAuxUpperCenter4, ButtonAuxUpperCenter3, ButtonAuxUpperCenter2, ButtonAuxUpperCenter1, ButtonAuxUpperLeft8=0x28, // Upper left auxiliary panel buttons ButtonAuxUpperLeft7, ButtonAuxUpperLeft6, ButtonAuxUpperLeft5, ButtonAuxUpperLeft4, ButtonAuxUpperLeft3, ButtonAuxUpperLeft2, ButtonAuxUpperLeft1, ButtonAuxUpperRight8=0x30, // Upper right auxiliary panel buttons ButtonAuxUpperRight7, ButtonAuxUpperRight6, ButtonAuxUpperRight5, ButtonAuxUpperRight4, ButtonAuxUpperRight3, ButtonAuxUpperRight2, ButtonAuxUpperRight1, ButtonIcomHeadPluggedIn = 0x39, ButtonIcomSensor = 0x3A, ButtonIcomMikePluggedIn = 0x3B, ButtonDoor=0x3C, ButtonPanic=0x3D, ButtonThrottle1=0x3F, ButtonJoystickTrigger=0x40, // Joystick trigger button FirstMappableButton=ButtonJoystickTrigger, ButtonJoystickHatDown=0x41, // Joystick trigger hat down ButtonJoystickHatUp=0x42, // Joystick trigger hat up ButtonJoystickHatRight=0x43, // Joystick trigger hat left ButtonJoystickHatLeft=0x44, // Joystick trigger hat left ButtonJoystickPinky=0x45, // Joystick lowest button ButtonJoystickThumbLow=0x46, // Joystick middle thumb button ButtonJoystickThumbHigh=0x47, // Joystick upper thumb button (by hat) LastMappableButton=ButtonJoystickThumbHigh, // The PC keyboard buttons will eventually // be added here. ButtonMouseLeft, // left mouse button ButtonMouseRight, // right mouse button ButtonMouseCenter, // center mouse button (if available) ButtonCount // defines number of buttons }; ControlsUpdateManager buttonGroup[ButtonCount]; protected: ModeMask buttonActivateModeMask[ButtonCount]; //------------------------------------------------------------- // Mouse //------------------------------------------------------------- public: ControlsUpdateManager mouseGroup[1]; // Yes, only one mouse. Get real. protected: Mouse *mousePointer; public: //------------------------------------------------------------- // Strings (matched keyboard input) //------------------------------------------------------------- ControlsStringManager stringManager; public: //------------------------------------------------------------------- // RIO data //------------------------------------------------------------------- RIO *rioPointer; protected: Time lastRioRequest; public: //------------------------------------------------------------------- // Current IO type //------------------------------------------------------------------- enum IOType { None = 0, PrimaryGenericJoystick, PrimaryThrustMaster, PrimaryFlightStickPro, PrimaryRIO, PrimaryDirectInputJoystick }; IOType primaryControlType; //------------------------------------------------------------------- // Existence flags //------------------------------------------------------------------- struct { unsigned int mouseExists:1; unsigned int keyboardExists:1; unsigned int joystickExists:1; unsigned int RIOExists:1; }flags; //------------------------------------------------------------------- // Operator controls //------------------------------------------------------------------- protected: enum L4ControlsMode { normalMode = 0, calibrationMode }; void EnterControlsMode( L4ControlsMode new_mode, Scalar time_until_exit, Receiver::MessageID message_on_exit ); void ExitControlsMode(); void ManageControlsMode(); L4ControlsMode l4ControlsMode; Time exitModeTime; Receiver::MessageID exitMessageID; enum { maxStringIDs = 16 }; ControlsStringID temporaryStringID[maxStringIDs]; // //-------------------- // RIO Stream Spoofing //-------------------- // public: Logical GetNextRIOEvent(RIO::RIOEvent *rio_event); void ProcessRIOEvent( RIO::RIOEvent &rio_event, Logical *new_RIO_values ); void StartRecording() {Check(this); streamStart = Now(); streamEnabled=True;} void SaveRecording(const char* file_name); void LoadPlayback(const char* file_name); void StartPlayback() {Check(this); streamStart = Now(); streamEnabled=True;} Logical IsRecording() {return rioStream && !playbackMode;} Logical IsPlayingBack() {return rioStream && playbackMode;} Logical AnalogHasChanged(); protected: MemoryStream *rioStream; Time streamStart; Logical playbackMode; Logical streamEnabled; Scalar previousJoystickX, previousJoystickY, previousThrottle, previousPedalLeft, previousPedalRight; };