- Added joystick axis -> button mapping.

SVN r1683 (trunk)
This commit is contained in:
Randy Heit 2009-06-27 00:35:41 +00:00
parent 7ccca5733f
commit 5dc5a56a17
4 changed files with 95 additions and 41 deletions

View File

@ -1,4 +1,7 @@
June 26, 2009 (Changes by Graf Zahl) June 26, 2009
- Added joystick axis -> button mapping.
June 26, 2009 (Changes by Graf Zahl)
- Added Gez's actor replacement per skill submission. - Added Gez's actor replacement per skill submission.
June 25, 2009 June 25, 2009

View File

@ -246,6 +246,11 @@ const char *KeyNames[NUM_KEYS] =
"mwheelup", "mwheeldown", // the mouse wheel "mwheelup", "mwheeldown", // the mouse wheel
"mwheelright", "mwheelleft", "mwheelright", "mwheelleft",
"axis1plus","axis1minus","axis2plus","axis2minus", // joystick axes as buttons
"axis3plus","axis3minus","axis4plus","axis4minus",
"axis5plus","axis5minus","axis6plus","axis6minus",
"axis7plus","axis7minus","axis8plus","axis8minus",
}; };
static FString Bindings[NUM_KEYS]; static FString Bindings[NUM_KEYS];

View File

@ -102,7 +102,7 @@ enum ESkillLevels
// //
// DOOM keyboard definition. Everything below 0x100 matches // DOOM keyboard definition. Everything below 0x100 matches
// a DirectInput key code. // a mode 1 keyboard scan code.
// //
#define KEY_PAUSE 0xc5 // DIK_PAUSE #define KEY_PAUSE 0xc5 // DIK_PAUSE
#define KEY_RIGHTARROW 0xcd // DIK_RIGHT #define KEY_RIGHTARROW 0xcd // DIK_RIGHT
@ -170,7 +170,25 @@ enum ESkillLevels
#define KEY_MWHEELRIGHT 0x19A #define KEY_MWHEELRIGHT 0x19A
#define KEY_MWHEELLEFT 0x19B #define KEY_MWHEELLEFT 0x19B
#define NUM_KEYS 0x19C #define KEY_JOYAXIS1PLUS 0x19C
#define KEY_JOYAXIS1MINUS 0x19D
#define KEY_JOYAXIS2PLUS 0x19E
#define KEY_JOYAXIS2MINUS 0x19F
#define KEY_JOYAXIS3PLUS 0x1A0
#define KEY_JOYAXIS3MINUS 0x1A1
#define KEY_JOYAXIS4PLUS 0x1A2
#define KEY_JOYAXIS4MINUS 0x1A3
#define KEY_JOYAXIS5PLUS 0x1A4
#define KEY_JOYAXIS5MINUS 0x1A5
#define KEY_JOYAXIS6PLUS 0x1A6
#define KEY_JOYAXIS6MINUS 0x1A7
#define KEY_JOYAXIS7PLUS 0x1A8
#define KEY_JOYAXIS7MINUS 0x1A9
#define KEY_JOYAXIS8PLUS 0x1AA
#define KEY_JOYAXIS8MINUS 0x1AB
#define NUM_JOYAXISBUTTONS 8
#define NUM_KEYS 0x1AC
enum EJoyAxis enum EJoyAxis
{ {

View File

@ -118,6 +118,8 @@ public:
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
#define DEFAULT_DEADZONE 0.25f
// TYPES ------------------------------------------------------------------- // TYPES -------------------------------------------------------------------
class FDInputJoystick : public FInputDevice, IJoystickConfig class FDInputJoystick : public FInputDevice, IJoystickConfig
@ -157,10 +159,11 @@ protected:
DWORD Type; DWORD Type;
DWORD Ofs; DWORD Ofs;
LONG Min, Max; LONG Min, Max;
LONG Value; float Value;
float DeadZone; float DeadZone;
float Multiplier; float Multiplier;
EJoyAxis GameAxis; EJoyAxis GameAxis;
BYTE ButtonValue;
}; };
struct ButtonInfo struct ButtonInfo
{ {
@ -189,6 +192,7 @@ protected:
bool ReorderAxisPair(const GUID &x, const GUID &y, int pos); bool ReorderAxisPair(const GUID &x, const GUID &y, int pos);
HRESULT SetDataFormat(); HRESULT SetDataFormat();
bool SetConfigSection(bool create); bool SetConfigSection(bool create);
void GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
friend class FDInputJoystickManager; friend class FDInputJoystickManager;
}; };
@ -369,11 +373,42 @@ void FDInputJoystick::ProcessInput()
return; return;
} }
// Copy axis values. They will be returned in a separate call. // Convert axis values to floating point and save them for a later call
// to AddAxes(). Axes that are past their dead zone will also be translated
// into button presses.
for (i = 0; i < Axes.Size(); ++i) for (i = 0; i < Axes.Size(); ++i)
{ {
AxisInfo *info = &Axes[i]; AxisInfo *info = &Axes[i];
info->Value = *(LONG *)(state + info->Ofs); LONG value = *(LONG *)(state + info->Ofs);
double deadzone = info->DeadZone;
double axisval;
BYTE buttonstate;
// Scale to [-1.0, 1.0]
axisval = (value - info->Min) * 2.0 / (info->Max - info->Min) - 1.0;
// Cancel out dead zone
if (fabs(axisval) < deadzone)
{
axisval = 0;
buttonstate = 0;
}
// Make the dead zone the new 0
else if (axisval < 0)
{
axisval = (axisval + deadzone) / (1.0 - deadzone);
buttonstate = 2; // button minus
}
else
{
axisval = (axisval - deadzone) / (1.0 - deadzone);
buttonstate = 1; // button plus
}
info->Value = float(axisval);
if (i < NUM_JOYAXISBUTTONS)
{
GenerateButtonEvents(info->ButtonValue, buttonstate, 2, KEY_JOYAXIS1PLUS + i*2);
}
info->ButtonValue = buttonstate;
} }
// Compare button states and generate events for buttons that have changed. // Compare button states and generate events for buttons that have changed.
@ -397,7 +432,7 @@ void FDInputJoystick::ProcessInput()
{ {
ButtonInfo *info = &POVs[i]; ButtonInfo *info = &POVs[i];
DWORD povangle = *(DWORD *)(state + info->Ofs); DWORD povangle = *(DWORD *)(state + info->Ofs);
int pov, changed; int pov;
// Smoosh POV angles down into octants. 8 is centered. // Smoosh POV angles down into octants. 8 is centered.
pov = (LOWORD(povangle) == 0xFFFF) ? 8 : ((povangle + 2250) % 36000) / 4500; pov = (LOWORD(povangle) == 0xFFFF) ? 8 : ((povangle + 2250) % 36000) / 4500;
@ -406,20 +441,31 @@ void FDInputJoystick::ProcessInput()
pov = POVButtons[pov]; pov = POVButtons[pov];
// Send events for POV "buttons" that have changed. // Send events for POV "buttons" that have changed.
changed = pov ^ info->Value; GenerateButtonEvents(info->Value, pov, 4, KEY_JOYPOV1_UP + i*4);
if (changed != 0) info->Value = pov;
}
}
//===========================================================================
//
// FDInputJoystick :: GenerateButtonEvents
//
//===========================================================================
void FDInputJoystick::GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base)
{
int changed = oldbuttons ^ newbuttons;
if (changed != 0)
{
event_t ev = { 0 };
int mask = 1;
for (int j = 0; j < 4; mask <<= 1, ++j)
{ {
int j, mask; if (changed & mask)
info->Value = pov;
mask = 1;
for (j = 0; j < 4; mask <<= 1, ++j)
{ {
if (changed & mask) ev.data1 = base + j;
{ ev.type = (newbuttons & mask) ? EV_KeyDown : EV_KeyUp;
ev.data1 = KEY_JOYPOV1_UP + i*4 + j; D_PostEvent(&ev);
ev.type = (pov & mask) ? EV_KeyDown : EV_KeyUp;
D_PostEvent(&ev);
}
} }
} }
} }
@ -443,27 +489,8 @@ void FDInputJoystick::AddAxes(float axes[NUM_JOYAXIS])
for (unsigned i = 0; i < Axes.Size(); ++i) for (unsigned i = 0; i < Axes.Size(); ++i)
{ {
double axisval = Axes[i].Value;
float deadzone = Axes[i].DeadZone;
// Scale to [-1.0, 1.0]
axisval = (Axes[i].Value - Axes[i].Min) * 2.0 / (Axes[i].Max - Axes[i].Min) - 1.0;
// Cancel out dead zone
if (fabs(axisval) < deadzone)
{
continue;
}
// Make the dead zone the new 0
if (axisval < 0)
{
axisval = (axisval + deadzone) / (1.0 - deadzone);
}
else
{
axisval = (axisval - deadzone) / (1.0 - deadzone);
}
// Add to the game axis. // Add to the game axis.
axes[Axes[i].GameAxis] -= float(axisval * mul * Axes[i].Multiplier); axes[Axes[i].GameAxis] -= float(Axes[i].Value * mul * Axes[i].Multiplier);
} }
} }
@ -540,7 +567,8 @@ BOOL CALLBACK FDInputJoystick::EnumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpd
info.Min = diprg.lMin; info.Min = diprg.lMin;
info.Max = diprg.lMax; info.Max = diprg.lMax;
info.GameAxis = JOYAXIS_None; info.GameAxis = JOYAXIS_None;
info.Value = (diprg.lMin + diprg.lMax) / 2; info.Value = 0;
info.ButtonValue = 0;
joy->Axes.Push(info); joy->Axes.Push(info);
} }
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
@ -808,7 +836,7 @@ void FDInputJoystick::SetDefaultConfig()
Multiplier = 1; Multiplier = 1;
for (unsigned i = 0; i < Axes.Size(); ++i) for (unsigned i = 0; i < Axes.Size(); ++i)
{ {
Axes[i].DeadZone = 0.25f; Axes[i].DeadZone = DEFAULT_DEADZONE;
Axes[i].Multiplier = 1; Axes[i].Multiplier = 1;
} }
// Triggers on a 360 controller have a much smaller deadzone. // Triggers on a 360 controller have a much smaller deadzone.