Skip to content

Commit

Permalink
Merge pull request #24 from kodi-game/subclass
Browse files Browse the repository at this point in the history
Device subclass support
  • Loading branch information
garbear authored Jan 5, 2018
2 parents 0b3642e + 1048b6f commit 622768e
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ void UpdatePort(int port, bool connected, const game_controller* controller)

if (port >= GAME_INPUT_PORT_JOYSTICK_START)
{
const unsigned int device = CInputManager::Get().GetDevice(port);
const unsigned int device = CInputManager::Get().GetDeviceType(port);

if (CLIENT)
CLIENT->retro_set_controller_port_device(port, device);
Expand Down
16 changes: 16 additions & 0 deletions src/input/ButtonMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,22 @@ libretro_device_t CButtonMapper::GetLibretroType(const std::string& strControlle
return deviceType;
}

libretro_subclass_t CButtonMapper::GetSubclass(const std::string& strControllerId)
{
libretro_subclass_t subclass = 0;

for (auto& device : m_devices)
{
if (device->ControllerID() == strControllerId)
{
subclass = device->Subclass();
break;
}
}

return subclass;
}

int CButtonMapper::GetLibretroIndex(const std::string& strControllerId, const std::string& strFeatureName)
{
if (!strControllerId.empty() && !strFeatureName.empty())
Expand Down
2 changes: 2 additions & 0 deletions src/input/ButtonMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace LIBRETRO

libretro_device_t GetLibretroType(const std::string& strControllerId);

libretro_subclass_t GetSubclass(const std::string& strControllerId);

int GetLibretroIndex(const std::string& strControllerId, const std::string& strFeatureName);
libretro_device_t GetLibretroDevice(const std::string& strControllerId, const std::string& strFeatureName) const;
int GetAxisID(const std::string& strControllerId, const std::string& strFeatureName) const;
Expand Down
5 changes: 1 addition & 4 deletions src/input/InputDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,12 @@
#pragma once

#define BUTTONMAP_XML_ROOT "buttonmap"

#define BUTTONMAP_XML_ELM_CONTROLLER "controller"
#define BUTTONMAP_XML_ELM_FEATURE "feature"

#define BUTTONMAP_XML_ATTR_VERSION "version"

#define BUTTONMAP_XML_ATTR_CONTROLLER_ID "id"
#define BUTTONMAP_XML_ATTR_CONTROLLER_TYPE "type"

#define BUTTONMAP_XML_ATTR_CONTROLLER_SUBCLASS "subclass"
#define BUTTONMAP_XML_ATTR_FEATURE_NAME "name"
#define BUTTONMAP_XML_ATTR_FEATURE_MAPTO "mapto"
#define BUTTONMAP_XML_ATTR_FEATURE_AXIS "axis"
35 changes: 27 additions & 8 deletions src/input/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,23 @@ void CInputManager::DeviceConnected(int port, bool bConnected, const game_contro
m_devices[port].reset();
}

libretro_device_t CInputManager::GetDevice(unsigned int port)
libretro_device_t CInputManager::GetDeviceType(unsigned int port) const
{
libretro_device_t deviceType = 0;
libretro_device_t deviceType = RETRO_DEVICE_NONE;

if (m_devices[port])
deviceType = m_devices[port]->Type();
auto it = m_devices.find(port);
if (it != m_devices.end())
{
const auto &device = it->second;
if (device)
{
libretro_subclass_t subclass = device->Subclass();
if (subclass == RETRO_SUBCLASS_NONE)
deviceType = device->Type();
else
deviceType = RETRO_DEVICE_SUBCLASS(device->Type(), subclass);
}
}

return deviceType;
}
Expand Down Expand Up @@ -331,12 +342,20 @@ void CInputManager::SetControllerInfo(const retro_controller_info* info)
const retro_controller_description& type = info->types[i];

libretro_device_t baseType = type.id & RETRO_DEVICE_MASK;
std::string device = LibretroTranslator::GetDeviceName(baseType);
unsigned int subclass = type.id >> RETRO_DEVICE_TYPE_SHIFT;

std::string description = type.desc ? type.desc : "";

dsyslog("Device: \"%s\" (%d), Subclass: %u, Description: \"%s\"",
device.c_str(), static_cast<int>(baseType), subclass, description.c_str());
if (type.id & ~RETRO_DEVICE_MASK)
{
libretro_subclass_t subclass = (type.id >> RETRO_DEVICE_TYPE_SHIFT) - 1;
dsyslog("Device: %s, Subclass: %u, Description: \"%s\"",
LibretroTranslator::GetDeviceName(baseType), subclass, description.c_str());
}
else
{
dsyslog("Device: %s, Description: \"%s\"",
LibretroTranslator::GetDeviceName(baseType), description.c_str());
}
}

dsyslog("------------------------------------------------------------");
Expand Down
2 changes: 1 addition & 1 deletion src/input/InputManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace LIBRETRO
* \brief Get the libretro device abstraction for the device connected to
* the specified port
*/
libretro_device_t GetDevice(unsigned int port);
libretro_device_t GetDeviceType(unsigned int port) const;

bool OpenPort(unsigned int port);
DevicePtr GetPort(unsigned int port);
Expand Down
13 changes: 13 additions & 0 deletions src/input/LibretroDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#include "tinyxml.h"

#include <sstream>

using namespace LIBRETRO;

CLibretroDevice::CLibretroDevice(const game_controller* controller)
Expand All @@ -38,6 +40,7 @@ CLibretroDevice::CLibretroDevice(const game_controller* controller)
{
m_controllerId = controller->controller_id;
m_type = CButtonMapper::Get().GetLibretroType(m_controllerId);
m_subclass = CButtonMapper::Get().GetSubclass(m_controllerId);
}
}

Expand All @@ -50,13 +53,15 @@ bool CLibretroDevice::Deserialize(const TiXmlElement* pElement, unsigned int but
if (!pElement)
return false;

// Controller ID
const char* controllerId = pElement->Attribute(BUTTONMAP_XML_ATTR_CONTROLLER_ID);
if (!controllerId)
{
esyslog("<%s> tag has no \"%s\" attribute", BUTTONMAP_XML_ELM_CONTROLLER, BUTTONMAP_XML_ATTR_CONTROLLER_ID);
return false;
}

// Device type
const char* type = pElement->Attribute(BUTTONMAP_XML_ATTR_CONTROLLER_TYPE);
if (!type)
{
Expand All @@ -77,6 +82,14 @@ bool CLibretroDevice::Deserialize(const TiXmlElement* pElement, unsigned int but
return false;
}

// Device subclass
const char* subclass = pElement->Attribute(BUTTONMAP_XML_ATTR_CONTROLLER_SUBCLASS);
if (subclass)
std::istringstream(subclass) >> m_subclass;
else
m_subclass = RETRO_SUBCLASS_NONE;

// Features
const TiXmlElement* pFeature = pElement->FirstChildElement(BUTTONMAP_XML_ELM_FEATURE);
if (!pFeature)
{
Expand Down
6 changes: 6 additions & 0 deletions src/input/LibretroDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@

class TiXmlElement;

// No subclass
#define RETRO_SUBCLASS_NONE (-1)

namespace LIBRETRO
{
class CLibretroDevice;
typedef std::shared_ptr<CLibretroDevice> DevicePtr;
typedef unsigned int libretro_device_t;
using libretro_subclass_t = int;

struct FeatureMapItem
{
Expand All @@ -52,6 +56,7 @@ namespace LIBRETRO

std::string ControllerID(void) const { return m_controllerId; }
libretro_device_t Type(void) const { return m_type; }
libretro_subclass_t Subclass() const { return m_subclass; }
const FeatureMap& Features(void) const { return m_featureMap; }
CLibretroDeviceInput& Input() { return *m_input; }

Expand All @@ -60,6 +65,7 @@ namespace LIBRETRO
private:
std::string m_controllerId;
libretro_device_t m_type;
libretro_subclass_t m_subclass = RETRO_SUBCLASS_NONE;
FeatureMap m_featureMap;
std::unique_ptr<CLibretroDeviceInput> m_input;
};
Expand Down

0 comments on commit 622768e

Please sign in to comment.