| 
									
										
										
										
											2014-02-10 13:54:46 -05:00
										 |  |  | // Copyright 2014 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2013-06-16 20:07:10 -04:00
										 |  |  | #include <map>
 | 
					
						
							|  |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "Common/StringUtil.h"
 | 
					
						
							|  |  |  | #include "InputCommon/ControllerInterface/SDL/SDL.h"
 | 
					
						
							| 
									
										
										
										
											2013-06-16 20:07:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | #pragma comment(lib, "SDL2.lib")
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace ciface | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | namespace SDL | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 14:29:26 +02:00
										 |  |  | static std::string GetJoystickName(int index) | 
					
						
							| 
									
										
										
										
											2013-02-05 21:07:09 -06:00
										 |  |  | { | 
					
						
							|  |  |  | #if SDL_VERSION_ATLEAST(2, 0, 0)
 | 
					
						
							|  |  |  | 	return SDL_JoystickNameForIndex(index); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	return SDL_JoystickName(index); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-16 20:07:10 -04:00
										 |  |  | void Init( std::vector<Core::Device*>& devices ) | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-06 03:52:11 +00:00
										 |  |  | 	// this is used to number the joysticks
 | 
					
						
							|  |  |  | 	// multiple joysticks with the same name shall get unique ids starting at 0
 | 
					
						
							| 
									
										
										
										
											2014-02-16 23:51:41 -05:00
										 |  |  | 	std::map<std::string, int> name_counts; | 
					
						
							| 
									
										
										
										
											2010-06-06 03:52:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (SDL_Init( SDL_INIT_FLAGS ) >= 0) | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		// joysticks
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		for (int i = 0; i < SDL_NumJoysticks(); ++i) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2010-06-06 03:52:11 +00:00
										 |  |  | 			SDL_Joystick* dev = SDL_JoystickOpen(i); | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 			if (dev) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-02-05 21:07:09 -06:00
										 |  |  | 				Joystick* js = new Joystick(dev, i, name_counts[GetJoystickName(i)]++); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 				// only add if it has some inputs/outputs
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 				if (js->Inputs().size() || js->Outputs().size()) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 					devices.push_back( js ); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					delete js; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-06 03:52:11 +00:00
										 |  |  | Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsigned int index) | 
					
						
							|  |  |  | 	: m_joystick(joystick) | 
					
						
							|  |  |  | 	, m_sdl_index(sdl_index) | 
					
						
							|  |  |  | 	, m_index(index) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-06 03:52:11 +00:00
										 |  |  | 	// really bad HACKS:
 | 
					
						
							|  |  |  | 	// to not use SDL for an XInput device
 | 
					
						
							|  |  |  | 	// too many people on the forums pick the SDL device and ask:
 | 
					
						
							|  |  |  | 	// "why don't my 360 gamepad triggers/rumble work correctly"
 | 
					
						
							| 
									
										
										
										
											2010-06-06 06:28:18 +00:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | 	// checking the name is probably good (and hacky) enough
 | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	// but I'll double check with the num of buttons/axes
 | 
					
						
							| 
									
										
										
										
											2010-06-06 06:28:18 +00:00
										 |  |  | 	std::string lcasename = GetName(); | 
					
						
							|  |  |  | 	std::transform(lcasename.begin(), lcasename.end(), lcasename.begin(), tolower); | 
					
						
							| 
									
										
										
										
											2010-06-06 03:52:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if ((std::string::npos != lcasename.find("xbox 360")) && | 
					
						
							|  |  |  | 	    (10 == SDL_JoystickNumButtons(joystick)) && | 
					
						
							|  |  |  | 	    (5 == SDL_JoystickNumAxes(joystick)) && | 
					
						
							|  |  |  | 	    (1 == SDL_JoystickNumHats(joystick)) && | 
					
						
							|  |  |  | 	    (0 == SDL_JoystickNumBalls(joystick))) | 
					
						
							| 
									
										
										
										
											2010-06-06 06:28:18 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// this device won't be used
 | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-06-06 03:52:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-15 23:02:17 -05:00
										 |  |  | 	if (SDL_JoystickNumButtons(joystick) > 255 || | 
					
						
							|  |  |  | 	    SDL_JoystickNumAxes(joystick) > 255 || | 
					
						
							|  |  |  | 	    SDL_JoystickNumHats(joystick) > 255 || | 
					
						
							|  |  |  | 	    SDL_JoystickNumBalls(joystick) > 255) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// This device is invalid, don't use it
 | 
					
						
							|  |  |  | 		// Some crazy devices(HP webcam 2100) end up as HID devices
 | 
					
						
							|  |  |  | 		// SDL tries parsing these as joysticks
 | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	// get buttons
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	for (u8 i = 0; i != SDL_JoystickNumButtons(m_joystick); ++i) | 
					
						
							|  |  |  | 		AddInput(new Button(i, m_joystick)); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	// get hats
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	for (u8 i = 0; i != SDL_JoystickNumHats(m_joystick); ++i) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// each hat gets 4 input instances associated with it, (up down left right)
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 		for (u8 d = 0; d != 4; ++d) | 
					
						
							|  |  |  | 			AddInput(new Hat(i, m_joystick, d)); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// get axes
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	for (u8 i = 0; i != SDL_JoystickNumAxes(m_joystick); ++i) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// each axis gets a negative and a positive input instance associated with it
 | 
					
						
							| 
									
										
										
										
											2013-01-17 15:41:18 -06:00
										 |  |  | 		AddAnalogInputs(new Axis(i, m_joystick, -32768), | 
					
						
							|  |  |  | 			new Axis(i, m_joystick, 32767)); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_SDL_HAPTIC
 | 
					
						
							|  |  |  | 	// try to get supported ff effects
 | 
					
						
							|  |  |  | 	m_haptic = SDL_HapticOpenFromJoystick( m_joystick ); | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 	if (m_haptic) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		//SDL_HapticSetGain( m_haptic, 1000 );
 | 
					
						
							|  |  |  | 		//SDL_HapticSetAutocenter( m_haptic, 0 );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const unsigned int supported_effects = SDL_HapticQuery( m_haptic ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// constant effect
 | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 		if (supported_effects & SDL_HAPTIC_CONSTANT) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 			m_state_out.push_back(EffectIDState()); | 
					
						
							|  |  |  | 			AddOutput(new ConstantEffect(m_state_out.back())); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// ramp effect
 | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 		if (supported_effects & SDL_HAPTIC_RAMP) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 			m_state_out.push_back(EffectIDState()); | 
					
						
							|  |  |  | 			AddOutput(new RampEffect(m_state_out.back())); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// sine effect
 | 
					
						
							|  |  |  | 		if (supported_effects & SDL_HAPTIC_SINE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_state_out.push_back(EffectIDState()); | 
					
						
							|  |  |  | 			AddOutput(new SineEffect(m_state_out.back())); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-15 22:18:40 +02:00
										 |  |  | #ifdef SDL_HAPTIC_SQUARE
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 		// square effect
 | 
					
						
							|  |  |  | 		if (supported_effects & SDL_HAPTIC_SQUARE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_state_out.push_back(EffectIDState()); | 
					
						
							|  |  |  | 			AddOutput(new SquareEffect(m_state_out.back())); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-08-15 22:18:40 +02:00
										 |  |  | #endif // defined(SDL_HAPTIC_SQUARE)
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// triangle effect
 | 
					
						
							|  |  |  | 		if (supported_effects & SDL_HAPTIC_TRIANGLE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_state_out.push_back(EffectIDState()); | 
					
						
							|  |  |  | 			AddOutput(new TriangleEffect(m_state_out.back())); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Joystick::~Joystick() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef USE_SDL_HAPTIC
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	if (m_haptic) | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		// stop/destroy all effects
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 		SDL_HapticStopAll(m_haptic); | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 		for (auto &i : m_state_out) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (i.id != -1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				SDL_HapticDestroyEffect(m_haptic, i.id); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		// close haptic first
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 		SDL_HapticClose(m_haptic); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// close joystick
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	SDL_JoystickClose(m_joystick); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_SDL_HAPTIC
 | 
					
						
							|  |  |  | std::string Joystick::ConstantEffect::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "Constant"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string Joystick::RampEffect::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "Ramp"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | std::string Joystick::SineEffect::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "Sine"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-15 22:18:40 +02:00
										 |  |  | #ifdef SDL_HAPTIC_SQUARE
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | std::string Joystick::SquareEffect::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "Square"; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-08-15 22:18:40 +02:00
										 |  |  | #endif // defined(SDL_HAPTIC_SQUARE)
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | std::string Joystick::TriangleEffect::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "Triangle"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | void Joystick::ConstantEffect::SetState(ControlState state) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	if (state) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 		m_effect.effect.type = SDL_HAPTIC_CONSTANT; | 
					
						
							|  |  |  | 		m_effect.effect.constant.length = SDL_HAPTIC_INFINITY; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 		m_effect.effect.type = 0; | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 	const Sint16 old = m_effect.effect.constant.level; | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 	m_effect.effect.constant.level = (Sint16)(state * 0x7FFF); | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 	if (old != m_effect.effect.constant.level) | 
					
						
							|  |  |  | 		m_effect.changed = true; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | void Joystick::RampEffect::SetState(ControlState state) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	if (state) | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 		m_effect.effect.type = SDL_HAPTIC_RAMP; | 
					
						
							|  |  |  | 		m_effect.effect.ramp.length = SDL_HAPTIC_INFINITY; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 		m_effect.effect.type = 0; | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 	const Sint16 old = m_effect.effect.ramp.start; | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 	m_effect.effect.ramp.start = (Sint16)(state * 0x7FFF); | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 	if (old != m_effect.effect.ramp.start) | 
					
						
							|  |  |  | 		m_effect.changed = true; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | void Joystick::SineEffect::SetState(ControlState state) | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (state) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_effect.effect.type = SDL_HAPTIC_SINE; | 
					
						
							|  |  |  | 		m_effect.effect.periodic.length = 250; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 		m_effect.effect.type = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const Sint16 old = m_effect.effect.periodic.magnitude; | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	m_effect.effect.periodic.period = 5; | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 	m_effect.effect.periodic.magnitude = (Sint16)(state * 0x5000); | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	m_effect.effect.periodic.attack_length = 0; | 
					
						
							|  |  |  | 	m_effect.effect.periodic.fade_length = 500; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 	if (old != m_effect.effect.periodic.magnitude) | 
					
						
							|  |  |  | 		m_effect.changed = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-15 22:18:40 +02:00
										 |  |  | #ifdef SDL_HAPTIC_SQUARE
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | void Joystick::SquareEffect::SetState(ControlState state) | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (state) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_effect.effect.type = SDL_HAPTIC_SQUARE; | 
					
						
							|  |  |  | 		m_effect.effect.periodic.length = 250; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 		m_effect.effect.type = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const Sint16 old = m_effect.effect.periodic.magnitude; | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	m_effect.effect.periodic.period = 5; | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 	m_effect.effect.periodic.magnitude = state * 0x5000; | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	m_effect.effect.periodic.attack_length = 0; | 
					
						
							|  |  |  | 	m_effect.effect.periodic.fade_length = 100; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 	if (old != m_effect.effect.periodic.magnitude) | 
					
						
							|  |  |  | 		m_effect.changed = true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-08-15 22:18:40 +02:00
										 |  |  | #endif // defined(SDL_HAPTIC_SQUARE)
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | void Joystick::TriangleEffect::SetState(ControlState state) | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (state) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_effect.effect.type = SDL_HAPTIC_TRIANGLE; | 
					
						
							|  |  |  | 		m_effect.effect.periodic.length = 250; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 		m_effect.effect.type = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const Sint16 old = m_effect.effect.periodic.magnitude; | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	m_effect.effect.periodic.period = 5; | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 	m_effect.effect.periodic.magnitude = (Sint16)(state * 0x5000); | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 	m_effect.effect.periodic.attack_length = 0; | 
					
						
							|  |  |  | 	m_effect.effect.periodic.fade_length = 100; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 14:48:15 -06:00
										 |  |  | 	if (old != m_effect.effect.periodic.magnitude) | 
					
						
							|  |  |  | 		m_effect.changed = true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Joystick::UpdateInput() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// each joystick is doin this, o well
 | 
					
						
							|  |  |  | 	SDL_JoystickUpdate(); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Joystick::UpdateOutput() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef USE_SDL_HAPTIC
 | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 	for (auto &i : m_state_out) | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 		if (i.changed) // if SetState was called on this output
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 			if (-1 == i.id) // effect isn't currently uploaded
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 				if (i.effect.type) // if outputstate is >0  this would be true
 | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 					if ((i.id = SDL_HapticNewEffect(m_haptic, &i.effect)) > -1) // upload the effect
 | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 						SDL_HapticRunEffect(m_haptic, i.id, 1); // run the effect
 | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 			else // effect is already uploaded
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 				if (i.effect.type) // if ouputstate >0
 | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2014-02-16 23:51:41 -05:00
										 |  |  | 					SDL_HapticUpdateEffect(m_haptic, i.id, &i.effect); // update the effect
 | 
					
						
							| 
									
										
										
										
											2013-04-14 22:53:10 -04:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 					SDL_HapticStopEffect(m_haptic, i.id); // else, stop and remove the effect
 | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 					SDL_HapticDestroyEffect(m_haptic, i.id); | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 					i.id = -1; // mark it as not uploaded
 | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 02:19:15 -05:00
										 |  |  | 			i.changed = false; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-04-01 23:57:06 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string Joystick::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-05 21:07:09 -06:00
										 |  |  | 	return StripSpaces(GetJoystickName(m_sdl_index)); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string Joystick::GetSource() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "SDL"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Joystick::GetId() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return m_index; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string Joystick::Button::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::ostringstream ss; | 
					
						
							| 
									
										
										
										
											2011-03-14 21:07:28 +00:00
										 |  |  | 	ss << "Button " << (int)m_index; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	return ss.str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string Joystick::Axis::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::ostringstream ss; | 
					
						
							| 
									
										
										
										
											2011-03-14 21:07:28 +00:00
										 |  |  | 	ss << "Axis " << (int)m_index << (m_range<0 ? '-' : '+'); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | 	return ss.str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string Joystick::Hat::GetName() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-16 03:43:11 +00:00
										 |  |  | 	static char tmpstr[] = "Hat . ."; | 
					
						
							|  |  |  | 	// I don't think more than 10 hats are supported
 | 
					
						
							|  |  |  | 	tmpstr[4] = (char)('0' + m_index); | 
					
						
							|  |  |  | 	tmpstr[6] = "NESW"[m_direction]; | 
					
						
							|  |  |  | 	return tmpstr; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | ControlState Joystick::Button::GetState() const | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	return SDL_JoystickGetButton(m_js, m_index); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | ControlState Joystick::Axis::GetState() const | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	return std::max(0.0f, ControlState(SDL_JoystickGetAxis(m_js, m_index)) / m_range); | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | ControlState Joystick::Hat::GetState() const | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-14 01:20:11 +00:00
										 |  |  | 	return (SDL_JoystickGetHat(m_js, m_index) & (1 << m_direction)) > 0; | 
					
						
							| 
									
										
										
										
											2010-04-02 02:48:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | } |