Skip to content
This repository has been archived by the owner on May 16, 2021. It is now read-only.

Commit

Permalink
Merge pull request xbmc#43 from kodi-game/retroplayer
Browse files Browse the repository at this point in the history
Rumble and controller power off
  • Loading branch information
garbear committed Aug 10, 2016
2 parents 6090a90 + 4c2fcf2 commit 5d67d15
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 2 deletions.
2 changes: 1 addition & 1 deletion peripheral.joystick/addon.xml.in
Expand Up @@ -6,7 +6,7 @@
provider-name="Team-Kodi">
<requires>
<c-pluff version="0.1"/>
<import addon="kodi.peripheral" version="1.0.17"/>
<import addon="kodi.peripheral" version="1.0.19"/>
</requires>
<extension
point="kodi.peripheral"
Expand Down
19 changes: 19 additions & 0 deletions src/addon.cpp
Expand Up @@ -207,6 +207,16 @@ void FreeEvents(unsigned int event_count, PERIPHERAL_EVENT* events)
ADDON::PeripheralEvents::FreeStructs(event_count, events);
}

bool SendEvent(const PERIPHERAL_EVENT* event)
{
bool bHandled = false;

if (event != nullptr)
bHandled = CJoystickManager::Get().SendEvent(*event);

return bHandled;
}

PERIPHERAL_ERROR GetJoystickInfo(unsigned int index, JOYSTICK_INFO* info)
{
if (!info)
Expand Down Expand Up @@ -272,4 +282,13 @@ void ResetButtonMap(const JOYSTICK_INFO* joystick, const char* controller_id)
CStorageManager::Get().ResetButtonMap(ADDON::Joystick(*joystick), controller_id);
}

void PowerOffJoystick(unsigned int index)
{
JoystickPtr joystick = CJoystickManager::Get().GetJoystick(index);
if (!joystick || !joystick->SupportsPowerOff())
return;

joystick->PowerOff();
}

} // extern "C"
18 changes: 18 additions & 0 deletions src/api/Joystick.cpp
Expand Up @@ -119,6 +119,24 @@ bool CJoystick::GetEvents(std::vector<ADDON::PeripheralEvent>& events)
return false;
}

bool CJoystick::SendEvent(const ADDON::PeripheralEvent& event)
{
bool bHandled = false;

switch (event.Type())
{
case PERIPHERAL_EVENT_TYPE_SET_MOTOR:
{
bHandled = SetMotor(event.DriverIndex(), event.MotorState());
break;
}
default:
break;
}

return bHandled;
}

void CJoystick::GetButtonEvents(std::vector<ADDON::PeripheralEvent>& events)
{
const std::vector<JOYSTICK_STATE_BUTTON>& buttons = m_stateBuffer.buttons;
Expand Down
7 changes: 7 additions & 0 deletions src/api/Joystick.h
Expand Up @@ -80,6 +80,11 @@ namespace JOYSTICK
*/
virtual bool GetEvents(std::vector<ADDON::PeripheralEvent>& events);

/*!
* Send an event to a joystick
*/
virtual bool SendEvent(const ADDON::PeripheralEvent& event);

/*!
* Tries to power off the joystick.
*/
Expand All @@ -91,6 +96,8 @@ namespace JOYSTICK
*/
virtual bool ScanEvents(void) = 0;

virtual bool SetMotor(unsigned int motorIndex, float magnitude) { return false; }

virtual void SetButtonValue(unsigned int buttonIndex, JOYSTICK_STATE_BUTTON buttonValue);
virtual void SetHatValue(unsigned int hatIndex, JOYSTICK_STATE_HAT hatValue);
virtual void SetAxisValue(unsigned int axisIndex, JOYSTICK_STATE_AXIS axisValue);
Expand Down
19 changes: 19 additions & 0 deletions src/api/JoystickManager.cpp
Expand Up @@ -223,6 +223,25 @@ bool CJoystickManager::GetEvents(std::vector<ADDON::PeripheralEvent>& events)
return true;
}

bool CJoystickManager::SendEvent(const ADDON::PeripheralEvent& event)
{
bool bHandled = false;

CLockObject lock(m_joystickMutex);

for (const JoystickPtr& joystick : m_joysticks)
{
if (joystick->Index() == event.PeripheralIndex())
{
bHandled = joystick->SendEvent(event);
if (bHandled)
break;
}
}

return bHandled;
}

void CJoystickManager::TriggerScan(void)
{
if (m_scanner)
Expand Down
9 changes: 9 additions & 0 deletions src/api/JoystickManager.h
Expand Up @@ -79,6 +79,15 @@ namespace JOYSTICK
*/
bool GetEvents(std::vector<ADDON::PeripheralEvent>& events);

/*!
* \brief Send an event to a joystick
*
* \param event The event
*
* \return True if the event was handled
*/
bool SendEvent(const ADDON::PeripheralEvent& event);

/*!
* \brief Trigger a scan for joysticks through the callback
*/
Expand Down
38 changes: 38 additions & 0 deletions src/api/xinput/JoystickInterfaceXInput.cpp
Expand Up @@ -23,12 +23,37 @@
#include "XInputDLL.h"
#include "api/JoystickTypes.h"

#include <array>
#include <Xinput.h>

using namespace JOYSTICK;

#define MAX_JOYSTICKS 4

// --- DefaultFeatures ---------------------------------------------------------

namespace JOYSTICK
{
struct FeatureStruct
{
const char* controllerId;
const char* name;
JOYSTICK_FEATURE_TYPE type;
unsigned int driverIndex;
};

std::array<FeatureStruct, 4> DefaultFeatures = {
{
{ "game.controller.default", "leftmotor", JOYSTICK_FEATURE_TYPE_MOTOR, CJoystickXInput::MOTOR_LEFT },
{ "game.controller.default", "rightmotor", JOYSTICK_FEATURE_TYPE_MOTOR, CJoystickXInput::MOTOR_RIGHT },
{ "game.controller.ps", "strongmotor", JOYSTICK_FEATURE_TYPE_MOTOR, CJoystickXInput::MOTOR_LEFT },
{ "game.controller.ps", "weakmotor", JOYSTICK_FEATURE_TYPE_MOTOR, CJoystickXInput::MOTOR_RIGHT },
}
};
}

// --- CJoystickInterfaceXInput ------------------------------------------------

const char* CJoystickInterfaceXInput::Name(void) const
{
return INTERFACE_XINPUT;
Expand Down Expand Up @@ -58,3 +83,16 @@ bool CJoystickInterfaceXInput::ScanForJoysticks(JoystickVector& joysticks)

return true;
}

void CJoystickInterfaceXInput::GetFeatures(const std::string& controllerId, FeatureVector& features)
{
for (auto& featureStruct : DefaultFeatures)
{
if (controllerId == featureStruct.controllerId)
{
ADDON::JoystickFeature feature(featureStruct.name, featureStruct.type);
feature.SetPrimitive(ADDON::DriverPrimitive::CreateMotor(featureStruct.driverIndex));
features.push_back(std::move(feature));
}
}
}
1 change: 1 addition & 0 deletions src/api/xinput/JoystickInterfaceXInput.h
Expand Up @@ -34,5 +34,6 @@ namespace JOYSTICK
virtual bool Initialize(void) override;
virtual void Deinitialize(void) override;
virtual bool ScanForJoysticks(JoystickVector& joysticks) override;
virtual void GetFeatures(const std::string& controllerId, FeatureVector& features) override;
};
}
27 changes: 27 additions & 0 deletions src/api/xinput/JoystickXInput.cpp
Expand Up @@ -33,6 +33,7 @@ using namespace JOYSTICK;
#define AXIS_COUNT 6
#define MAX_AXIS 32768
#define MAX_TRIGGER 255
#define MAX_MOTOR 65535

CJoystickXInput::CJoystickXInput(unsigned int controllerID)
: CJoystick(INTERFACE_XINPUT),
Expand All @@ -44,6 +45,12 @@ CJoystickXInput::CJoystickXInput(unsigned int controllerID)
SetButtonCount(BUTTON_COUNT);
SetHatCount(HAT_COUNT);
SetAxisCount(AXIS_COUNT);
SetMotorCount(MOTOR_COUNT);

m_motorSpeeds[MOTOR_LEFT] = 0.0f;
m_motorSpeeds[MOTOR_RIGHT] = 0.0f;

SetSupportsPowerOff(true);
}

bool CJoystickXInput::Equals(const CJoystick* rhs) const
Expand Down Expand Up @@ -97,3 +104,23 @@ bool CJoystickXInput::ScanEvents(void)

return true;
}

bool CJoystickXInput::SetMotor(unsigned int motorIndex, float magnitude)
{
bool bSuccess = false;

if (motorIndex < MOTOR_COUNT && 0.0f <= magnitude && magnitude <= 1.0f)
{
m_motorSpeeds[motorIndex] = magnitude;

XINPUT_VIBRATION vibrationState;

vibrationState.wLeftMotorSpeed = static_cast<WORD>(m_motorSpeeds[MOTOR_LEFT] * MAX_MOTOR);
vibrationState.wRightMotorSpeed = static_cast<WORD>(m_motorSpeeds[MOTOR_RIGHT] * MAX_MOTOR);

// TODO: Only dispatch after both left and right events have been received
bSuccess = CXInputDLL::Get().SetState(m_controllerID, vibrationState);
}

return bSuccess;
}
9 changes: 9 additions & 0 deletions src/api/xinput/JoystickXInput.h
Expand Up @@ -28,6 +28,13 @@ namespace JOYSTICK
class CJoystickXInput : public CJoystick
{
public:
enum
{
MOTOR_LEFT = 0,
MOTOR_RIGHT = 1,
MOTOR_COUNT = 2,
};

CJoystickXInput(unsigned int controllerID);
virtual ~CJoystickXInput(void) { }

Expand All @@ -37,9 +44,11 @@ namespace JOYSTICK

protected:
virtual bool ScanEvents(void) override;
virtual bool SetMotor(unsigned int motorIndex, float magnitude) override;

private:
unsigned int m_controllerID; // XInput port, in the range (0, 3)
DWORD m_dwPacketNumber; // If unchanged, controller state hasn't changed (currently ignored)
float m_motorSpeeds[MOTOR_COUNT];
};
}
1 change: 1 addition & 0 deletions src/storage/ButtonMapDefinitions.h
Expand Up @@ -57,3 +57,4 @@
#define BUTTONMAP_XML_ATTR_FEATURE_BUTTON "button"
#define BUTTONMAP_XML_ATTR_FEATURE_HAT "hat"
#define BUTTONMAP_XML_ATTR_FEATURE_AXIS "axis"
#define BUTTONMAP_XML_ATTR_FEATURE_MOTOR "motor"
3 changes: 2 additions & 1 deletion src/storage/ButtonMapTranslator.cpp
Expand Up @@ -35,6 +35,7 @@ std::string ButtonMapTranslator::ToString(const ADDON::DriverPrimitive& primitiv
switch (primitive.Type())
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
{
strPrimitive << primitive.DriverIndex();
break;
Expand Down Expand Up @@ -74,7 +75,7 @@ ADDON::DriverPrimitive ButtonMapTranslator::ToDriverPrimitive(const std::string&

if (bIsButton)
{
primitive = ADDON::DriverPrimitive(std::atoi(strPrimitive.c_str()));
primitive = ADDON::DriverPrimitive::CreateButton(std::atoi(strPrimitive.c_str()));
}
else if (bIsHat)
{
Expand Down
12 changes: 12 additions & 0 deletions src/storage/xml/ButtonMapXml.cpp
Expand Up @@ -232,6 +232,12 @@ bool CButtonMapXml::Serialize(const FeatureVector& features, TiXmlElement* pElem

break;
}
case JOYSTICK_FEATURE_TYPE_MOTOR:
{
SerializePrimitive(featureElem, feature.Primitive());

break;
}
default:
break;
}
Expand All @@ -247,6 +253,7 @@ bool CButtonMapXml::IsValid(const ADDON::JoystickFeature& feature)
switch (feature.Type())
{
case JOYSTICK_FEATURE_TYPE_SCALAR:
case JOYSTICK_FEATURE_TYPE_MOTOR:
{
if (feature.Primitive().Type() != JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN)
bIsValid = true;
Expand Down Expand Up @@ -324,6 +331,11 @@ void CButtonMapXml::SerializePrimitive(TiXmlElement* pElement, const ADDON::Driv
pElement->SetAttribute(BUTTONMAP_XML_ATTR_FEATURE_AXIS, strPrimitive);
break;
}
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
{
pElement->SetAttribute(BUTTONMAP_XML_ATTR_FEATURE_MOTOR, strPrimitive);
break;
}
default:
break;
}
Expand Down

0 comments on commit 5d67d15

Please sign in to comment.