Selecting NOV, STD, VET or EXP on the Upper Right MFD lit nothing and dimmed nothing. Two separate faults had to line up for that. SetControlsMode announced the change as L4VTVControlsMapper::NotifyOfControlModeChange - explicitly qualified, which suppresses the virtual call and lands on the base class no-op. The code that drives the four lamps is VTVRIOMapper's override, so a mode change never reached it. Its neighbour has always gone out unqualified from VTVControlsMapper::SetConfigurationState, which is why the configuration lamps behaved and these did not. previousControlMode is the lamp the next change dims, and nothing wrote it after construction set it to -1. Even once the call arrived, the dim step would have matched nothing and the panel would have accumulated lamps rather than following the selection. The one call that did dispatch is the one in VTVRIOMapper's own constructor, where the vtable is already the derived one - which is why NOV lit at the start and then nothing ever moved. B / S / V / M are gone from the Thrustmaster mapper's key handler. The driving mode is a panel decision, four buttons carrying the lamps that say which one you are in, and a bare letter key changing it behind the player's back is not that. It reads worse in 4.12 than it ever did in the pod: the whole letter board is the MFD banks now, so on that path those four letters would have fired their bank button and silently changed the driving mode as well. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2119 lines
50 KiB
C++
2119 lines
50 KiB
C++
#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<ControlsKey> *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
|
|
//----------------------------------------
|
|
//
|
|
// Unqualified, so the platform's override is the one that runs. The
|
|
// RIO carries the four mode lamps on the Upper Right MFD and lights
|
|
// them from here (VTVRIOMapper::NotifyOfControlModeChange); naming
|
|
// the class suppressed the virtual call and landed on the base's
|
|
// no-op instead, so the lamps never followed the mode the pilot had
|
|
// just selected. Its neighbour has always gone out this way - see
|
|
// VTVControlsMapper::SetConfigurationState.
|
|
//
|
|
if (previous_mode != controlMode)
|
|
{
|
|
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);
|
|
}
|
|
//-----------------------------------
|
|
// Move the lamps with the mappings.
|
|
// Doing it here rather than in the
|
|
// switch handler keeps the keyboard
|
|
// presets (1-6) in step as well.
|
|
//-----------------------------------
|
|
NotifyOfPresetChange(previousPresetNumber, preset_number);
|
|
//-----------------------------------
|
|
// Save the new preset number
|
|
//-----------------------------------
|
|
previousPresetNumber = preset_number;
|
|
}
|
|
|
|
Check_Fpu();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
L4VTVControlsMapper::NotifyOfPresetChange(
|
|
int /*old_preset*/,
|
|
int /*new_preset*/
|
|
)
|
|
{
|
|
Check(this);
|
|
// The base mapper has no preset lamps to move.
|
|
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<ControlsKey> *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
|
|
//-------------------------------------------------------
|
|
//
|
|
// B / S / V / M used to drop straight into Basic, Standard,
|
|
// Veteran and Master here. The driving mode is a panel
|
|
// decision - the four buttons on the Upper Right MFD, with the
|
|
// lamps that say which one you are in - and a bare letter key
|
|
// changing it behind the player's back is not that. Worse in
|
|
// 4.12 than it ever was in the pod: the whole letter board is
|
|
// the MFD banks now, so those four letters are buttons in their
|
|
// own right and would have fired twice.
|
|
//
|
|
// Nothing replaces them. Press the mode you want.
|
|
//
|
|
//-------------------------------------------------------
|
|
// 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<ControlsButton>
|
|
config_msg(
|
|
VTV::ZoomInMessageID,
|
|
sizeof(ReceiverDataMessageOf<ControlsButton>),
|
|
1
|
|
);
|
|
GetEntity()->Dispatch(&config_msg);
|
|
break;
|
|
}
|
|
|
|
case '>':
|
|
case '.':
|
|
{
|
|
ReceiverDataMessageOf<ControlsButton>
|
|
config_msg(
|
|
VTV::ZoomOutMessageID,
|
|
sizeof(ReceiverDataMessageOf<ControlsButton>),
|
|
1
|
|
);
|
|
GetEntity()->Dispatch(&config_msg);
|
|
break;
|
|
}
|
|
|
|
case 'h':
|
|
case 'H':
|
|
//-------------------------------------------------------
|
|
// Horn blast
|
|
//-------------------------------------------------------
|
|
{
|
|
static ControlsButton horn_state=1;
|
|
ReceiverDataMessageOf<ControlsButton>
|
|
config_msg(
|
|
ActivateHornMessageID,
|
|
sizeof(ReceiverDataMessageOf<ControlsButton>),
|
|
horn_state
|
|
);
|
|
Dispatch(&config_msg);
|
|
horn_state = -horn_state;
|
|
break;
|
|
}
|
|
|
|
case 'z':
|
|
case 'Z':
|
|
//---------------------------------------------------------
|
|
// Chute
|
|
//---------------------------------------------------------
|
|
{
|
|
ReceiverDataMessageOf<ControlsButton>
|
|
config_msg(
|
|
Chute::ActivateMessageID,
|
|
sizeof(ReceiverDataMessageOf<ControlsButton>),
|
|
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<ControlsButton>
|
|
config_msg(
|
|
Booster::ActivateMessageID,
|
|
sizeof(ReceiverDataMessageOf<ControlsButton>),
|
|
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<ControlsButton>
|
|
config_msg(
|
|
ToggleReticleMessageID,
|
|
sizeof(ReceiverDataMessageOf<ControlsButton>),
|
|
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<ControlsKey> *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<ControlsButton>
|
|
config_msg(
|
|
Booster::ActivateMessageID,
|
|
sizeof(ReceiverDataMessageOf<ControlsButton>),
|
|
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<ControlsButton> *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<ControlsButton> *message
|
|
)
|
|
{
|
|
Check(this);
|
|
//-------------------------------------------
|
|
// Switch on 'press' only (ignore release)
|
|
//-------------------------------------------
|
|
if (message->dataContents > 0)
|
|
{
|
|
//-----------------------------------
|
|
// Choose a new preset. PresetEnable
|
|
// ignores a repeat of the lit switch
|
|
// and moves the lamps itself.
|
|
//-----------------------------------
|
|
PresetEnable(
|
|
(message->dataContents - 1) - LBE4ControlsManager::ButtonSecondary7
|
|
);
|
|
}
|
|
Check_Fpu();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
VTVRIOMapper::CenterJoystickMessageHandler(
|
|
ReceiverDataMessageOf<ControlsButton> *message
|
|
)
|
|
{
|
|
Check(this);
|
|
if (message->dataContents > 0)
|
|
{
|
|
Check(application);
|
|
LBE4ControlsManager
|
|
*controls = (LBE4ControlsManager *) application->GetControlsManager();
|
|
Check(controls);
|
|
|
|
controls->CenterRIOJoystick();
|
|
}
|
|
Check_Fpu();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
VTVRIOMapper::ConfigureControlsMessageHandler(
|
|
ReceiverDataMessageOf<ControlsButton> *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);
|
|
}
|
|
}
|
|
|
|
//----------------------------------
|
|
// Remember what is lit
|
|
//----------------------------------
|
|
//
|
|
// previousControlMode is the lamp the NEXT change dims, and nothing
|
|
// used to write it after construction set it to -1. Every mode
|
|
// therefore lit its own lamp against a dim that matched nothing, and
|
|
// the panel accumulated lamps instead of following the selection.
|
|
//
|
|
previousControlMode = controlMode;
|
|
|
|
//-----------------------------------
|
|
// Invoke ancestral method
|
|
//-----------------------------------
|
|
L4VTVControlsMapper::NotifyOfControlModeChange(new_mode);
|
|
|
|
Check_Fpu();
|
|
}
|
|
|
|
void
|
|
VTVRIOMapper::NotifyOfConfigurationModeChange(Logical new_state)
|
|
{
|
|
Check(this);
|
|
|
|
for(int i=0; i<configLampCount; ++i)
|
|
{
|
|
if (configLamp[i] != NULL)
|
|
{
|
|
Check(configLamp[i]);
|
|
configLamp[i]->SetAlertState(new_state);
|
|
}
|
|
}
|
|
//-----------------------------------
|
|
// Invoke ancestral method
|
|
//-----------------------------------
|
|
L4VTVControlsMapper::NotifyOfConfigurationModeChange(new_state);
|
|
|
|
Check_Fpu();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// The six amber switches down the map's right flank. Called by PresetEnable,
|
|
// so the lamps follow the mappings no matter what asked for the change.
|
|
//
|
|
void
|
|
VTVRIOMapper::NotifyOfPresetChange(int old_preset, int new_preset)
|
|
{
|
|
Check(this);
|
|
|
|
//----------------------------------
|
|
// Set the old preset lamp to 'dim'
|
|
//----------------------------------
|
|
if (old_preset >= 0)
|
|
{
|
|
Verify(old_preset < presetCount);
|
|
|
|
if (presetLamp[old_preset] != NULL)
|
|
{
|
|
Check(presetLamp[old_preset]);
|
|
presetLamp[old_preset]->SetState(L4Lamp::LampStateDim);
|
|
}
|
|
}
|
|
//----------------------------------
|
|
// Set the new preset lamp to 'on'
|
|
//----------------------------------
|
|
if (new_preset >= 0)
|
|
{
|
|
Verify(new_preset < presetCount);
|
|
|
|
if (presetLamp[new_preset] != NULL)
|
|
{
|
|
Check(presetLamp[new_preset]);
|
|
presetLamp[new_preset]->SetState(L4Lamp::LampStateOn);
|
|
}
|
|
}
|
|
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;
|
|
|
|
//------------------------------------------------
|
|
// There are no lamps until the mapping blocks
|
|
// below make them - and under NOMODES they never
|
|
// do, so the notify methods must see NULLs.
|
|
//------------------------------------------------
|
|
{
|
|
int
|
|
i;
|
|
|
|
for(i=0; i<configLampCount; ++i) configLamp[i] = NULL;
|
|
for(i=0; i<modeLampCount; ++i) modeLamp[i] = NULL;
|
|
for(i=0; i<presetCount; ++i) presetLamp[i] = NULL;
|
|
}
|
|
|
|
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; i<configLampCount; ++i)
|
|
{
|
|
if (configLamp[i] != NULL)
|
|
{
|
|
Check(configLamp[i]);
|
|
configLamp[i]->SetState(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; i<modeLampCount; ++i)
|
|
{
|
|
controls->buttonGroup[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; i<presetCount; ++i)
|
|
{
|
|
controls->buttonGroup[button_number[i]].Add(
|
|
RPL4ModeManager::ModeAlwaysActive,
|
|
this,
|
|
SelectPresetMessageID,
|
|
this
|
|
);
|
|
|
|
// These lamps are explicitly controlled by NotifyOfPresetChange.
|
|
// They are six, and they are NOT the four mode lamps above.
|
|
presetLamp[i] = CreateControlledLamp(button_number[i]);
|
|
|
|
if (presetLamp[i] != NULL)
|
|
{
|
|
Check(presetLamp[i]);
|
|
presetLamp[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<configLampCount; ++i)
|
|
{
|
|
if (configLamp[i] != NULL)
|
|
{
|
|
Unregister_Object(configLamp[i]);
|
|
delete configLamp[i];
|
|
configLamp[i] = NULL;
|
|
}
|
|
}
|
|
|
|
for(i=0; i<modeLampCount; ++i)
|
|
{
|
|
if (modeLamp[i] != NULL)
|
|
{
|
|
Unregister_Object(modeLamp[i]);
|
|
delete modeLamp[i];
|
|
modeLamp[i] = NULL;
|
|
}
|
|
}
|
|
|
|
for(i=0; i<presetCount; ++i)
|
|
{
|
|
if (presetLamp[i] != NULL)
|
|
{
|
|
Unregister_Object(presetLamp[i]);
|
|
delete presetLamp[i];
|
|
presetLamp[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
Check_Fpu();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Logical
|
|
VTVRIOMapper::TestInstance() const
|
|
{
|
|
return IsDerivedFrom(*GetClassDerivations());
|
|
}
|