Xbox controllers require JoyHat events to be tracked on windows #86
|
@ -38,7 +38,7 @@ uint8_t EventThread::keyStates[] = { false };
|
||||||
|
|
||||||
EventThread::JoyState EventThread::joyState =
|
EventThread::JoyState EventThread::joyState =
|
||||||
{
|
{
|
||||||
{ 0 }, { false }
|
{ 0 }, { 0 }, { false }
|
||||||
};
|
};
|
||||||
|
|
||||||
EventThread::MouseState EventThread::mouseState =
|
EventThread::MouseState EventThread::mouseState =
|
||||||
|
@ -274,8 +274,12 @@ void EventThread::process(RGSSThreadData &rtData)
|
||||||
joyState.buttons[event.jbutton.button] = false;
|
joyState.buttons[event.jbutton.button] = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_JOYHATMOTION :
|
||||||
|
joyState.hats[event.jhat.hat] = event.jhat.value;
|
||||||
|
break;
|
||||||
|
|
||||||
case SDL_JOYAXISMOTION :
|
case SDL_JOYAXISMOTION :
|
||||||
joyState.axis[event.jaxis.axis] = event.jaxis.value;
|
joyState.axes[event.jaxis.axis] = event.jaxis.value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_JOYDEVICEADDED :
|
case SDL_JOYDEVICEADDED :
|
||||||
|
|
|
@ -46,7 +46,8 @@ public:
|
||||||
|
|
||||||
struct JoyState
|
struct JoyState
|
||||||
{
|
{
|
||||||
int axis[256];
|
int axes[256];
|
||||||
|
uint8_t hats[256];
|
||||||
bool buttons[256];
|
bool buttons[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ struct JsAxisBinding : public Binding
|
||||||
|
|
||||||
bool sourceActive() const
|
bool sourceActive() const
|
||||||
{
|
{
|
||||||
int val = EventThread::joyState.axis[source];
|
int val = EventThread::joyState.axes[source];
|
||||||
|
|
||||||
if (dir == Negative)
|
if (dir == Negative)
|
||||||
return val < -JAXIS_THRESHOLD;
|
return val < -JAXIS_THRESHOLD;
|
||||||
|
@ -150,6 +150,34 @@ struct JsAxisBinding : public Binding
|
||||||
AxisDir dir;
|
AxisDir dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Joystick hat binding */
|
||||||
|
struct JsHatBinding : public Binding
|
||||||
|
{
|
||||||
|
JsHatBinding() {}
|
||||||
|
|
||||||
|
JsHatBinding(uint8_t source,
|
||||||
|
uint8_t pos,
|
||||||
|
Input::ButtonCode target)
|
||||||
|
: Binding(target),
|
||||||
|
source(source),
|
||||||
|
pos(pos)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool sourceActive() const
|
||||||
|
{
|
||||||
|
/* For a diagonal input accept it as an input for both the axes */
|
||||||
|
return (pos & EventThread::joyState.hats[source]) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sourceRepeatable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t source;
|
||||||
|
uint8_t pos;
|
||||||
|
};
|
||||||
|
|
||||||
/* Mouse button binding */
|
/* Mouse button binding */
|
||||||
struct MsBinding : public Binding
|
struct MsBinding : public Binding
|
||||||
{
|
{
|
||||||
|
@ -241,6 +269,7 @@ struct InputPrivate
|
||||||
std::vector<KbBinding> kbStatBindings;
|
std::vector<KbBinding> kbStatBindings;
|
||||||
std::vector<KbBinding> kbBindings;
|
std::vector<KbBinding> kbBindings;
|
||||||
std::vector<JsAxisBinding> jsABindings;
|
std::vector<JsAxisBinding> jsABindings;
|
||||||
|
std::vector<JsHatBinding> jsHBindings;
|
||||||
std::vector<JsButtonBinding> jsBBindings;
|
std::vector<JsButtonBinding> jsBBindings;
|
||||||
std::vector<MsBinding> msBindings;
|
std::vector<MsBinding> msBindings;
|
||||||
|
|
||||||
|
@ -348,6 +377,7 @@ struct InputPrivate
|
||||||
{
|
{
|
||||||
kbBindings.clear();
|
kbBindings.clear();
|
||||||
jsABindings.clear();
|
jsABindings.clear();
|
||||||
|
jsHBindings.clear();
|
||||||
jsBBindings.clear();
|
jsBBindings.clear();
|
||||||
|
|
||||||
for (size_t i = 0; i < d.size(); ++i)
|
for (size_t i = 0; i < d.size(); ++i)
|
||||||
|
@ -381,6 +411,16 @@ struct InputPrivate
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case JHat :
|
||||||
|
{
|
||||||
|
JsHatBinding bind;
|
||||||
|
bind.source = src.d.jh.hat;
|
||||||
|
bind.pos = src.d.jh.pos;
|
||||||
|
bind.target = desc.target;
|
||||||
|
jsHBindings.push_back(bind);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case JButton :
|
case JButton :
|
||||||
{
|
{
|
||||||
JsButtonBinding bind;
|
JsButtonBinding bind;
|
||||||
|
@ -402,6 +442,7 @@ struct InputPrivate
|
||||||
|
|
||||||
appendBindings(kbBindings);
|
appendBindings(kbBindings);
|
||||||
appendBindings(jsABindings);
|
appendBindings(jsABindings);
|
||||||
|
appendBindings(jsHBindings);
|
||||||
appendBindings(jsBBindings);
|
appendBindings(jsBBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,20 @@ static void addAxisBinding(BDescVec &d, uint8_t axis, AxisDir dir, Input::Button
|
||||||
d.push_back(desc);
|
d.push_back(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void addHatBinding(BDescVec &d, uint8_t hat, uint8_t pos, Input::ButtonCode target)
|
||||||
|
{
|
||||||
|
SourceDesc src;
|
||||||
|
src.type = JHat;
|
||||||
|
src.d.jh.hat = hat;
|
||||||
|
src.d.jh.pos = pos;
|
||||||
|
|
||||||
|
BindingDesc desc;
|
||||||
|
desc.src = src;
|
||||||
|
desc.target = target;
|
||||||
|
|
||||||
|
d.push_back(desc);
|
||||||
|
}
|
||||||
|
|
||||||
BDescVec genDefaultBindings(const Config &conf)
|
BDescVec genDefaultBindings(const Config &conf)
|
||||||
{
|
{
|
||||||
BDescVec d;
|
BDescVec d;
|
||||||
|
@ -150,11 +164,16 @@ BDescVec genDefaultBindings(const Config &conf)
|
||||||
addAxisBinding(d, 0, Positive, Input::Right);
|
addAxisBinding(d, 0, Positive, Input::Right);
|
||||||
addAxisBinding(d, 1, Negative, Input::Up );
|
addAxisBinding(d, 1, Negative, Input::Up );
|
||||||
addAxisBinding(d, 1, Positive, Input::Down );
|
addAxisBinding(d, 1, Positive, Input::Down );
|
||||||
|
|
||||||
|
addHatBinding(d, 0, SDL_HAT_LEFT, Input::Left );
|
||||||
|
addHatBinding(d, 0, SDL_HAT_RIGHT, Input::Right);
|
||||||
|
addHatBinding(d, 0, SDL_HAT_UP, Input::Up );
|
||||||
|
addHatBinding(d, 0, SDL_HAT_DOWN, Input::Down );
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FORMAT_VER 1
|
#define FORMAT_VER 2
|
||||||
|
|
||||||
struct Header
|
struct Header
|
||||||
{
|
{
|
||||||
|
@ -247,6 +266,10 @@ static bool verifyDesc(const BindingDesc &desc)
|
||||||
return src.d.scan < SDL_NUM_SCANCODES;
|
return src.d.scan < SDL_NUM_SCANCODES;
|
||||||
case JButton:
|
case JButton:
|
||||||
return true;
|
return true;
|
||||||
|
case JHat:
|
||||||
|
/* Only accept single directional binds */
|
||||||
|
return src.d.jh.pos == SDL_HAT_LEFT || src.d.jh.pos == SDL_HAT_RIGHT ||
|
||||||
|
src.d.jh.pos == SDL_HAT_UP || src.d.jh.pos == SDL_HAT_DOWN;
|
||||||
case JAxis:
|
case JAxis:
|
||||||
return src.d.ja.dir == Negative || src.d.ja.dir == Positive;
|
return src.d.ja.dir == Negative || src.d.ja.dir == Positive;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
#include <SDL_scancode.h>
|
#include <SDL_scancode.h>
|
||||||
|
#include <SDL_joystick.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -40,7 +41,8 @@ enum SourceType
|
||||||
Invalid,
|
Invalid,
|
||||||
Key,
|
Key,
|
||||||
JButton,
|
JButton,
|
||||||
JAxis
|
JAxis,
|
||||||
|
JHat
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SourceDesc
|
struct SourceDesc
|
||||||
|
@ -60,6 +62,13 @@ struct SourceDesc
|
||||||
/* Joystick axis direction */
|
/* Joystick axis direction */
|
||||||
AxisDir dir;
|
AxisDir dir;
|
||||||
} ja;
|
} ja;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/* Joystick axis index */
|
||||||
|
uint8_t hat;
|
||||||
|
/* Joystick axis direction */
|
||||||
|
uint8_t pos;
|
||||||
|
} jh;
|
||||||
} d;
|
} d;
|
||||||
|
|
||||||
bool operator==(const SourceDesc &o) const
|
bool operator==(const SourceDesc &o) const
|
||||||
|
@ -77,6 +86,8 @@ struct SourceDesc
|
||||||
return d.jb == o.d.jb;
|
return d.jb == o.d.jb;
|
||||||
case JAxis:
|
case JAxis:
|
||||||
return (d.ja.axis == o.d.ja.axis) && (d.ja.dir == o.d.ja.dir);
|
return (d.ja.axis == o.d.ja.axis) && (d.ja.dir == o.d.ja.dir);
|
||||||
|
case JHat:
|
||||||
|
return (d.jh.hat == o.d.jh.hat) && (d.jh.pos == o.d.jh.pos);
|
||||||
default:
|
default:
|
||||||
assert(!"unreachable");
|
assert(!"unreachable");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -81,6 +81,7 @@ static elementsN(vButtons);
|
||||||
std::string sourceDescString(const SourceDesc &src)
|
std::string sourceDescString(const SourceDesc &src)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
char pos;
|
||||||
|
|
||||||
switch (src.type)
|
switch (src.type)
|
||||||
{
|
{
|
||||||
|
@ -104,6 +105,32 @@ std::string sourceDescString(const SourceDesc &src)
|
||||||
snprintf(buf, sizeof(buf), "JS %d", src.d.jb);
|
snprintf(buf, sizeof(buf), "JS %d", src.d.jb);
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
|
case JHat:
|
||||||
|
switch(src.d.jh.pos)
|
||||||
|
{
|
||||||
|
case SDL_HAT_UP:
|
||||||
|
pos = 'U';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_HAT_DOWN:
|
||||||
|
pos = 'D';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_HAT_LEFT:
|
||||||
|
pos = 'L';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_HAT_RIGHT:
|
||||||
|
pos = 'R';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pos = '-';
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "Hat %d:%c",
|
||||||
|
src.d.jh.hat, pos);
|
||||||
|
return buf;
|
||||||
|
|
||||||
case JAxis:
|
case JAxis:
|
||||||
snprintf(buf, sizeof(buf), "Axis %d%c",
|
snprintf(buf, sizeof(buf), "Axis %d%c",
|
||||||
src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+');
|
src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+');
|
||||||
|
@ -616,6 +643,21 @@ struct SettingsMenuPrivate
|
||||||
desc.d.jb = event.jbutton.button;
|
desc.d.jb = event.jbutton.button;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_JOYHATMOTION:
|
||||||
|
{
|
||||||
|
int v = event.jhat.value;
|
||||||
|
|
||||||
|
/* Only register if single directional input */
|
||||||
|
if (v != SDL_HAT_LEFT && v != SDL_HAT_RIGHT &&
|
||||||
|
v != SDL_HAT_UP && v != SDL_HAT_DOWN)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
desc.type = JHat;
|
||||||
|
desc.d.jh.hat = event.jhat.hat;
|
||||||
|
desc.d.jh.pos = v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_JOYAXISMOTION:
|
||||||
{
|
{
|
||||||
int v = event.jaxis.value;
|
int v = event.jaxis.value;
|
||||||
|
@ -1008,6 +1050,7 @@ bool SettingsMenu::onEvent(const SDL_Event &event)
|
||||||
|
|
||||||
case SDL_JOYBUTTONDOWN :
|
case SDL_JOYBUTTONDOWN :
|
||||||
case SDL_JOYBUTTONUP :
|
case SDL_JOYBUTTONUP :
|
||||||
|
case SDL_JOYHATMOTION :
|
||||||
case SDL_JOYAXISMOTION :
|
case SDL_JOYAXISMOTION :
|
||||||
if (!p->hasFocus)
|
if (!p->hasFocus)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1084,6 +1127,7 @@ bool SettingsMenu::onEvent(const SDL_Event &event)
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_JOYBUTTONDOWN:
|
||||||
|
case SDL_JOYHATMOTION:
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_JOYAXISMOTION:
|
||||||
if (p->state != AwaitingInput)
|
if (p->state != AwaitingInput)
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue