Added support for joystick sliders to input system.

Added extra debugging output to calibration input detection routine (activated by pressing Shift).
This commit is contained in:
Nik Henson 2011-11-01 23:24:37 +00:00
parent e431b79f57
commit dfa77e9207
4 changed files with 171 additions and 73 deletions

View file

@ -201,7 +201,7 @@ const char *CInputSystem::s_validKeyNames[] =
MousePartsStruct CInputSystem::s_mseParts[] = MousePartsStruct CInputSystem::s_mseParts[] =
{ {
// X Axis (Axis 0) // X Axis (Axis 1)
{ "XAXIS", MouseXAxis }, { "XAXIS", MouseXAxis },
{ "XAXIS_INV", MouseXAxisInv }, { "XAXIS_INV", MouseXAxisInv },
{ "XAXIS_POS", MouseXAxisPos }, { "XAXIS_POS", MouseXAxisPos },
@ -213,7 +213,7 @@ MousePartsStruct CInputSystem::s_mseParts[] =
{ "AXIS1_POS", MouseXAxisPos }, { "AXIS1_POS", MouseXAxisPos },
{ "AXIS1_NEG", MouseXAxisNeg }, { "AXIS1_NEG", MouseXAxisNeg },
// Y Axis (Axis 1) // Y Axis (Axis 2)
{ "YAXIS", MouseYAxis }, { "YAXIS", MouseYAxis },
{ "YAXIS_INV", MouseYAxisInv }, { "YAXIS_INV", MouseYAxisInv },
{ "YAXIS_POS", MouseYAxisPos }, { "YAXIS_POS", MouseYAxisPos },
@ -225,7 +225,7 @@ MousePartsStruct CInputSystem::s_mseParts[] =
{ "AXIS2_POS", MouseYAxisPos }, { "AXIS2_POS", MouseYAxisPos },
{ "AXIS2_NEG", MouseYAxisNeg }, { "AXIS2_NEG", MouseYAxisNeg },
// Z/Wheel Axis (Axis 2) // Z/Wheel Axis (Axis 3)
{ "ZAXIS", MouseZAxis }, { "ZAXIS", MouseZAxis },
{ "ZAXIS_INV", MouseZAxisInv }, { "ZAXIS_INV", MouseZAxisInv },
{ "ZAXIS_POS", MouseZAxisPos }, { "ZAXIS_POS", MouseZAxisPos },
@ -237,7 +237,7 @@ MousePartsStruct CInputSystem::s_mseParts[] =
{ "AXIS3_POS", MouseZAxisPos }, { "AXIS3_POS", MouseZAxisPos },
{ "AXIS3_NEG", MouseZAxisNeg }, { "AXIS3_NEG", MouseZAxisNeg },
// Left/Middle/Right Buttons (Buttons 0-2) // Left/Middle/Right Buttons (Buttons 1-3)
{ "LEFT_BUTTON", MouseButtonLeft }, { "LEFT_BUTTON", MouseButtonLeft },
{ "BUTTON1", MouseButtonLeft }, { "BUTTON1", MouseButtonLeft },
{ "MIDDLE_BUTTON", MouseButtonMiddle }, { "MIDDLE_BUTTON", MouseButtonMiddle },
@ -245,7 +245,7 @@ MousePartsStruct CInputSystem::s_mseParts[] =
{ "RIGHT_BUTTON", MouseButtonRight }, { "RIGHT_BUTTON", MouseButtonRight },
{ "BUTTON3", MouseButtonRight }, { "BUTTON3", MouseButtonRight },
// Extra Buttons (Buttons 3 & 4) // Extra Buttons (Buttons 4 & 5)
{ "BUTTONX1", MouseButtonX1 }, { "BUTTONX1", MouseButtonX1 },
{ "BUTTON4", MouseButtonX1 }, { "BUTTON4", MouseButtonX1 },
{ "BUTTONX2", MouseButtonX2 }, { "BUTTONX2", MouseButtonX2 },
@ -257,7 +257,7 @@ MousePartsStruct CInputSystem::s_mseParts[] =
JoyPartsStruct CInputSystem::s_joyParts[] = JoyPartsStruct CInputSystem::s_joyParts[] =
{ {
// X-Axis (Axis 0) // X-Axis (Axis 1)
{ "XAXIS", JoyXAxis }, { "XAXIS", JoyXAxis },
{ "XAXIS_INV", JoyXAxisInv }, { "XAXIS_INV", JoyXAxisInv },
{ "XAXIS_POS", JoyXAxisPos }, { "XAXIS_POS", JoyXAxisPos },
@ -269,7 +269,7 @@ JoyPartsStruct CInputSystem::s_joyParts[] =
{ "AXIS1_POS", JoyXAxisPos }, { "AXIS1_POS", JoyXAxisPos },
{ "AXIS1_NEG", JoyXAxisNeg }, { "AXIS1_NEG", JoyXAxisNeg },
// Y-Axis (Axis 1) // Y-Axis (Axis 2)
{ "YAXIS", JoyYAxis }, { "YAXIS", JoyYAxis },
{ "YAXIS_INV", JoyYAxisInv }, { "YAXIS_INV", JoyYAxisInv },
{ "YAXIS_POS", JoyYAxisPos }, { "YAXIS_POS", JoyYAxisPos },
@ -281,7 +281,7 @@ JoyPartsStruct CInputSystem::s_joyParts[] =
{ "AXIS2_POS", JoyYAxisPos }, { "AXIS2_POS", JoyYAxisPos },
{ "AXIS2_NEG", JoyYAxisNeg }, { "AXIS2_NEG", JoyYAxisNeg },
// Z-Axis (Axis 2) // Z-Axis (Axis 3)
{ "ZAXIS", JoyZAxis }, { "ZAXIS", JoyZAxis },
{ "ZAXIS_INV", JoyZAxisInv }, { "ZAXIS_INV", JoyZAxisInv },
{ "ZAXIS_POS", JoyZAxisPos }, { "ZAXIS_POS", JoyZAxisPos },
@ -291,7 +291,7 @@ JoyPartsStruct CInputSystem::s_joyParts[] =
{ "AXIS3_POS", JoyZAxisPos }, { "AXIS3_POS", JoyZAxisPos },
{ "AXIS3_NEG", JoyZAxisNeg }, { "AXIS3_NEG", JoyZAxisNeg },
// RX-Axis (Axis 3) // RX-Axis (Axis 4)
{ "RXAXIS", JoyRXAxis }, { "RXAXIS", JoyRXAxis },
{ "RXAXIS_INV", JoyRXAxisInv }, { "RXAXIS_INV", JoyRXAxisInv },
{ "RXAXIS_POS", JoyRXAxisPos }, { "RXAXIS_POS", JoyRXAxisPos },
@ -301,7 +301,7 @@ JoyPartsStruct CInputSystem::s_joyParts[] =
{ "AXIS4_POS", JoyRXAxisPos }, { "AXIS4_POS", JoyRXAxisPos },
{ "AXIS4_NEG", JoyRXAxisNeg }, { "AXIS4_NEG", JoyRXAxisNeg },
// RY-Axis (Axis 4) // RY-Axis (Axis 5)
{ "RYAXIS", JoyRYAxis }, { "RYAXIS", JoyRYAxis },
{ "RYAXIS_INV", JoyRYAxisInv }, { "RYAXIS_INV", JoyRYAxisInv },
{ "RYAXIS_POS", JoyRYAxisPos }, { "RYAXIS_POS", JoyRYAxisPos },
@ -311,7 +311,7 @@ JoyPartsStruct CInputSystem::s_joyParts[] =
{ "AXIS5_POS", JoyRYAxisPos }, { "AXIS5_POS", JoyRYAxisPos },
{ "AXIS5_NEG", JoyRYAxisNeg }, { "AXIS5_NEG", JoyRYAxisNeg },
// RZ-Axis (Axis 5) // RZ-Axis (Axis 6)
{ "RZAXIS", JoyRZAxis }, { "RZAXIS", JoyRZAxis },
{ "RZAXIS_INV", JoyRZAxisInv }, { "RZAXIS_INV", JoyRZAxisInv },
{ "RZAXIS_POS", JoyRZAxisPos }, { "RZAXIS_POS", JoyRZAxisPos },
@ -321,31 +321,51 @@ JoyPartsStruct CInputSystem::s_joyParts[] =
{ "AXIS6_POS", JoyRZAxisPos }, { "AXIS6_POS", JoyRZAxisPos },
{ "AXIS6_NEG", JoyRZAxisNeg }, { "AXIS6_NEG", JoyRZAxisNeg },
// POV Hat 0 // Slider 1 (Axis 7)
{ "SLIDER1", JoyS1Axis },
{ "SLIDER1_INV", JoyS1AxisInv },
{ "SLIDER1_POS", JoyS1AxisPos },
{ "SLIDER1_NEG", JoyS1AxisNeg },
{ "AXIS7", JoyS1Axis },
{ "AXIS7_INV", JoyS1AxisInv },
{ "AXIS7_POS", JoyS1AxisPos },
{ "AXIS7_NEG", JoyS1AxisNeg },
// Slider 2 (Axis 8)
{ "SLIDER2", JoyS1Axis },
{ "SLIDER2_INV", JoyS1AxisInv },
{ "SLIDER2_POS", JoyS1AxisPos },
{ "SLIDER2_NEG", JoyS1AxisNeg },
{ "AXIS8", JoyS1Axis },
{ "AXIS8_INV", JoyS1AxisInv },
{ "AXIS8_POS", JoyS1AxisPos },
{ "AXIS8_NEG", JoyS1AxisNeg },
// POV Hat 1
{ "POV1_UP", JoyPOV0Up }, { "POV1_UP", JoyPOV0Up },
{ "POV1_DOWN", JoyPOV0Down }, { "POV1_DOWN", JoyPOV0Down },
{ "POV1_LEFT", JoyPOV0Left }, { "POV1_LEFT", JoyPOV0Left },
{ "POV1_RIGHT", JoyPOV0Right }, { "POV1_RIGHT", JoyPOV0Right },
// POV Hat 1 // POV Hat 2
{ "POV2_UP", JoyPOV1Up }, { "POV2_UP", JoyPOV1Up },
{ "POV2_DOWN", JoyPOV1Down }, { "POV2_DOWN", JoyPOV1Down },
{ "POV2_LEFT", JoyPOV1Left }, { "POV2_LEFT", JoyPOV1Left },
{ "POV2_RIGHT", JoyPOV1Right }, { "POV2_RIGHT", JoyPOV1Right },
// POV Hat 2 // POV Hat 3
{ "POV3_UP", JoyPOV2Up }, { "POV3_UP", JoyPOV2Up },
{ "POV3_DOWN", JoyPOV2Down }, { "POV3_DOWN", JoyPOV2Down },
{ "POV3_LEFT", JoyPOV2Left }, { "POV3_LEFT", JoyPOV2Left },
{ "POV3_RIGHT", JoyPOV2Right }, { "POV3_RIGHT", JoyPOV2Right },
// POV Hat 3 // POV Hat 4
{ "POV4_UP", JoyPOV3Up }, { "POV4_UP", JoyPOV3Up },
{ "POV4_DOWN", JoyPOV3Down }, { "POV4_DOWN", JoyPOV3Down },
{ "POV4_LEFT", JoyPOV3Left }, { "POV4_LEFT", JoyPOV3Left },
{ "POV4_RIGHT", JoyPOV3Right }, { "POV4_RIGHT", JoyPOV3Right },
// Buttons 0-31 // Buttons 1-32
{ "BUTTON1", JoyButton0 }, { "BUTTON1", JoyButton0 },
{ "BUTTON2", JoyButton1 }, { "BUTTON2", JoyButton1 },
{ "BUTTON3", JoyButton2 }, { "BUTTON3", JoyButton2 },
@ -383,11 +403,13 @@ JoyPartsStruct CInputSystem::s_joyParts[] =
{ NULL, JoyUnknown } { NULL, JoyUnknown }
}; };
const char *CInputSystem::s_axisNames[] = { "X", "Y", "Z", "RX", "RY", "RZ" }; const char *CInputSystem::s_axisIds[] = { "X", "Y", "Z", "RX", "RY", "RZ", "S1", "S2" };
const char *CInputSystem::s_axisNames[] = { "X-Axis", "Y-Axis", "Z-Axis", "RX-Axis", "RY-Axis", "RZ-Axis", "Slider1", "Slider2" };
const char *CInputSystem::GetDefaultAxisName(int axisNum) const char *CInputSystem::GetDefaultAxisName(int axisNum)
{ {
return (axisNum >= 0 && axisNum < 6 ? s_axisNames[axisNum] : ""); return (axisNum >= 0 && axisNum < NUM_JOY_AXES ? s_axisNames[axisNum] : "");
} }
CInputSystem::CInputSystem(const char *systemName) : CInputSystem::CInputSystem(const char *systemName) :
@ -1039,8 +1061,8 @@ CInputSource *CInputSystem::ParseSingleSource(string str)
void CInputSystem::PrintKeySettings(int kbdNum, KeySettings *settings) void CInputSystem::PrintKeySettings(int kbdNum, KeySettings *settings)
{ {
printf(" Sensitivity = %d %%\n", settings->sensitivity); printf(" Sensitivity = %u %%\n", settings->sensitivity);
printf(" Decay Speed = %d %%\n", settings->decaySpeed); printf(" Decay Speed = %u %%\n", settings->decaySpeed);
} }
KeySettings *CInputSystem::ReadKeySettings(CINIFile *ini, const char *section, int kbdNum) KeySettings *CInputSystem::ReadKeySettings(CINIFile *ini, const char *section, int kbdNum)
@ -1079,10 +1101,7 @@ void CInputSystem::WriteKeySettings(CINIFile *ini, const char *section, KeySetti
void CInputSystem::PrintMouseSettings(int mseNum, MouseSettings *settings) void CInputSystem::PrintMouseSettings(int mseNum, MouseSettings *settings)
{ {
for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++) for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
{ printf(" %-7s Dead Zone = %u %%\n", s_axisNames[axisNum], settings->deadZones[axisNum]);
const char *axisName = s_axisNames[axisNum];
printf(" %s-Axis Dead Zone = %d %%\n", axisName, settings->deadZones[axisNum]);
}
} }
MouseSettings *CInputSystem::ReadMouseSettings(CINIFile *ini, const char *section, int mseNum) MouseSettings *CInputSystem::ReadMouseSettings(CINIFile *ini, const char *section, int mseNum)
@ -1098,10 +1117,7 @@ MouseSettings *CInputSystem::ReadMouseSettings(CINIFile *ini, const char *sectio
baseKey.append(IntToString(mseNum + 1)); baseKey.append(IntToString(mseNum + 1));
bool read = false; bool read = false;
for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++) for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
{ read |= ini->Get(section, baseKey + s_axisIds[axisNum] + "DeadZone", settings->deadZones[axisNum]) == OKAY;
const char *axisName = s_axisNames[axisNum];
read |= ini->Get(section, baseKey + axisName + "DeadZone", settings->deadZones[axisNum]) == OKAY;
}
if (read) if (read)
return settings; return settings;
delete settings; delete settings;
@ -1119,9 +1135,8 @@ void CInputSystem::WriteMouseSettings(CINIFile *ini, const char *section, MouseS
baseKey.append(IntToString(settings->mseNum + 1)); baseKey.append(IntToString(settings->mseNum + 1));
for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++) for (int axisNum = 0; axisNum < NUM_MOUSE_AXES; axisNum++)
{ {
const char *axisName = s_axisNames[axisNum];
if (settings->deadZones[axisNum] != common->deadZones[axisNum]) if (settings->deadZones[axisNum] != common->deadZones[axisNum])
ini->Set(section, baseKey + axisName + "DeadZone", settings->deadZones[axisNum]); ini->Set(section, baseKey + s_axisIds[axisNum] + "DeadZone", settings->deadZones[axisNum]);
} }
} }
@ -1133,11 +1148,11 @@ void CInputSystem::PrintJoySettings(int joyNum, JoySettings *settings)
if (joyDetails && !joyDetails->hasAxis[axisNum]) if (joyDetails && !joyDetails->hasAxis[axisNum])
continue; continue;
const char *axisName = s_axisNames[axisNum]; const char *axisName = s_axisNames[axisNum];
printf(" %-2s-Axis Min Value = %d\n", axisName, settings->axisMinVals[axisNum]); printf(" %-7s Min Value = %d\n", axisName, settings->axisMinVals[axisNum]);
printf(" %-2s-Axis Center/Off Value = %d\n", axisName, settings->axisOffVals[axisNum]); printf(" %-7s Center/Off Value = %d\n", axisName, settings->axisOffVals[axisNum]);
printf(" %-2s-Axis Max Value = %d\n", axisName, settings->axisMaxVals[axisNum]); printf(" %-7s Max Value = %d\n", axisName, settings->axisMaxVals[axisNum]);
printf(" %-2s-Axis Dead Zone = %d %%\n", axisName, settings->deadZones[axisNum]); printf(" %-7s Dead Zone = %u %%\n", axisName, settings->deadZones[axisNum]);
printf(" %-2s-Axis Saturation = %d %%\n", axisName, settings->saturations[axisNum]); printf(" %-7s Saturation = %u %%\n", axisName, settings->saturations[axisNum]);
} }
} }
@ -1155,12 +1170,12 @@ JoySettings *CInputSystem::ReadJoySettings(CINIFile *ini, const char *section, i
bool read = false; bool read = false;
for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++) for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
{ {
const char *axisName = s_axisNames[axisNum]; const char *axisId = s_axisIds[axisNum];
read |= ini->Get(section, baseKey + axisName + "MinVal", settings->axisMinVals[axisNum]) == OKAY; read |= ini->Get(section, baseKey + axisId + "MinVal", settings->axisMinVals[axisNum]) == OKAY;
read |= ini->Get(section, baseKey + axisName + "OffVal", settings->axisOffVals[axisNum]) == OKAY; read |= ini->Get(section, baseKey + axisId + "OffVal", settings->axisOffVals[axisNum]) == OKAY;
read |= ini->Get(section, baseKey + axisName + "MaxVal", settings->axisMaxVals[axisNum]) == OKAY; read |= ini->Get(section, baseKey + axisId + "MaxVal", settings->axisMaxVals[axisNum]) == OKAY;
read |= ini->Get(section, baseKey + axisName + "DeadZone", settings->deadZones[axisNum]) == OKAY; read |= ini->Get(section, baseKey + axisId + "DeadZone", settings->deadZones[axisNum]) == OKAY;
read |= ini->Get(section, baseKey + axisName + "Saturation", settings->saturations[axisNum]) == OKAY; read |= ini->Get(section, baseKey + axisId + "Saturation", settings->saturations[axisNum]) == OKAY;
} }
if (read) if (read)
return settings; return settings;
@ -1179,17 +1194,17 @@ void CInputSystem::WriteJoySettings(CINIFile *ini, const char *section, JoySetti
baseKey.append(IntToString(settings->joyNum + 1)); baseKey.append(IntToString(settings->joyNum + 1));
for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++) for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
{ {
const char *axisName = s_axisNames[axisNum]; const char *axisId = s_axisIds[axisNum];
if (settings->axisMinVals[axisNum] != common->axisMinVals[axisNum]) if (settings->axisMinVals[axisNum] != common->axisMinVals[axisNum])
ini->Set(section, baseKey + axisName + "MinVal", settings->axisMinVals[axisNum]); ini->Set(section, baseKey + axisId + "MinVal", settings->axisMinVals[axisNum]);
if (settings->axisOffVals[axisNum] != common->axisOffVals[axisNum]) if (settings->axisOffVals[axisNum] != common->axisOffVals[axisNum])
ini->Set(section, baseKey + axisName + "OffVal", settings->axisOffVals[axisNum]); ini->Set(section, baseKey + axisId + "OffVal", settings->axisOffVals[axisNum]);
if (settings->axisMaxVals[axisNum] != common->axisMaxVals[axisNum]) if (settings->axisMaxVals[axisNum] != common->axisMaxVals[axisNum])
ini->Set(section, baseKey + axisName + "MaxVal", settings->axisMaxVals[axisNum]); ini->Set(section, baseKey + axisId + "MaxVal", settings->axisMaxVals[axisNum]);
if (settings->deadZones[axisNum] != common->deadZones[axisNum]) if (settings->deadZones[axisNum] != common->deadZones[axisNum])
ini->Set(section, baseKey + axisName + "DeadZone", settings->deadZones[axisNum]); ini->Set(section, baseKey + axisId + "DeadZone", settings->deadZones[axisNum]);
if (settings->saturations[axisNum] != common->saturations[axisNum]) if (settings->saturations[axisNum] != common->saturations[axisNum])
ini->Set(section, baseKey + axisName + "Saturation", settings->saturations[axisNum]); ini->Set(section, baseKey + axisId + "Saturation", settings->saturations[axisNum]);
} }
} }
@ -1285,7 +1300,7 @@ EMousePart CInputSystem::GetMouseButton(int butNum)
bool CInputSystem::IsAxis(EJoyPart joyPart) bool CInputSystem::IsAxis(EJoyPart joyPart)
{ {
return joyPart >= JoyXAxis && joyPart <= JoyRZAxisNeg; return joyPart >= JoyXAxis && joyPart <= JoyS2AxisNeg;
} }
bool CInputSystem::IsFullAxis(EJoyPart joyPart) bool CInputSystem::IsFullAxis(EJoyPart joyPart)
@ -1293,6 +1308,11 @@ bool CInputSystem::IsFullAxis(EJoyPart joyPart)
return IsAxis(joyPart) && (((joyPart - JoyXAxis) % 4) == AXIS_FULL || ((joyPart - JoyXAxis) % 4) == AXIS_INVERTED); return IsAxis(joyPart) && (((joyPart - JoyXAxis) % 4) == AXIS_FULL || ((joyPart - JoyXAxis) % 4) == AXIS_INVERTED);
} }
bool CInputSystem::IsSliderAxis(EJoyPart joyPart)
{
return joyPart >= JoyS1Axis && joyPart <= JoyS2AxisNeg;
}
bool CInputSystem::GetAxisDetails(EJoyPart joyPart, int &axisNum, int &axisDir) bool CInputSystem::GetAxisDetails(EJoyPart joyPart, int &axisNum, int &axisDir)
{ {
if (!IsAxis(joyPart)) if (!IsAxis(joyPart))
@ -1754,6 +1774,8 @@ void CInputSystem::UngrabMouse()
SetMouseVisibility(true); SetMouseVisibility(true);
} }
#include <SDL.h>
bool CInputSystem::SendForceFeedbackCmd(int joyNum, int axisNum, ForceFeedbackCmd ffCmd) bool CInputSystem::SendForceFeedbackCmd(int joyNum, int axisNum, ForceFeedbackCmd ffCmd)
{ {
const JoyDetails *joyDetails = GetJoyDetails(joyNum); const JoyDetails *joyDetails = GetJoyDetails(joyNum);
@ -1775,10 +1797,13 @@ bool CInputSystem::DetectJoystickAxis(unsigned joyNum, unsigned &axisNum, const
bool cancelled = false; bool cancelled = false;
CInputSource *escape = ParseSource(escapeMapping); CInputSource *escape = ParseSource(escapeMapping);
CInputSource *confirm = ParseSource(confirmMapping); CInputSource *confirm = ParseSource(confirmMapping);
CInputSource *output = ParseSource("KEY_SHIFT");
if (escape) if (escape)
escape->Acquire(); escape->Acquire();
if (confirm) if (confirm)
confirm->Acquire(); confirm->Acquire();
if (output)
output->Acquire();
printf("Move axis around and then press Return (or press Esc to cancel): "); printf("Move axis around and then press Return (or press Esc to cancel): ");
fflush(stdout); // required on terminals that use buffering fflush(stdout); // required on terminals that use buffering
@ -1786,6 +1811,7 @@ bool CInputSystem::DetectJoystickAxis(unsigned joyNum, unsigned &axisNum, const
unsigned maxRange; unsigned maxRange;
unsigned maxAxisNum; unsigned maxAxisNum;
bool firstOut = true;
int minVals[NUM_JOY_AXES]; int minVals[NUM_JOY_AXES];
int maxVals[NUM_JOY_AXES]; int maxVals[NUM_JOY_AXES];
for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++) for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
@ -1836,6 +1862,23 @@ bool CInputSystem::DetectJoystickAxis(unsigned joyNum, unsigned &axisNum, const
maxVals[loopAxisNum] = max<int>(joyVal, maxVals[loopAxisNum]); maxVals[loopAxisNum] = max<int>(joyVal, maxVals[loopAxisNum]);
} }
// Check if output source is triggered, and if so output value for debugging
if (output && output->IsActive())
{
if (firstOut)
puts("");
printf(" [");
for (unsigned loopAxisNum = 0; loopAxisNum < NUM_JOY_AXES; loopAxisNum++)
{
int joyVal = GetJoyAxisValue(joyNum, loopAxisNum);
if (loopAxisNum > 0)
printf(", ");
printf("%s: %d", s_axisIds[loopAxisNum], joyVal);
}
puts("]");
firstOut = false;
}
// Don't poll continuously // Don't poll continuously
Wait(1000/60); Wait(1000/60);
} }
@ -1872,6 +1915,8 @@ Finish:
escape->Release(); escape->Release();
if (confirm) if (confirm)
confirm->Release(); confirm->Release();
if (output)
output->Release();
return !cancelled; return !cancelled;
} }
@ -1920,6 +1965,8 @@ Repeat:
puts(" - for a horizontal joystick axis, push it all the way to the right."); puts(" - for a horizontal joystick axis, push it all the way to the right.");
if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ) if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
puts(" - for a vertical joystick axis, push it all the way downwards."); puts(" - for a vertical joystick axis, push it all the way downwards.");
if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
puts(" - for a joystick slider, push it all the way to its extreme.");
puts(" - for a steering wheel, turn it all the way to the right."); puts(" - for a steering wheel, turn it all the way to the right.");
puts(" - for a pedal, press it all the way to the floor."); puts(" - for a pedal, press it all the way to the floor.");
break; break;
@ -1930,6 +1977,8 @@ Repeat:
puts(" - for a horizontal joystick axis, push it all the way to the left."); puts(" - for a horizontal joystick axis, push it all the way to the left.");
if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ) if (axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
puts(" - for a vertical joystick axis, push it all the way updwards."); puts(" - for a vertical joystick axis, push it all the way updwards.");
if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
puts(" - for a joystick slider, return it to its off position.");
puts(" - for a steering wheel, turn it all the way to the left."); puts(" - for a steering wheel, turn it all the way to the left.");
puts(" - for a pedal, let go of the pedal completely. If there is another pedal"); puts(" - for a pedal, let go of the pedal completely. If there is another pedal");
puts(" that shares the same axis then press that one all the way to the floor."); puts(" that shares the same axis then press that one all the way to the floor.");
@ -1937,7 +1986,10 @@ Repeat:
case 2: case 2:
puts("Step 3:"); puts("Step 3:");
puts(" Return axis to its central/'off' position and hold, ie:"); puts(" Return axis to its central/'off' position and hold, ie:");
puts(" - for a joystick axis, let it return to the middle."); if (axisNum == AXIS_X || axisNum == AXIS_RX || axisNum == AXIS_Y || axisNum == AXIS_RY || axisNum == AXIS_Z || axisNum == AXIS_RZ)
puts(" - for a joystick axis, let it return to the middle.");
else if (axisNum == AXIS_S1 || axisNum == AXIS_S2)
puts(" - for a joystick slider, keep it at its off position.");
puts(" - for a steering weel, turn it back to the center."); puts(" - for a steering weel, turn it back to the center.");
puts(" - for a pedal, let go of pedal completely. Likewise for any other pedal"); puts(" - for a pedal, let go of pedal completely. Likewise for any other pedal");
puts(" that shares the same axis."); puts(" that shares the same axis.");
@ -2046,7 +2098,7 @@ Repeat:
printf(" Min Value = %d\n", negVal); printf(" Min Value = %d\n", negVal);
printf(" Center/Off Value = %d\n", offVal); printf(" Center/Off Value = %d\n", offVal);
printf(" Max Value = %d\n", posVal); printf(" Max Value = %d\n", posVal);
printf(" Dead Zone = %d %%\n", deadZone); printf(" Dead Zone = %u %%\n", deadZone);
printf("\nAccept these settings: y/n? "); printf("\nAccept these settings: y/n? ");
fflush(stdout); // required on terminals that use buffering fflush(stdout); // required on terminals that use buffering

View file

@ -73,7 +73,7 @@ class CINIFile;
#define NUM_MOUSE_AXES 3 #define NUM_MOUSE_AXES 3
#define NUM_MOUSE_BUTTONS 5 #define NUM_MOUSE_BUTTONS 5
#define NUM_JOY_PARTS ((int)JoyButton31 + 1) #define NUM_JOY_PARTS ((int)JoyButton31 + 1)
#define NUM_JOY_AXES 6 #define NUM_JOY_AXES 8
#define NUM_JOY_POVS 4 #define NUM_JOY_POVS 4
#define NUM_JOY_BUTTONS 32 #define NUM_JOY_BUTTONS 32
@ -84,6 +84,8 @@ class CINIFile;
#define AXIS_RX 3 #define AXIS_RX 3
#define AXIS_RY 4 #define AXIS_RY 4
#define AXIS_RZ 5 #define AXIS_RZ 5
#define AXIS_S1 6
#define AXIS_S2 7
// Axis directions // Axis directions
#define AXIS_FULL 0 #define AXIS_FULL 0
@ -152,6 +154,14 @@ enum EJoyPart
JoyRZAxisInv, JoyRZAxisInv,
JoyRZAxisPos, JoyRZAxisPos,
JoyRZAxisNeg, JoyRZAxisNeg,
JoyS1Axis,
JoyS1AxisInv,
JoyS1AxisPos,
JoyS1AxisNeg,
JoyS2Axis,
JoyS2AxisInv,
JoyS2AxisPos,
JoyS2AxisNeg,
JoyPOV0Up, JoyPOV0Up,
JoyPOV0Down, JoyPOV0Down,
JoyPOV0Left, JoyPOV0Left,
@ -322,7 +332,8 @@ private:
// Lookup table for translating joystick mapping strings to their respective joystick parts // Lookup table for translating joystick mapping strings to their respective joystick parts
static JoyPartsStruct s_joyParts[]; static JoyPartsStruct s_joyParts[];
// Names of axes // Ids and names of axes
static const char *s_axisIds[];
static const char *s_axisNames[]; static const char *s_axisNames[];
// Number of keyboards, mice and joysticks // Number of keyboards, mice and joysticks
@ -570,6 +581,11 @@ protected:
*/ */
bool IsFullAxis(EJoyPart joyPart); bool IsFullAxis(EJoyPart joyPart);
/*
* Returns true if the given EJoyPart represents a slider axis, eg JoyS1Axis.
*/
bool IsSliderAxis(EJoyPart joyPart);
/* /*
* Returns true if joystick part represents an axis and sets axisPart and axisDir as follows: * Returns true if joystick part represents an axis and sets axisPart and axisDir as follows:
* axisNum will be the axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ) * axisNum will be the axis number (AXIS_X, AXIS_Y, AXIS_Z, AXIS_RX, AXIS_RY or AXIS_RZ)

View file

@ -217,7 +217,6 @@ void CSDLInputSystem::OpenJoysticks()
joyDetails.axisHasFF[axisNum] = false; // SDL 1.2 does not support force feedback joyDetails.axisHasFF[axisNum] = false; // SDL 1.2 does not support force feedback
char *axisName = joyDetails.axisName[axisNum]; char *axisName = joyDetails.axisName[axisNum];
strcpy(axisName, CInputSystem::GetDefaultAxisName(axisNum)); // SDL 1.2 does not support axis names strcpy(axisName, CInputSystem::GetDefaultAxisName(axisNum)); // SDL 1.2 does not support axis names
strcat(axisName, "-Axis");
} }
joyDetails.numPOVs = SDL_JoystickNumHats(joystick); joyDetails.numPOVs = SDL_JoystickNumHats(joystick);
joyDetails.numButtons = SDL_JoystickNumButtons(joystick); joyDetails.numButtons = SDL_JoystickNumButtons(joystick);

View file

@ -293,8 +293,9 @@ struct DIEnumDevsContext
static BOOL CALLBACK DI8EnumDevicesCallback(LPCDIDEVICEINSTANCE instance, LPVOID context) static BOOL CALLBACK DI8EnumDevicesCallback(LPCDIDEVICEINSTANCE instance, LPVOID context)
{ {
// Keep track of all joystick device GUIDs
DIEnumDevsContext *diDevsContext = (DIEnumDevsContext*)context; DIEnumDevsContext *diDevsContext = (DIEnumDevsContext*)context;
// Keep track of all joystick device GUIDs
DIJoyInfo info; DIJoyInfo info;
memset(&info, 0, sizeof(DIJoyInfo)); memset(&info, 0, sizeof(DIJoyInfo));
info.guid = instance->guidInstance; info.guid = instance->guidInstance;
@ -304,16 +305,22 @@ static BOOL CALLBACK DI8EnumDevicesCallback(LPCDIDEVICEINSTANCE instance, LPVOID
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
struct DIEnumAxesContext struct DIEnumObjsContext
{ {
JoyDetails *joyDetails; JoyDetails *joyDetails;
unsigned sliderCount;
bool enumError; bool enumError;
}; };
static BOOL CALLBACK DI8EnumAxesCallback(LPCDIDEVICEOBJECTINSTANCE instance, LPVOID context) static BOOL CALLBACK DI8EnumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE instance, LPVOID context)
{ {
// Work out which axis is currently being enumerated from the GUID DIEnumObjsContext *diObjsContext = (DIEnumObjsContext*)context;
DIEnumAxesContext *diAxesContext = (DIEnumAxesContext*)context;
// Get data format for object
int objNum = DIDFT_GETINSTANCE(instance->dwType);
DIOBJECTDATAFORMAT fmt = c_dfDIJoystick2.rgodf[objNum];
// Work out which axis or slider is currently being enumerated from the GUID
int axisNum; int axisNum;
if (instance->guidType == GUID_XAxis) axisNum = AXIS_X; if (instance->guidType == GUID_XAxis) axisNum = AXIS_X;
else if (instance->guidType == GUID_YAxis) axisNum = AXIS_Y; else if (instance->guidType == GUID_YAxis) axisNum = AXIS_Y;
@ -321,12 +328,24 @@ static BOOL CALLBACK DI8EnumAxesCallback(LPCDIDEVICEOBJECTINSTANCE instance, LPV
else if (instance->guidType == GUID_RxAxis) axisNum = AXIS_RX; else if (instance->guidType == GUID_RxAxis) axisNum = AXIS_RX;
else if (instance->guidType == GUID_RyAxis) axisNum = AXIS_RY; else if (instance->guidType == GUID_RyAxis) axisNum = AXIS_RY;
else if (instance->guidType == GUID_RzAxis) axisNum = AXIS_RZ; else if (instance->guidType == GUID_RzAxis) axisNum = AXIS_RZ;
else else if (instance->guidType == GUID_Slider)
{ {
// If couldn't match GUID (which, according to MSDN, is an optional attribute), then flag error and try matching using a different method // Work out which slider from count
diAxesContext->enumError = true; switch (diObjsContext->sliderCount++)
{
case 0: axisNum = AXIS_S1; break;
case 1: axisNum = AXIS_S2; break;
default:
// If couldn't match then ignore slider
return DIENUM_CONTINUE;
}
}
else if (instance->dwType & DIDFT_AXIS)
{
// If is an axis but couldn't match GUID above (which, according to MSDN, is an optional attribute), then flag error and try matching via offset
int objNum = DIDFT_GETINSTANCE(instance->dwType); int objNum = DIDFT_GETINSTANCE(instance->dwType);
DIOBJECTDATAFORMAT fmt = c_dfDIJoystick2.rgodf[objNum]; DIOBJECTDATAFORMAT fmt = c_dfDIJoystick2.rgodf[objNum];
diObjsContext->enumError = true;
switch (fmt.dwOfs) switch (fmt.dwOfs)
{ {
case DIJOFS_X: axisNum = AXIS_X; break; case DIJOFS_X: axisNum = AXIS_X; break;
@ -340,11 +359,16 @@ static BOOL CALLBACK DI8EnumAxesCallback(LPCDIDEVICEOBJECTINSTANCE instance, LPV
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
} }
else
{
// Ignore all other types of object
return DIENUM_CONTINUE;
}
// If axis overlaps with a previous ones, flag error // If axis overlaps with a previous one, flag error
JoyDetails *joyDetails = diAxesContext->joyDetails; JoyDetails *joyDetails = diObjsContext->joyDetails;
if (joyDetails->hasAxis[axisNum]) if (joyDetails->hasAxis[axisNum])
diAxesContext->enumError = true; diObjsContext->enumError = true;
// Record fact that axis is present and also whether it has force feedback available // Record fact that axis is present and also whether it has force feedback available
joyDetails->hasAxis[axisNum] = true; joyDetails->hasAxis[axisNum] = true;
@ -353,7 +377,7 @@ static BOOL CALLBACK DI8EnumAxesCallback(LPCDIDEVICEOBJECTINSTANCE instance, LPV
// Get axis name from DirectInput and store that too // Get axis name from DirectInput and store that too
char *axisName = joyDetails->axisName[axisNum]; char *axisName = joyDetails->axisName[axisNum];
strcpy(axisName, CInputSystem::GetDefaultAxisName(axisNum)); strcpy(axisName, CInputSystem::GetDefaultAxisName(axisNum));
strcat(axisName, "-Axis ("); strcat(axisName, " (");
strncat(axisName, instance->tszName, MAX_NAME_LENGTH - strlen(axisName) - 1); strncat(axisName, instance->tszName, MAX_NAME_LENGTH - strlen(axisName) - 1);
strcat(axisName, ")"); strcat(axisName, ")");
@ -1050,12 +1074,16 @@ void CDirectInputSystem::OpenJoysticks()
joyDetails.hasAxis[AXIS_RX] = true; joyDetails.hasAxis[AXIS_RX] = true;
joyDetails.hasAxis[AXIS_RY] = true; joyDetails.hasAxis[AXIS_RY] = true;
joyDetails.hasAxis[AXIS_RZ] = true; joyDetails.hasAxis[AXIS_RZ] = true;
joyDetails.hasAxis[AXIS_S1] = false;
joyDetails.hasAxis[AXIS_S2] = false;
joyDetails.axisHasFF[AXIS_X] = true; // Force feedback simulated on left and right sticks joyDetails.axisHasFF[AXIS_X] = true; // Force feedback simulated on left and right sticks
joyDetails.axisHasFF[AXIS_Y] = true; joyDetails.axisHasFF[AXIS_Y] = true;
joyDetails.axisHasFF[AXIS_Z] = false; joyDetails.axisHasFF[AXIS_Z] = false;
joyDetails.axisHasFF[AXIS_RX] = true; joyDetails.axisHasFF[AXIS_RX] = true;
joyDetails.axisHasFF[AXIS_RY] = true; joyDetails.axisHasFF[AXIS_RY] = true;
joyDetails.axisHasFF[AXIS_RZ] = false; joyDetails.axisHasFF[AXIS_RZ] = false;
joyDetails.axisHasFF[AXIS_S1] = false;
joyDetails.axisHasFF[AXIS_S2] = false;
// Keep track of XInput device number // Keep track of XInput device number
it->xInputNum = xNum++; it->xInputNum = xNum++;
@ -1109,10 +1137,10 @@ void CDirectInputSystem::OpenJoysticks()
joyDetails.numButtons = devCaps.dwButtons; joyDetails.numButtons = devCaps.dwButtons;
// Enumerate axes // Enumerate axes
DIEnumAxesContext diAxesContext; DIEnumObjsContext diObjsContext;
diAxesContext.joyDetails = &joyDetails; memset(&diObjsContext, 0, sizeof(DIEnumObjsContext));
diAxesContext.enumError = false; diObjsContext.joyDetails = &joyDetails;
if (FAILED(hr = joystick->EnumObjects(DI8EnumAxesCallback, &diAxesContext, DIDFT_AXIS))) if (FAILED(hr = joystick->EnumObjects(DI8EnumObjectsCallback, &diObjsContext, DIDFT_ALL)))
{ {
ErrorLog("Unable to enumerate axes of DirectInput joystick %d (error %d) - skipping joystick.\n", joyNum, hr); ErrorLog("Unable to enumerate axes of DirectInput joystick %d (error %d) - skipping joystick.\n", joyNum, hr);
@ -1121,7 +1149,7 @@ void CDirectInputSystem::OpenJoysticks()
} }
// If enumeration failed for some reason then include all possible joystick axes so that no axis is left off due to error // If enumeration failed for some reason then include all possible joystick axes so that no axis is left off due to error
if (diAxesContext.enumError) if (diObjsContext.enumError)
{ {
for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++) for (int axisNum = 0; axisNum < NUM_JOY_AXES; axisNum++)
{ {
@ -1131,7 +1159,6 @@ void CDirectInputSystem::OpenJoysticks()
joyDetails.axisHasFF[axisNum] = false; joyDetails.axisHasFF[axisNum] = false;
char *axisName = joyDetails.axisName[axisNum]; char *axisName = joyDetails.axisName[axisNum];
strcpy(axisName, CInputSystem::GetDefaultAxisName(axisNum)); strcpy(axisName, CInputSystem::GetDefaultAxisName(axisNum));
strcat(axisName, "-Axis");
} }
} }
} }
@ -1379,6 +1406,8 @@ HRESULT CDirectInputSystem::CreateJoystickEffect(LPDIRECTINPUTDEVICE8 joystick,
case AXIS_RX: axisOfs = DIJOFS_RX; break; case AXIS_RX: axisOfs = DIJOFS_RX; break;
case AXIS_RY: axisOfs = DIJOFS_RY; break; case AXIS_RY: axisOfs = DIJOFS_RY; break;
case AXIS_RZ: axisOfs = DIJOFS_RZ; break; case AXIS_RZ: axisOfs = DIJOFS_RZ; break;
case AXIS_S1: axisOfs = DIJOFS_SLIDER(0); break;
case AXIS_S2: axisOfs = DIJOFS_SLIDER(1); break;
default: return E_FAIL; default: return E_FAIL;
} }
@ -1428,7 +1457,7 @@ HRESULT CDirectInputSystem::CreateJoystickEffect(LPDIRECTINPUTDEVICE8 joystick,
dic.lNegativeCoefficient = 0; dic.lNegativeCoefficient = 0;
dic.dwPositiveSaturation = DI_FFNOMINALMAX; dic.dwPositiveSaturation = DI_FFNOMINALMAX;
dic.dwNegativeSaturation = DI_FFNOMINALMAX; dic.dwNegativeSaturation = DI_FFNOMINALMAX;
dic.lDeadBand = (LONG)(0.05 * DI_FFNOMINALMAX); // 5% deadband dic.lDeadBand = (LONG)(0.05 * DI_FFNOMINALMAX); // 5% deadband
eff.cbTypeSpecificParams = sizeof(DICONDITION); eff.cbTypeSpecificParams = sizeof(DICONDITION);
eff.lpvTypeSpecificParams = &dic; eff.lpvTypeSpecificParams = &dic;
@ -1670,6 +1699,8 @@ int CDirectInputSystem::GetJoyAxisValue(int joyNum, int axisNum)
case AXIS_RX: return (int)m_diJoyStates[joyNum].lRx; case AXIS_RX: return (int)m_diJoyStates[joyNum].lRx;
case AXIS_RY: return (int)m_diJoyStates[joyNum].lRy; case AXIS_RY: return (int)m_diJoyStates[joyNum].lRy;
case AXIS_RZ: return (int)m_diJoyStates[joyNum].lRz; case AXIS_RZ: return (int)m_diJoyStates[joyNum].lRz;
case AXIS_S1: return (int)m_diJoyStates[joyNum].rglSlider[0];
case AXIS_S2: return (int)m_diJoyStates[joyNum].rglSlider[1];
default: return 0; default: return 0;
} }
} }
@ -1831,7 +1862,7 @@ bool CDirectInputSystem::ProcessForceFeedbackCmd(int joyNum, int axisNum, ForceF
lFFMag = (LONG)(-ffCmd.force * (float)(g_Config.dInputConstForceLeftMax * DI_EFFECTS_SCALE)); // Invert sign for DirectInput effect lFFMag = (LONG)(-ffCmd.force * (float)(g_Config.dInputConstForceLeftMax * DI_EFFECTS_SCALE)); // Invert sign for DirectInput effect
dicf.lMagnitude = min<LONG>(lFFMag, DI_EFFECTS_MAX); dicf.lMagnitude = min<LONG>(lFFMag, DI_EFFECTS_MAX);
} }
eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
eff.lpvTypeSpecificParams = &dicf; eff.lpvTypeSpecificParams = &dicf;
break; break;