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 =
 | 
			
		||||
{
 | 
			
		||||
	{ 0 }, { false }
 | 
			
		||||
	{ 0 }, { 0 }, { false }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
EventThread::MouseState EventThread::mouseState =
 | 
			
		||||
| 
						 | 
				
			
			@ -274,8 +274,12 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
			
		|||
			joyState.buttons[event.jbutton.button] = false;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SDL_JOYHATMOTION :
 | 
			
		||||
			joyState.hats[event.jhat.hat] = event.jhat.value;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SDL_JOYAXISMOTION :
 | 
			
		||||
			joyState.axis[event.jaxis.axis] = event.jaxis.value;
 | 
			
		||||
			joyState.axes[event.jaxis.axis] = event.jaxis.value;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SDL_JOYDEVICEADDED :
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,8 @@ public:
 | 
			
		|||
 | 
			
		||||
	struct JoyState
 | 
			
		||||
	{
 | 
			
		||||
		int axis[256];
 | 
			
		||||
		int axes[256];
 | 
			
		||||
		uint8_t hats[256];
 | 
			
		||||
		bool buttons[256];
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,7 +133,7 @@ struct JsAxisBinding : public Binding
 | 
			
		|||
 | 
			
		||||
	bool sourceActive() const
 | 
			
		||||
	{
 | 
			
		||||
		int val = EventThread::joyState.axis[source];
 | 
			
		||||
		int val = EventThread::joyState.axes[source];
 | 
			
		||||
 | 
			
		||||
		if (dir == Negative)
 | 
			
		||||
			return val < -JAXIS_THRESHOLD;
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +150,34 @@ struct JsAxisBinding : public Binding
 | 
			
		|||
	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 */
 | 
			
		||||
struct MsBinding : public Binding
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -241,6 +269,7 @@ struct InputPrivate
 | 
			
		|||
	std::vector<KbBinding> kbStatBindings;
 | 
			
		||||
	std::vector<KbBinding> kbBindings;
 | 
			
		||||
	std::vector<JsAxisBinding> jsABindings;
 | 
			
		||||
	std::vector<JsHatBinding> jsHBindings;
 | 
			
		||||
	std::vector<JsButtonBinding> jsBBindings;
 | 
			
		||||
	std::vector<MsBinding> msBindings;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -348,6 +377,7 @@ struct InputPrivate
 | 
			
		|||
	{
 | 
			
		||||
		kbBindings.clear();
 | 
			
		||||
		jsABindings.clear();
 | 
			
		||||
		jsHBindings.clear();
 | 
			
		||||
		jsBBindings.clear();
 | 
			
		||||
 | 
			
		||||
		for (size_t i = 0; i < d.size(); ++i)
 | 
			
		||||
| 
						 | 
				
			
			@ -381,6 +411,16 @@ struct InputPrivate
 | 
			
		|||
 | 
			
		||||
				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 :
 | 
			
		||||
			{
 | 
			
		||||
				JsButtonBinding bind;
 | 
			
		||||
| 
						 | 
				
			
			@ -402,6 +442,7 @@ struct InputPrivate
 | 
			
		|||
 | 
			
		||||
		appendBindings(kbBindings);
 | 
			
		||||
		appendBindings(jsABindings);
 | 
			
		||||
		appendBindings(jsHBindings);
 | 
			
		||||
		appendBindings(jsBBindings);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,6 +129,20 @@ static void addAxisBinding(BDescVec &d, uint8_t axis, AxisDir dir, Input::Button
 | 
			
		|||
	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 d;
 | 
			
		||||
| 
						 | 
				
			
			@ -150,11 +164,16 @@ BDescVec genDefaultBindings(const Config &conf)
 | 
			
		|||
	addAxisBinding(d, 0, Positive, Input::Right);
 | 
			
		||||
	addAxisBinding(d, 1, Negative, Input::Up   );
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define FORMAT_VER 1
 | 
			
		||||
#define FORMAT_VER 2
 | 
			
		||||
 | 
			
		||||
struct Header
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -247,6 +266,10 @@ static bool verifyDesc(const BindingDesc &desc)
 | 
			
		|||
		return src.d.scan < SDL_NUM_SCANCODES;
 | 
			
		||||
	case JButton:
 | 
			
		||||
		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:
 | 
			
		||||
		return src.d.ja.dir == Negative || src.d.ja.dir == Positive;
 | 
			
		||||
	default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@
 | 
			
		|||
#include "input.h"
 | 
			
		||||
 | 
			
		||||
#include <SDL_scancode.h>
 | 
			
		||||
#include <SDL_joystick.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +41,8 @@ enum SourceType
 | 
			
		|||
	Invalid,
 | 
			
		||||
	Key,
 | 
			
		||||
	JButton,
 | 
			
		||||
	JAxis
 | 
			
		||||
	JAxis,
 | 
			
		||||
	JHat
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SourceDesc
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +62,13 @@ struct SourceDesc
 | 
			
		|||
			/* Joystick axis direction */
 | 
			
		||||
			AxisDir dir;
 | 
			
		||||
		} ja;
 | 
			
		||||
		struct
 | 
			
		||||
		{
 | 
			
		||||
			/* Joystick axis index */
 | 
			
		||||
			uint8_t hat;
 | 
			
		||||
			/* Joystick axis direction */
 | 
			
		||||
			uint8_t pos;
 | 
			
		||||
		} jh;
 | 
			
		||||
	} d;
 | 
			
		||||
 | 
			
		||||
	bool operator==(const SourceDesc &o) const
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +86,8 @@ struct SourceDesc
 | 
			
		|||
			return d.jb == o.d.jb;
 | 
			
		||||
		case JAxis:
 | 
			
		||||
			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:
 | 
			
		||||
			assert(!"unreachable");
 | 
			
		||||
			return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,6 +81,7 @@ static elementsN(vButtons);
 | 
			
		|||
std::string sourceDescString(const SourceDesc &src)
 | 
			
		||||
{
 | 
			
		||||
	char buf[128];
 | 
			
		||||
	char pos;
 | 
			
		||||
 | 
			
		||||
	switch (src.type)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +105,32 @@ std::string sourceDescString(const SourceDesc &src)
 | 
			
		|||
		snprintf(buf, sizeof(buf), "JS %d", src.d.jb);
 | 
			
		||||
		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:
 | 
			
		||||
		snprintf(buf, sizeof(buf), "Axis %d%c",
 | 
			
		||||
		         src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+');
 | 
			
		||||
| 
						 | 
				
			
			@ -616,6 +643,21 @@ struct SettingsMenuPrivate
 | 
			
		|||
			desc.d.jb = event.jbutton.button;
 | 
			
		||||
			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:
 | 
			
		||||
		{
 | 
			
		||||
			int v = event.jaxis.value;
 | 
			
		||||
| 
						 | 
				
			
			@ -1011,6 +1053,7 @@ bool SettingsMenu::onEvent(const SDL_Event &event)
 | 
			
		|||
 | 
			
		||||
	case SDL_JOYBUTTONDOWN :
 | 
			
		||||
	case SDL_JOYBUTTONUP :
 | 
			
		||||
	case SDL_JOYHATMOTION :
 | 
			
		||||
	case SDL_JOYAXISMOTION :
 | 
			
		||||
		if (!p->hasFocus)
 | 
			
		||||
			return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -1087,6 +1130,7 @@ bool SettingsMenu::onEvent(const SDL_Event &event)
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
	case SDL_JOYBUTTONDOWN:
 | 
			
		||||
	case SDL_JOYHATMOTION:
 | 
			
		||||
	case SDL_JOYAXISMOTION:
 | 
			
		||||
		if (p->state != AwaitingInput)
 | 
			
		||||
			return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue