#include "rpl4.h" #pragma hdrstop #include "..\rp\chute.h" #include "rpl4mppr.h" #include "rpl4grnd.h" #include "rpl4app.h" #include "rpl4mode.h" #include "..\munga_l4\l4ctrl.h" #include "..\munga_l4\l4keybd.h" #include "..\rp\booster.h" #include "..\rp\vtv.h" #include "..\munga\appmsg.h" L4Lamp * CreateControlledLamp( int lamp_number, ModeMask mode_mask=RPL4ModeManager::ModeAlwaysActive ) { Check(application); if (application->GetGaugeRenderer() == NULL) { return NULL; } else { Check(application->GetGaugeRenderer()); //------------------------------------------ // Create the lamp //------------------------------------------ L4LampManager *lamp_manager = (L4LampManager *) application-> GetGaugeRenderer()->GetLampManager(); Check(lamp_manager); L4Lamp *lamp = new L4Lamp( lamp_number, mode_mask, lamp_manager ); Register_Object(lamp); lamp->SetAutomaticOperation(False); Check_Fpu(); return lamp; } } //----------------------------------------------------------------------- void MakeButtonLampEvent( LBE4ControlsManager *controls, int button_number, Receiver *receiver, Receiver::MessageID message_id, Plug *dependant, ModeMask mode_mask = RPL4ModeManager::ModeAlwaysActive ) { Check(controls); Check(receiver); Check(dependant); controls->buttonGroup[button_number].Add( mode_mask, receiver, message_id, dependant ); controls->MakeLinkedLamp(button_number, mode_mask); } void MakeButtonLampEventPair( LBE4ControlsManager *controls, int button_number1, int button_number2, Receiver *receiver, Receiver::MessageID message_id, Plug *dependant, ModeMask mode_mask = RPL4ModeManager::ModeAlwaysActive ) { MakeButtonLampEvent( controls, button_number1, receiver, message_id, dependant, mode_mask ); MakeButtonLampEvent( controls, button_number2, receiver, message_id, dependant, mode_mask ); } //----------------------------------------------------------------------- void MakeButtonLampDirect( LBE4ControlsManager *controls, int button_number, ControlsButton *direct_target, Plug *dependent, ModeMask mode_mask = RPL4ModeManager::ModeAlwaysActive ) { Check(controls); controls->buttonGroup[button_number].Add( mode_mask, direct_target, dependent ); controls->MakeLinkedLamp(button_number, mode_mask); } void MakeButtonLampDirectPair( LBE4ControlsManager *controls, int button_number1, int button_number2, ControlsButton *direct_target, Plug *dependent, ModeMask mode_mask = RPL4ModeManager::ModeAlwaysActive ) { MakeButtonLampDirect( controls, button_number1, direct_target, dependent, mode_mask ); MakeButtonLampDirect( controls, button_number2, direct_target, dependent, mode_mask ); } //----------------------------------------------------------------------- void CreateDirectSystemMapping( LBE4ControlsManager *controls, int button_number, ControlsButton *direct_target, Receiver *receiver, Receiver::MessageID configure_message_id ) { Check(controls); Check(receiver); //------------------------------------------------- // When not configuring, press button to activate //------------------------------------------------- MakeButtonLampDirect( controls, button_number, direct_target, receiver, RPL4ModeManager::ModeNonConfig ); //------------------------------------------------- // When configuring, the same button allows mapping //------------------------------------------------- MakeButtonLampEvent( controls, button_number, receiver, configure_message_id, receiver, RPL4ModeManager::ModeConfigReady ); } void CreateDirectSystemMappingPair( LBE4ControlsManager *controls, int button_number1, int button_number2, ControlsButton *direct_target, Receiver *receiver, Receiver::MessageID configure_message_id ) { Check(controls); Check(receiver); CreateDirectSystemMapping( controls, button_number1, direct_target, receiver, configure_message_id ); CreateDirectSystemMapping( controls, button_number2, direct_target, receiver, configure_message_id ); } //----------------------------------------------------------------------- void CreateEventSystemMapping( LBE4ControlsManager *controls, int button_number, Receiver *receiver, Receiver::MessageID active_message_id, Receiver::MessageID configure_message_id ) { Check(controls); Check(receiver); //------------------------------------------------- // When not configuring, press button to activate //------------------------------------------------- MakeButtonLampEvent( controls, button_number, receiver, active_message_id, receiver, RPL4ModeManager::ModeNonConfig ); //------------------------------------------------- // When configuring, the same button allows mapping //------------------------------------------------- MakeButtonLampEvent( controls, button_number, receiver, configure_message_id, receiver, RPL4ModeManager::ModeConfigReady ); } void CreateEventSystemMappingPair( LBE4ControlsManager *controls, int button_number1, int button_number2, Receiver *receiver, Receiver::MessageID active_message_id, Receiver::MessageID configure_message_id ) { CreateEventSystemMapping( controls, button_number1, receiver, active_message_id, configure_message_id ); CreateEventSystemMapping( controls, button_number2, receiver, active_message_id, configure_message_id ); } //############################################################################# //########################### L4VTVControlsMapper ############################## //############################################################################# //############################################################################# // Shared Data Support // L4VTVControlsMapper::SharedData L4VTVControlsMapper::DefaultData( L4VTVControlsMapper::GetClassDerivations(), L4VTVControlsMapper::GetMessageHandlers(), L4VTVControlsMapper::GetAttributeIndex(), L4VTVControlsMapper::StateCount ); Derivation* L4VTVControlsMapper::GetClassDerivations() { static Derivation classDerivations(VTVControlsMapper::GetClassDerivations(), "L4VTVControlsMapper"); return &classDerivations; } //############################################################################# // Messaging Support // const Receiver::HandlerEntry L4VTVControlsMapper::MessageHandlerEntries[]= { MESSAGE_ENTRY(L4VTVControlsMapper, Keypress) }; Receiver::MessageHandlerSet& L4VTVControlsMapper::GetMessageHandlers() { static Receiver::MessageHandlerSet messageHandlers(ELEMENTS(L4VTVControlsMapper::MessageHandlerEntries), L4VTVControlsMapper::MessageHandlerEntries, VTVControlsMapper::GetMessageHandlers()); return messageHandlers; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void L4VTVControlsMapper::KeypressMessageHandler( ReceiverDataMessageOf *message ) { Check(this); Check(message); switch (message->dataContents) { case PCK_F11: { Check(application); GaugeRenderer *renderer = application->GetGaugeRenderer(); if (renderer != NULL) { Check(renderer); renderer->ProfileReport(); } } break; } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void L4VTVControlsMapper::SetControlsMode(int new_mode) { Check(this); //------------------------------------------- // Get mode manager //------------------------------------------- Check(application); RPL4ModeManager *mode_manager = Cast_Object( RPL4ModeManager*, application->GetModeManager() ); Check(mode_manager); int previous_mode = controlMode; //------------------------------------------- // Change modes //------------------------------------------- switch (new_mode) { case BasicMode: //-------------------------------------- // If we aren't already in basic mode, // switch us there //-------------------------------------- if (controlMode != BasicMode) { controlMode = BasicMode; mode_manager->AddModeMask(RPL4ModeManager::ModeBasic); mode_manager->RemoveModeMask(RPL4ModeManager::ModeStandard); //---------------------------------------- // Ensure configuring is turned off //---------------------------------------- if (GetSimulationState() == ConfigurationState) { mode_manager->AddModeMask(RPL4ModeManager::ModeNonConfig); mode_manager->RemoveModeMask(RPL4ModeManager::ModeConfiguring); SetSimulationState(DefaultState); } } break; case StandardMode: //--------------------------------------- // If we aren't already in standard mode, // switch us there //--------------------------------------- if (controlMode != StandardMode) { controlMode = StandardMode; mode_manager->AddModeMask(RPL4ModeManager::ModeStandard); mode_manager->RemoveModeMask(RPL4ModeManager::ModeBasic); } break; case VeteranMode: //--------------------------------------- // If we aren't already in veteran mode, // switch us there //--------------------------------------- if (controlMode != VeteranMode) { controlMode = VeteranMode; mode_manager->AddModeMask(RPL4ModeManager::ModeStandard); mode_manager->RemoveModeMask(RPL4ModeManager::ModeBasic); } break; case MasterMode: //--------------------------------------- // If we aren't already in master mode, // switch us there //--------------------------------------- if (controlMode != MasterMode) { controlMode = MasterMode; mode_manager->AddModeMask(RPL4ModeManager::ModeStandard); mode_manager->RemoveModeMask(RPL4ModeManager::ModeBasic); } break; default: Tell( "L4VTVControlsMapper::SetControlsMode(" << new_mode << ")\n" ); Fail("out of range"); break; } //---------------------------------------- // Notify of mode change //---------------------------------------- if (previous_mode != controlMode) { L4VTVControlsMapper::NotifyOfControlModeChange(controlMode); } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void L4VTVControlsMapper::SetConfigurationMode(Logical new_state) { Check(this); //------------------------------------------- // Call ancestral method //------------------------------------------- VTVControlsMapper::SetConfigurationState(new_state); //------------------------------------------- // Get mode manager //------------------------------------------- Check(application); RPL4ModeManager *mode_manager = Cast_Object( RPL4ModeManager*, application->GetModeManager() ); Check(mode_manager); //------------------------------------------- // Modify mode //------------------------------------------- if (GetSimulationState() == ConfigurationState) { mode_manager->RemoveModeMask(RPL4ModeManager::ModeAllNonConfig); // Note: this removes ALL presets as well mode_manager->AddModeMask(RPL4ModeManager::ModeConfigReady); } else { mode_manager->RemoveModeMask(RPL4ModeManager::ModeConfigReady); mode_manager->AddModeMask(RPL4ModeManager::ModeNonConfig); mode_manager->AddModeMask(previousPresetModeMask); } Check_Fpu(); } //############################################################################# // Platform-specific updates // void L4VTVControlsMapper::NotifyOfControlModeChange(int new_mode) { Check(this); // The gauges are controlled directly by modes, so we do nothing here. //----------------------------------- // Invoke ancestral method //----------------------------------- VTVControlsMapper::NotifyOfControlModeChange(new_mode); Check_Fpu(); } void L4VTVControlsMapper::NotifyOfConfigurationModeChange(Logical new_state) { Check(this); // The gauges are controlled directly by modes, so we do nothing here. //----------------------------------- // Invoke ancestral method //----------------------------------- VTVControlsMapper::NotifyOfConfigurationModeChange(new_state); Check_Fpu(); } //############################################################################# // Construction and Destruction Support // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // L4VTVControlsMapper::L4VTVControlsMapper( VTV *player_vehicle, int subsystem_ID, SubsystemResource *subsystem_resource, SharedData &shared_data ): VTVControlsMapper( player_vehicle, subsystem_ID, subsystem_resource, shared_data ) { Check(application); RPL4ModeManager *mode_manager = Cast_Object( RPL4ModeManager*, application->GetModeManager() ); Check(mode_manager); //------------------------------------------ // Initialize presets //------------------------------------------ previousPresetModeMask = RPL4ModeManager::ModePreset1; previousPresetNumber = 0; mode_manager->AddModeMask(previousPresetModeMask); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // L4VTVControlsMapper::~L4VTVControlsMapper() { Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical L4VTVControlsMapper::TestInstance() const { return IsDerivedFrom(*GetClassDerivations()); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void L4VTVControlsMapper::CreateTemporaryEventMappings( Receiver *receiver, Receiver::MessageID config_message_id ) { Check(this); Check(receiver); Check(application); LBE4ControlsManager *controls_mgr = Cast_Object( LBE4ControlsManager *, application->GetControlsManager() ); Check(controls_mgr); //------------------------------------------------ // Create temporary mappings for configuration //------------------------------------------------ for( int i=LBE4ControlsManager::FirstMappableButton; i<=LBE4ControlsManager::LastMappableButton; ++i ) { //--------------------------------- // Skip past hat switches //--------------------------------- if (i == LBE4ControlsManager::ButtonJoystickHatDown) { i = LBE4ControlsManager::ButtonJoystickPinky; } controls_mgr->buttonGroup[i].Add( RPL4ModeManager::ModeConfigReady, receiver, config_message_id, receiver ); } Check_Fpu(); } void L4VTVControlsMapper::RemoveTemporaryEventMappings() { Check(this); Check(application); LBE4ControlsManager *controls_mgr = Cast_Object( LBE4ControlsManager *, application->GetControlsManager() ); Check(controls_mgr); //------------------------------------------------ // Remove temporary mappings //------------------------------------------------ for( int i=LBE4ControlsManager::FirstMappableButton; i<=LBE4ControlsManager::LastMappableButton; ++i ) { //--------------------------------- // Skip past hat switches //--------------------------------- if (i == LBE4ControlsManager::ButtonJoystickHatDown) { i = LBE4ControlsManager::ButtonJoystickPinky; } controls_mgr->buttonGroup[i].Remove(RPL4ModeManager::ModeConfigReady); } Check_Fpu(); } void L4VTVControlsMapper::AddOrErase( unsigned int /*button_ID*/, Receiver */*target*/, Receiver::MessageID /*message_ID*/ ) { Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void L4VTVControlsMapper::AddOrErase( unsigned int /*button_ID*/, ControlsButton */*destination*/ ) { Check_Fpu(); } void L4VTVControlsMapper::PresetEnable(int preset_number) { Check(this); static ModeMask mode_table[presetCount] = { RPL4ModeManager::ModePreset1, RPL4ModeManager::ModePreset2, RPL4ModeManager::ModePreset3, RPL4ModeManager::ModePreset4, RPL4ModeManager::ModePreset5, RPL4ModeManager::ModePreset6 }; mustMatch = preset_number; // HACK - for backward watcher compatibility if (preset_number != previousPresetNumber) { Check(application); RPL4ModeManager *mode_manager = Cast_Object( RPL4ModeManager*, application->GetModeManager() ); Check(mode_manager); //----------------------------------- // Disable the old presets //----------------------------------- mode_manager->RemoveModeMask(previousPresetModeMask); //----------------------------------- // Enable the new presets //----------------------------------- if (preset_number >= 0) { Verify(preset_number < presetCount); previousPresetModeMask = mode_table[preset_number]; mode_manager->AddModeMask(previousPresetModeMask); } //----------------------------------- // Save the new preset number //----------------------------------- previousPresetNumber = preset_number; } Check_Fpu(); } //############################################################################# //########################### ThrustmasterMapper ############################## //############################################################################# //############################################################################# // Shared Data Support // VTVThrustmasterMapper::SharedData VTVThrustmasterMapper::DefaultData( VTVThrustmasterMapper::GetClassDerivations(), VTVThrustmasterMapper::MessageHandlers, VTVThrustmasterMapper::GetAttributeIndex(), VTVThrustmasterMapper::StateCount ); Derivation* VTVThrustmasterMapper::GetClassDerivations() { static Derivation classDerivations(L4VTVControlsMapper::GetClassDerivations(), "VTVThrustmasterMapper"); return &classDerivations; } //############################################################################# // Messaging Support // const Receiver::HandlerEntry VTVThrustmasterMapper::MessageHandlerEntries[]= { MESSAGE_ENTRY(VTVThrustmasterMapper, Keypress) }; Receiver::MessageHandlerSet VTVThrustmasterMapper::MessageHandlers( ELEMENTS(VTVThrustmasterMapper::MessageHandlerEntries), VTVThrustmasterMapper::MessageHandlerEntries, L4VTVControlsMapper::GetMessageHandlers() ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVThrustmasterMapper::KeypressMessageHandler( ReceiverDataMessageOf *message ) { Check(this); Check(message); LBE4ControlsManager *controls = Cast_Object(LBE4ControlsManager*,application->GetControlsManager()); Check(controls); switch (message->dataContents) { //------------------------------------------------------- // Joystick //------------------------------------------------------- case PCK_F1: Tell("Aligning Joystick...\n"); controls->BeginAlignJoystick(); GetEntity()->SetSimulationState(VTV::StasisState); break; case PCK_F2: Tell("Joystick Aligned...\n"); controls->EndAlignJoystick(); GetEntity()->SetSimulationState(VTV::DefaultState); break; case PCK_F12: //------------------------------------------------------- // Exit //------------------------------------------------------- Check(application); if ( application->GetApplicationState() != Application::EndingMission && application->GetApplicationState() != Application::StoppingMission ) { DEBUG_STREAM << "Keystroke invoking mission stop...\n" << std::flush; Exit_Code = 1; Application::StopMissionMessage message(Exit_Code); application->Dispatch(&message); } break; //------------------------------------------------------- // Control eyepoint views //------------------------------------------------------- case PCK_UP: // look forward lookLeft = -1; lookRight = -1; lookBehind = -1; lookUp = -1; break; case PCK_LEFT: // look left lookLeft = 1; lookRight = -1; lookBehind = -1; lookUp = -1; break; case PCK_RIGHT: // look right lookLeft = -1; lookRight = 1; lookBehind = -1; lookUp = -1; break; case PCK_DOWN: // look behind lookLeft = -1; lookRight = -1; lookBehind = 1; lookUp = -1; break; case PCK_CTL_UP: // look up lookLeft = -1; lookRight = -1; lookBehind = -1; lookUp = 1; break; //------------------------------------------------------- // Set driving modes //------------------------------------------------------- case 'b': case 'B': SetControlsMode(BasicMode); break; case 's': case 'S': SetControlsMode(StandardMode); break; case 'v': case 'V': SetControlsMode(VeteranMode); break; case 'm': case 'M': SetControlsMode(MasterMode); break; //------------------------------------------------------- // Configuration stuff //------------------------------------------------------- case 'c': case 'C': //------------------------------ // Not allowed in 'basic' mode //------------------------------ if (controlMode != BasicMode) { static Logical config_state = False; //---------------------------- // Invert configuration state //---------------------------- config_state ^= True; //---------------------------- // Send message to base class //---------------------------- SetConfigurationMode(config_state); } break; //------------------------------------------------------- // Map scale stuff //------------------------------------------------------- case '<': case ',': { ReceiverDataMessageOf config_msg( VTV::ZoomInMessageID, sizeof(ReceiverDataMessageOf), 1 ); GetEntity()->Dispatch(&config_msg); break; } case '>': case '.': { ReceiverDataMessageOf config_msg( VTV::ZoomOutMessageID, sizeof(ReceiverDataMessageOf), 1 ); GetEntity()->Dispatch(&config_msg); break; } case 'h': case 'H': //------------------------------------------------------- // Horn blast //------------------------------------------------------- { static ControlsButton horn_state=1; ReceiverDataMessageOf config_msg( ActivateHornMessageID, sizeof(ReceiverDataMessageOf), horn_state ); Dispatch(&config_msg); horn_state = -horn_state; break; } case 'z': case 'Z': //--------------------------------------------------------- // Chute //--------------------------------------------------------- { ReceiverDataMessageOf config_msg( Chute::ActivateMessageID, sizeof(ReceiverDataMessageOf), 1 ); for (int i=0; i < GetEntity()->GetSubsystemCount(); i++) { Subsystem *sub = GetEntity()->GetSubsystem(i); if (sub && sub->GetClassID() == VTV::ChuteClassID) { sub->Dispatch(&config_msg); break; } } break; } case 'w': case 'W': //--------------------------------------------------------- // Booster //--------------------------------------------------------- { ReceiverDataMessageOf config_msg( Booster::ActivateMessageID, sizeof(ReceiverDataMessageOf), 1 ); for (int i=0; i < GetEntity()->GetSubsystemCount(); i++) { Subsystem *sub = GetEntity()->GetSubsystem(i); if (sub && sub->GetClassID() == VTV::BoosterClassID) { sub->Dispatch(&config_msg); break; } } break; } case 'd': case 'D': //--------------------------------------------------------- // Demopack //--------------------------------------------------------- { /*for (int i=0; i < GetEntity()->GetSubsystemCount(); i++) { Subsystem *sub = GetEntity()->GetSubsystem(i); if (sub && sub->GetClassID() == VTV::DemolitionPackDropperClassID) { ((DemolitionPackDropper*)sub)->Fire(); break; } }*/ } case 'r': case 'R': //------------------------------------------------------- // Toggle reticle //------------------------------------------------------- { ReceiverDataMessageOf config_msg( ToggleReticleMessageID, sizeof(ReceiverDataMessageOf), 1 ); Dispatch(&config_msg); break; } //------------------------------------------------------- // Trigger presets //------------------------------------------------------- case '1': case '2': case '3': case '4': case '5': case '6': PresetEnable(message->dataContents - '1'); break; //------------------------------------------------------- // Suspend/resume //------------------------------------------------------- case '[': { Check(application); Enumeration state = application->GetApplicationState(); if ( state != Application::EndingMission && state != Application::StoppingMission && state != Application::SuspendingMission ) { DEBUG_STREAM << "Keystroke invoking mission suspend...\n" << std::flush; Application::SuspendMissionMessage message; application->Dispatch(&message); } } break; case ']': Check(application); if ( application->GetApplicationState() == Application::SuspendingMission ) { DEBUG_STREAM << "Keystroke invoking mission resume...\n" << std::flush; Application::ResumeMissionMessage message; application->Dispatch(&message); } break; default: L4VTVControlsMapper::KeypressMessageHandler(message); break; } Check_Fpu(); } //############################################################################# // Model Support // void VTVThrustmasterMapper::InterpretControls(Scalar time_slice) { // //---------------------------------------- // Use the hat buttons to set the throttle //---------------------------------------- // LBE4ControlsManager *controls = Cast_Object( LBE4ControlsManager*, application->GetControlsManager() ); Check(controls); throttlePosition = controls->scalarGroup[LBE4ControlsManager::ScalarThrottle].previousValue; /*if (throttleUp > 0) { throttlePosition = 1.0f; reverseThrust = 0; } else if (throttleDown > 0) { throttlePosition = 1.0f; reverseThrust = 1; } else { throttlePosition = 0.0f; reverseThrust = 0; }*/ // //---------------------------------------- // Sum the pedal inputs //---------------------------------------- // pedalsPosition = leftPedal - rightPedal; VTVControlsMapper::InterpretControls(time_slice); Check_Fpu(); } //############################################################################# // Construction and Destruction Support // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VTVThrustmasterMapper::VTVThrustmasterMapper( VTV *player_vehicle, int subsystem_ID, SubsystemResource *subsystem_resource ): L4VTVControlsMapper( player_vehicle, subsystem_ID, subsystem_resource, DefaultData ) { SetPerformance(&VTVThrustmasterMapper::InterpretControls); leftPedal = 0.0f; rightPedal = 0.0f; LBE4ControlsManager *controls = Cast_Object(LBE4ControlsManager*,application->GetControlsManager()); Check(controls); controls ->joystickGroup[LBE4ControlsManager::JoystickPhysical] .Add(RPL4ModeManager::ModeAlwaysActive, &stickPosition, this); // //-------------- // Pedal mapping //-------------- // controls ->scalarGroup[LBE4ControlsManager::ScalarLeftPedal] .Add(RPL4ModeManager::ModeAlwaysActive, &leftPedal, this); controls ->scalarGroup[LBE4ControlsManager::ScalarRightPedal] .Add(RPL4ModeManager::ModeAlwaysActive, &rightPedal, this); controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatRight] .Add(RPL4ModeManager::ModeAlwaysActive, &lookRight, this); controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatLeft] .Add(RPL4ModeManager::ModeAlwaysActive, &lookLeft, this); controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatUp] .Add(RPL4ModeManager::ModeAlwaysActive, &lookUp, this); controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatDown] .Add(RPL4ModeManager::ModeAlwaysActive, &lookBehind, this); controls ->buttonGroup[LBE4ControlsManager::ButtonThrottle1] .Add(RPL4ModeManager::ModeAlwaysActive, &reverseThrust, this); controls ->keyboardGroup[LBE4ControlsManager::KeyboardPC] .Add(RPL4ModeManager::ModeAlwaysActive, this, KeypressMessageID, this); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VTVThrustmasterMapper::~VTVThrustmasterMapper() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical VTVThrustmasterMapper::TestInstance() const { return IsDerivedFrom(*GetClassDerivations()); } //############################################################################# //################################ RIOMapper ################################## //############################################################################# //############################################################################# // Shared Data Support // VTVRIOMapper::SharedData VTVRIOMapper::DefaultData( VTVRIOMapper::GetClassDerivations(), VTVRIOMapper::MessageHandlers, VTVRIOMapper::GetAttributeIndex(), VTVRIOMapper::StateCount ); Derivation* VTVRIOMapper::GetClassDerivations() { static Derivation classDerivations(L4VTVControlsMapper::GetClassDerivations(), "VTVRIOMapper"); return &classDerivations; } //############################################################################# // Messaging Support // const Receiver::HandlerEntry VTVRIOMapper::MessageHandlerEntries[]= { MESSAGE_ENTRY(VTVRIOMapper, Keypress), MESSAGE_ENTRY(VTVRIOMapper, SwitchMode), MESSAGE_ENTRY(VTVRIOMapper, SelectPreset), MESSAGE_ENTRY(VTVRIOMapper, CenterJoystick), MESSAGE_ENTRY(VTVRIOMapper, ConfigureControls) }; Receiver::MessageHandlerSet VTVRIOMapper::MessageHandlers( ELEMENTS(VTVRIOMapper::MessageHandlerEntries), VTVRIOMapper::MessageHandlerEntries, L4VTVControlsMapper::GetMessageHandlers() ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVRIOMapper::KeypressMessageHandler( ReceiverDataMessageOf *message ) { Check(this); Check(message); switch (message->dataContents) { case PCK_F1: { Check(application); LBE4ControlsManager *controls = Cast_Object( LBE4ControlsManager*, application->GetControlsManager() ); Check(controls); Tell("Centered RIO Joystick\n"); controls->CenterRIOJoystick(); } break; case PCK_F12: Check(application); if ( application->GetApplicationState() != Application::EndingMission && application->GetApplicationState() != Application::StoppingMission ) { DEBUG_STREAM << "Keystroke invoking mission stop...\n" << std::flush; Exit_Code = 1; Application::StopMissionMessage message(Exit_Code); application->Dispatch(&message); } break; case 'W': case 'w': { ReceiverDataMessageOf config_msg( Booster::ActivateMessageID, sizeof(ReceiverDataMessageOf), 1 ); for (int i=0; i < GetEntity()->GetSubsystemCount(); i++) { Subsystem *sub = GetEntity()->GetSubsystem(i); if (sub && sub->GetClassID() == VTV::BoosterClassID) { sub->Dispatch(&config_msg); break; } } break; } break; //------------------------------------------------------- // Control eyepoint views //------------------------------------------------------- case PCK_UP: // look forward lookLeft = -1; lookRight = -1; lookBehind = -1; lookUp = -1; break; case PCK_LEFT: // look left lookLeft = 1; lookRight = -1; lookBehind = -1; lookUp = -1; break; case PCK_RIGHT: // look right lookLeft = -1; lookRight = 1; lookBehind = -1; lookUp = -1; break; case PCK_DOWN: // look behind lookLeft = -1; lookRight = -1; lookBehind = 1; lookUp = -1; break; case PCK_CTL_UP: // look up lookLeft = -1; lookRight = -1; lookBehind = -1; lookUp = 1; break; default: L4VTVControlsMapper::KeypressMessageHandler(message); break; } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVRIOMapper::SwitchModeMessageHandler( ReceiverDataMessageOf *message ) { Check(this); //------------------------------------------- // Switch on 'press' only (ignore release) //------------------------------------------- if (message->dataContents > 0) { //---------------------------------- // Pick the selected mode //---------------------------------- switch (message->dataContents - 1) { case LBE4ControlsManager::ButtonAuxUpperRight5: SetControlsMode(BasicMode); break; case LBE4ControlsManager::ButtonAuxUpperRight6: SetControlsMode(StandardMode); break; case LBE4ControlsManager::ButtonAuxUpperRight7: SetControlsMode(VeteranMode); break; case LBE4ControlsManager::ButtonAuxUpperRight8: SetControlsMode(MasterMode); break; } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVRIOMapper::SelectPresetMessageHandler( ReceiverDataMessageOf *message ) { Check(this); //------------------------------------------- // Switch on 'press' only (ignore release) //------------------------------------------- if (message->dataContents > 0) { //----------------------------------- // Choose a new preset //----------------------------------- int current_preset_number = (message->dataContents - 1) - LBE4ControlsManager::ButtonSecondary7; if (previousPresetNumber != current_preset_number) { //----------------------------------- // Set the old preset lamp to 'dim' //----------------------------------- if (previousPresetNumber >= 0) { Verify(previousPresetNumber < presetCount); if (modeLamp[previousPresetNumber] != NULL) { Check(modeLamp[previousPresetNumber]); modeLamp[previousPresetNumber]->SetState(L4Lamp::LampStateDim); } } //----------------------------------- // Set the new preset lamp to 'on' //----------------------------------- if (current_preset_number >= 0) { Verify(current_preset_number < presetCount); if (modeLamp[current_preset_number] != NULL) { Check(modeLamp[current_preset_number]); modeLamp[current_preset_number]->SetState(L4Lamp::LampStateOn); } } //----------------------------------- // Change presets //----------------------------------- PresetEnable(current_preset_number); } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVRIOMapper::CenterJoystickMessageHandler( ReceiverDataMessageOf *message ) { Check(this); if (message->dataContents > 0) { Check(application); LBE4ControlsManager *controls = (LBE4ControlsManager *) application->GetControlsManager(); Check(controls); controls->CenterRIOJoystick(); } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVRIOMapper::ConfigureControlsMessageHandler( ReceiverDataMessageOf *message ) { Check(this); //------------------------------------------------------------- // Allow the VTVControlsMapper to process the message //------------------------------------------------------------- // OBSOLETE // VTVControlsMapper::ConfigureControlsMessageHandler(message); //------------------------------------------- // Switch on 'press' only (ignore release) //------------------------------------------- if (message->dataContents > 0) { //------------------------------------------- // Modify mode //------------------------------------------- if (GetSimulationState() == ConfigurationState) { SetConfigurationMode(False); } else { SetConfigurationMode(True); } } Check_Fpu(); } //############################################################################# // Model Support // void VTVRIOMapper::InterpretControls(Scalar time_slice) { // //---------------------------------------- // Reverse if throttle button held in //---------------------------------------- // if (throttleReverse > 0) { reverseThrust = 1; throttleReverse = 0; } else if (throttleReverse < 0) { reverseThrust = 0; throttleReverse = 0; } // //---------------------------------------- // Sum the pedal inputs //---------------------------------------- // pedalsPosition = leftPedal - rightPedal; VTVControlsMapper::InterpretControls(time_slice); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVRIOMapper::AddOrErase( unsigned int button_ID, Receiver *target, Receiver::MessageID message_ID ) { Check(this); Check(target); Check(application); LBE4ControlsManager *controls = Cast_Object(LBE4ControlsManager*,application->GetControlsManager()); Check(controls); controls->buttonGroup[button_ID-1] .AddOrErase(previousPresetModeMask, target, message_ID, this); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VTVRIOMapper::AddOrErase( unsigned int button_ID, ControlsButton *destination ) { Check(this); Check_Pointer(destination); Check(application); LBE4ControlsManager *controls = Cast_Object(LBE4ControlsManager*,application->GetControlsManager()); Check(controls); controls->buttonGroup[button_ID-1] .AddOrErase(previousPresetModeMask, destination, this); Check_Fpu(); } //############################################################################# // Platform-specific updates // void VTVRIOMapper::NotifyOfControlModeChange(int new_mode) { Check(this); int lamp_number; //---------------------------------- // Set the old mode button to 'dim' //---------------------------------- switch (previousControlMode) { case BasicMode: lamp_number = 0; break; case StandardMode: lamp_number = 1; break; case VeteranMode: lamp_number = 2; break; case MasterMode: lamp_number = 3; break; default: lamp_number = -1; break; } if (lamp_number >= 0) { Verify(lamp_number < modeLampCount); if (modeLamp[lamp_number] != NULL) { Check(modeLamp[lamp_number]); modeLamp[lamp_number]->SetState(L4Lamp::LampStateDim); } } //---------------------------------- // Pick the selected mode //---------------------------------- switch (controlMode) { case BasicMode: lamp_number = 0; break; case StandardMode: lamp_number = 1; break; case VeteranMode: lamp_number = 2; break; case MasterMode: lamp_number = 3; break; default: lamp_number = -1; break; } if (lamp_number >= 0) { Verify(lamp_number < modeLampCount); if (modeLamp[lamp_number] != NULL) { Check(modeLamp[lamp_number]); modeLamp[lamp_number]->SetState(L4Lamp::LampStateOn); } } //----------------------------------- // Invoke ancestral method //----------------------------------- L4VTVControlsMapper::NotifyOfControlModeChange(new_mode); Check_Fpu(); } void VTVRIOMapper::NotifyOfConfigurationModeChange(Logical new_state) { Check(this); for(int i=0; iSetAlertState(new_state); } } //----------------------------------- // Invoke ancestral method //----------------------------------- L4VTVControlsMapper::NotifyOfConfigurationModeChange(new_state); Check_Fpu(); } //############################################################################# // Construction and Destruction Support // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VTVRIOMapper::VTVRIOMapper( VTV *player_vehicle, int subsystem_ID, SubsystemResource *subsystem_resource ): L4VTVControlsMapper( player_vehicle, subsystem_ID, subsystem_resource, DefaultData ) { SetPerformance(&VTVRIOMapper::InterpretControls); throttleUp = 0; throttleDown = 0; throttleReverse = 0; leftPedal = 0.0f; rightPedal = 0.0f; Check(application); LBE4ControlsManager *controls = Cast_Object( LBE4ControlsManager*, application->GetControlsManager() ); Check(controls); VTV *vtv = GetEntity(); Check(vtv); // //------------------ // Throttle mappings //------------------ // controls ->scalarGroup[LBE4ControlsManager::ScalarThrottle] .Add(RPL4ModeManager::ModeAlwaysActive, &throttlePosition, this); controls ->buttonGroup[LBE4ControlsManager::ButtonThrottle1] .Add(RPL4ModeManager::ModeAlwaysActive, &reverseThrust, this); // //------------------ // Joystick mappings //------------------ // controls ->joystickGroup[LBE4ControlsManager::JoystickPhysical] .Add(RPL4ModeManager::ModeAlwaysActive, &stickPosition, this); // //------------------ // Eyepoint mappings //------------------ // controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatLeft] .Add(RPL4ModeManager::ModeAlwaysActive, &lookLeft, this); controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatRight] .Add(RPL4ModeManager::ModeAlwaysActive, &lookRight, this); controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatUp] .Add(RPL4ModeManager::ModeAlwaysActive, &lookUp, this); controls ->buttonGroup[LBE4ControlsManager::ButtonJoystickHatDown] .Add(RPL4ModeManager::ModeAlwaysActive, &lookBehind, this); // //-------------- // Pedal mapping //-------------- // controls ->scalarGroup[LBE4ControlsManager::ScalarLeftPedal] .Add(RPL4ModeManager::ModeAlwaysActive, &leftPedal, this); controls ->scalarGroup[LBE4ControlsManager::ScalarRightPedal] .Add(RPL4ModeManager::ModeAlwaysActive, &rightPedal, this); // //----------------- // Keyboard mapping //----------------- // controls ->keyboardGroup[LBE4ControlsManager::KeyboardPC] .Add(RPL4ModeManager::ModeAlwaysActive, this, KeypressMessageID, this); //---------------------------------------------------------------- // Configuration mapping //---------------------------------------------------------------- // Lamps explicitly controlled by ConfigureControlsMessageHandler configLamp[0] = CreateControlledLamp( LBE4ControlsManager::ButtonAuxUpperRight1, RPL4ModeManager::ModeStandard ); configLamp[1] = CreateControlledLamp( LBE4ControlsManager::ButtonAuxUpperRight2, RPL4ModeManager::ModeStandard ); if (!getenv("NOMODES")) { int i; for(i=0; iSetState(L4Lamp::LampStateDim); } } controls ->buttonGroup[LBE4ControlsManager::ButtonAuxUpperRight1] .Add( RPL4ModeManager::ModeStandard, this, ConfigureControlsMessageID, this ); controls ->buttonGroup[LBE4ControlsManager::ButtonAuxUpperRight2] .Add( RPL4ModeManager::ModeStandard, this, ConfigureControlsMessageID, this ); } //---------------------------------------------------------------- // Joystick centering //---------------------------------------------------------------- MakeButtonLampEventPair( controls, LBE4ControlsManager::ButtonAuxUpperRight3, LBE4ControlsManager::ButtonAuxUpperRight4, this, CenterJoystickMessageID, this ); //---------------------------------------------------------------- // Secondary mappings //---------------------------------------------------------------- MakeButtonLampEvent( controls, LBE4ControlsManager::ButtonSecondary1, vtv, VTV::ZoomInMessageID, this ); MakeButtonLampEvent( controls, LBE4ControlsManager::ButtonSecondary2, vtv, VTV::ZoomOutMessageID, this ); MakeButtonLampEvent( controls, LBE4ControlsManager::ButtonSecondary3, this, ToggleReticleMessageID, this ); MakeButtonLampEvent( controls, LBE4ControlsManager::ButtonSecondary4, this, ActivateHornMessageID, this ); //---------------------------------------------------------------- // Mode mapping //---------------------------------------------------------------- previousControlMode = -1; if (!getenv("NOMODES")) { int i; static int button_number[modeLampCount] = { LBE4ControlsManager::ButtonAuxUpperRight5, LBE4ControlsManager::ButtonAuxUpperRight6, LBE4ControlsManager::ButtonAuxUpperRight7, LBE4ControlsManager::ButtonAuxUpperRight8 }; for(i=0; ibuttonGroup[button_number[i]].Add( RPL4ModeManager::ModeAlwaysActive, this, SwitchModeMessageID, this ); //---------------------------------------------- // These lamps are explicitly controlled by // VTVRIOMapper::NotifyOfControlModeChange //---------------------------------------------- modeLamp[i] = CreateControlledLamp(button_number[i]); if (modeLamp[i] != NULL) { Check(modeLamp[i]); } } } //---------------------------------------------------------------- // Preset mapping //---------------------------------------------------------------- if (!getenv("NOMODES")) { int i; static int button_number[presetCount] = { LBE4ControlsManager::ButtonSecondary7, LBE4ControlsManager::ButtonSecondary8, LBE4ControlsManager::ButtonSecondary9, LBE4ControlsManager::ButtonSecondary10, LBE4ControlsManager::ButtonSecondary11, LBE4ControlsManager::ButtonSecondary12 }; for(i=0; ibuttonGroup[button_number[i]].Add( RPL4ModeManager::ModeAlwaysActive, this, SelectPresetMessageID, this ); // These lamps are explicitly controlled by SelectPresetMessageHandler modeLamp[i] = CreateControlledLamp(button_number[i]); if (modeLamp[i] != NULL) { Check(modeLamp[i]); modeLamp[i]->SetState( (i==0)? L4Lamp::LampStateOn : L4Lamp::LampStateDim ); } } NotifyOfControlModeChange(BasicMode); } //---------------------------------------------------------------- // liftcut mapping //---------------------------------------------------------------- CreateDirectSystemMappingPair( controls, LBE4ControlsManager::ButtonAuxUpperLeft1, LBE4ControlsManager::ButtonAuxUpperLeft2, &liftCut, this, ConfigureLiftCutMappablesMessageID ); //---------------------------------------------------------------- // sideslip mapping //---------------------------------------------------------------- CreateDirectSystemMappingPair( controls, LBE4ControlsManager::ButtonAuxUpperLeft3, LBE4ControlsManager::ButtonAuxUpperLeft4, &sideSlip, this, ConfigureSideSlipMappablesMessageID ); //---------------------------------------------------------------- // intercom PTT mapping //---------------------------------------------------------------- CreateEventSystemMappingPair( controls, LBE4ControlsManager::ButtonAuxUpperLeft5, LBE4ControlsManager::ButtonAuxUpperLeft6, this, ActivatePTTMessageID, ConfigurePTTMappablesMessageID ); //---------------------------------------------------------------- // horn mapping //---------------------------------------------------------------- CreateEventSystemMappingPair( controls, LBE4ControlsManager::ButtonAuxUpperLeft7, LBE4ControlsManager::ButtonAuxUpperLeft8, this, ActivateHornMessageID, ConfigureHornMappablesMessageID ); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VTVRIOMapper::~VTVRIOMapper() { Check(this); // HACK - gaugeRenderer::ShutdownImplementation() removes all lamps. // When this destructor gets called, the lamps have (usually) already // been deleted. The fix is to have all lamp operations go through // the lamp manager, referring to the lamp by ID and modeMask...then, // when a request is made for a nonexistent lamp, the request is ignored. #if 0 int i; //----------------------------------------------- // First check to see if the lamp manager exists. // If it doesn't, then the lamps have either // not been created or else have already // been deleted. //----------------------------------------------- Check(application); if (application->GetGaugeRenderer() != NULL) { Check(application->GetGaugeRenderer()); if (application->GetGaugeRenderer()->GetLampManager() != NULL) { Check(application->GetGaugeRenderer()->GetLampManager()); //-------------------------------------------- // Delete controlled lamp objects //-------------------------------------------- for(i=0; i