aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Brown <themagnificentmrb@gmail.com>2016-04-13 18:35:05 -0700
committerGarrett Brown <themagnificentmrb@gmail.com>2016-08-06 12:55:52 -0700
commitc1819651563ee9350be07dde810fcd682b5ea7d3 (patch)
treedcf83147cf32cbb3513ec48112604d2f19b62a00
parent3c295e15494aea6ad47597659e06c377a77024c1 (diff)
[peripheral API] v1.0.18 - Add rumble capability
-rw-r--r--Kodi.xcodeproj/project.pbxproj12
-rw-r--r--addons/kodi.peripheral/addon.xml4
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_dll.h9
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h24
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp65
-rw-r--r--xbmc/games/controllers/windows/GUIConfigurationWizard.cpp2
-rw-r--r--xbmc/input/joysticks/CMakeLists.txt2
-rw-r--r--xbmc/input/joysticks/DriverPrimitive.cpp9
-rw-r--r--xbmc/input/joysticks/DriverPrimitive.h22
-rw-r--r--xbmc/input/joysticks/IDriverReceiver.h42
-rw-r--r--xbmc/input/joysticks/IInputHandler.h12
-rw-r--r--xbmc/input/joysticks/IInputReceiver.h44
-rw-r--r--xbmc/input/joysticks/JoystickTypes.h12
-rw-r--r--xbmc/input/joysticks/generic/ButtonMapping.cpp2
-rw-r--r--xbmc/input/joysticks/generic/CMakeLists.txt2
-rw-r--r--xbmc/input/joysticks/generic/DriverReceiving.cpp49
-rw-r--r--xbmc/input/joysticks/generic/DriverReceiving.h53
-rw-r--r--xbmc/input/joysticks/generic/InputHandling.cpp3
-rw-r--r--xbmc/input/joysticks/generic/Makefile1
-rw-r--r--xbmc/peripherals/PeripheralTypes.h1
-rw-r--r--xbmc/peripherals/addons/AddonButtonMap.cpp7
-rw-r--r--xbmc/peripherals/addons/AddonInputHandling.cpp26
-rw-r--r--xbmc/peripherals/addons/AddonInputHandling.h11
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.cpp19
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.h1
-rw-r--r--xbmc/peripherals/addons/PeripheralAddonTranslator.cpp22
-rw-r--r--xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp12
-rw-r--r--xbmc/peripherals/bus/virtual/PeripheralBusAddon.h15
-rw-r--r--xbmc/peripherals/devices/Peripheral.cpp16
-rw-r--r--xbmc/peripherals/devices/Peripheral.h5
-rw-r--r--xbmc/peripherals/devices/PeripheralJoystick.cpp33
-rw-r--r--xbmc/peripherals/devices/PeripheralJoystick.h16
32 files changed, 496 insertions, 57 deletions
diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj
index a9f87d2f6d..436be8c44e 100644
--- a/Kodi.xcodeproj/project.pbxproj
+++ b/Kodi.xcodeproj/project.pbxproj
@@ -253,6 +253,8 @@
5EB3113C1A978B9B00551907 /* CueInfoLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EB3113A1A978B9B00551907 /* CueInfoLoader.cpp */; };
5EE4F9181A9FF36F002E20F8 /* CueInfoLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EB3113A1A978B9B00551907 /* CueInfoLoader.cpp */; };
5EF801001A97892A0035AA4D /* ReplayGain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF800FE1A97892A0035AA4D /* ReplayGain.cpp */; };
+ 6861B9EA1CC248EE00F62655 /* DriverReceiving.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6861B9E81CC248EE00F62655 /* DriverReceiving.cpp */; };
+ 6861B9EB1CC248EE00F62655 /* DriverReceiving.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6861B9E81CC248EE00F62655 /* DriverReceiving.cpp */; };
68AE5BA51C92412900C4D527 /* AddonCallbacksPeripheral.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68AE5BA31C92412900C4D527 /* AddonCallbacksPeripheral.cpp */; };
68AE5BA61C92412900C4D527 /* AddonCallbacksPeripheral.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68AE5BA31C92412900C4D527 /* AddonCallbacksPeripheral.cpp */; };
68AE5BBD1C9241DF00C4D527 /* DefaultJoystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68AE5BAC1C9241DF00C4D527 /* DefaultJoystick.cpp */; };
@@ -2743,6 +2745,10 @@
5EB3113B1A978B9B00551907 /* CueInfoLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueInfoLoader.h; sourceTree = "<group>"; };
5EF800FE1A97892A0035AA4D /* ReplayGain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplayGain.cpp; sourceTree = "<group>"; };
5EF800FF1A97892A0035AA4D /* ReplayGain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplayGain.h; sourceTree = "<group>"; };
+ 6861B9E81CC248EE00F62655 /* DriverReceiving.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DriverReceiving.cpp; path = joysticks/generic/DriverReceiving.cpp; sourceTree = "<group>"; };
+ 6861B9E91CC248EE00F62655 /* DriverReceiving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DriverReceiving.h; path = joysticks/generic/DriverReceiving.h; sourceTree = "<group>"; };
+ 6861B9EC1CC248F600F62655 /* IDriverReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IDriverReceiver.h; path = joysticks/IDriverReceiver.h; sourceTree = "<group>"; };
+ 6861B9ED1CC248F600F62655 /* IInputReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IInputReceiver.h; path = joysticks/IInputReceiver.h; sourceTree = "<group>"; };
68AE5BA01C923E5300C4D527 /* kodi_vfs_utils.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = kodi_vfs_utils.hpp; path = "kodi-addon-dev-kit/include/kodi/kodi_vfs_utils.hpp"; sourceTree = "<group>"; };
68AE5BA31C92412900C4D527 /* AddonCallbacksPeripheral.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AddonCallbacksPeripheral.cpp; path = addons/binary/interfaces/api1/Peripheral/AddonCallbacksPeripheral.cpp; sourceTree = "<group>"; };
68AE5BA41C92412900C4D527 /* AddonCallbacksPeripheral.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AddonCallbacksPeripheral.h; path = addons/binary/interfaces/api1/Peripheral/AddonCallbacksPeripheral.h; sourceTree = "<group>"; };
@@ -6123,7 +6129,9 @@
68AE5BB01C9241DF00C4D527 /* IButtonMap.h */,
68AE5BB11C9241DF00C4D527 /* IButtonMapper.h */,
68AE5BB21C9241DF00C4D527 /* IDriverHandler.h */,
+ 6861B9EC1CC248F600F62655 /* IDriverReceiver.h */,
68AE5BB31C9241DF00C4D527 /* IInputHandler.h */,
+ 6861B9ED1CC248F600F62655 /* IInputReceiver.h */,
68AE5BB41C9241DF00C4D527 /* IKeymapHandler.h */,
68AE5BB51C9241DF00C4D527 /* JoystickMonitor.cpp */,
68AE5BB61C9241DF00C4D527 /* JoystickMonitor.h */,
@@ -6142,6 +6150,8 @@
children = (
68AE5BC81C9241F800C4D527 /* ButtonMapping.cpp */,
68AE5BC91C9241F800C4D527 /* ButtonMapping.h */,
+ 6861B9E81CC248EE00F62655 /* DriverReceiving.cpp */,
+ 6861B9E91CC248EE00F62655 /* DriverReceiving.h */,
68AE5BCA1C9241F800C4D527 /* FeatureHandling.cpp */,
68AE5BCB1C9241F800C4D527 /* FeatureHandling.h */,
68AE5BCC1C9241F800C4D527 /* InputHandling.cpp */,
@@ -10014,6 +10024,7 @@
8883CEA10DD817D1004E8B72 /* DVDOverlayCodecSSA.cpp in Sources */,
8883CEA70DD81807004E8B72 /* DVDSubtitleParserSSA.cpp in Sources */,
8883CEA80DD81807004E8B72 /* DVDSubtitlesLibass.cpp in Sources */,
+ 6861B9EA1CC248EE00F62655 /* DriverReceiving.cpp in Sources */,
5EF801001A97892A0035AA4D /* ReplayGain.cpp in Sources */,
8863281D0E07B37200BB3DAB /* GUIDialogFullScreenInfo.cpp in Sources */,
8863281E0E07B37200BB3DAB /* GUIViewStatePictures.cpp in Sources */,
@@ -10847,6 +10858,7 @@
E49911AE174E5CFE00741B6D /* AEStreamInfo.cpp in Sources */,
E49911AF174E5CFE00741B6D /* AEUtil.cpp in Sources */,
E49911B1174E5CFE00741B6D /* AEFactory.cpp in Sources */,
+ 6861B9EB1CC248EE00F62655 /* DriverReceiving.cpp in Sources */,
E49911B2174E5D0A00741B6D /* EmuFileWrapper.cpp in Sources */,
E49911B3174E5D0A00741B6D /* emu_dummy.cpp in Sources */,
E49911B4174E5D0A00741B6D /* emu_kernel32.cpp in Sources */,
diff --git a/addons/kodi.peripheral/addon.xml b/addons/kodi.peripheral/addon.xml
index f2732cf5b4..9c2572de03 100644
--- a/addons/kodi.peripheral/addon.xml
+++ b/addons/kodi.peripheral/addon.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<addon id="kodi.peripheral" version="1.0.17" provider-name="Team-Kodi">
- <backwards-compatibility abi="1.0.16"/>
+<addon id="kodi.peripheral" version="1.0.18" provider-name="Team-Kodi">
+ <backwards-compatibility abi="1.0.18"/>
<requires>
<import addon="xbmc.core" version="0.1.0"/>
</requires>
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_dll.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_dll.h
index 31433a401a..08db4a292e 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_dll.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_dll.h
@@ -100,6 +100,14 @@ extern "C"
* @param events The array of allocated events
*/
void FreeEvents(unsigned int event_count, PERIPHERAL_EVENT* events);
+
+ /*!
+ * @brief Send an input event to the specified peripheral
+ * @param peripheralIndex The index of the device receiving the input event
+ * @param event The input event
+ * @return true if the event was handled, false otherwise
+ */
+ bool SendEvent(const PERIPHERAL_EVENT* event);
///}
/// @name Joystick operations
@@ -180,6 +188,7 @@ extern "C"
pClient->FreeScanResults = FreeScanResults;
pClient->GetEvents = GetEvents;
pClient->FreeEvents = FreeEvents;
+ pClient->SendEvent = SendEvent;
#ifdef PERIPHERAL_ADDON_JOYSTICKS
pClient->GetJoystickInfo = GetJoystickInfo;
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h
index f81ee74df9..be815ad3a5 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h
@@ -50,10 +50,10 @@
#endif
/* current Peripheral API version */
-#define PERIPHERAL_API_VERSION "1.0.17"
+#define PERIPHERAL_API_VERSION "1.0.18"
/* min. Peripheral API version */
-#define PERIPHERAL_MIN_API_VERSION "1.0.16"
+#define PERIPHERAL_MIN_API_VERSION "1.0.18"
/* indicates a joystick has no preference for port number */
#define NO_PORT_REQUESTED (-1)
@@ -122,6 +122,7 @@ extern "C"
PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON, /*!< @brief state changed for joystick driver button */
PERIPHERAL_EVENT_TYPE_DRIVER_HAT, /*!< @brief state changed for joystick driver hat */
PERIPHERAL_EVENT_TYPE_DRIVER_AXIS, /*!< @brief state changed for joystick driver axis */
+ PERIPHERAL_EVENT_TYPE_SET_MOTOR, /*!< @brief set the state for joystick rumble motor */
} PERIPHERAL_EVENT_TYPE;
typedef enum JOYSTICK_STATE_BUTTON
@@ -152,6 +153,8 @@ extern "C"
*/
typedef float JOYSTICK_STATE_AXIS;
+ typedef float JOYSTICK_STATE_MOTOR;
+
typedef struct PERIPHERAL_EVENT
{
unsigned int peripheral_index;
@@ -160,6 +163,7 @@ extern "C"
JOYSTICK_STATE_BUTTON driver_button_state;
JOYSTICK_STATE_HAT driver_hat_state;
JOYSTICK_STATE_AXIS driver_axis_state;
+ JOYSTICK_STATE_MOTOR motor_state;
} ATTRIBUTE_PACKED PERIPHERAL_EVENT;
///}
@@ -173,6 +177,7 @@ extern "C"
unsigned int button_count; /*!< @brief number of buttons reported by the driver */
unsigned int hat_count; /*!< @brief number of hats reported by the driver */
unsigned int axis_count; /*!< @brief number of axes reported by the driver */
+ unsigned int motor_count; /*!< @brief number of motors reported by the driver */
} ATTRIBUTE_PACKED JOYSTICK_INFO;
typedef enum JOYSTICK_DRIVER_PRIMITIVE_TYPE
@@ -181,6 +186,7 @@ extern "C"
JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON,
JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION,
JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS,
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR,
} JOYSTICK_DRIVER_PRIMITIVE_TYPE;
typedef struct JOYSTICK_DRIVER_BUTTON
@@ -216,6 +222,11 @@ extern "C"
JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction;
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_SEMIAXIS;
+ typedef struct JOYSTICK_DRIVER_MOTOR
+ {
+ int index;
+ } ATTRIBUTE_PACKED JOYSTICK_DRIVER_MOTOR;
+
typedef struct JOYSTICK_DRIVER_PRIMITIVE
{
JOYSTICK_DRIVER_PRIMITIVE_TYPE type;
@@ -224,6 +235,7 @@ extern "C"
struct JOYSTICK_DRIVER_BUTTON button;
struct JOYSTICK_DRIVER_HAT hat;
struct JOYSTICK_DRIVER_SEMIAXIS semiaxis;
+ struct JOYSTICK_DRIVER_MOTOR motor;
};
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_PRIMITIVE;
@@ -233,6 +245,7 @@ extern "C"
JOYSTICK_FEATURE_TYPE_SCALAR,
JOYSTICK_FEATURE_TYPE_ANALOG_STICK,
JOYSTICK_FEATURE_TYPE_ACCELEROMETER,
+ JOYSTICK_FEATURE_TYPE_MOTOR,
} JOYSTICK_FEATURE_TYPE;
typedef struct JOYSTICK_FEATURE_SCALAR
@@ -255,6 +268,11 @@ extern "C"
struct JOYSTICK_DRIVER_PRIMITIVE positive_z;
} ATTRIBUTE_PACKED JOYSTICK_FEATURE_ACCELEROMETER;
+ typedef struct JOYSTICK_FEATURE_MOTOR
+ {
+ struct JOYSTICK_DRIVER_PRIMITIVE primitive;
+ } ATTRIBUTE_PACKED JOYSTICK_FEATURE_MOTOR;
+
typedef struct JOYSTICK_FEATURE
{
char* name;
@@ -264,6 +282,7 @@ extern "C"
struct JOYSTICK_FEATURE_SCALAR scalar;
struct JOYSTICK_FEATURE_ANALOG_STICK analog_stick;
struct JOYSTICK_FEATURE_ACCELEROMETER accelerometer;
+ struct JOYSTICK_FEATURE_MOTOR motor;
};
} ATTRIBUTE_PACKED JOYSTICK_FEATURE;
///}
@@ -282,6 +301,7 @@ extern "C"
void (__cdecl* FreeScanResults)(unsigned int, PERIPHERAL_INFO*);
PERIPHERAL_ERROR (__cdecl* GetEvents)(unsigned int*, PERIPHERAL_EVENT**);
void (__cdecl* FreeEvents)(unsigned int, PERIPHERAL_EVENT*);
+ bool (__cdecl* SendEvent)(const PERIPHERAL_EVENT*);
/// @name Joystick operations
///{
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp
index 4423cb4d39..d4d725b2af 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp
@@ -204,6 +204,7 @@ namespace ADDON
JOYSTICK_STATE_BUTTON ButtonState(void) const { return m_event.driver_button_state; }
JOYSTICK_STATE_HAT HatState(void) const { return m_event.driver_hat_state; }
JOYSTICK_STATE_AXIS AxisState(void) const { return m_event.driver_axis_state; }
+ JOYSTICK_STATE_MOTOR MotorState(void) const { return m_event.motor_state; }
void SetType(PERIPHERAL_EVENT_TYPE type) { m_event.type = type; }
void SetPeripheralIndex(unsigned int index) { m_event.peripheral_index = index; }
@@ -211,6 +212,7 @@ namespace ADDON
void SetButtonState(JOYSTICK_STATE_BUTTON state) { m_event.driver_button_state = state; }
void SetHatState(JOYSTICK_STATE_HAT state) { m_event.driver_hat_state = state; }
void SetAxisState(JOYSTICK_STATE_AXIS state) { m_event.driver_axis_state = state; }
+ void SetMotorState(JOYSTICK_STATE_MOTOR state) { m_event.motor_state = state; }
void ToStruct(PERIPHERAL_EVENT& event) const
{
@@ -243,7 +245,8 @@ namespace ADDON
m_requestedPort(NO_PORT_REQUESTED),
m_buttonCount(0),
m_hatCount(0),
- m_axisCount(0)
+ m_axisCount(0),
+ m_motorCount(0)
{
}
@@ -258,7 +261,8 @@ namespace ADDON
m_requestedPort(info.requested_port),
m_buttonCount(info.button_count),
m_hatCount(info.hat_count),
- m_axisCount(info.axis_count)
+ m_axisCount(info.axis_count),
+ m_motorCount(info.motor_count)
{
}
@@ -275,6 +279,7 @@ namespace ADDON
m_buttonCount = rhs.m_buttonCount;
m_hatCount = rhs.m_hatCount;
m_axisCount = rhs.m_axisCount;
+ m_motorCount = rhs.m_motorCount;
}
return *this;
}
@@ -284,6 +289,7 @@ namespace ADDON
unsigned int ButtonCount(void) const { return m_buttonCount; }
unsigned int HatCount(void) const { return m_hatCount; }
unsigned int AxisCount(void) const { return m_axisCount; }
+ unsigned int MotorCount(void) const { return m_motorCount; }
// Derived property: Counts are unknown if all are zero
bool AreElementCountsKnown(void) const { return m_buttonCount != 0 || m_hatCount != 0 || m_axisCount != 0; }
@@ -293,6 +299,7 @@ namespace ADDON
void SetButtonCount(unsigned int buttonCount) { m_buttonCount = buttonCount; }
void SetHatCount(unsigned int hatCount) { m_hatCount = hatCount; }
void SetAxisCount(unsigned int axisCount) { m_axisCount = axisCount; }
+ void SetMotorCount(unsigned int motorCount) { m_motorCount = motorCount; }
void ToStruct(JOYSTICK_INFO& info) const
{
@@ -303,6 +310,7 @@ namespace ADDON
info.button_count = m_buttonCount;
info.hat_count = m_hatCount;
info.axis_count = m_axisCount;
+ info.motor_count = m_motorCount;
std::strcpy(info.provider, m_provider.c_str());
}
@@ -320,6 +328,7 @@ namespace ADDON
unsigned int m_buttonCount;
unsigned int m_hatCount;
unsigned int m_axisCount;
+ unsigned int m_motorCount;
};
typedef PeripheralVector<Joystick, JOYSTICK_INFO> Joysticks;
@@ -332,6 +341,7 @@ namespace ADDON
* 1) a button
* 2) a hat direction
* 3) a semiaxis (either the positive or negative half of an axis)
+ * 4) a motor
*
* The type determines the fields in use:
*
@@ -345,9 +355,24 @@ namespace ADDON
* Semiaxis:
* - driver index
* - semiaxis direction
+ *
+ * Motor:
+ * - driver index
*/
class DriverPrimitive
{
+ protected:
+ /*!
+ * \brief Construct a driver primitive of the specified type
+ */
+ DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE type, unsigned int driverIndex) :
+ m_type(type),
+ m_driverIndex(driverIndex),
+ m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
+ m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN)
+ {
+ }
+
public:
/*!
* \brief Construct an invalid driver primitive
@@ -363,12 +388,9 @@ namespace ADDON
/*!
* \brief Construct a driver primitive representing a button
*/
- DriverPrimitive(unsigned int buttonIndex) :
- m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON),
- m_driverIndex(buttonIndex),
- m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
- m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN)
+ static DriverPrimitive CreateButton(unsigned int buttonIndex)
{
+ return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON, buttonIndex);
}
/*!
@@ -395,6 +417,14 @@ namespace ADDON
{
}
+ /*!
+ * \brief Construct a driver primitive representing a motor
+ */
+ static DriverPrimitive CreateMotor(unsigned int motorIndex)
+ {
+ return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR, motorIndex);
+ }
+
DriverPrimitive(const JOYSTICK_DRIVER_PRIMITIVE& primitive) :
m_type(primitive.type),
m_driverIndex(0),
@@ -420,6 +450,11 @@ namespace ADDON
m_semiAxisDirection = primitive.semiaxis.direction;
break;
}
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
+ {
+ m_driverIndex = primitive.motor.index;
+ break;
+ }
default:
break;
}
@@ -437,6 +472,7 @@ namespace ADDON
switch (m_type)
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
{
return m_driverIndex == other.m_driverIndex;
}
@@ -479,6 +515,11 @@ namespace ADDON
driver_primitive.semiaxis.direction = m_semiAxisDirection;
break;
}
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
+ {
+ driver_primitive.motor.index = m_driverIndex;
+ break;
+ }
default:
break;
}
@@ -499,6 +540,7 @@ namespace ADDON
* 1) scalar[1]
* 2) analog stick
* 3) accelerometer
+ * 4) motor
*
* [1] All three driver primitives (buttons, hats and axes) have a state that
* can be represented using a single scalar value. For this reason,
@@ -520,6 +562,9 @@ namespace ADDON
* - positive X
* - positive Y
* - positive Z
+ *
+ * Motor:
+ * - primitive
*/
class JoystickFeature
{
@@ -565,6 +610,9 @@ namespace ADDON
SetPositiveY(feature.accelerometer.positive_y);
SetPositiveZ(feature.accelerometer.positive_z);
break;
+ case JOYSTICK_FEATURE_TYPE_MOTOR:
+ SetPrimitive(feature.motor.primitive);
+ break;
default:
break;
}
@@ -636,6 +684,9 @@ namespace ADDON
PositiveY().ToStruct(feature.accelerometer.positive_y);
PositiveZ().ToStruct(feature.accelerometer.positive_z);
break;
+ case JOYSTICK_FEATURE_TYPE_MOTOR:
+ Primitive().ToStruct(feature.motor.primitive);
+ break;
default:
break;
}
diff --git a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
index b48986ba65..729d8e1926 100644
--- a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
+++ b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
@@ -137,7 +137,7 @@ bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap, cons
bool bHandled = false;
// Handle esc key separately
- if (primitive.Type() == CDriverPrimitive::BUTTON &&
+ if (primitive.Type() == PRIMITIVE_TYPE::BUTTON &&
primitive.Index() == ESC_KEY_CODE)
{
bHandled = Abort(false);
diff --git a/xbmc/input/joysticks/CMakeLists.txt b/xbmc/input/joysticks/CMakeLists.txt
index db2db696fe..57306bd402 100644
--- a/xbmc/input/joysticks/CMakeLists.txt
+++ b/xbmc/input/joysticks/CMakeLists.txt
@@ -9,7 +9,9 @@ set(HEADERS DefaultJoystick.h
IButtonMap.h
IButtonMapper.h
IDriverHandler.h
+ IDriverReceiver.h
IInputHandler.h
+ IInputReceiver.h
IKeymapHandler.h
JoystickMonitor.h
JoystickTranslator.h
diff --git a/xbmc/input/joysticks/DriverPrimitive.cpp b/xbmc/input/joysticks/DriverPrimitive.cpp
index 70bd2e0d9b..8630a40253 100644
--- a/xbmc/input/joysticks/DriverPrimitive.cpp
+++ b/xbmc/input/joysticks/DriverPrimitive.cpp
@@ -30,9 +30,9 @@ CDriverPrimitive::CDriverPrimitive(void)
{
}
-CDriverPrimitive::CDriverPrimitive(unsigned int buttonIndex)
- : m_type(BUTTON),
- m_driverIndex(buttonIndex),
+CDriverPrimitive::CDriverPrimitive(PRIMITIVE_TYPE type, unsigned int index)
+ : m_type(type),
+ m_driverIndex(index),
m_hatDirection(),
m_semiAxisDirection()
{
@@ -61,6 +61,7 @@ bool CDriverPrimitive::operator==(const CDriverPrimitive& rhs) const
switch (m_type)
{
case BUTTON:
+ case MOTOR:
return m_driverIndex == rhs.m_driverIndex;
case HAT:
return m_driverIndex == rhs.m_driverIndex && m_hatDirection == rhs.m_hatDirection;
@@ -102,7 +103,7 @@ bool CDriverPrimitive::operator<(const CDriverPrimitive& rhs) const
bool CDriverPrimitive::IsValid(void) const
{
- if (m_type == BUTTON)
+ if (m_type == BUTTON || m_type == MOTOR)
return true;
if (m_type == HAT)
diff --git a/xbmc/input/joysticks/DriverPrimitive.h b/xbmc/input/joysticks/DriverPrimitive.h
index 626a368bf5..fad150b706 100644
--- a/xbmc/input/joysticks/DriverPrimitive.h
+++ b/xbmc/input/joysticks/DriverPrimitive.h
@@ -55,6 +55,9 @@ namespace JOYSTICK
* - driver index
* - semiaxis direction (positive/negative)
*
+ * Motor:
+ * - driver index
+ *
* For more info, see "Chapter 2. Joystick drivers" in the documentation
* thread: http://forum.kodi.tv/showthread.php?tid=257764
*/
@@ -62,25 +65,14 @@ namespace JOYSTICK
{
public:
/*!
- * \brief Type of driver primitive
- */
- enum PrimitiveType
- {
- UNKNOWN = 0, // primitive has no type (invalid)
- BUTTON, // a digital button
- HAT, // one of the four direction arrows on a D-pad
- SEMIAXIS, // the positive or negative half of an axis
- };
-
- /*!
* \brief Construct an invalid driver primitive
*/
CDriverPrimitive(void);
/*!
- * \brief Construct a driver primitive representing a button
+ * \brief Construct a driver primitive representing a button or motor
*/
- CDriverPrimitive(unsigned int buttonIndex);
+ CDriverPrimitive(PRIMITIVE_TYPE type, unsigned int index);
/*!
* \brief Construct a driver primitive representing one of the four
@@ -105,7 +97,7 @@ namespace JOYSTICK
/*!
* \brief The type of driver primitive
*/
- PrimitiveType Type(void) const { return m_type; }
+ PRIMITIVE_TYPE Type(void) const { return m_type; }
/*!
* \brief The index used by the driver (valid for all types)
@@ -133,7 +125,7 @@ namespace JOYSTICK
bool IsValid(void) const;
private:
- PrimitiveType m_type;
+ PRIMITIVE_TYPE m_type;
unsigned int m_driverIndex;
HAT_DIRECTION m_hatDirection;
SEMIAXIS_DIRECTION m_semiAxisDirection;
diff --git a/xbmc/input/joysticks/IDriverReceiver.h b/xbmc/input/joysticks/IDriverReceiver.h
new file mode 100644
index 0000000000..c1a2a2083f
--- /dev/null
+++ b/xbmc/input/joysticks/IDriverReceiver.h
@@ -0,0 +1,42 @@
+/*
+* Copyright (C) 2016 Team Kodi
+* http://kodi.tv
+*
+* This Program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* This Program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this Program; see the file COPYING. If not, see
+* <http://www.gnu.org/licenses/>.
+*
+*/
+#pragma once
+
+namespace JOYSTICK
+{
+ /*!
+ * \brief Interface for sending input events to joystick drivers
+ */
+ class IDriverReceiver
+ {
+ public:
+ virtual ~IDriverReceiver(void) { }
+
+ /*!
+ * \brief Set the value of a rumble motor
+ *
+ * \param motorIndex The driver index of the motor to rumble
+ * \param magnitude The motor's new magnitude of vibration in the closed interval [0, 1]
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool SetMotorState(unsigned int motorIndex, float magnitude) = 0;
+ };
+}
diff --git a/xbmc/input/joysticks/IInputHandler.h b/xbmc/input/joysticks/IInputHandler.h
index 20ce7efcae..7c13c84609 100644
--- a/xbmc/input/joysticks/IInputHandler.h
+++ b/xbmc/input/joysticks/IInputHandler.h
@@ -25,12 +25,16 @@
namespace JOYSTICK
{
+ class IInputReceiver;
+
/*!
* \brief Interface for handling input events for game controllers
*/
class IInputHandler
{
public:
+ IInputHandler(void) : m_receiver(nullptr) { }
+
virtual ~IInputHandler(void) { }
/*!
@@ -93,5 +97,13 @@ namespace JOYSTICK
* \return True if the event was handled otherwise false
*/
virtual bool OnAccelerometerMotion(const FeatureName& feature, float x, float y, float z) { return false; }
+
+ // Input receiver interface
+ void SetInputReceiver(IInputReceiver* receiver) { m_receiver = receiver; }
+ void ResetInputReceiver(void) { m_receiver = nullptr; }
+ IInputReceiver* InputReceiver(void) { return m_receiver; }
+
+ private:
+ IInputReceiver* m_receiver;
};
}
diff --git a/xbmc/input/joysticks/IInputReceiver.h b/xbmc/input/joysticks/IInputReceiver.h
new file mode 100644
index 0000000000..5bc89d72fa
--- /dev/null
+++ b/xbmc/input/joysticks/IInputReceiver.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014-2016 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "JoystickTypes.h"
+
+namespace JOYSTICK
+{
+ /*!
+ * \brief Interface for sending input events to game controllers
+ */
+ class IInputReceiver
+ {
+ public:
+ virtual ~IInputReceiver(void) { }
+
+ /*!
+ * \brief Set the value of a rumble motor
+ *
+ * \param feature The name of the motor to rumble
+ * \param magnitude The motor's new magnitude of vibration in the closed interval [0, 1]
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool SetRumbleState(const FeatureName& feature, float magnitude) = 0;
+ };
+}
diff --git a/xbmc/input/joysticks/JoystickTypes.h b/xbmc/input/joysticks/JoystickTypes.h
index dce8a46215..25e15162cc 100644
--- a/xbmc/input/joysticks/JoystickTypes.h
+++ b/xbmc/input/joysticks/JoystickTypes.h
@@ -123,4 +123,16 @@ namespace JOYSTICK
DIGITAL,
ANALOG,
};
+
+ /*!
+ * \brief Type of driver primitive
+ */
+ enum PRIMITIVE_TYPE
+ {
+ UNKNOWN = 0, // primitive has no type (invalid)
+ BUTTON, // a digital button
+ HAT, // one of the four direction arrows on a D-pad
+ SEMIAXIS, // the positive or negative half of an axis
+ MOTOR, // a rumble motor
+ };
}
diff --git a/xbmc/input/joysticks/generic/ButtonMapping.cpp b/xbmc/input/joysticks/generic/ButtonMapping.cpp
index e49d32d24c..6bbe3382a2 100644
--- a/xbmc/input/joysticks/generic/ButtonMapping.cpp
+++ b/xbmc/input/joysticks/generic/ButtonMapping.cpp
@@ -49,7 +49,7 @@ bool CButtonMapping::OnButtonMotion(unsigned int buttonIndex, bool bPressed)
{
if (bPressed)
{
- CDriverPrimitive buttonPrimitive(buttonIndex);
+ CDriverPrimitive buttonPrimitive(PRIMITIVE_TYPE::BUTTON, buttonIndex);
if (buttonPrimitive.IsValid())
{
MapPrimitive(buttonPrimitive);
diff --git a/xbmc/input/joysticks/generic/CMakeLists.txt b/xbmc/input/joysticks/generic/CMakeLists.txt
index 2d7a219010..f44258a548 100644
--- a/xbmc/input/joysticks/generic/CMakeLists.txt
+++ b/xbmc/input/joysticks/generic/CMakeLists.txt
@@ -1,8 +1,10 @@
set(SOURCES ButtonMapping.cpp
+ DriverReceiving.cpp
FeatureHandling.cpp
InputHandling.cpp)
set(HEADERS ButtonMapping.h
+ DriverReceiving.h
FeatureHandling.h
InputHandling.h)
diff --git a/xbmc/input/joysticks/generic/DriverReceiving.cpp b/xbmc/input/joysticks/generic/DriverReceiving.cpp
new file mode 100644
index 0000000000..d44eabd1c0
--- /dev/null
+++ b/xbmc/input/joysticks/generic/DriverReceiving.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "DriverReceiving.h"
+#include "input/joysticks/DriverPrimitive.h"
+#include "input/joysticks/IButtonMap.h"
+#include "input/joysticks/IDriverReceiver.h"
+
+using namespace JOYSTICK;
+
+CDriverReceiving::CDriverReceiving(IDriverReceiver* receiver, IButtonMap* buttonMap)
+ : m_receiver(receiver),
+ m_buttonMap(buttonMap)
+{
+}
+
+bool CDriverReceiving::SetRumbleState(const FeatureName& feature, float magnitude)
+{
+ bool bHandled = false;
+
+ if (m_receiver != nullptr && m_buttonMap != nullptr)
+ {
+ CDriverPrimitive primitive;
+ if (m_buttonMap->GetScalar(feature, primitive))
+ {
+ if (primitive.Type() == PRIMITIVE_TYPE::MOTOR)
+ bHandled = m_receiver->SetMotorState(primitive.Index(), magnitude);
+ }
+ }
+
+ return bHandled;
+}
diff --git a/xbmc/input/joysticks/generic/DriverReceiving.h b/xbmc/input/joysticks/generic/DriverReceiving.h
new file mode 100644
index 0000000000..531ffc92df
--- /dev/null
+++ b/xbmc/input/joysticks/generic/DriverReceiving.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "input/joysticks/IInputReceiver.h"
+#include "input/joysticks/JoystickTypes.h"
+
+#include <map>
+
+namespace JOYSTICK
+{
+ class IDriverReceiver;
+ class IButtonMap;
+
+ /*!
+ * \brief Class to translate input events from higher-level features to driver primitives
+ *
+ * A button map is used to translate controller features to driver primitives.
+ * The button map has been abstracted away behind the IButtonMap interface
+ * so that it can be provided by an add-on.
+ */
+ class CDriverReceiving : public IInputReceiver
+ {
+ public:
+ CDriverReceiving(IDriverReceiver* receiver, IButtonMap* buttonMap);
+
+ virtual ~CDriverReceiving(void) { }
+
+ // implementation of IInputReceiver
+ virtual bool SetRumbleState(const FeatureName& feature, float magnitude) override;
+
+ private:
+ IDriverReceiver* const m_receiver;
+ IButtonMap* const m_buttonMap;
+ };
+}
diff --git a/xbmc/input/joysticks/generic/InputHandling.cpp b/xbmc/input/joysticks/generic/InputHandling.cpp
index 1a35e52862..8982491037 100644
--- a/xbmc/input/joysticks/generic/InputHandling.cpp
+++ b/xbmc/input/joysticks/generic/InputHandling.cpp
@@ -21,7 +21,6 @@
#include "InputHandling.h"
#include "input/joysticks/DriverPrimitive.h"
#include "input/joysticks/IButtonMap.h"
-#include "input/joysticks/IInputHandler.h"
#include "input/joysticks/JoystickUtils.h"
using namespace JOYSTICK;
@@ -38,7 +37,7 @@ CInputHandling::~CInputHandling(void)
bool CInputHandling::OnButtonMotion(unsigned int buttonIndex, bool bPressed)
{
- return OnDigitalMotion(CDriverPrimitive(buttonIndex), bPressed);
+ return OnDigitalMotion(CDriverPrimitive(PRIMITIVE_TYPE::BUTTON, buttonIndex), bPressed);
}
bool CInputHandling::OnHatMotion(unsigned int hatIndex, HAT_STATE state)
diff --git a/xbmc/input/joysticks/generic/Makefile b/xbmc/input/joysticks/generic/Makefile
index 19134f1b34..189df859f5 100644
--- a/xbmc/input/joysticks/generic/Makefile
+++ b/xbmc/input/joysticks/generic/Makefile
@@ -1,4 +1,5 @@
SRCS=ButtonMapping.cpp \
+ DriverReceiving.cpp \
FeatureHandling.cpp \
InputHandling.cpp \
diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h
index f93adc2811..565de4bf66 100644
--- a/xbmc/peripherals/PeripheralTypes.h
+++ b/xbmc/peripherals/PeripheralTypes.h
@@ -59,6 +59,7 @@ namespace PERIPHERALS
FEATURE_TUNER,
FEATURE_IMON,
FEATURE_JOYSTICK,
+ FEATURE_RUMBLE,
};
enum PeripheralType
diff --git a/xbmc/peripherals/addons/AddonButtonMap.cpp b/xbmc/peripherals/addons/AddonButtonMap.cpp
index ae65bd8c88..ff61dd9763 100644
--- a/xbmc/peripherals/addons/AddonButtonMap.cpp
+++ b/xbmc/peripherals/addons/AddonButtonMap.cpp
@@ -107,7 +107,8 @@ bool CAddonButtonMap::GetScalar(const FeatureName& feature, CDriverPrimitive& pr
{
const ADDON::JoystickFeature& addonFeature = it->second;
- if (addonFeature.Type() == JOYSTICK_FEATURE_TYPE_SCALAR)
+ if (addonFeature.Type() == JOYSTICK_FEATURE_TYPE_SCALAR ||
+ addonFeature.Type() == JOYSTICK_FEATURE_TYPE_MOTOR)
{
primitive = CPeripheralAddonTranslator::TranslatePrimitive(addonFeature.Primitive());
retVal = true;
@@ -129,7 +130,9 @@ bool CAddonButtonMap::AddScalar(const FeatureName& feature, const CDriverPrimiti
{
UnmapPrimitive(primitive);
- ADDON::JoystickFeature scalar(feature, JOYSTICK_FEATURE_TYPE_SCALAR);
+ const bool bMotor = (primitive.Type() == PRIMITIVE_TYPE::MOTOR);
+
+ ADDON::JoystickFeature scalar(feature, bMotor ? JOYSTICK_FEATURE_TYPE_MOTOR : JOYSTICK_FEATURE_TYPE_SCALAR);
scalar.SetPrimitive(CPeripheralAddonTranslator::TranslatePrimitive(primitive));
m_features[feature] = scalar;
diff --git a/xbmc/peripherals/addons/AddonInputHandling.cpp b/xbmc/peripherals/addons/AddonInputHandling.cpp
index 24ec85784e..7a29c9ea77 100644
--- a/xbmc/peripherals/addons/AddonInputHandling.cpp
+++ b/xbmc/peripherals/addons/AddonInputHandling.cpp
@@ -19,15 +19,18 @@
*/
#include "AddonInputHandling.h"
+#include "input/joysticks/generic/DriverReceiving.h"
#include "input/joysticks/generic/InputHandling.h"
#include "input/joysticks/IInputHandler.h"
+#include "input/joysticks/IDriverReceiver.h"
#include "peripherals/addons/AddonButtonMap.h"
+#include "peripherals/devices/PeripheralJoystick.h"
#include "peripherals/Peripherals.h"
using namespace JOYSTICK;
using namespace PERIPHERALS;
-CAddonInputHandling::CAddonInputHandling(CPeripheral* peripheral, IInputHandler* handler)
+CAddonInputHandling::CAddonInputHandling(CPeripheral* peripheral, IInputHandler* handler, IDriverReceiver* receiver)
{
PeripheralAddonPtr addon = g_peripherals.GetAddon(peripheral);
@@ -39,15 +42,28 @@ CAddonInputHandling::CAddonInputHandling(CPeripheral* peripheral, IInputHandler*
{
m_buttonMap.reset(new CAddonButtonMap(peripheral, addon, handler->ControllerID()));
if (m_buttonMap->Load())
+ {
m_driverHandler.reset(new CInputHandling(handler, m_buttonMap.get()));
+
+ if (receiver)
+ {
+ m_inputReceiver.reset(new CDriverReceiving(receiver, m_buttonMap.get()));
+
+ // Interfaces are connected here because they share button map as a common resource
+ handler->SetInputReceiver(m_inputReceiver.get());
+ }
+ }
else
+ {
m_buttonMap.reset();
+ }
}
}
CAddonInputHandling::~CAddonInputHandling(void)
{
m_driverHandler.reset();
+ m_inputReceiver.reset();
m_buttonMap.reset();
}
@@ -80,3 +96,11 @@ void CAddonInputHandling::ProcessAxisMotions(void)
if (m_driverHandler)
m_driverHandler->ProcessAxisMotions();
}
+
+bool CAddonInputHandling::SetRumbleState(const JOYSTICK::FeatureName& feature, float magnitude)
+{
+ if (m_inputReceiver)
+ return m_inputReceiver->SetRumbleState(feature, magnitude);
+
+ return false;
+}
diff --git a/xbmc/peripherals/addons/AddonInputHandling.h b/xbmc/peripherals/addons/AddonInputHandling.h
index c7bef2ea5d..54f1020e4a 100644
--- a/xbmc/peripherals/addons/AddonInputHandling.h
+++ b/xbmc/peripherals/addons/AddonInputHandling.h
@@ -20,12 +20,14 @@
#pragma once
#include "input/joysticks/IDriverHandler.h"
+#include "input/joysticks/IInputReceiver.h"
#include <memory>
namespace JOYSTICK
{
class IButtonMap;
+ class IDriverReceiver;
class IInputHandler;
}
@@ -33,10 +35,11 @@ namespace PERIPHERALS
{
class CPeripheral;
- class CAddonInputHandling : public JOYSTICK::IDriverHandler
+ class CAddonInputHandling : public JOYSTICK::IDriverHandler,
+ public JOYSTICK::IInputReceiver
{
public:
- CAddonInputHandling(CPeripheral* peripheral, JOYSTICK::IInputHandler* handler);
+ CAddonInputHandling(CPeripheral* peripheral, JOYSTICK::IInputHandler* handler, JOYSTICK::IDriverReceiver* receiver);
virtual ~CAddonInputHandling(void);
@@ -46,8 +49,12 @@ namespace PERIPHERALS
virtual bool OnAxisMotion(unsigned int axisIndex, float position) override;
virtual void ProcessAxisMotions(void) override;
+ // implementation of IInputReceiver
+ virtual bool SetRumbleState(const JOYSTICK::FeatureName& feature, float magnitude) override;
+
private:
std::unique_ptr<JOYSTICK::IDriverHandler> m_driverHandler;
+ std::unique_ptr<JOYSTICK::IInputReceiver> m_inputReceiver;
std::unique_ptr<JOYSTICK::IButtonMap> m_buttonMap;
};
}
diff --git a/xbmc/peripherals/addons/PeripheralAddon.cpp b/xbmc/peripherals/addons/PeripheralAddon.cpp
index 2911123bd6..0587e37306 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddon.cpp
@@ -455,6 +455,23 @@ bool CPeripheralAddon::ProcessEvents(void)
return false;
}
+bool CPeripheralAddon::SendRumbleEvent(unsigned int peripheralIndex, unsigned int driverIndex, float magnitude)
+{
+ bool bHandled = false;
+
+ PERIPHERAL_EVENT eventStruct = { };
+
+ eventStruct.peripheral_index = peripheralIndex;
+ eventStruct.type = PERIPHERAL_EVENT_TYPE_SET_MOTOR;
+ eventStruct.driver_index = driverIndex;
+ eventStruct.motor_state = magnitude;
+
+ try { bHandled = m_pStruct->SendEvent(&eventStruct); }
+ catch (std::exception &e) { LogException(e, "SendEvent()"); }
+
+ return bHandled;
+}
+
bool CPeripheralAddon::GetJoystickProperties(unsigned int index, CPeripheralJoystick& joystick)
{
if (!m_bProvidesJoysticks)
@@ -622,6 +639,7 @@ void CPeripheralAddon::GetJoystickInfo(const CPeripheral* device, ADDON::Joystic
joystickInfo.SetButtonCount(joystick->ButtonCount());
joystickInfo.SetHatCount(joystick->HatCount());
joystickInfo.SetAxisCount(joystick->AxisCount());
+ joystickInfo.SetMotorCount(joystick->MotorCount());
}
}
@@ -632,6 +650,7 @@ void CPeripheralAddon::SetJoystickInfo(CPeripheralJoystick& joystick, const ADDO
joystick.SetButtonCount(joystickInfo.ButtonCount());
joystick.SetHatCount(joystickInfo.HatCount());
joystick.SetAxisCount(joystickInfo.AxisCount());
+ joystick.SetMotorCount(joystickInfo.MotorCount());
}
bool CPeripheralAddon::LogError(const PERIPHERAL_ERROR error, const char *strMethod) const
diff --git a/xbmc/peripherals/addons/PeripheralAddon.h b/xbmc/peripherals/addons/PeripheralAddon.h
index 347c1ee17d..e439c82095 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.h
+++ b/xbmc/peripherals/addons/PeripheralAddon.h
@@ -75,6 +75,7 @@ namespace PERIPHERALS
//@{
bool PerformDeviceScan(PeripheralScanResults &results);
bool ProcessEvents(void);
+ bool SendRumbleEvent(unsigned int index, unsigned int driverIndex, float magnitude);
//@}
/** @name Joystick methods */
diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
index 2399eb0564..2c00677f62 100644
--- a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
@@ -63,7 +63,7 @@ CDriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(const ADDON::Dri
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
{
- retVal = CDriverPrimitive(primitive.DriverIndex());
+ retVal = CDriverPrimitive(PRIMITIVE_TYPE::BUTTON, primitive.DriverIndex());
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
@@ -76,6 +76,11 @@ CDriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(const ADDON::Dri
retVal = CDriverPrimitive(primitive.DriverIndex(), TranslateSemiAxisDirection(primitive.SemiAxisDirection()));
break;
}
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
+ {
+ retVal = CDriverPrimitive(PRIMITIVE_TYPE::MOTOR, primitive.DriverIndex());
+ break;
+ }
default:
break;
}
@@ -89,21 +94,26 @@ ADDON::DriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(const CDri
switch (primitive.Type())
{
- case CDriverPrimitive::BUTTON:
+ case BUTTON:
{
- retVal = ADDON::DriverPrimitive(primitive.Index());
+ retVal = ADDON::DriverPrimitive::CreateButton(primitive.Index());
break;
}
- case CDriverPrimitive::HAT:
+ case HAT:
{
retVal = ADDON::DriverPrimitive(primitive.Index(), TranslateHatDirection(primitive.HatDirection()));
break;
}
- case CDriverPrimitive::SEMIAXIS:
+ case SEMIAXIS:
{
retVal = ADDON::DriverPrimitive(primitive.Index(), TranslateSemiAxisDirection(primitive.SemiAxisDirection()));
break;
}
+ case MOTOR:
+ {
+ retVal = ADDON::DriverPrimitive::CreateMotor(primitive.Index());
+ break;
+ }
default:
break;
}
@@ -182,6 +192,7 @@ JOYSTICK::FEATURE_TYPE CPeripheralAddonTranslator::TranslateFeatureType(JOYSTICK
case JOYSTICK_FEATURE_TYPE_SCALAR: return JOYSTICK::FEATURE_TYPE::SCALAR;
case JOYSTICK_FEATURE_TYPE_ANALOG_STICK: return JOYSTICK::FEATURE_TYPE::ANALOG_STICK;
case JOYSTICK_FEATURE_TYPE_ACCELEROMETER: return JOYSTICK::FEATURE_TYPE::ACCELEROMETER;
+ case JOYSTICK_FEATURE_TYPE_MOTOR: return JOYSTICK::FEATURE_TYPE::MOTOR;
default:
break;
}
@@ -195,6 +206,7 @@ JOYSTICK_FEATURE_TYPE CPeripheralAddonTranslator::TranslateFeatureType(JOYSTICK:
case JOYSTICK::FEATURE_TYPE::SCALAR: return JOYSTICK_FEATURE_TYPE_SCALAR;
case JOYSTICK::FEATURE_TYPE::ANALOG_STICK: return JOYSTICK_FEATURE_TYPE_ANALOG_STICK;
case JOYSTICK::FEATURE_TYPE::ACCELEROMETER: return JOYSTICK_FEATURE_TYPE_ACCELEROMETER;
+ case JOYSTICK::FEATURE_TYPE::MOTOR: return JOYSTICK_FEATURE_TYPE_MOTOR;
default:
break;
}
diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
index e563222c21..b533686db6 100644
--- a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
+++ b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
@@ -135,6 +135,18 @@ bool CPeripheralBusAddon::InitializeProperties(CPeripheral* peripheral)
return bSuccess;
}
+bool CPeripheralBusAddon::SendRumbleEvent(const std::string& strLocation, unsigned int motorIndex, float magnitude)
+{
+ bool bHandled = false;
+
+ PeripheralAddonPtr addon;
+ unsigned int peripheralIndex;
+ if (SplitLocation(strLocation, addon, peripheralIndex))
+ bHandled = addon->SendRumbleEvent(peripheralIndex, motorIndex, magnitude);
+
+ return bHandled;
+}
+
void CPeripheralBusAddon::ProcessEvents(void)
{
PeripheralAddonVector addons;
diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.h b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.h
index 626938db4c..42d3495c6e 100644
--- a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.h
+++ b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.h
@@ -60,6 +60,19 @@ namespace PERIPHERALS
*/
bool InitializeProperties(CPeripheral* peripheral);
+ /*!
+ * \brief Set the rumble state of a rumble motor
+ *
+ * \param strLocation The location of the peripheral with the motor
+ * \param motorIndex The index of the motor being rumbled
+ * \param magnitude The amount of vibration in the closed interval [0.0, 1.0]
+ *
+ * \return true if the rumble motor's state is set, false otherwise
+ *
+ * TODO: Move declaration to parent class
+ */
+ bool SendRumbleEvent(const std::string& strLocation, unsigned int motorIndex, float magnitude);
+
// Inherited from CPeripheralBus
virtual void Register(CPeripheral *peripheral) override;
virtual void GetFeatures(std::vector<PeripheralFeature> &features) const override;
@@ -70,6 +83,7 @@ namespace PERIPHERALS
virtual size_t GetNumberOfPeripherals(void) const override;
virtual size_t GetNumberOfPeripheralsWithId(const int iVendorId, const int iProductId) const override;
virtual void GetDirectory(const std::string &strPath, CFileItemList &items) const override;
+ virtual void ProcessEvents(void) override;
// implementation of IAddonMgrCallback
bool RequestRestart(ADDON::AddonPtr addon, bool datachanged) override;
@@ -81,7 +95,6 @@ namespace PERIPHERALS
// Inherited from CPeripheralBus
virtual bool PerformDeviceScan(PeripheralScanResults &results) override;
virtual void UnregisterRemovedDevices(const PeripheralScanResults &results) override;
- virtual void ProcessEvents(void) override;
private:
void UpdateAddons(void);
diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp
index 95aa63a03d..587cdc7cb7 100644
--- a/xbmc/peripherals/devices/Peripheral.cpp
+++ b/xbmc/peripherals/devices/Peripheral.cpp
@@ -23,6 +23,7 @@
#include <utility>
#include "guilib/LocalizeStrings.h"
+#include "input/joysticks/IInputHandler.h"
#include "peripherals/Peripherals.h"
#include "settings/lib/Setting.h"
#include "peripherals/addons/AddonButtonMapping.h"
@@ -543,22 +544,21 @@ void CPeripheral::ClearSettings(void)
void CPeripheral::RegisterJoystickInputHandler(IInputHandler* handler)
{
- std::map<IInputHandler*, IDriverHandler*>::iterator it = m_inputHandlers.find(handler);
+ auto it = m_inputHandlers.find(handler);
if (it == m_inputHandlers.end())
{
- CAddonInputHandling* inputHandling = new CAddonInputHandling(this, handler);
- RegisterJoystickDriverHandler(inputHandling, false);
- m_inputHandlers[handler] = inputHandling;
+ CAddonInputHandling* addonInput = new CAddonInputHandling(this, handler, GetDriverReceiver());
+ RegisterJoystickDriverHandler(addonInput, false);
+ m_inputHandlers[handler].reset(addonInput);
}
}
void CPeripheral::UnregisterJoystickInputHandler(IInputHandler* handler)
{
- std::map<IInputHandler*, IDriverHandler*>::iterator it = m_inputHandlers.find(handler);
+ auto it = m_inputHandlers.find(handler);
if (it != m_inputHandlers.end())
{
- UnregisterJoystickDriverHandler(it->second);
- delete it->second;
+ UnregisterJoystickDriverHandler(it->second.get());
m_inputHandlers.erase(it);
}
}
@@ -568,7 +568,7 @@ void CPeripheral::RegisterJoystickButtonMapper(IButtonMapper* mapper)
std::map<IButtonMapper*, IDriverHandler*>::iterator it = m_buttonMappers.find(mapper);
if (it == m_buttonMappers.end())
{
- CAddonButtonMapping* addonMapping = new CAddonButtonMapping(this, mapper);
+ IDriverHandler* addonMapping = new CAddonButtonMapping(this, mapper);
RegisterJoystickDriverHandler(addonMapping, false);
m_buttonMappers[mapper] = addonMapping;
}
diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h
index 646f588c29..cd481bf731 100644
--- a/xbmc/peripherals/devices/Peripheral.h
+++ b/xbmc/peripherals/devices/Peripheral.h
@@ -32,6 +32,7 @@ namespace JOYSTICK
{
class IButtonMapper;
class IDriverHandler;
+ class IDriverReceiver;
class IInputHandler;
}
@@ -181,6 +182,8 @@ namespace PERIPHERALS
virtual void RegisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper);
virtual void UnregisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper);
+ virtual JOYSTICK::IDriverReceiver* GetDriverReceiver() { return nullptr; }
+
protected:
virtual void ClearSettings(void);
@@ -204,7 +207,7 @@ namespace PERIPHERALS
std::map<std::string, PeripheralDeviceSetting> m_settings;
std::set<std::string> m_changedSettings;
CPeripheralBus* m_bus;
- std::map<JOYSTICK::IInputHandler*, JOYSTICK::IDriverHandler*> m_inputHandlers;
+ std::map<JOYSTICK::IInputHandler*, std::unique_ptr<JOYSTICK::IDriverHandler>> m_inputHandlers;
std::map<JOYSTICK::IButtonMapper*, JOYSTICK::IDriverHandler*> m_buttonMappers;
};
}
diff --git a/xbmc/peripherals/devices/PeripheralJoystick.cpp b/xbmc/peripherals/devices/PeripheralJoystick.cpp
index 5e9f82cd3d..283fa34cb6 100644
--- a/xbmc/peripherals/devices/PeripheralJoystick.cpp
+++ b/xbmc/peripherals/devices/PeripheralJoystick.cpp
@@ -35,9 +35,11 @@ CPeripheralJoystick::CPeripheralJoystick(const PeripheralScanResult& scanResult,
m_requestedPort(JOYSTICK_PORT_UNKNOWN),
m_buttonCount(0),
m_hatCount(0),
- m_axisCount(0)
+ m_axisCount(0),
+ m_motorCount(0)
{
m_features.push_back(FEATURE_JOYSTICK);
+ // FEATURE_RUMBLE conditionally added via SetMotorCount()
}
CPeripheralJoystick::~CPeripheralJoystick(void)
@@ -79,6 +81,10 @@ bool CPeripheralJoystick::InitialiseFeature(const PeripheralFeature feature)
}
#endif
}
+ else if (feature == FEATURE_RUMBLE)
+ {
+ bSuccess = true; // Nothing to do
+ }
}
if (bSuccess)
@@ -219,3 +225,28 @@ void CPeripheralJoystick::ProcessAxisMotions(void)
for (std::vector<DriverHandler>::iterator it = m_driverHandlers.begin(); it != m_driverHandlers.end(); ++it)
it->handler->ProcessAxisMotions();
}
+
+bool CPeripheralJoystick::SetMotorState(unsigned int motorIndex, float magnitude)
+{
+ bool bHandled = false;
+
+ if (m_mappedBusType == PERIPHERAL_BUS_ADDON)
+ {
+ CPeripheralBusAddon* addonBus = static_cast<CPeripheralBusAddon*>(m_bus);
+ if (addonBus)
+ {
+ bHandled = addonBus->SendRumbleEvent(m_strLocation, motorIndex, magnitude);
+ }
+ }
+ return bHandled;
+}
+
+void CPeripheralJoystick::SetMotorCount(unsigned int motorCount)
+{
+ m_motorCount = motorCount;
+
+ if (m_motorCount == 0)
+ m_features.erase(std::remove(m_features.begin(), m_features.end(), FEATURE_RUMBLE), m_features.end());
+ else if (std::find(m_features.begin(), m_features.end(), FEATURE_RUMBLE) == m_features.end())
+ m_features.push_back(FEATURE_RUMBLE);
+}
diff --git a/xbmc/peripherals/devices/PeripheralJoystick.h b/xbmc/peripherals/devices/PeripheralJoystick.h
index 965285e897..b8ef977872 100644
--- a/xbmc/peripherals/devices/PeripheralJoystick.h
+++ b/xbmc/peripherals/devices/PeripheralJoystick.h
@@ -22,6 +22,7 @@
#include "Peripheral.h"
#include "input/joysticks/DefaultJoystick.h"
#include "input/joysticks/IDriverHandler.h"
+#include "input/joysticks/IDriverReceiver.h"
#include "input/joysticks/JoystickMonitor.h"
#include "input/joysticks/JoystickTypes.h"
#include "threads/CriticalSection.h"
@@ -34,7 +35,8 @@
namespace PERIPHERALS
{
class CPeripheralJoystick : public CPeripheral, //! @todo extend CPeripheralHID
- public JOYSTICK::IDriverHandler
+ public JOYSTICK::IDriverHandler,
+ public JOYSTICK::IDriverReceiver
{
public:
CPeripheralJoystick(const PeripheralScanResult& scanResult, CPeripheralBus* bus);
@@ -45,6 +47,7 @@ namespace PERIPHERALS
virtual bool InitialiseFeature(const PeripheralFeature feature) override;
virtual void RegisterJoystickDriverHandler(IDriverHandler* handler, bool bPromiscuous) override;
virtual void UnregisterJoystickDriverHandler(IDriverHandler* handler) override;
+ virtual JOYSTICK::IDriverReceiver* GetDriverReceiver() override { return this; }
// implementation of IDriverHandler
virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override;
@@ -52,6 +55,9 @@ namespace PERIPHERALS
virtual bool OnAxisMotion(unsigned int axisIndex, float position) override;
virtual void ProcessAxisMotions(void) override;
+ // implementation of IDriverReceiver
+ virtual bool SetMotorState(unsigned int motorIndex, float magnitude) override;
+
/*!
* \brief Get the name of the driver or API providing this joystick
*/
@@ -74,18 +80,23 @@ namespace PERIPHERALS
unsigned int ButtonCount(void) const { return m_buttonCount; }
unsigned int HatCount(void) const { return m_hatCount; }
unsigned int AxisCount(void) const { return m_axisCount; }
+ unsigned int MotorCount(void) const { return m_motorCount; }
+ /*!
+ * \brief Set joystick properties
+ */
void SetProvider(const std::string& provider) { m_strProvider = provider; }
void SetRequestedPort(int port) { m_requestedPort = port; }
void SetButtonCount(unsigned int buttonCount) { m_buttonCount = buttonCount; }
void SetHatCount(unsigned int hatCount) { m_hatCount = hatCount; }
void SetAxisCount(unsigned int axisCount) { m_axisCount = axisCount; }
+ void SetMotorCount(unsigned int motorCount); // specialized to update m_features
protected:
struct DriverHandler
{
JOYSTICK::IDriverHandler* handler;
- bool bPromiscuous;
+ bool bPromiscuous;
};
std::string m_strProvider;
@@ -93,6 +104,7 @@ namespace PERIPHERALS
unsigned int m_buttonCount;
unsigned int m_hatCount;
unsigned int m_axisCount;
+ unsigned int m_motorCount;
JOYSTICK::CDefaultJoystick m_defaultInputHandler;
JOYSTICK::CJoystickMonitor m_joystickMonitor;
std::vector<DriverHandler> m_driverHandlers;