Merge pull request #86 from Daverball/controller-fix
Xbox controllers require JoyHat events to be tracked on windows
This commit is contained in:
		
						commit
						02f19c03c9
					
				
					 6 changed files with 130 additions and 6 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					@ -1011,6 +1053,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;
 | 
				
			||||||
| 
						 | 
					@ -1087,6 +1130,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…
	
	Add table
		Add a link
		
	
		Reference in a new issue