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.
1536 lines
39 KiB
C++
1536 lines
39 KiB
C++
|
|
#include "AdeptHeaders.hpp"
|
|
#include "control_mapping.hpp"
|
|
#include "Tool.hpp"
|
|
#include "Joystick.hpp"
|
|
#include "interface.hpp"
|
|
#include "missionlang\resource.h"
|
|
|
|
extern int g_bUseOrgJoy; // jcem
|
|
|
|
namespace Adept
|
|
{
|
|
CControlMappingList *g_ControlList=NULL;
|
|
}
|
|
|
|
CControlMappingList::CControlMappingList (const char *filename,Entity::ClassData *classdata)
|
|
{
|
|
m_Mappings.clear ();
|
|
m_nCount = 0;
|
|
m_pcdHead = NULL;
|
|
m_fInvertJoyY = false;
|
|
m_fInvertMouseY = true;
|
|
m_Joystick = 0;
|
|
m_joyStickAllowed = true;
|
|
m_mouseAllowed = false;
|
|
m_joystickButtons = 0;
|
|
m_joyStickShiftValue = -1;
|
|
m_ForceFeedBack = true;
|
|
m_MouseSensitivity = 0.25f;
|
|
m_JoystickXAxisType = TURNING_AXIS;
|
|
m_JoystickRudderAxisType = TORSO_AXIS;
|
|
m_MouseXAxisType = TURNING_AXIS;
|
|
InitializeThrottleConstants();
|
|
LoadList (filename,classdata);
|
|
}
|
|
|
|
CControlMappingList::CControlMappingList (const ResourceID& control_stream)
|
|
{
|
|
m_Mappings.clear ();
|
|
m_nCount = 0;
|
|
m_pcdHead = NULL;
|
|
m_fInvertJoyY = false;
|
|
m_fInvertMouseY = true;
|
|
m_Joystick = 0;
|
|
m_joyStickAllowed = true;
|
|
m_mouseAllowed = false;
|
|
m_joystickButtons = 0;
|
|
m_joyStickShiftValue = -1;
|
|
m_ForceFeedBack = true;
|
|
m_MouseSensitivity = 0.25f;
|
|
m_JoystickXAxisType = TURNING_AXIS;
|
|
m_JoystickRudderAxisType = TORSO_AXIS;
|
|
m_MouseXAxisType = TURNING_AXIS;
|
|
InitializeThrottleConstants();
|
|
LoadList (control_stream);
|
|
}
|
|
|
|
CControlMappingList::CControlMappingList (void)
|
|
{
|
|
m_Mappings.clear ();
|
|
m_nCount = 0;
|
|
m_pcdHead = NULL;
|
|
m_fInvertJoyY = false;
|
|
m_fInvertMouseY = true;
|
|
m_Joystick = 0;
|
|
m_joyStickAllowed = true;
|
|
m_mouseAllowed = false;
|
|
m_joystickButtons = 0;
|
|
m_joyStickShiftValue = -1;
|
|
m_ForceFeedBack = true;
|
|
m_MouseSensitivity = 0.25f;
|
|
m_JoystickXAxisType = TURNING_AXIS;
|
|
m_JoystickRudderAxisType = TORSO_AXIS;
|
|
m_MouseXAxisType = TURNING_AXIS;
|
|
InitializeThrottleConstants();
|
|
}
|
|
|
|
CControlMappingList::~CControlMappingList (void)
|
|
{
|
|
if (m_pcdHead)
|
|
{
|
|
delete[] m_pcdHead;
|
|
m_pcdHead = NULL;
|
|
}
|
|
}
|
|
|
|
void CControlMappingList::SaveList (MemoryStream& resource_locker)
|
|
{
|
|
stlport::vector<ControlData>::iterator iter;
|
|
resource_locker << m_Joystick;
|
|
resource_locker << m_ForceFeedBack;
|
|
resource_locker << m_MouseSensitivity;
|
|
resource_locker << m_joyStickShiftValue;
|
|
resource_locker << m_mouseAllowed;
|
|
resource_locker << m_JoystickXAxisType;
|
|
resource_locker << m_JoystickRudderAxisType;
|
|
resource_locker << m_MouseXAxisType;
|
|
|
|
// Can't save in options.mw4 file, save in options.ini file instead
|
|
#if 0
|
|
resource_locker << m_joystick_throttle_center;
|
|
resource_locker << m_joystick_throttle_dead_low;
|
|
resource_locker << m_joystick_throttle_dead_high;
|
|
#else
|
|
NotationFile startup_ini("options.ini", NotationFile::Standard, true);
|
|
Stuff::Page *joypage = startup_ini.FindPage("joystick");
|
|
if (!joypage)
|
|
{
|
|
startup_ini.AddPage("joystick");
|
|
}
|
|
// if (g_bUseOrgJoy) { // jcem
|
|
if (Close_Enough(m_joystick_throttle_center, m_joystick_throttle_dead_low))
|
|
joypage->SetEntry("OneWayThrottle", true);
|
|
else
|
|
joypage->SetEntry("OneWayThrottle", false);
|
|
// }
|
|
|
|
startup_ini.Save();
|
|
#endif
|
|
|
|
resource_locker << m_Mappings.size ();
|
|
for (iter = m_Mappings.begin ();iter != m_Mappings.end ();iter++)
|
|
{
|
|
resource_locker.WriteBytes (&(*iter),sizeof (*iter));
|
|
}
|
|
}
|
|
|
|
void CControlMappingList::SaveList (const ResourceID& control_stream)
|
|
{
|
|
Check_Object (ControlsManager::Instance);
|
|
|
|
Resource resource_locker(control_stream);
|
|
SaveList (resource_locker);
|
|
}
|
|
|
|
void CControlMappingList::LoadList (MemoryStream& resource_locker)
|
|
{
|
|
m_Mappings.clear ();
|
|
gos_PushCurrentHeap(Adept::g_Heap);
|
|
|
|
int mapping_count;
|
|
resource_locker >> m_Joystick;
|
|
resource_locker >> m_ForceFeedBack;
|
|
resource_locker >> m_MouseSensitivity;
|
|
resource_locker >> m_joyStickShiftValue;
|
|
resource_locker >> m_mouseAllowed;
|
|
resource_locker >> m_JoystickXAxisType;
|
|
resource_locker >> m_JoystickRudderAxisType;
|
|
resource_locker >> m_MouseXAxisType;
|
|
|
|
// Load from options.ini file instead
|
|
#if 0
|
|
resource_locker >> m_joystick_throttle_center;
|
|
resource_locker >> m_joystick_throttle_dead_low;
|
|
resource_locker >> m_joystick_throttle_dead_high;
|
|
#else
|
|
NotationFile startup_ini("options.ini", NotationFile::Standard, true);
|
|
Stuff::Page *joypage = startup_ini.FindPage("joystick");
|
|
if (joypage)
|
|
{
|
|
bool bOneWay = false;
|
|
// if (g_bUseOrgJoy) { // jcem
|
|
joypage->GetEntry("OneWayThrottle", &bOneWay);
|
|
// }
|
|
if (bOneWay) {
|
|
joypage->GetEntry("OneThrottleCenter", &m_joystick_throttle_center);
|
|
joypage->GetEntry("OneThrottleCenter", &m_joystick_throttle_dead_low);
|
|
joypage->GetEntry("OneThrottleHigh", &m_joystick_throttle_dead_high);
|
|
}
|
|
else {
|
|
// if (g_bUseOrgJoy) { // jcem
|
|
joypage->GetEntry("BiThrottleCenter", &m_joystick_throttle_center);
|
|
joypage->GetEntry("BiThrottleLow", &m_joystick_throttle_dead_low);
|
|
joypage->GetEntry("BiThrottleHigh", &m_joystick_throttle_dead_high);
|
|
// } else { // jcem
|
|
// m_joystick_throttle_center = 0.3;
|
|
// m_joystick_throttle_dead_low = 0.025;
|
|
// m_joystick_throttle_dead_high = 0.025;
|
|
// }
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (m_Joystick >= gosJoystick_CountJoysticks (false))
|
|
{
|
|
m_Joystick = 0;
|
|
m_joystickButtons = 0;
|
|
}
|
|
if (m_joystickButtons == 0 && gosJoystick_CountJoysticks(false) > 0)
|
|
{
|
|
gosJoystick_Info ji;
|
|
memset(&ji,0,sizeof(ji));
|
|
gosJoystick_GetInfo(m_Joystick, &ji);
|
|
|
|
m_joystickButtons = ji.nButtons;
|
|
}
|
|
|
|
resource_locker >> mapping_count;
|
|
const ControlData *mapping = Cast_Pointer(const ControlData*,resource_locker.GetPointer());
|
|
m_Mappings.reserve (mapping_count);
|
|
for (int i=0; i<mapping_count; ++i, ++mapping)
|
|
{
|
|
#ifndef LAB_ONLY // in release build remove no string mapping command, these should only be debug command
|
|
if (mapping->nameresid == 0)
|
|
continue;
|
|
#endif
|
|
m_Mappings.push_back (*mapping);
|
|
}
|
|
gos_PopCurrentHeap();
|
|
GetInvertStateOfList();
|
|
}
|
|
|
|
void CControlMappingList::LoadList (const ResourceID& control_stream)
|
|
{
|
|
m_Mappings.clear ();
|
|
|
|
Resource resource_locker(control_stream);
|
|
LoadList (resource_locker);
|
|
}
|
|
|
|
void CControlMappingList::LoadDefault (void)
|
|
{
|
|
m_Joystick = 0;
|
|
m_mouseAllowed = false;
|
|
int count = gosJoystick_CountJoysticks (false);
|
|
if (count)
|
|
{
|
|
gosJoystick_Info info;
|
|
gosJoystick_GetInfo (m_Joystick,&info);
|
|
m_joyStickShiftValue = info.nButtons-1;
|
|
if (m_joyStickShiftValue < 8)
|
|
{
|
|
m_joyStickShiftValue = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_joyStickShiftValue = -1;
|
|
}
|
|
m_ForceFeedBack = true;
|
|
m_MouseSensitivity = 0.02f;
|
|
m_JoystickXAxisType = TURNING_AXIS;
|
|
m_JoystickRudderAxisType = TORSO_AXIS;
|
|
m_MouseXAxisType = TURNING_AXIS;
|
|
InitializeThrottleConstants();
|
|
|
|
m_Mappings.clear ();
|
|
gos_PushCurrentHeap(Adept::g_Heap);
|
|
FillDefault(m_Mappings);
|
|
gos_PopCurrentHeap();
|
|
|
|
// Resource res ("content\\Interfaces\\Common\\interface.control");
|
|
// res.LoadData ();
|
|
// Verify (res.DoesResourceExist ());
|
|
// LoadList (res);
|
|
}
|
|
|
|
int CControlMappingList::GetList(bool fRestoreDefaults)
|
|
{
|
|
if (fRestoreDefaults)
|
|
{
|
|
m_Mappings.clear ();
|
|
gos_PushCurrentHeap(Adept::g_Heap);
|
|
FillDefault(m_Mappings);
|
|
gos_PopCurrentHeap();
|
|
}
|
|
|
|
stlport::vector<ControlData>::iterator iter;
|
|
for (iter = m_Mappings.begin ();iter != m_Mappings.end ();iter++)
|
|
{
|
|
if (iter->mesg_id != 0)
|
|
{
|
|
if ((iter->group == ControlsManager::VirtualButtonGroupID) && ((iter->element == MOUSE_WHEEL_UP)||(iter->element == MOUSE_WHEEL_DOWN)))
|
|
iter->group = ControlsManager::MouseButtonGroupID;
|
|
}
|
|
}
|
|
|
|
// Calculate worst-case size of array
|
|
m_nCount = 0;
|
|
for (iter = m_Mappings.begin ();iter != m_Mappings.end (); iter++)
|
|
{
|
|
//
|
|
//If this is a Direct command (0 == mesg_id) then we ignore it, UI doesn't allow remapping axes...
|
|
//
|
|
if (iter->mesg_id && (iter->group == ControlsManager::JoystickButtonGroupID
|
|
|| iter->group == ControlsManager::MouseButtonGroupID
|
|
|| iter->group == ControlsManager::VirtualButtonGroupID
|
|
|| iter->group == ControlsManager::JoystickHatID) )
|
|
{
|
|
m_nCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Allocate and clear control array
|
|
// This is allocated to + 1 and cleared to zero to allow for an end-of-list object.
|
|
// It would be far better to maintain a new list size, but we're approaching ZBR, so I'll refrain from
|
|
// casual changes.
|
|
//
|
|
delete[] m_pcdHead;
|
|
m_pcdHead = new ControlDef[m_nCount + 1]; //BUGBUG:DAN - make this use constructor/destructor instead
|
|
memset(m_pcdHead, 0, (m_nCount + 1) * sizeof(ControlDef));
|
|
|
|
ControlDef *pcdPtr;
|
|
for (iter = m_Mappings.begin ();iter != m_Mappings.end (); iter++)
|
|
{
|
|
//
|
|
//If this is a Direct command (0 == mesg_id) then we ignore it, UI doesn't allow remapping axes...
|
|
//
|
|
if (iter->mesg_id)
|
|
{
|
|
//
|
|
//Search list of control defs to see if command with this mesg_id already exists. We do this
|
|
//because each command will have three entries in the vector, one for key/mouse/joy and the order
|
|
//these items are stored in the vector isn't guaranteed. The code that interacts with gosScript
|
|
//wants all the info for a particular command (unique mesg_id) in one place.
|
|
//
|
|
pcdPtr = m_pcdHead;
|
|
while (pcdPtr->mesg_id && pcdPtr->mesg_id != iter->mesg_id)
|
|
{
|
|
pcdPtr++;
|
|
}
|
|
|
|
//
|
|
//Determine type of command being iterated and save the key/joy/mouse id (iter->element)
|
|
//
|
|
bool skip = false;
|
|
switch (iter->group)
|
|
{
|
|
case ControlsManager::MouseButtonGroupID:
|
|
if (!pcdPtr->cd_mouse_valid)
|
|
{
|
|
pcdPtr->nMouse = iter->element;
|
|
pcdPtr->cd_mouse = *iter;
|
|
pcdPtr->cd_mouse_valid = true;
|
|
break;
|
|
}
|
|
skip = true;
|
|
break;
|
|
|
|
case ControlsManager::VirtualButtonGroupID:
|
|
if (!pcdPtr->cd_key_valid)
|
|
{
|
|
pcdPtr->nKey = iter->element;
|
|
pcdPtr->control_mask = iter->control_mask;
|
|
pcdPtr->cd_key = *iter;
|
|
pcdPtr->cd_key_valid = true;
|
|
break;
|
|
}
|
|
skip = true;
|
|
break;
|
|
|
|
case ControlsManager::JoystickButtonGroupID:
|
|
if (!pcdPtr->cd_joy_valid)
|
|
{
|
|
pcdPtr->nJoy = iter->element;
|
|
pcdPtr->cd_joy = *iter;
|
|
pcdPtr->cd_joy_valid = true;
|
|
break;
|
|
}
|
|
skip = true;
|
|
break;
|
|
|
|
case ControlsManager::JoystickHatID:
|
|
if (!pcdPtr->cd_joy_valid)
|
|
{
|
|
pcdPtr->nJoy = iter->element+10;
|
|
pcdPtr->cd_joy = *iter;
|
|
pcdPtr->cd_joy_valid = true;
|
|
break;
|
|
}
|
|
skip = true;
|
|
break;
|
|
|
|
default:
|
|
skip = true;
|
|
break;
|
|
}
|
|
|
|
if (!skip)
|
|
{
|
|
//
|
|
//If this is the first vector entry for this command, save the common info
|
|
//
|
|
if (!pcdPtr->mesg_id)
|
|
{
|
|
pcdPtr->mesg_id = iter->mesg_id;
|
|
pcdPtr->nameresid = iter->nameresid;
|
|
pcdPtr->control_type = iter->control_type;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Determine the size of the new list by looking for the end-of-list object (mesg_id == 0)
|
|
//
|
|
int nWho = 0;
|
|
pcdPtr = m_pcdHead;
|
|
while (pcdPtr->mesg_id)
|
|
{
|
|
pcdPtr->nIdx = nWho++; // BUGBUG:DAN Adjust for category offset
|
|
pcdPtr++;
|
|
}
|
|
|
|
m_nCount = nWho; // actual size of used elements in array
|
|
|
|
return m_nCount;
|
|
}
|
|
|
|
|
|
void CControlMappingList::JoystickXAxis (int value, Plug* owner)
|
|
{
|
|
Verify (value>=0);
|
|
Verify (value < 3);
|
|
m_JoystickXAxisType = value;
|
|
if (owner)
|
|
ApplyList (owner);
|
|
}
|
|
void CControlMappingList::JoystickRudderAxis (int value, Plug* owner)
|
|
{
|
|
Verify (value>=0);
|
|
Verify (value < 3);
|
|
m_JoystickRudderAxisType = value;
|
|
if (owner)
|
|
ApplyList (owner);
|
|
}
|
|
void CControlMappingList::MouseXAxis (int value, Plug* owner)
|
|
{
|
|
Verify (value>=0);
|
|
Verify (value < 3);
|
|
m_MouseXAxisType = value;
|
|
if (owner)
|
|
ApplyList (owner);
|
|
}
|
|
void CControlMappingList::ForceFeedBack (bool value, Plug* owner)
|
|
{
|
|
m_ForceFeedBack = value;
|
|
if (owner)
|
|
ApplyList (owner);
|
|
}
|
|
|
|
void CControlMappingList::MouseSensitivity (Scalar value, Plug* owner)
|
|
{
|
|
m_MouseSensitivity = value;
|
|
if (owner)
|
|
ApplyList (owner);
|
|
}
|
|
void CControlMappingList::Joystick(int id, Plug* owner)
|
|
{
|
|
m_Joystick = id;
|
|
|
|
gosJoystick_Info ji;
|
|
memset(&ji,0,sizeof(ji));
|
|
gosJoystick_GetInfo(id, &ji);
|
|
|
|
m_joystickButtons = ji.nButtons;
|
|
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
void CControlMappingList::SetJoyYInvert(bool b, Plug* owner)
|
|
{
|
|
m_fInvertJoyY = b;
|
|
SetInvertStateOfList();
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
void CControlMappingList::SetMouseYInvert(bool b, Plug* owner)
|
|
{
|
|
m_fInvertMouseY = b;
|
|
SetInvertStateOfList();
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
void CControlMappingList::SetMouseAllowed(bool b, Plug* owner)
|
|
{
|
|
m_mouseAllowed = b;
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
void CControlMappingList::SetJoyStickAllowed(bool b, Plug* owner)
|
|
{
|
|
m_joyStickAllowed = b;
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
int CControlMappingList::SetJoyStickShiftAllowed(bool b, Plug* owner, int* pIndex1, int* pIndex2)
|
|
{
|
|
int retCount = 0;
|
|
if (b)
|
|
{
|
|
int count = gosJoystick_CountJoysticks (false);
|
|
if (count)
|
|
{
|
|
gosJoystick_Info info;
|
|
gosJoystick_GetInfo (m_Joystick,&info);
|
|
m_joyStickShiftValue = info.nButtons-1;
|
|
if (m_joyStickShiftValue < 8)
|
|
{
|
|
m_joyStickShiftValue = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_joyStickShiftValue = -1;
|
|
}
|
|
retCount = SetJoyStickShiftValue(m_joyStickShiftValue, owner, pIndex1, pIndex2);
|
|
}
|
|
else
|
|
{
|
|
m_joyStickShiftValue = -1;
|
|
}
|
|
if (owner)
|
|
ApplyList(owner);
|
|
return retCount;
|
|
}
|
|
|
|
int CControlMappingList::SetJoyStickShiftValue(int n, Plug* owner, int* pChangeIndex1, int* pChangeIndex2)
|
|
{
|
|
m_joyStickShiftValue = n;
|
|
|
|
if (m_pcdHead == NULL)
|
|
GetList(false);
|
|
|
|
// Looking to unmap any use of this button (shifted or non-shifted)
|
|
int returnIndex[2];
|
|
int returnCount = 0;
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
if (m_pcdHead[i].cd_joy_valid && m_pcdHead[i].nJoy == m_joyStickShiftValue)
|
|
{
|
|
returnIndex[returnCount] = i;
|
|
returnCount++;
|
|
|
|
m_pcdHead[i].nJoy = 0;
|
|
m_pcdHead[i].cd_joy_valid = false;
|
|
m_pcdHead[i].cd_joy.element = 0;
|
|
m_pcdHead[i].cd_joy.control_mask = 0;
|
|
}
|
|
}
|
|
gosASSERT(returnCount <= 2);
|
|
SetList(owner);
|
|
|
|
*pChangeIndex1 = returnIndex[0];
|
|
*pChangeIndex2 = returnIndex[1];
|
|
return returnCount;
|
|
}
|
|
|
|
void CControlMappingList::JoyStickThrottleCenter(Stuff::Scalar s, Plug* owner)
|
|
{
|
|
m_joystick_throttle_center = s;
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
void CControlMappingList::JoyStickThrottleLow(Stuff::Scalar s, Plug* owner)
|
|
{
|
|
m_joystick_throttle_dead_low = s;
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
void CControlMappingList::JoyStickThrottleHigh(Stuff::Scalar s, Plug* owner)
|
|
{
|
|
m_joystick_throttle_dead_high = s;
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
void CControlMappingList::SetInvertStateOfList()
|
|
{
|
|
//
|
|
//Iterate vector and set correct inversion state for any joystick or mouse Y axes
|
|
//
|
|
stlport::vector<ControlData>::iterator iter;
|
|
for (iter = m_Mappings.begin (); iter != m_Mappings.end (); iter++)
|
|
{
|
|
if (0 == iter->mesg_id)
|
|
{
|
|
switch (iter->group)
|
|
{
|
|
case ControlsManager::JoystickAxisGroupID:
|
|
if (Joystick::YAxis == iter->element)
|
|
{
|
|
iter->invert = m_fInvertJoyY;
|
|
}
|
|
break;
|
|
|
|
case ControlsManager::MousePosYID:
|
|
case ControlsManager::MouseDeltaYID:
|
|
iter->invert = m_fInvertMouseY;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CControlMappingList::GetInvertStateOfList()
|
|
{
|
|
//
|
|
//Iterate vector and set correct inversion state for any joystick or mouse Y axes
|
|
//
|
|
stlport::vector<ControlData>::iterator iter;
|
|
bool joyInvertFound = false;
|
|
bool mouseInvertFound = false;
|
|
for (iter = m_Mappings.begin (); iter != m_Mappings.end (); iter++)
|
|
{
|
|
if (0 == iter->mesg_id)
|
|
{
|
|
switch (iter->group)
|
|
{
|
|
case ControlsManager::JoystickAxisGroupID:
|
|
if (Joystick::YAxis == iter->element)
|
|
{
|
|
m_fInvertJoyY = iter->invert;
|
|
joyInvertFound = true;
|
|
if (mouseInvertFound)
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case ControlsManager::MousePosYID:
|
|
case ControlsManager::MouseDeltaYID:
|
|
{
|
|
m_fInvertMouseY = iter->invert;
|
|
mouseInvertFound = true;
|
|
if (joyInvertFound)
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
gosASSERT(mouseInvertFound);
|
|
gosASSERT(joyInvertFound);
|
|
}
|
|
|
|
void CControlMappingList::SetList(Plug* owner)
|
|
{
|
|
gosASSERT(m_pcdHead != NULL);
|
|
if (m_pcdHead == NULL)
|
|
GetList(false);
|
|
|
|
//
|
|
//Put everything that's not already in our mapping list into the dest list
|
|
//
|
|
stlport::vector<ControlData>::iterator sIter;
|
|
stlport::vector<ControlData> newList;
|
|
for (sIter = m_Mappings.begin ();sIter != m_Mappings.end (); ++sIter)
|
|
{
|
|
//
|
|
if (sIter->mesg_id == 0)
|
|
newList.push_back(*sIter);
|
|
else if (sIter->group != ControlsManager::JoystickButtonGroupID
|
|
&& sIter->group != ControlsManager::MouseButtonGroupID
|
|
&& sIter->group != ControlsManager::VirtualButtonGroupID
|
|
&& sIter->group != ControlsManager::JoystickHatID)
|
|
{
|
|
newList.push_back(*sIter);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Now put everything in our mapping list into the ControlData form and add it to the new list
|
|
//
|
|
ControlDef* pcdPtr = m_pcdHead;
|
|
for (int i = 0; i < m_nCount; ++i)
|
|
{
|
|
if (pcdPtr->cd_key_valid || (!pcdPtr->cd_mouse_valid && !pcdPtr->cd_joy_valid))
|
|
{
|
|
newList.push_back(pcdPtr->cd_key);
|
|
}
|
|
|
|
if (pcdPtr->cd_mouse_valid)
|
|
{
|
|
newList.push_back(pcdPtr->cd_mouse);
|
|
}
|
|
|
|
if (pcdPtr->cd_joy_valid)
|
|
{
|
|
newList.push_back(pcdPtr->cd_joy);
|
|
}
|
|
pcdPtr++;
|
|
}
|
|
|
|
//
|
|
// Now copy the new temp list to the final m_Mappings position
|
|
//
|
|
m_Mappings = newList;
|
|
SetInvertStateOfList();
|
|
if (owner)
|
|
ApplyList(owner);
|
|
}
|
|
|
|
|
|
|
|
void CControlMappingList::FillDefault (stlport::vector<ControlData>& list)
|
|
{
|
|
HKL hkl;
|
|
char *str;
|
|
int index;
|
|
|
|
hkl = GetKeyboardLayout (0);
|
|
index = PRIMARYLANGID (LOWORD (hkl));
|
|
switch (index)
|
|
{
|
|
case LANG_FRENCH:
|
|
str = "content\\Interfaces\\Common\\freinterface.control";
|
|
break;
|
|
case LANG_GERMAN:
|
|
str = "content\\Interfaces\\Common\\gerinterface.control";
|
|
break;
|
|
case LANG_SPANISH:
|
|
str = "content\\Interfaces\\Common\\spainterface.control";
|
|
break;
|
|
case LANG_JAPANESE:
|
|
str = "content\\Interfaces\\Common\\japinterface.control";
|
|
break;
|
|
case LANG_KOREAN:
|
|
str = "content\\Interfaces\\Common\\korinterface.control";
|
|
break;
|
|
case LANG_CHINESE:
|
|
str = "content\\Interfaces\\Common\\chiinterface.control";
|
|
break;
|
|
case LANG_ITALIAN:
|
|
str = "content\\Interfaces\\Common\\itainterface.control";
|
|
break;
|
|
case LANG_PORTUGUESE:
|
|
str = "content\\Interfaces\\Common\\porinterface.control";
|
|
break;
|
|
case LANG_DANISH:
|
|
str = "content\\Interfaces\\Common\\daninterface.control";
|
|
break;
|
|
case LANG_NORWEGIAN:
|
|
str = "content\\Interfaces\\Common\\norinterface.control";
|
|
break;
|
|
case LANG_SWEDISH:
|
|
str = "content\\Interfaces\\Common\\sweinterface.control";
|
|
break;
|
|
case LANG_FINNISH:
|
|
str = "content\\Interfaces\\Common\\fininterface.control";
|
|
break;
|
|
default:
|
|
str = "content\\Interfaces\\Common\\interface.control";
|
|
break;
|
|
}
|
|
Resource res (str);
|
|
res.LoadData ();
|
|
Verify (res.DoesResourceExist ());
|
|
|
|
int mapping_count;
|
|
res >> m_Joystick;
|
|
res >> m_ForceFeedBack;
|
|
res >> m_MouseSensitivity;
|
|
res >> m_joyStickShiftValue;
|
|
res >> m_mouseAllowed;
|
|
res >> m_JoystickXAxisType;
|
|
res >> m_JoystickRudderAxisType;
|
|
res >> m_MouseXAxisType;
|
|
res >> mapping_count;
|
|
const ControlData *mapping = Cast_Pointer(const ControlData*,res.GetPointer());
|
|
list.reserve (mapping_count);
|
|
for (int i=0; i<mapping_count; ++i, ++mapping)
|
|
{
|
|
#ifndef LAB_ONLY // in release build remove no string mapping command, these should only be debug command
|
|
if (mapping->nameresid == 0)
|
|
continue;
|
|
#endif
|
|
list.push_back (*mapping);
|
|
}
|
|
GetInvertStateOfList();
|
|
}
|
|
|
|
void CControlMappingList::ApplyList (Plug *owner)
|
|
{
|
|
Verify (owner);
|
|
ControlsManager::Instance->SetJoystick (m_Joystick);
|
|
if (IsJoyStickShiftAllowed())
|
|
ControlsManager::Instance->JoyStickShift (m_joyStickShiftValue);
|
|
else
|
|
ControlsManager::Instance->JoyStickShift (-1);
|
|
|
|
if (owner->IsDerivedFrom (Interface::DefaultData))
|
|
{
|
|
Interface *inter;
|
|
inter = Cast_Object (Interface *,owner);
|
|
inter->ForceFeedBack (m_ForceFeedBack);
|
|
inter->MouseSensitivity (m_MouseSensitivity);
|
|
inter->MouseAllowed (m_mouseAllowed);
|
|
inter->JoystickXAxisType (m_JoystickXAxisType);
|
|
inter->JoystickRudderAxisType (m_JoystickRudderAxisType);
|
|
inter->MouseXAxisType (m_MouseXAxisType);
|
|
inter->JoyStickThrottleCenter(m_joystick_throttle_center);
|
|
inter->JoyStickThrottleLow(m_joystick_throttle_dead_low);
|
|
inter->JoyStickThrottleHigh(m_joystick_throttle_dead_high);
|
|
}
|
|
|
|
ControlsManager::Instance->RemoveAllMappings ();
|
|
|
|
ControlsManager::Instance->CreateMapping( // need to add the escape key
|
|
NULL,
|
|
0,
|
|
Application::GetInstance(),
|
|
Application::PauseGameMessageID,
|
|
Application::GetInstance(),
|
|
-1,
|
|
ControlsManager::VirtualButtonGroupID,
|
|
KEY_ESCAPE,
|
|
false,
|
|
1,
|
|
1
|
|
);
|
|
|
|
stlport::vector<ControlData>::iterator iter;
|
|
for (iter = m_Mappings.begin ();iter != m_Mappings.end ();iter++)
|
|
{
|
|
if (iter->mesg_id != 0)
|
|
{
|
|
if ((iter->group == ControlsManager::MouseButtonGroupID) && ((iter->element == MOUSE_WHEEL_UP)||(iter->element == MOUSE_WHEEL_DOWN)))
|
|
iter->group = ControlsManager::VirtualButtonGroupID;
|
|
}
|
|
}
|
|
|
|
for (iter = m_Mappings.begin ();iter != m_Mappings.end ();iter++)
|
|
{
|
|
//
|
|
//----------------------
|
|
// Connect mapping to us
|
|
//----------------------
|
|
//
|
|
Entity *entity = Cast_Object (Entity *,owner);
|
|
Check_Object(entity);
|
|
|
|
//
|
|
//-------------------------------------------------------
|
|
// If this is a direct mapping, find the attribute to use
|
|
//-------------------------------------------------------
|
|
//
|
|
if (iter->mesg_id == 0)
|
|
{
|
|
if (!AxisButtonUsed (iter->group,iter->element))
|
|
{
|
|
ControlsManager::Instance->CreateMapping(entity,iter->attr_id,NULL,0,owner,iter->control_mask,iter->group,iter->element,iter->invert,iter->nameresid,iter->control_type);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((iter->group == ControlsManager::MouseButtonGroupID) && ((iter->element == MOUSE_WHEEL_UP)||(iter->element == MOUSE_WHEEL_DOWN)))
|
|
iter->group = ControlsManager::VirtualButtonGroupID;
|
|
|
|
if (!((iter->group == ControlsManager::VirtualButtonGroupID) && ((iter->element == 0)||(iter->element >= LAST_AXIS_MAPID))))
|
|
ControlsManager::Instance->CreateMapping(NULL,0,entity,iter->mesg_id,owner,iter->control_mask,iter->group,iter->element,false,iter->nameresid,iter->control_type);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CControlMappingList::AxisButtonUsed (int group,int element)
|
|
{
|
|
int value1=-1,value2=-1,value3=-1,value4=-1; // there is no -1, so a comparison against this will fail
|
|
switch (group)
|
|
{
|
|
case ControlsManager::JoystickAxisGroupID:
|
|
switch (element)
|
|
{
|
|
case Joystick::XAxis:
|
|
value1 = JOYX_LEFT;
|
|
value2 = JOYX_RIGHT;
|
|
break;
|
|
case Joystick::YAxis:
|
|
value1 = JOYY_UP;
|
|
value2 = JOYY_DOWN;
|
|
break;
|
|
case Joystick::ThrottleAxis:
|
|
value1 = JOYTHROTTLE_UP;
|
|
value2 = JOYTHROTTLE_DOWN;
|
|
break;
|
|
case Joystick::RudderAxis:
|
|
value1 = JOYRUDDER_LEFT;
|
|
value2 = JOYRUDDER_RIGHT;
|
|
break;
|
|
}
|
|
break;
|
|
case ControlsManager::JoystickHatID:
|
|
value1 = HAT_LEFT;
|
|
value2 = HAT_RIGHT;
|
|
value3 = HAT_UP;
|
|
value4 = HAT_DOWN;
|
|
break;
|
|
case ControlsManager::MousePosXID:
|
|
case ControlsManager::MouseDeltaXID:
|
|
value1 = MOUSEX_LEFT;
|
|
value2 = MOUSEX_RIGHT;
|
|
break;
|
|
case ControlsManager::MousePosYID:
|
|
case ControlsManager::MouseDeltaYID:
|
|
value1 = MOUSEY_UP;
|
|
value2 = MOUSEY_DOWN;
|
|
break;
|
|
case ControlsManager::MouseWheelDeltaID:
|
|
value1 = MOUSE_WHEEL_UP;
|
|
value2 = MOUSE_WHEEL_DOWN;
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
stlport::vector<ControlData>::iterator iter;
|
|
for (iter = m_Mappings.begin ();iter != m_Mappings.end ();iter++)
|
|
{
|
|
if (iter->group == ControlsManager::VirtualButtonGroupID)
|
|
{
|
|
if (iter->element == value1)
|
|
return true;
|
|
if (iter->element == value2)
|
|
return true;
|
|
if (iter->element == value3)
|
|
return true;
|
|
if (iter->element == value4)
|
|
return true;
|
|
}
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
stlport::vector<ControlData>::iterator CControlMappingList::StartList (void)
|
|
{
|
|
return m_Mappings.begin ();
|
|
}
|
|
|
|
stlport::vector<ControlData>::iterator CControlMappingList::EndList (void)
|
|
{
|
|
return m_Mappings.end ();
|
|
}
|
|
|
|
void CControlMappingList::ReplaceList (stlport::vector<ControlData>::iterator start,stlport::vector<ControlData>::iterator end)
|
|
{
|
|
}
|
|
|
|
void CControlMappingList::LoadList (const char *filename,Entity::ClassData *classdata)
|
|
{
|
|
//-------------------------
|
|
// Open up the mapping file
|
|
//-------------------------
|
|
//
|
|
Tool *tool = Tool::Instance;
|
|
Check_Object(tool);
|
|
|
|
//
|
|
//--------------------------------------------------------
|
|
// Create a list of all the control mappings, one per page
|
|
//--------------------------------------------------------
|
|
//
|
|
m_Mappings.clear ();
|
|
NotationFile mapping_file (filename);
|
|
|
|
NotationFile::PageIterator *mappings = mapping_file.MakePageIterator();
|
|
Check_Object(mappings);
|
|
int mapping_count = mappings->GetSize();
|
|
if (!mapping_count)
|
|
STOP(("%s: Empty file!", mapping_file.GetFileName()));
|
|
|
|
//
|
|
//----------------------------------
|
|
// For each page, create one mapping
|
|
//----------------------------------
|
|
//
|
|
Page *mapping;
|
|
while ((mapping = mappings->ReadAndNext()) != NULL)
|
|
{
|
|
ControlData data;
|
|
|
|
//
|
|
//-------------------
|
|
// Get the IO Mapping
|
|
//-------------------
|
|
//
|
|
const char *control_name,*page_name = mapping->GetName();
|
|
|
|
mapping->GetEntry("IOMapping", &control_name, true);
|
|
if (
|
|
!tool->FindControlGroupAndElement(
|
|
&data.group,
|
|
&data.element,
|
|
control_name
|
|
)
|
|
)
|
|
STOP((
|
|
"%s: {[%s]IOMapping=%s}: Unknown control name!",
|
|
mapping_file.GetFileName(),
|
|
page_name,
|
|
control_name
|
|
));
|
|
|
|
//
|
|
//----------------------------------
|
|
// Find out who this mapping goes to
|
|
//----------------------------------
|
|
//
|
|
Entity::ClassData *class_data = classdata;
|
|
|
|
//
|
|
//---------------------------------------
|
|
// If there is a modemask entry, parse it
|
|
//---------------------------------------
|
|
//
|
|
data.control_mask = ControlsManager::PlainFlag;
|
|
const char *control_mask;
|
|
if (mapping->GetEntry("ControlMask", &control_mask))
|
|
{
|
|
//
|
|
//----------------------------------
|
|
// Initialize the string for parsing
|
|
//----------------------------------
|
|
//
|
|
data.control_mask = 0;
|
|
int len = strlen(control_mask) + 1;
|
|
char *modes = new char[len];
|
|
Register_Pointer(modes);
|
|
Mem_Copy(modes, control_mask, len, len);
|
|
char *mode_copy = modes;
|
|
while (*modes)
|
|
{
|
|
//
|
|
//---------------------
|
|
// Skip any white space
|
|
//---------------------
|
|
//
|
|
while (*modes == ' ' || *modes == '\t' || *modes == '|')
|
|
++modes;
|
|
if (!*modes)
|
|
break;
|
|
|
|
//
|
|
//----------------------------
|
|
// Isolate the string we found
|
|
//----------------------------
|
|
//
|
|
char *mode = modes;
|
|
while (
|
|
*modes != ' '
|
|
&& *modes != '\t'
|
|
&& *modes != '|'
|
|
&& *modes
|
|
)
|
|
{
|
|
++modes;
|
|
}
|
|
if (*modes)
|
|
*modes++ = '\0';
|
|
|
|
//
|
|
//--------------------------
|
|
// Parse the isolated string
|
|
//--------------------------
|
|
//
|
|
|
|
int new_mode;
|
|
if (!_stricmp(mode, "Plain"))
|
|
new_mode = ControlsManager::PlainFlag;
|
|
else if (!_stricmp(mode, "Shift"))
|
|
new_mode = ControlsManager::ShiftFlag;
|
|
else if (!_stricmp(mode, "Ctrl"))
|
|
new_mode = ControlsManager::CtrlFlag;
|
|
else if (!_stricmp(mode, "Alt"))
|
|
new_mode = ControlsManager::AltFlag;
|
|
else if (!_stricmp(mode, "JoyShift"))
|
|
new_mode = ControlsManager::ShiftFlag;
|
|
else if (!_stricmp(mode, "CtrlShift"))
|
|
new_mode = ControlsManager::CtrlShiftFlag;
|
|
else if (!_stricmp(mode, "ShiftAlt"))
|
|
new_mode = ControlsManager::ShiftAltFlag;
|
|
else if (!_stricmp(mode, "CtrlAlt"))
|
|
new_mode = ControlsManager::CtrlAltFlag;
|
|
else if (!_stricmp(mode, "CtrlShiftAlt"))
|
|
new_mode = ControlsManager::CtrlShiftAltFlag;
|
|
else if (!_stricmp(mode, "AlwaysActive"))
|
|
new_mode = ControlsManager::AlwaysActive;
|
|
else
|
|
{
|
|
STOP((
|
|
"%s: {[%s]ControlMask=%s}: %s is an unknown control mode!",
|
|
mapping_file.GetFileName(),
|
|
page_name,
|
|
control_mask,
|
|
mode
|
|
));
|
|
new_mode = 0;
|
|
}
|
|
|
|
data.control_mask |= new_mode;
|
|
}
|
|
if (!data.control_mask)
|
|
data.control_mask = ControlsManager::PlainFlag;
|
|
Unregister_Pointer(mode_copy);
|
|
delete mode_copy;
|
|
}
|
|
|
|
//
|
|
//------------------------------------
|
|
// Find the type of connection to make
|
|
//------------------------------------
|
|
//
|
|
const char *type;
|
|
mapping->GetEntry("Type", &type, true);
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// If this is an event mapping, we have to have a message ID. How do we
|
|
// check a message name against an unknown message list?
|
|
//----------------------------------------------------------------------
|
|
//
|
|
if (!_stricmp(type, "EventMapping"))
|
|
{
|
|
// mapping_request->mappingType = ControlsMappingRequest::EventMapping;
|
|
const char *message;
|
|
mapping->GetEntry("MessageID", &message, true);
|
|
if (class_data)
|
|
{
|
|
Check_Object(class_data);
|
|
const Receiver::MessageEntry *entry =
|
|
class_data->FindMessageEntry(message);
|
|
if (!entry)
|
|
STOP((
|
|
"%s: {[%s]MessageID=%s}: Unknown message ID!",
|
|
mapping_file.GetFileName(),
|
|
page_name,
|
|
message
|
|
));
|
|
|
|
data.mesg_id = entry->messageID;
|
|
}
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// If this is a direct mapping, we have to have an attribute ID. How do
|
|
// we find an unknown attribute of an unknown subsystem?
|
|
//----------------------------------------------------------------------
|
|
//
|
|
else if (!_stricmp(type, "DirectMapping"))
|
|
{
|
|
// mapping_request->mappingType = ControlsMappingRequest::DirectMapping;
|
|
const char *attribute;
|
|
mapping->GetEntry("AttributeID", &attribute, true);
|
|
bool invert=false;
|
|
mapping->GetEntry("Invert",&invert,false);
|
|
data.invert = invert;
|
|
if (class_data)
|
|
{
|
|
Check_Object(class_data);
|
|
AttributeEntry *entry =
|
|
Cast_Pointer(Entity::ClassData*,class_data)
|
|
->attributeTable.GetAttributeEntry(attribute);
|
|
if (!entry)
|
|
{
|
|
STOP((
|
|
"%s: {[%s]AttributeID=%s}: Unknown attribute ID!",
|
|
mapping_file.GetFileName(),
|
|
page_name,
|
|
attribute
|
|
));
|
|
}
|
|
Check_Object(entry);
|
|
data.attr_id = entry->attributeID;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
STOP((
|
|
"%s: {[%s]Type=%s}: Unknown mapping type!",
|
|
mapping_file.GetFileName(),
|
|
page_name,
|
|
type
|
|
));
|
|
}
|
|
|
|
// MSL 5.05 MFD Comm
|
|
int nameid=0;
|
|
mapping->GetEntry("NameResID", &nameid, false);
|
|
data.nameresid = nameid;
|
|
type = "FIRE_COMMAND";
|
|
mapping->GetEntry("Area",&type,false);
|
|
if (!_stricmp(type, "FIRE_COMMAND"))
|
|
data.control_type = ControlData::Fire_Control;
|
|
else if (!_stricmp(type, "MOVE_COMMAND"))
|
|
data.control_type = ControlData::Move_Control;
|
|
else if (!_stricmp(type, "MISC_COMMAND"))
|
|
data.control_type = ControlData::Misc_Control;
|
|
else if (!_stricmp(type, "LANCEMATE_COMMAND"))
|
|
data.control_type = ControlData::Lancemate_Control;
|
|
else if (!_stricmp(type, "COMM_COMMAND"))
|
|
data.control_type = ControlData::Comm_Control;
|
|
else
|
|
{
|
|
STOP(("%s: {[%s]Control Area=%s}: Unknown Control Area!",mapping_file.GetFileName(),page_name,type));
|
|
}
|
|
|
|
m_Mappings.push_back (data);
|
|
}
|
|
|
|
Check_Object(mappings);
|
|
delete mappings;
|
|
}
|
|
|
|
|
|
|
|
int CControlMappingList::compareControls(const void *elem1, const void *elem2)
|
|
{
|
|
ControlDef *pcd1 = (ControlDef *) elem1;
|
|
ControlDef *pcd2 = (ControlDef *) elem2;
|
|
|
|
return pcd1->control_type - pcd2->control_type;
|
|
}
|
|
|
|
|
|
int CControlMappingList::AssignControlKey(Plug* owner, int nRow, int newKey, int newModifier)
|
|
{
|
|
gosASSERT(nRow < m_nCount);
|
|
gosASSERT(newKey != 0);
|
|
|
|
//
|
|
//Look for event collisions so we can unmap re-used events...
|
|
//
|
|
int returnIndex = nRow;
|
|
ControlData cd;
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
if (m_pcdHead[i].nKey == newKey && m_pcdHead[i].control_mask == newModifier)
|
|
{
|
|
if (i != nRow)
|
|
{
|
|
returnIndex = i;
|
|
m_pcdHead[i].nKey = 0;
|
|
m_pcdHead[i].control_mask = 0;
|
|
m_pcdHead[i].cd_key.element = 0;
|
|
m_pcdHead[i].cd_key.control_mask = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Init properties that change from old settings
|
|
cd = m_pcdHead[nRow].cd_key;
|
|
cd.control_mask = newModifier;
|
|
cd.element = newKey;
|
|
gosASSERT(cd.group == ControlsManager::VirtualButtonGroupID);
|
|
|
|
m_pcdHead[nRow].nKey = newKey;
|
|
m_pcdHead[nRow].control_mask = newModifier;
|
|
m_pcdHead[nRow].cd_key = cd;
|
|
m_pcdHead[nRow].cd_key_valid = true;
|
|
|
|
SetList(owner);
|
|
return returnIndex;
|
|
}
|
|
|
|
|
|
int CControlMappingList::AssignControlJoy(Plug* owner, int nRow, int newJoy, int shift)
|
|
{
|
|
gosASSERT(nRow < m_nCount);
|
|
|
|
//
|
|
//Look for event collisions so we can unmap re-used events...
|
|
//
|
|
int returnIndex = nRow;
|
|
ControlData cd;
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
if (m_pcdHead[i].cd_joy_valid && m_pcdHead[i].nJoy == newJoy && m_pcdHead[i].cd_joy.control_mask == shift)
|
|
{
|
|
if (i != nRow)
|
|
{
|
|
returnIndex = i;
|
|
m_pcdHead[i].nJoy = 0;
|
|
gosASSERT(m_pcdHead[i].cd_joy_valid);
|
|
m_pcdHead[i].cd_joy_valid = false;
|
|
m_pcdHead[i].cd_joy.element = 0;
|
|
m_pcdHead[i].cd_joy.control_mask = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
cd = m_pcdHead[nRow].cd_key;
|
|
|
|
// Init properties that change from old settings
|
|
if (newJoy<10) {
|
|
cd.group = ControlsManager::JoystickButtonGroupID;
|
|
cd.element = newJoy;
|
|
cd.control_mask = shift;
|
|
cd.mesg_id = m_pcdHead[nRow].mesg_id;
|
|
cd.nameresid = m_pcdHead[nRow].nameresid;
|
|
}
|
|
else {
|
|
cd.group = ControlsManager::JoystickHatID;
|
|
cd.element = newJoy-10;
|
|
cd.control_mask = shift;
|
|
cd.mesg_id = m_pcdHead[nRow].mesg_id;
|
|
cd.nameresid = m_pcdHead[nRow].nameresid;
|
|
}
|
|
|
|
m_pcdHead[nRow].nJoy = newJoy;
|
|
m_pcdHead[nRow].cd_joy = cd;
|
|
m_pcdHead[nRow].cd_joy_valid = true;
|
|
|
|
SetList(owner);
|
|
return returnIndex;
|
|
}
|
|
|
|
|
|
|
|
int CControlMappingList::AssignControlMouse(Plug* owner, int nRow, int newMouse)
|
|
{
|
|
gosASSERT(nRow < m_nCount);
|
|
|
|
//
|
|
//Look for event collisions so we can unmap re-used events...
|
|
//
|
|
int returnIndex = m_pcdHead[nRow].nIdx;
|
|
ControlData cd;
|
|
for (int i = 0; i < m_nCount; i++)
|
|
{
|
|
if (m_pcdHead[i].cd_mouse_valid && m_pcdHead[i].nMouse == newMouse)
|
|
{
|
|
if (i != nRow)
|
|
{
|
|
returnIndex = i; //m_pcdHead[i]->nIdx;
|
|
m_pcdHead[i].nMouse = 0;
|
|
gosASSERT(m_pcdHead[i].cd_mouse_valid);
|
|
m_pcdHead[i].cd_mouse_valid = false;
|
|
m_pcdHead[i].cd_mouse.element = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
cd = m_pcdHead[nRow].cd_key;
|
|
cd.group = ControlsManager::MouseButtonGroupID;
|
|
// Init properties that change from old settings
|
|
cd.element = newMouse;
|
|
cd.mesg_id = m_pcdHead[nRow].mesg_id;
|
|
cd.nameresid = m_pcdHead[nRow].nameresid;
|
|
|
|
m_pcdHead[nRow].nMouse = newMouse;
|
|
m_pcdHead[nRow].cd_mouse = cd;
|
|
m_pcdHead[nRow].cd_mouse_valid = true;
|
|
|
|
SetList(owner);
|
|
return returnIndex;
|
|
}
|
|
|
|
|
|
|
|
CControlMappingList::ControlDef::ControlDef()
|
|
{
|
|
mesg_id = 0;
|
|
nameresid = 0;
|
|
control_type = 0;
|
|
control_mask = 0;
|
|
nKey = 0;
|
|
nMouse = 0;
|
|
nJoy = 0;
|
|
nIdx = 0;
|
|
cd_mouse_valid = false;
|
|
cd_joy_valid = false;
|
|
cd_key_valid = false;
|
|
}
|
|
|
|
CControlMappingList::ControlDef::~ControlDef()
|
|
{
|
|
}
|
|
|
|
static char buffer[200];
|
|
|
|
|
|
|
|
const char* CControlMappingList::ControlDef::KeyName() const
|
|
{
|
|
const int MyCtrl = 1;
|
|
const int MyShift = 2;
|
|
const int MyAlt = 4;
|
|
|
|
buffer[0] = 0;
|
|
if (nKey == 0)
|
|
return buffer;
|
|
|
|
int flag = 0;
|
|
switch(control_mask)
|
|
{
|
|
case ControlsManager::AlwaysActive:
|
|
case ControlsManager::PlainFlag:
|
|
break;
|
|
|
|
case ControlsManager::ShiftFlag:
|
|
flag = MyShift;
|
|
break;
|
|
|
|
case ControlsManager::CtrlFlag:
|
|
flag = MyCtrl;
|
|
break;
|
|
|
|
case ControlsManager::AltFlag:
|
|
flag = MyAlt;
|
|
break;
|
|
|
|
case ControlsManager::CtrlShiftFlag:
|
|
flag = MyCtrl | MyShift;
|
|
break;
|
|
|
|
case ControlsManager::ShiftAltFlag:
|
|
flag = MyAlt | MyShift;
|
|
break;
|
|
|
|
case ControlsManager::CtrlAltFlag:
|
|
flag = MyAlt | MyCtrl;
|
|
break;
|
|
|
|
case ControlsManager::CtrlShiftAltFlag:
|
|
flag = MyShift | MyCtrl | MyAlt;
|
|
break;
|
|
|
|
default:
|
|
gosASSERT(!"Unknown control data type");
|
|
break;
|
|
}
|
|
|
|
// Now composite each modifier present into one long string
|
|
buffer[0] = 0;
|
|
if (flag & MyShift)
|
|
{
|
|
strcpy(buffer, gos_DescribeKey(KEY_LSHIFT << 8));
|
|
strcat(buffer, " ");
|
|
}
|
|
|
|
if (flag & MyCtrl)
|
|
{
|
|
strcat(buffer, gos_DescribeKey(KEY_LCONTROL << 8));
|
|
strcat(buffer, " ");
|
|
}
|
|
|
|
if (flag & MyAlt)
|
|
{
|
|
strcat(buffer, gos_DescribeKey(KEY_LMENU << 8));
|
|
strcat(buffer, " ");
|
|
}
|
|
|
|
strcat(buffer, gos_DescribeKey(nKey << 8));
|
|
|
|
return buffer;
|
|
}
|
|
|
|
const char* CControlMappingList::ControlDef::JoyName() const
|
|
{
|
|
char buffer2[200];
|
|
buffer2[0] = 0;
|
|
buffer[0] = 0;
|
|
|
|
if (cd_joy.control_mask == ControlsManager::ShiftFlag)
|
|
{
|
|
strcpy(buffer, gos_DescribeKey(KEY_LSHIFT << 8));
|
|
strcat(buffer, " ");
|
|
}
|
|
|
|
if (cd_joy_valid && nJoy < 10)
|
|
sprintf(buffer2, "%d", nJoy + 1);
|
|
else if (cd_joy_valid)
|
|
strcat(buffer, Application::GetInstance()->GetLocString(IDS_CONTROL_HATLEFT+nJoy-10));
|
|
else
|
|
buffer2[0] = 0;
|
|
|
|
strcat(buffer, buffer2);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
const char* CControlMappingList::ControlDef::MouseName() const
|
|
{
|
|
if (cd_mouse_valid)
|
|
sprintf(buffer, "%d", nMouse + 1);
|
|
else
|
|
buffer[0] = 0;
|
|
return buffer;
|
|
}
|
|
|
|
void CControlMappingList::InitializeThrottleConstants()
|
|
{
|
|
bool bNeedToSave = false;
|
|
NotationFile startup_ini("options.ini", NotationFile::Standard, true);
|
|
Stuff::Page *joypage = startup_ini.FindPage("joystick");
|
|
if (!joypage)
|
|
{
|
|
joypage = startup_ini.AddPage("joystick");
|
|
bNeedToSave = true;
|
|
}
|
|
|
|
Stuff::Scalar temp;
|
|
if (!joypage->GetEntry("BiThrottleCenter", &temp)) {
|
|
joypage->AppendEntry("BiThrottleCenter", 0.30f);
|
|
bNeedToSave = true;
|
|
}
|
|
|
|
if (!joypage->GetEntry("BiThrottleLow", &temp)) {
|
|
joypage->AppendEntry("BiThrottleLow", 0.25f);
|
|
bNeedToSave = true;
|
|
}
|
|
|
|
if (!joypage->GetEntry("BiThrottleHigh", &temp)) {
|
|
joypage->AppendEntry("BiThrottleHigh", 0.06f);
|
|
bNeedToSave = true;
|
|
}
|
|
|
|
if (!joypage->GetEntry("OneThrottleCenter", &temp)) {
|
|
joypage->AppendEntry("OneThrottleCenter", 0.30f);
|
|
bNeedToSave = true;
|
|
}
|
|
|
|
if (!joypage->GetEntry("OneThrottleHigh", &temp)) {
|
|
joypage->AppendEntry("OneThrottleHigh", 0.06f);
|
|
bNeedToSave = true;
|
|
}
|
|
|
|
if (bNeedToSave)
|
|
startup_ini.Save();
|
|
|
|
joypage->GetEntry("BiThrottleCenter", &m_joystick_throttle_center);
|
|
joypage->GetEntry("BiThrottleLow", &m_joystick_throttle_dead_low);
|
|
joypage->GetEntry("BiThrottleHigh", &m_joystick_throttle_dead_high);
|
|
}
|