Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1939 lines
46 KiB
C++

//==========================================================================//
// File: controls.cc //
// Project: MUNGA Brick: Controls Manager //
// Contents: Interface specification for Controls //
//--------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ----------------------------------------------------------//
// 11/21/94 CPB Initial coding. //
// 01/25/95 CPB Major surgery! Removed Entities, added Subsystems. //
//--------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//==========================================================================//
#include "AdeptHeaders.hpp"
#include "Controls.hpp"
#include "EntityAttribute.hpp"
#include "Joystick.hpp"
#include "Application.hpp"
#include "Interface.hpp"
//############################################################################
//####################### ControlsInstance #############################
//############################################################################
//
// Shared Data Support
//
ControlsInstance::ClassData*
ControlsInstance::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsInstance::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
ControlsInstanceClassID,
"Adept::ControlsInstance",
Plug::DefaultData
);
Register_Object(DefaultData);
gos_EnableSetting (gos_Set_NumLockMode,1);
gos_EnableSetting (gos_Set_ScrollLockMode,0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsInstance::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ControlsInstance::ControlsInstance(
ClassData *class_data,
int control_mask,
Plug *owner
):
Plug(class_data),
dependantPlug(this)
{
Check_Pointer(this);
controlMask = control_mask;
dependantPlug.Add(owner);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ControlsInstance::~ControlsInstance()
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsInstance::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//############################################################################
//######################### DirectControlsInstance ###########################
//############################################################################
DirectControlsInstance::ClassData*
DirectControlsInstance::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
DirectControlsInstance::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
DirectControlsInstanceClassID,
"Adept::DirectControlsInstance",
ControlsInstance::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
DirectControlsInstance::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DirectControlsInstance::DirectControlsInstance(
int control_mask,
Entity *entity_to_control,
Entity::AttributeID attribute_ID,
RegisteredClass::ClassID attribute_type,
Plug *dependant,
bool invert
):
ControlsInstance(DefaultData, control_mask, dependant)
{
entity = entity_to_control;
Check_Object(entity);
attributeEntry = entity->GetAttributeEntry(attribute_ID);
Check_Object(attributeEntry);
Verify(attributeEntry->attributeType == attribute_type);
m_Invert = invert;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DirectControlsInstance::~DirectControlsInstance()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
DirectControlsInstance::Update(void *data_source)
{
Scalar hack;
hack = -*((Scalar *) data_source);
Check_Object(attributeEntry);
if (m_Invert)
attributeEntry->SetValue(entity, &hack);
else
attributeEntry->SetValue(entity, data_source);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
DirectControlsInstance::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//############################################################################
//######################### EventControlsInstance ############################
//############################################################################
//
// Shared Data Support
//
EventControlsInstance::ClassData*
EventControlsInstance::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
EventControlsInstance::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
EventControlsInstanceClassID,
"Adept::EventControlsInstance",
ControlsInstance::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
EventControlsInstance::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EventControlsInstance::EventControlsInstance(
ClassData *class_data,
int control_mask,
Receiver *receiver,
Receiver::MessageID message_id,
Plug *dependant
):
ControlsInstance(class_data, control_mask, dependant)
{
Check_Object(receiver);
receiverPointer = receiver;
messageID = message_id;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EventControlsInstance::~EventControlsInstance()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
EventControlsInstance::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//############################################################################
//######################### ControlsMappingGroup #############################
//############################################################################
//
// Shared Data Support
//
ControlsMappingGroup::ClassData*
ControlsMappingGroup::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsMappingGroup::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
ControlsMappingGroupClassID,
"Adept::ControlsMappingGroup",
Plug::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsMappingGroup::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//
// The ControlsMappingGroup object maintains a group of ControlInstances.
//
// ControlsMappingGroup.Update() will call ControlsInstance.Update()
// for each instance in the group.
//
ControlsMappingGroup::ControlsMappingGroup():
Plug(DefaultData),
instanceList(NULL)
{
Check_Pointer(this);
}
ControlsMappingGroup::~ControlsMappingGroup()
{
Check_Object(this);
Remove(0); // remove all mappings
}
void ControlsMappingGroup::Remove(const Entity::AttributeID& attr_id,const Receiver::MessageID& mesg_id)
{
Check_Object(this);
ChainIteratorOf<ControlsInstance*> i(&instanceList);
ControlsInstance *controls_instance;
while ((controls_instance=i.ReadAndNext()) != NULL)
{
Check_Object(controls_instance);
//---------------------------------------------
// Remove mapping bit(s)
//---------------------------------------------
if ((attr_id != 0) && (controls_instance->IsDerivedFrom (DirectControlsInstance::DefaultData)))
{
DirectControlsInstance *di;
di = Cast_Object (DirectControlsInstance *,controls_instance);
if (di->attributeEntry->attributeID == attr_id)
{
Unregister_Object (controls_instance);
delete controls_instance;
}
}
else if ((mesg_id != 0) && (controls_instance->IsDerivedFrom (EventControlsInstance::DefaultData)))
{
EventControlsInstance *ei;
ei = Cast_Object (EventControlsInstance *,controls_instance);
if (ei->messageID == mesg_id)
{
Unregister_Object (controls_instance);
delete controls_instance;
}
}
}
}
void ControlsMappingGroup::Remove(int control_mask)
{
Check_Object(this);
ChainIteratorOf<ControlsInstance*> i(&instanceList);
ControlsInstance *controls_instance;
while ((controls_instance=i.ReadAndNext()) != NULL)
{
Check_Object(controls_instance);
//---------------------------------------------
// Remove mapping bit(s)
//---------------------------------------------
controls_instance->controlMask &= ~control_mask;
//---------------------------------------------
// If no bits left, delete mapping
//---------------------------------------------
if (controls_instance->controlMask == (int)0)
{
Unregister_Object(controls_instance);
delete controls_instance;
}
}
}
void
ControlsMappingGroup::Update(void *data_source, int control_mask)
{
Check_Object(this);
Check_Pointer(data_source);
ChainIteratorOf<ControlsInstance*>
i(&instanceList);
ControlsInstance
*controls_instance = NULL;
while ((controls_instance=i.ReadAndNext()) != NULL)
{
//------------------------------------------------
// Process only if at least one mode bit matches
//------------------------------------------------
Check_Object(controls_instance);
if (controls_instance->controlMask & control_mask)
{
controls_instance->Update(data_source);
}
}
}
bool
ControlsMappingGroup::CurrentFilterStatus(int control_mask)
{
Check_Object(this);
ChainIteratorOf<ControlsInstance*>
i(&instanceList);
ControlsInstance
*controls_instance;
while ((controls_instance=i.ReadAndNext()) != NULL)
{
Check_Object(controls_instance);
if (controls_instance->controlMask & control_mask)
{
return true;
}
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsMappingGroup::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//############################################################################
//########################### ControlsManager ################################
//############################################################################
//---------------------------------------------------------------------------
// Class derivation
//---------------------------------------------------------------------------
ControlsManager::ClassData*
ControlsManager::DefaultData = NULL;
ControlsManager*
ControlsManager::Instance = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsManager::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
ControlsManagerClassID,
"Adept::ControlsManager",
Receiver::DefaultData,
0, NULL
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsManager::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//
//############################################################################
// ControlsManager
//
// Creator method
//----------------------------------------------------------------------------
// Enter: virtualDataPtr
//############################################################################
//
ControlsManager::ControlsManager():
Receiver(DefaultData),
activeButtons(NULL),
m_ChatInterface (NULL)
{
activeDestination = NULL;
activeReceiver = NULL;
activeMessageID = (Receiver::MessageID) 0;
activeDependant = NULL;
m_ChatMode = false;
m_ListChanged = false;
m_IgnoreCommands = false;
//
//---------------------------
// Get mode mask for updating
//---------------------------
//
m_ClearingChatEnter=false;
m_ClearingChatEscape = false;
controlMask = 0;
int i;
pressAnyKey = false;
//
//-----------------------------------------------------------------
// See if there is a GOS joystick. If so, create and initialize it
//-----------------------------------------------------------------
//
systemJoystick = NULL;
joystickAxisGroup = NULL;
joystickButtonGroup = NULL;
joystickHat = NULL;
/*
if (gosJoystick_CountJoysticks() > 0)
{
gosJoystick_SetPolling(0, true);
systemJoystick = new Joystick(
0, //Joystick ID
0.08f, //XAxis dead zone percent
0.05f, //YAxis dead zone percent
0.05f, //ThrottleAxis dead zone percent
0.15f //RudderAxis dead zone percent
);
Register_Object(systemJoystick);
//
//-------------------------
// Create the axis managers
//-------------------------
//
joystickAxisGroup =
new ControlsUpdateManagerOf<Scalar>[Joystick::AxisCount];
Register_Pointer(joystickAxisGroup);
for (i=0; i<Joystick::AxisCount; ++i)
{
joystickAxisGroup[i].ForceUpdate(
&systemJoystick->axisValues[i],
controlMask
);
}
//
//---------------------------
// Create the button managers
//---------------------------
//
joystickButtonGroup =
new ControlsUpdateManagerOf<int>[
systemJoystick->buttonCount
];
Register_Pointer(joystickButtonGroup);
int initial_button_value = 0;
for (i=0; i<systemJoystick->buttonCount; ++i)
{
joystickButtonGroup[i].ForceUpdate(
&initial_button_value,
controlMask
);
}
//
//---------------------------
// Create the button managers
//---------------------------
//
if (systemJoystick->HasHat())
{
joystickHat = new ControlsUpdateManagerOf<Radian>;
Register_Object(joystickHat);
Radian rad(Two_Pi);
joystickHat->ForceUpdate(&rad, controlMask);
}
}
*/
//
//-----------------------------------
// Check to see if a mouse is present
//-----------------------------------
//
Scalar initial_data(0.0f);
mousePosX.ForceUpdate(&initial_data, controlMask);
mousePosY.ForceUpdate(&initial_data, controlMask);
Scalar initial_speed(0);
mouseDeltaX.ForceUpdate(&initial_speed, controlMask);
mouseDeltaY.ForceUpdate(&initial_speed, controlMask);
int press=0;
mouseWheelDelta.ForceUpdate(&press,controlMask);
for (i=0; i<ELEMENTS(mouseButtonGroup); ++i)
mouseButtonGroup[i].ForceUpdate(&press, controlMask);
//
//-------------------------------
// Set up the button value arrays
//-------------------------------
//
int key=0;
for (i=0; i<ELEMENTS(virtualButtonGroup); ++i)
virtualButtonGroup[i].ForceUpdate(&key, controlMask);
//
//------------------------
// Initialize the keyboard
//------------------------
//
systemKeyboard.Update(&press, controlMask);
}
//
//############################################################################
// ~ControlsManager
//
// Destructor method
//############################################################################
//
ControlsManager::~ControlsManager()
{
Check_Object(this);
//
//--------------------
// Delete the joystick
//--------------------
//
if (systemJoystick)
{
Check_Object(systemJoystick);
Unregister_Pointer(joystickHat);
delete[] joystickHat;
Unregister_Pointer(joystickButtonGroup);
delete[] joystickButtonGroup;
Unregister_Pointer(joystickAxisGroup);
delete[] joystickAxisGroup;
Unregister_Object(systemJoystick);
delete systemJoystick;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::JoyStickShift (int value)
{
m_JoyStickShiftButton = value;
if (systemJoystick)
systemJoystick->ShiftButton (value);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::SetJoystick (int id)
{
int i;
if (systemJoystick)
{
Check_Object(systemJoystick);
Unregister_Pointer(joystickHat);
delete[] joystickHat;
Unregister_Pointer(joystickButtonGroup);
delete[] joystickButtonGroup;
Unregister_Pointer(joystickAxisGroup);
delete[] joystickAxisGroup;
Unregister_Object(systemJoystick);
delete systemJoystick;
}
systemJoystick = NULL;
joystickAxisGroup = NULL;
joystickButtonGroup = NULL;
joystickHat = NULL;
if (gosJoystick_CountJoysticks(false) > id)
{
gosJoystick_SetPolling(id, true);
systemJoystick = new Joystick(
id, //Joystick ID
0.08f, //XAxis dead zone percent
0.05f, //YAxis dead zone percent
0.05f, //ThrottleAxis dead zone percent
0.15f //RudderAxis dead zone percent
);
Register_Object(systemJoystick);
if (systemJoystick)
systemJoystick->ShiftButton (m_JoyStickShiftButton);
//
//-------------------------
// Create the axis managers
//-------------------------
//
joystickAxisGroup = new ControlsUpdateManagerOf<Scalar>[Joystick::AxisCount];
Register_Pointer(joystickAxisGroup);
for (i=0; i<Joystick::AxisCount; ++i)
{
joystickAxisGroup[i].ForceUpdate(&systemJoystick->axisValues[i],controlMask);
}
//
//---------------------------
// Create the button managers
//---------------------------
//
joystickButtonGroup = new ControlsUpdateManagerOf<int>[systemJoystick->buttonCount];
Register_Pointer(joystickButtonGroup);
int initial_button_value = 0;
for (i=0; i<systemJoystick->buttonCount; ++i)
{
joystickButtonGroup[i].ForceUpdate(&initial_button_value,controlMask);
}
//
//---------------------------
// Create the button managers
//---------------------------
//
if (systemJoystick->HasHat())
{
joystickHat = new ControlsUpdateManagerOf<int>[4];
Register_Pointer(joystickHat);
int initial_button_value = 0;
for (i=0; i<4; ++i)
{
joystickHat[i].ForceUpdate(&initial_button_value, controlMask);
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::RemoveAllMappings()
{
Check_Object(this);
pressAnyKey = false;
m_ListChanged = true;
m_AllMappings.clear ();
int i;
if (systemJoystick)
{
Check_Object(systemJoystick);
Check_Pointer(joystickAxisGroup);
for (i=0; i<Joystick::AxisCount; ++i)
{
Check_Object(&joystickAxisGroup[i]);
joystickAxisGroup[i].RemoveAll();
}
for (i=0; i<systemJoystick->buttonCount; ++i)
{
Check_Object(&joystickButtonGroup[i]);
joystickButtonGroup[i].RemoveAll();
}
if (joystickHat)
{
Check_Object(joystickHat);
for (i=0; i<4; ++i)
{
Check_Object(&joystickHat[i]);
joystickHat[i].RemoveAll();
}
}
}
//
//---------------------------
// Remove mappings from mouse
//---------------------------
//
mousePosX.RemoveAll();
mousePosY.RemoveAll();
mouseDeltaX.RemoveAll();
mouseDeltaY.RemoveAll();
mouseWheelDelta.RemoveAll ();
for (i=0; i<ELEMENTS(mouseButtonGroup); ++i)
{
Check_Object(&mouseButtonGroup[i]);
mouseButtonGroup[i].RemoveAll();
}
//
//----------------------------------------
// Remove mappings from the system buttons
//----------------------------------------
//
for (i=0; i<ELEMENTS(virtualButtonGroup); ++i)
{
Check_Object(&virtualButtonGroup[i]);
virtualButtonGroup[i].RemoveAll();
}
//
//----------------------------------
// Remove mappings from the keyboard
//----------------------------------
//
ButtonIterator buttons(&activeButtons);
ControlsUpdateManagerOf<int>* button;
while ((button = buttons.GetCurrent()) != NULL)
{
buttons.Remove();
}
systemKeyboard.RemoveAll();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int ControlsManager::Remove(int group,int element,int control_mask)
{
stlport::vector<ControlData>::iterator iter;
int count;
iter = m_AllMappings.begin ();
count = 0;
while (iter != m_AllMappings.end ())
{
if ((iter->group == group) && (iter->element == element))
{
iter = m_AllMappings.erase (iter);
count++;
}
else
iter++;
}
switch (group)
{
case JoystickAxisGroupID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (static_cast<unsigned>(element) < Joystick::AxisCount && systemJoystick->HasAxis(element) )
joystickAxisGroup[element].Remove (control_mask);
}
break;
case JoystickButtonGroupID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (static_cast<unsigned>(element) < systemJoystick->buttonCount)
joystickButtonGroup[element].Remove (control_mask);
}
break;
case JoystickHatID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (systemJoystick->HasHat())
{
Check_Object(joystickHat);
if (static_cast<unsigned>(element) < 4)
joystickHat[element].Remove (control_mask);
}
}
break;
//
//-----------------------
// Add the mouse mappings
//-----------------------
//
case MousePosXID:
Check_Object(&mousePosX);
mousePosX.Remove (control_mask);
break;
case MousePosYID:
Check_Object(&mousePosY);
mousePosY.Remove (control_mask);
break;
case MouseDeltaXID:
Check_Object(&mouseDeltaX);
mouseDeltaX.Remove (control_mask);
break;
case MouseDeltaYID:
Check_Object(&mouseDeltaY);
mouseDeltaY.Remove (control_mask);
break;
case MouseWheelDeltaID:
Check_Object(&mouseWheelDelta);
mouseWheelDelta.Remove (control_mask);
break;
case MouseButtonGroupID:
Verify(static_cast<unsigned>(element) < ELEMENTS(mouseButtonGroup));
mouseButtonGroup[element].Remove (control_mask);
break;
//
//-----------------------------------
// Add the keyboard 'button' mappings
//-----------------------------------
//
case VirtualButtonGroupID:
Verify(static_cast<unsigned>(element) < ELEMENTS(virtualButtonGroup));
virtualButtonGroup[element].Remove (control_mask);
break;
case SystemKeyboardID:
systemKeyboard.Remove (control_mask);
break;
default:
STOP(("Unknown mapping group!\n"));
break;
}
return count;
}
int ControlsManager::Remove (const Entity::AttributeID& attr_id,const MessageID& mesg_id)
{
Verify ((attr_id == 0) || (mesg_id == 0));
stlport::vector<ControlData>::iterator iter;
int count;
iter = m_AllMappings.begin ();
count = 0;
while (iter != m_AllMappings.end ())
{
if ((iter->attr_id == attr_id) && (iter->mesg_id == mesg_id))
{
iter = m_AllMappings.erase (iter);
count++;
}
else
iter++;
}
//
//------------------------------
// Remove mappings from joystick
//------------------------------
//
int i;
if (systemJoystick)
{
Check_Object(systemJoystick);
Check_Pointer(joystickAxisGroup);
for (i=0; i<Joystick::AxisCount; ++i)
{
Check_Object(&joystickAxisGroup[i]);
joystickAxisGroup[i].Remove(attr_id,mesg_id);
}
for (i=0; i<systemJoystick->buttonCount; ++i)
{
Check_Object(&joystickButtonGroup[i]);
joystickButtonGroup[i].Remove(attr_id,mesg_id);
}
if (joystickHat)
{
Check_Object(joystickHat);
for (i=0; i<4; ++i)
{
Check_Object(&joystickHat[i]);
joystickHat[i].Remove(attr_id,mesg_id);
}
}
}
//
//---------------------------
// Remove mappings from mouse
//---------------------------
//
mousePosX.Remove(attr_id,mesg_id);
mousePosY.Remove(attr_id,mesg_id);
mouseDeltaX.Remove(attr_id,mesg_id);
mouseDeltaY.Remove(attr_id,mesg_id);
mouseWheelDelta.Remove(attr_id,mesg_id);
for (i=0; i<ELEMENTS(mouseButtonGroup); ++i)
{
Check_Object(&mouseButtonGroup[i]);
mouseButtonGroup[i].Remove(attr_id,mesg_id);
}
//
//----------------------------------------
// Remove mappings from the system buttons
//----------------------------------------
//
for (i=0; i<ELEMENTS(virtualButtonGroup); ++i)
{
Check_Object(&virtualButtonGroup[i]);
virtualButtonGroup[i].Remove(attr_id,mesg_id);
}
//
//----------------------------------
// Remove mappings from the keyboard
//----------------------------------
//
systemKeyboard.Remove(attr_id,mesg_id);
return count;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::Remove(int control_mask)
{
Check_Object(this);
stlport::vector<ControlData>::iterator iter;
iter = m_AllMappings.begin ();
while (iter != m_AllMappings.end ())
{
if (iter->control_mask == control_mask)
iter = m_AllMappings.erase (iter);
else
iter++;
}
//
//------------------------------
// Remove mappings from joystick
//------------------------------
//
int i;
if (systemJoystick)
{
Check_Object(systemJoystick);
Check_Pointer(joystickAxisGroup);
for (i=0; i<Joystick::AxisCount; ++i)
{
Check_Object(&joystickAxisGroup[i]);
joystickAxisGroup[i].Remove(control_mask);
}
for (i=0; i<systemJoystick->buttonCount; ++i)
{
Check_Object(&joystickButtonGroup[i]);
joystickButtonGroup[i].Remove(control_mask);
}
if (joystickHat)
{
Check_Object(joystickHat);
for (i=0; i<4; ++i)
{
Check_Object(&joystickHat[i]);
joystickHat[i].Remove(control_mask);
}
}
}
//
//---------------------------
// Remove mappings from mouse
//---------------------------
//
mousePosX.Remove(control_mask);
mousePosY.Remove(control_mask);
mouseDeltaX.Remove(control_mask);
mouseDeltaY.Remove(control_mask);
mouseWheelDelta.Remove(control_mask);
for (i=0; i<ELEMENTS(mouseButtonGroup); ++i)
{
Check_Object(&mouseButtonGroup[i]);
mouseButtonGroup[i].Remove(control_mask);
}
//
//----------------------------------------
// Remove mappings from the system buttons
//----------------------------------------
//
for (i=0; i<ELEMENTS(virtualButtonGroup); ++i)
{
Check_Object(&virtualButtonGroup[i]);
virtualButtonGroup[i].Remove(control_mask);
}
//
//----------------------------------
// Remove mappings from the keyboard
//----------------------------------
//
systemKeyboard.Remove(control_mask);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::CenterMouse(void)
{
gos_SetMousePosition (0.5f,0.5f);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::TowardsCenterMouse (Scalar amountx,Scalar amounty)
{
Scalar posx,posy;
if (amountx < 0)
amountx *= -1.0f;
if (amounty < 0)
amounty *= -1.0f;
gos_GetMouseInfo(&posx,&posy,NULL,NULL,NULL,NULL);
if (posx < 0.5f)
{
posx += amountx;
Max_Clamp (posx,0.5f);
}
else if (posx > 0.5f)
{
posx -= amountx;
Min_Clamp (posx,0.5f);
}
if (posy < 0.5f)
{
posy += amounty;
Max_Clamp (posy,0.5f);
}
else if (posy > 0.5f)
{
posy -= amounty;
Min_Clamp (posy,0.5f);
}
gos_SetMousePosition (posx,posy);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsManager::Execute()
{
Check_Object(this);
if (m_IgnoreCommands)
{
return;
}
bool wheelup=false,wheeldown = false;
bool mousex_left = false;
bool mousex_right = false;
bool mousey_up = false;
bool mousey_down = false;
bool joyx_left = false;
bool joyx_right = false;
bool joyy_up = false;
bool joyy_down = false;
bool joyrudder_left = false;
bool joyrudder_right = false;
bool joythrottle_up = false;
bool joythrottle_down = false;
bool hat_left = false;
bool hat_right = false;
bool hat_up = false;
bool hat_down = false;
//
//---------------------
// Set the control mask
//---------------------
//
int control_mode = 0;
if (gos_GetKeyStatus(KEY_LSHIFT))
control_mode |= ShiftMode;
if (gos_GetKeyStatus(KEY_LCONTROL))
control_mode |= CtrlMode;
if (gos_GetKeyStatus(KEY_LMENU))
control_mode |= AltMode;
//
//----------------------------
// Read system joystick inputs
//----------------------------
//
if (systemJoystick)
{
int temp_mode = control_mode;
temp_mode &= ShiftMode;
if (systemJoystick->ShiftButton ())
temp_mode |= ShiftMode;
controlMask = 1<<temp_mode;
Check_Object(systemJoystick);
systemJoystick->Update(
controlMask,
joystickAxisGroup,
joystickButtonGroup,
joystickHat
);
if (systemJoystick->HasAxis (Joystick::XAxis))
{
if (systemJoystick->axisValues[Joystick::XAxis] < -0.5f)
joyx_left = true;
else if (systemJoystick->axisValues[Joystick::XAxis] > 0.5f)
joyx_right = true;
}
if (systemJoystick->HasAxis (Joystick::YAxis))
{
if (systemJoystick->axisValues[Joystick::YAxis] < -0.5f)
joyy_up = true;
else if (systemJoystick->axisValues[Joystick::YAxis] > 0.5f)
joyy_down = true;
}
if (systemJoystick->HasAxis (Joystick::ThrottleAxis))
{
if (systemJoystick->axisValues[Joystick::ThrottleAxis] < 0.25f)
joythrottle_up = true;
else if (systemJoystick->axisValues[Joystick::ThrottleAxis] > 0.75f)
joythrottle_down = true;
}
if (systemJoystick->HasAxis (Joystick::RudderAxis))
{
if (systemJoystick->axisValues[Joystick::RudderAxis] < -0.5f)
joyrudder_left = true;
else if (systemJoystick->axisValues[Joystick::RudderAxis] > 0.5f)
joyrudder_right = true;
}
if (systemJoystick->HasHat ())
{
Scalar value = systemJoystick->hatValue;
if (value == -1.0f)
{
}
else if ((value > 0.875f) || (value < 0.125f))
hat_up = true;
else if ((value>= 0.125f) && (value <= 0.375f))
hat_right = true;
else if ((value> 0.375f) && (value < 0.625f))
hat_down = true;
else if ((value>= 0.625f) && (value <= 0.875f))
hat_left = true;
}
}
controlMask = 1<<control_mode;
//
//---------------
// Read the mouse
//---------------
//
{
int temp_mode = control_mode;
temp_mode &= ShiftMode;
controlMask = 1<<temp_mode;
Scalar posx,posy,temp;
int deltax,deltay;
int wheel;
DWORD buttons;
gos_GetMouseInfo(&posx,&posy,&deltax,&deltay,&wheel,&buttons);
if (deltax < -25)
mousex_left = true;
else if (deltax>25)
mousex_right = true;
if (deltay < -25)
mousey_up = true;
else if (deltay>25)
mousey_down = true;
mousePosX.ForceUpdate(&posx, 1);
mousePosY.ForceUpdate(&posy, 1);
temp = (float)deltax;
// temp = posx - lastMousePosX;
mouseDeltaX.ForceUpdate(&temp, 1);
temp = (float) deltay;
// temp = posy - lastMousePosY;
mouseDeltaY.ForceUpdate(&temp, 1);
if (wheel == 999)
wheel = 0;
if (wheel < 0)
wheeldown = true;
else if (wheel > 0)
wheelup = true;
mouseWheelDelta.Update (&wheel,1);
int button_state = (buttons&0x01) ? 1 : -1;
mouseButtonGroup[0].Update(&button_state, 1);
button_state = (buttons&0x02) ? 1 : -1;
mouseButtonGroup[1].Update(&button_state, 1);
button_state = (buttons&0x04) ? 1 : -1;
mouseButtonGroup[2].Update(&button_state, 1);
button_state = (buttons&0x08) ? 1 : -1;
mouseButtonGroup[3].Update(&button_state, 1);
button_state = (buttons&0x10) ? 1 : -1;
mouseButtonGroup[4].Update(&button_state, 1);
}
controlMask = 1<<control_mode;
//
//-----------------------------------------------------------------------
// Read the button states for the active buttons. For each one found,
// figure out where it is in the array, and thus find the virtual keycode
// to check
//-----------------------------------------------------------------------
//
if (!m_ChatMode)
{
Check_Object(Application::GetInstance());
if(Application::GetInstance()->applicationMode == Application::NormalGameMode)
{
ButtonIterator buttons(&activeButtons);
ControlsUpdateManagerOf<int>* button;
while ((button = buttons.ReadAndNext()) != NULL)
{
if (m_ChatMode) // just entered it
break;
if (m_ListChanged)
{
m_ListChanged = false; // the mappings have changed under it.
return;
}
Check_Object(button);
int key = button - virtualButtonGroup;
Verify(static_cast<unsigned>(key) < ELEMENTS(virtualButtonGroup));
DWORD status;
switch (key)
{
case MOUSE_WHEEL_UP:
if (wheelup)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case MOUSE_WHEEL_DOWN:
if (wheeldown)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case MOUSEX_LEFT:
if (mousex_left)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case MOUSEX_RIGHT:
if (mousex_right)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case MOUSEY_UP:
if (mousey_up)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case MOUSEY_DOWN:
if (mousey_down)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYX_LEFT:
if (joyx_left)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYX_RIGHT:
if (joyx_right)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYY_UP:
if (joyy_up)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYY_DOWN:
if (joyy_down)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYRUDDER_LEFT:
if (joyrudder_left)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYRUDDER_RIGHT:
if (joyrudder_right)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYTHROTTLE_UP:
if (joythrottle_up)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case JOYTHROTTLE_DOWN:
if (joythrottle_down)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case HAT_LEFT:
if (hat_left)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case HAT_RIGHT:
if (hat_right)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case HAT_UP:
if (hat_up)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
case HAT_DOWN:
if (hat_down)
status = KEY_PRESSED;
else
status = KEY_FREE;
break;
default:
status = gos_GetKeyStatus(static_cast<gosEnum_KeyIndex>(key));
break;
}
if (status == KEY_FREE)
{
if (m_ClearingChatEnter && (static_cast<gosEnum_KeyIndex>(key) == KEY_RETURN))
{
m_ClearingChatEnter = false;
}
else if (m_ClearingChatEscape && (static_cast<gosEnum_KeyIndex>(key) == KEY_ESCAPE))
{
m_ClearingChatEscape = false;
}
else
{
key = -key;
button->Update(&key, AlwaysActive);
}
}
else
{
if (m_ClearingChatEnter && (static_cast<gosEnum_KeyIndex>(key) == KEY_RETURN))
{
}
else if (m_ClearingChatEscape && (static_cast<gosEnum_KeyIndex>(key) == KEY_ESCAPE))
{
}
else
{
button->Update(&key, controlMask);
}
}
}
//
//-------------------------
// Read the keyboard stream
//-------------------------
//
int keypress = (int)(gos_GetKey()&255);
if (keypress != 0)
{
pressAnyKey = true;
systemKeyboard.Update(&keypress, controlMask);
}
}
}
else
{
if (m_ChatInterface.GetCurrent ())
{
Check_Object (m_ChatInterface.GetCurrent ());
DWORD key;
while ((key = gos_GetKey()) != 0)
{
if (m_ChatInterface.GetCurrent ())
m_ChatInterface.GetCurrent ()->pushChatKey (key);
}
}
else
{
LeaveChatMode ();
}
}
}
void ControlsManager::EnterChatMode (Interface *dest)
{
Check_Object(Application::GetInstance());
if(Application::GetInstance()->applicationMode == Application::NormalGameMode)
{
ButtonIterator buttons(&activeButtons);
ControlsUpdateManagerOf<int>* button;
while ((button = buttons.ReadAndNext()) != NULL)
{
Check_Object(button);
int key = button - virtualButtonGroup;
Verify(static_cast<unsigned>(key) < ELEMENTS(virtualButtonGroup));
key = -key;
button->Update(&key, AlwaysActive);
}
}
m_ChatMode = true;
if (m_ChatInterface.GetCurrent ())
m_ChatInterface.Remove ();
m_ChatInterface.Add (dest);
}
void ControlsManager::LeaveChatMode (void)
{
if (m_ChatInterface.GetCurrent ())
m_ChatInterface.Remove ();
m_ChatMode = false;
m_ClearingChatEnter = true;
m_ClearingChatEscape = true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::Remap (Entity *entity_to_control,Entity::AttributeID attribute_ID,Receiver *receiver,MessageID message,Stuff::Plug *owner,int control_mask,int group,int element,bool invert,int nameid,int type)
{
Check_Object(this);
Check_Object(owner);
Remove (attribute_ID,message);
Remove (group,element,control_mask);
CreateMapping (entity_to_control,attribute_ID,receiver,message,owner,control_mask,group,element,invert,nameid,type);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::CreateMapping(Entity *entity_to_control,Entity::AttributeID attribute_ID,Receiver *receiver,MessageID message,Plug *owner,int control_mask,int group,int element,bool invert,int nameid,int type)
{
Check_Object(this);
Check_Object(owner);
m_AllMappings.push_back (ControlData (attribute_ID,message,control_mask,group,element,owner,invert,nameid,type));
//
//------------------------------------------------------------------
// If this is a direct mapping, get the attribute we will be routing
// input into
//------------------------------------------------------------------
//
if (entity_to_control != NULL)
{
//
//--------------------------------------------------------------------
// Figure out which group we will be creating the mapping from. If it
// is to a joystick group, make sure that the stick exists and has
// sufficient capabilities
//--------------------------------------------------------------------
//
Check_Object(entity_to_control);
switch (group)
{
case JoystickAxisGroupID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (
static_cast<unsigned>(element) < Joystick::AxisCount
&& systemJoystick->HasAxis(element)
)
joystickAxisGroup[element].Add(
control_mask,
entity_to_control,
attribute_ID,
ScalarClassID,
owner,
invert
);
}
break;
case JoystickButtonGroupID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (static_cast<unsigned>(element) < systemJoystick->buttonCount)
joystickButtonGroup[element].Add(
control_mask,
entity_to_control,
attribute_ID,
IntClassID,
owner,
false
);
}
break;
case JoystickHatID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (systemJoystick->HasHat())
{
// To support old pilot options.mw4
if (static_cast<unsigned>(element) == Joystick::HatAxis)
joystickAxisGroup[Joystick::HatAxis].Add(
control_mask,
entity_to_control,
attribute_ID,
ScalarClassID,
owner,
invert
);
}
}
break;
//
//-----------------------
// Add the mouse mappings
//-----------------------
//
case MousePosXID:
Check_Object(&mousePosX);
mousePosX.Add(
control_mask,
entity_to_control,
attribute_ID,
ScalarClassID,
owner,
invert
);
break;
case MousePosYID:
Check_Object(&mousePosY);
mousePosY.Add(
control_mask,
entity_to_control,
attribute_ID,
ScalarClassID,
owner,
invert
);
break;
case MouseDeltaXID:
Check_Object(&mouseDeltaX);
mouseDeltaX.Add(
control_mask,
entity_to_control,
attribute_ID,
ScalarClassID,
owner,
invert
);
break;
case MouseDeltaYID:
Check_Object(&mouseDeltaY);
mouseDeltaY.Add(
control_mask,
entity_to_control,
attribute_ID,
ScalarClassID,
owner,
invert
);
break;
case MouseWheelDeltaID:
Check_Object(&mouseWheelDelta);
mouseWheelDelta.Add(
control_mask,
entity_to_control,
attribute_ID,
IntClassID,
owner,
false
);
break;
case MouseButtonGroupID:
Verify(static_cast<unsigned>(element) < ELEMENTS(mouseButtonGroup));
mouseButtonGroup[element].Add(
control_mask,
entity_to_control,
attribute_ID,
IntClassID,
owner,
false
);
break;
//
//-----------------------------------
// Add the keyboard 'button' mappings
//-----------------------------------
//
case VirtualButtonGroupID:
Verify(static_cast<unsigned>(element) < ELEMENTS(virtualButtonGroup));
virtualButtonGroup[element].Add(
control_mask,
entity_to_control,
attribute_ID,
IntClassID,
owner,
false
);
ActivateButton(element);
break;
//
//---------------------------------
// Add the keyboard stream mappings
//---------------------------------
//
case SystemKeyboardID:
SPEW((0, "Direct mappings not advisable for keyboard!"));
systemKeyboard.Add(
control_mask,
entity_to_control,
attribute_ID,
IntClassID,
owner,
false
);
break;
default:
STOP(("Unknown mapping group!\n"));
break;
}
}
//
//-------------------------------------------------------------
// Otherwise, it is an event mapping, so extract the message ID
//-------------------------------------------------------------
//
else
{
//
//--------------------------------------------------------------------
// Figure out which group we will be creating the mapping from. If it
// is to a joystick group, make sure that the stick exists and has
// sufficient capabilities
//--------------------------------------------------------------------
//
Check_Object(receiver);
switch (group)
{
case JoystickAxisGroupID:
SPEW((0, "Event mappings not advisable for joystick axes!"));
if (systemJoystick)
{
Check_Object(systemJoystick);
if (
static_cast<unsigned>(element) < Joystick::AxisCount
&& systemJoystick->HasAxis(element)
)
joystickAxisGroup[element].Add(
control_mask,
receiver,
message,
owner
);
}
break;
case JoystickButtonGroupID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (static_cast<unsigned>(element) < systemJoystick->buttonCount)
joystickButtonGroup[element].Add(
control_mask,
receiver,
message,
owner
);
}
break;
case JoystickHatID:
if (systemJoystick)
{
Check_Object(systemJoystick);
if (systemJoystick->HasHat())
{
Check_Object(joystickHat);
if (static_cast<unsigned>(element) < 4)
joystickHat[element].Add(
control_mask,
receiver,
message,
owner
);
}
}
break;
//
//-----------------------
// Add the mouse mappings
//-----------------------
//
case MousePosXID:
mousePosX.Add(
control_mask,
receiver,
message,
owner
);
break;
case MousePosYID:
mousePosY.Add(
control_mask,
receiver,
message,
owner
);
break;
case MouseDeltaXID:
mouseDeltaX.Add(
control_mask,
receiver,
message,
owner
);
break;
case MouseDeltaYID:
mouseDeltaY.Add(
control_mask,
receiver,
message,
owner
);
break;
case MouseWheelDeltaID:
mouseWheelDelta.Add(
control_mask,
receiver,
message,
owner
);
break;
case MouseButtonGroupID:
Verify(static_cast<unsigned>(element) < ELEMENTS(mouseButtonGroup));
mouseButtonGroup[element].Add(
control_mask,
receiver,
message,
owner
);
break;
//
//-----------------------------------
// Add the keyboard 'button' mappings
//-----------------------------------
//
case VirtualButtonGroupID:
Verify(static_cast<unsigned>(element) < ELEMENTS(virtualButtonGroup));
Verify(static_cast<unsigned>(element) > 0);
virtualButtonGroup[element].Add(
control_mask,
receiver,
message,
owner
);
ActivateButton(element);
break;
//
//---------------------------------
// Add the keyboard stream mappings
//---------------------------------
//
case SystemKeyboardID:
systemKeyboard.Add(
control_mask,
receiver,
message,
owner
);
break;
default:
STOP(("Unknown mapping group!\n"));
break;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void ControlsManager::ActivateButton(int button_num)
{
Check_Object(this);
Verify(static_cast<unsigned>(button_num) < ELEMENTS(virtualButtonGroup));
ControlsUpdateManagerOf<int>* button = &virtualButtonGroup[button_num];
Check_Object(button);
//
//-------------------------------------------------
// Check to see if this button is already activated
//-------------------------------------------------
//
if (!activeButtons.IsPlugMember(button))
activeButtons.Add(button);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ControlsManager::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}