/*
* Copyright (C) 2014-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
#include "../AddonBase.h"
#include "peripheral/PeripheralUtils.h"
#ifdef __cplusplus
namespace kodi
{
namespace addon
{
//##############################################################################
/// @defgroup cpp_kodi_addon_peripheral_Defs Definitions, structures and enumerators
/// @ingroup cpp_kodi_addon_peripheral
/// @brief %Peripheral add-on general variables
///
/// Used to exchange the available options between Kodi and addon.
///
///
//##############################################################################
/// @defgroup cpp_kodi_addon_peripheral_Defs_General 1. General
/// @ingroup cpp_kodi_addon_peripheral_Defs
/// @brief **%Peripheral add-on general variables**\n
/// Used to exchange the available options between Kodi and addon.
///
/// This group also includes @ref cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities
/// with which Kodi an @ref kodi::addon::CInstancePeripheral::GetCapabilities()
/// queries the supported **modules** of the addon.
///
//##############################################################################
/// @defgroup cpp_kodi_addon_peripheral_Defs_Peripheral 2. Peripheral
/// @ingroup cpp_kodi_addon_peripheral_Defs
/// @brief **%Peripheral add-on operation variables**\n
/// Used to exchange the available options between Kodi and addon.
///
//##############################################################################
/// @defgroup cpp_kodi_addon_peripheral_Defs_Event 3. Event
/// @ingroup cpp_kodi_addon_peripheral_Defs
/// @brief **%Event add-on operation variables**\n
/// Used to exchange the available options between Kodi and addon.
///
//##############################################################################
/// @defgroup cpp_kodi_addon_peripheral_Defs_Joystick 4. Joystick
/// @ingroup cpp_kodi_addon_peripheral_Defs
/// @brief **%Joystick add-on operation variables**\n
/// Used to exchange the available options between Kodi and addon.
///
//==============================================================================
/// @addtogroup cpp_kodi_addon_peripheral
/// @brief \cpp_class{ kodi::addon::CInstancePeripheral }
/// **%Peripheral add-on instance**
///
/// The peripheral add-ons provides access to many joystick and gamepad
/// interfaces across various platforms. An input addon is used to map the
/// buttons/axis on your physical input device, to the buttons/axis of your
/// virtual system. This is necessary because different retro systems usually
/// have different button layouts. A controller configuration utility is also
/// in the works.
///
/// ----------------------------------------------------------------------------
///
/// Here is an example of what the `addon.xml.in` would look like for an
/// peripheral addon:
///
/// ~~~~~~~~~~~~~{.xml}
///
///
/// @ADDON_DEPENDS@
///
///
/// My peripheral addon
/// My peripheral addon description
/// @PLATFORM@
///
///
/// ~~~~~~~~~~~~~
///
/// Description to peripheral related addon.xml values:
/// | Name | Description
/// |:------------------------------|----------------------------------------
/// | `provides_joysticks` | Set to "true" if addon provides joystick support.
/// | `provides_buttonmaps` | Set to "true" if button map is used and supported by addon.
/// | `point` | Addon type specification
At all addon types and for this kind always "kodi.peripheral".
/// | `library_@PLATFORM@` | Sets the used library name, which is automatically set by cmake at addon build.
///
/// @remark For more detailed description of the `addon.xml`, see also https://kodi.wiki/view/Addon.xml.
///
///
/// --------------------------------------------------------------------------
///
/// **Here is an example of how addon can be used as a single:**
/// ~~~~~~~~~~~~~{.cpp}
/// #include
///
/// class CMyPeripheralAddon : public kodi::addon::CAddonBase,
/// public kodi::addon::CInstancePeripheral
/// {
/// public:
/// CMyPeripheralAddon();
///
/// void GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities) override;
/// ...
/// };
///
/// CMyPeripheralAddon::CMyPeripheralAddon()
/// {
/// ...
/// }
///
/// void CMyPeripheralAddon::GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities)
/// {
/// capabilities.SetProvidesJoysticks(true);
/// capabilities.SetProvidesButtonmaps(true);
/// ...
/// }
///
/// ADDONCREATOR(CMyPeripheralAddon)
/// ~~~~~~~~~~~~~
///
/// @note It is imperative to use the necessary functions of this class in the
/// addon.
///
/// --------------------------------------------------------------------------
///
///
/// **Here is another example where the peripheral is used together with
/// other instance types:**
///
/// ~~~~~~~~~~~~~{.cpp}
/// #include
///
/// class CMyPeripheralAddon : public kodi::addon::CInstancePeripheral
/// {
/// public:
/// CMyPeripheralAddon(KODI_HANDLE instance, const std::string& version);
///
/// void GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities) override;
/// ...
/// };
///
/// CMyPeripheralAddon::CMyPeripheralAddon(KODI_HANDLE instance, const std::string& version)
/// : CInstancePeripheral(instance, version)
/// {
/// ...
/// }
///
/// void CMyPeripheralAddon::GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities)
/// {
/// capabilities.SetProvidesJoysticks(true);
/// capabilities.SetProvidesButtonmaps(true);
/// ...
/// }
///
/// //----------------------------------------------------------------------
///
/// class CMyAddon : public kodi::addon::CAddonBase
/// {
/// public:
/// CMyAddon() = default;
/// ADDON_STATUS CreateInstance(int instanceType,
/// const std::string& instanceID,
/// KODI_HANDLE instance,
/// const std::string& version,
/// KODI_HANDLE& addonInstance) override;
/// };
///
/// // If you use only one instance in your add-on, can be instanceType and
/// // instanceID ignored
/// ADDON_STATUS CMyAddon::CreateInstance(int instanceType,
/// const std::string& instanceID,
/// KODI_HANDLE instance,
/// const std::string& version,
/// KODI_HANDLE& addonInstance)
/// {
/// if (instanceType == ADDON_INSTANCE_PERIPHERAL)
/// {
/// kodi::Log(ADDON_LOG_INFO, "Creating my peripheral addon");
/// addonInstance = new CMyPeripheralAddon(instance, version);
/// return ADDON_STATUS_OK;
/// }
/// else if (...)
/// {
/// ...
/// }
/// return ADDON_STATUS_UNKNOWN;
/// }
///
/// ADDONCREATOR(CMyAddon)
/// ~~~~~~~~~~~~~
///
/// The destruction of the example class `CMyPeripheralAddon` is called from
/// Kodi's header. Manually deleting the add-on instance is not required.
///
class ATTRIBUTE_HIDDEN CInstancePeripheral : public IAddonInstance
{
public:
//============================================================================
/// @ingroup cpp_kodi_addon_peripheral
/// @brief %Peripheral class constructor.
///
/// Used by an add-on that only supports peripheral.
///
CInstancePeripheral()
: IAddonInstance(ADDON_INSTANCE_PERIPHERAL, GetKodiTypeVersion(ADDON_INSTANCE_PERIPHERAL))
{
if (CAddonBase::m_interface->globalSingleInstance != nullptr)
throw std::logic_error("kodi::addon::CInstancePeripheral: Creation of more as one in single "
"instance way is not allowed!");
SetAddonStruct(CAddonBase::m_interface->firstKodiInstance);
CAddonBase::m_interface->globalSingleInstance = this;
}
//----------------------------------------------------------------------------
//============================================================================
/// @ingroup cpp_kodi_addon_peripheral
/// @brief %Peripheral addon class constructor used to support multiple
/// instance types.
///
/// @param[in] instance The instance value given to
/// `kodi::addon::CAddonBase::CreateInstance(...)`.
/// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to
/// allow compatibility to older Kodi versions.
///
/// @note Recommended to set `kodiVersion`.
///
///
/// --------------------------------------------------------------------------
///
//////*Here's example about the use of this:**
/// ~~~~~~~~~~~~~{.cpp}
/// class CMyPeripheralAddon : public kodi::addon::CInstancePeripheral
/// {
/// public:
/// CMyPeripheralAddon(KODI_HANDLE instance, const std::string& kodiVersion)
/// : kodi::addon::CInstancePeripheral(instance, kodiVersion)
/// {
/// ...
/// }
///
/// ...
/// };
///
/// ADDON_STATUS CMyAddon::CreateInstance(int instanceType,
/// const std::string& instanceID,
/// KODI_HANDLE instance,
/// const std::string& version,
/// KODI_HANDLE& addonInstance)
/// {
/// kodi::Log(ADDON_LOG_INFO, "Creating my peripheral");
/// addonInstance = new CMyPeripheralAddon(instance, version);
/// return ADDON_STATUS_OK;
/// }
/// ~~~~~~~~~~~~~
///
explicit CInstancePeripheral(KODI_HANDLE instance, const std::string& kodiVersion = "")
: IAddonInstance(ADDON_INSTANCE_PERIPHERAL,
!kodiVersion.empty() ? kodiVersion
: GetKodiTypeVersion(ADDON_INSTANCE_PERIPHERAL))
{
if (CAddonBase::m_interface->globalSingleInstance != nullptr)
throw std::logic_error("kodi::addon::CInstancePeripheral: Creation of multiple together with "
"single instance way is not allowed!");
SetAddonStruct(instance);
}
//----------------------------------------------------------------------------
//============================================================================
/// @ingroup cpp_kodi_addon_peripheral
/// @brief Destructor.
///
~CInstancePeripheral() override = default;
//----------------------------------------------------------------------------
//============================================================================
/// @defgroup cpp_kodi_addon_peripheral_peripheralOp 1. Peripheral operations
/// @ingroup cpp_kodi_addon_peripheral
/// @brief %Peripheral operations to handle control about.
///
///---------------------------------------------------------------------------
///
/// **%Peripheral parts in interface:**\n
/// Copy this to your project and extend with your parts or leave functions
/// complete away where not used or supported.
///
/// @copydetails cpp_kodi_addon_peripheral_peripheralOp_header_addon_auto_check
/// @copydetails cpp_kodi_addon_peripheral_peripheralOp_source_addon_auto_check
///
///@{
//============================================================================
/// @brief Get the list of features that this add-on provides.
///
/// Called by the frontend to query the add-on's capabilities and supported
/// peripherals. All capabilities that the add-on supports should be set to true.
///
/// @param[out] capabilities The add-on's capabilities
///
/// @remarks Valid implementation required.
///
///
/// ----------------------------------------------------------------------------
///
/// @copydetails cpp_kodi_addon_peripheral_Defs_PeripheralCapabilities_Help
///
/// --------------------------------------------------------------------------
///
/// **Example:**
/// ~~~~~~~~~~~~~{.cpp}
/// void CMyPeripheralAddon::GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities)
/// {
/// capabilities.SetProvidesJoysticks(true);
/// capabilities.SetProvidesButtonmaps(true);
/// }
/// ~~~~~~~~~~~~~
///
virtual void GetCapabilities(kodi::addon::PeripheralCapabilities& capabilities) {}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Perform a scan for joysticks
///
/// The frontend calls this when a hardware change is detected. If an add-on
/// detects a hardware change, it can trigger this function using the
/// @ref TriggerScan() callback.
///
/// @param[in] scan_results Assigned to allocated memory
/// @return @ref PERIPHERAL_NO_ERROR if successful
///
///
/// --------------------------------------------------------------------------
///
/// @copydetails cpp_kodi_addon_peripheral_Defs_Peripheral_Peripheral_Help
///
virtual PERIPHERAL_ERROR PerformDeviceScan(
std::vector>& scan_results)
{
return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Get all events that have occurred since the last call to
/// @ref GetEvents().
///
/// @param[out] events List of available events within addon
/// @return @ref PERIPHERAL_NO_ERROR if successful
///
/// ----------------------------------------------------------------------------
///
/// @copydetails cpp_kodi_addon_peripheral_Defs_Peripheral_PeripheralEvent_Help
///
virtual PERIPHERAL_ERROR GetEvents(std::vector& events)
{
return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Send an input event to the peripheral.
///
/// @param[in] event The input event
/// @return true if the event was handled, false otherwise
///
virtual bool SendEvent(const kodi::addon::PeripheralEvent& event) { return false; }
//----------------------------------------------------------------------------
///@}
//============================================================================
/// @defgroup cpp_kodi_addon_peripheral_joystickOp 2. Joystick operations
/// @ingroup cpp_kodi_addon_peripheral
/// @brief %Joystick operations to handle control about.
///
///
///---------------------------------------------------------------------------
///
/// **%Joystick parts in interface:**\n
/// Copy this to your project and extend with your parts or leave functions
/// complete away where not used or supported.
///
/// @copydetails cpp_kodi_addon_peripheral_joystickOp_header_addon_auto_check
/// @copydetails cpp_kodi_addon_peripheral_joystickOp_source_addon_auto_check
///
///@{
//============================================================================
/// @brief Get extended info about an attached joystick.
///
/// @param[in] index The joystick's driver index
/// @param[out] info The container for the allocated joystick info
/// @return @ref PERIPHERAL_NO_ERROR if successful
///
///
/// ----------------------------------------------------------------------------
///
/// @copydetails cpp_kodi_addon_peripheral_Defs_Joystick_Joystick_Help
///
virtual PERIPHERAL_ERROR GetJoystickInfo(unsigned int index, kodi::addon::Joystick& info)
{
return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Get the features that allow translating the joystick into the
/// controller profile.
///
/// @param[in] joystick The device's joystick properties; unknown values may
/// be left at their default
/// @param[in] controller_id The controller profile being requested, e.g.
/// `game.controller.default`
/// @param[out] features The array of allocated features
/// @return @ref PERIPHERAL_NO_ERROR if successful
///
virtual PERIPHERAL_ERROR GetFeatures(const kodi::addon::Joystick& joystick,
const std::string& controller_id,
std::vector& features)
{
return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Add or update joystick features.
///
/// @param[in] joystick The device's joystick properties; unknown values may be
/// left at their default
/// @param[in] controller_id The game controller profile being updated
/// @param[in] features The array of features
/// @return @ref PERIPHERAL_NO_ERROR if successful
///
virtual PERIPHERAL_ERROR MapFeatures(const kodi::addon::Joystick& joystick,
const std::string& controller_id,
const std::vector& features)
{
return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Get the driver primitives that should be ignored while mapping the
/// device.
///
/// @param[in] joystick The device's joystick properties; unknown values may
/// be left at their default
/// @param[out] primitives The array of allocated driver primitives to be
/// ignored
/// @return @ref PERIPHERAL_NO_ERROR if successful
///
virtual PERIPHERAL_ERROR GetIgnoredPrimitives(
const kodi::addon::Joystick& joystick, std::vector& primitives)
{
return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Set the list of driver primitives that are ignored for the device.
///
/// @param[in] joystick The device's joystick properties; unknown values may be left at their default
/// @param[in] primitives The array of driver primitives to ignore
/// @return @ref PERIPHERAL_NO_ERROR if successful
///
virtual PERIPHERAL_ERROR SetIgnoredPrimitives(
const kodi::addon::Joystick& joystick,
const std::vector& primitives)
{
return PERIPHERAL_ERROR_NOT_IMPLEMENTED;
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Save the button map for the given joystick.
///
/// @param[in] joystick The device's joystick properties
///
virtual void SaveButtonMap(const kodi::addon::Joystick& joystick) {}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Revert the button map to the last time it was loaded or committed to disk
/// @param[in] joystick The device's joystick properties
///
virtual void RevertButtonMap(const kodi::addon::Joystick& joystick) {}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Reset the button map for the given joystick and controller profile ID
/// @param[in] joystick The device's joystick properties
/// @param[in] controller_id The game controller profile being reset
///
virtual void ResetButtonMap(const kodi::addon::Joystick& joystick,
const std::string& controller_id)
{
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Powers off the given joystick if supported
/// @param[in] index The joystick's driver index
///
virtual void PowerOffJoystick(unsigned int index) {}
//----------------------------------------------------------------------------
///@}
//============================================================================
/// @defgroup cpp_kodi_addon_peripheral_callbacks 3. Callback functions
/// @ingroup cpp_kodi_addon_peripheral
/// @brief Callback to Kodi functions.
///
///@{
//============================================================================
/// @brief Used to get the full path where the add-on is installed.
///
/// @return The add-on installation path
///
const std::string AddonPath() const { return m_instanceData->props->addon_path; }
//----------------------------------------------------------------------------
//============================================================================
/// @brief Used to get the full path to the add-on's user profile.
///
/// @note The trailing folder (consisting of the add-on's ID) is not created
/// by default. If it is needed, you must call kodi::vfs::CreateDirectory()
/// to create the folder.
///
/// @return Path to the user profile
///
const std::string UserPath() const { return m_instanceData->props->user_path; }
//----------------------------------------------------------------------------
//============================================================================
/// @brief Trigger a scan for peripherals
///
/// The add-on calls this if a change in hardware is detected.
///
void TriggerScan(void)
{
return m_instanceData->toKodi->trigger_scan(m_instanceData->toKodi->kodiInstance);
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Notify the frontend that button maps have changed.
///
/// @param[in] deviceName [optional] The name of the device to refresh, or
/// empty/null for all devices
/// @param[in] controllerId [optional] The controller ID to refresh, or
/// empty/null for all controllers
///
void RefreshButtonMaps(const std::string& deviceName = "", const std::string& controllerId = "")
{
return m_instanceData->toKodi->refresh_button_maps(m_instanceData->toKodi->kodiInstance,
deviceName.c_str(), controllerId.c_str());
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Return the number of features belonging to the specified
/// controller.
///
/// @param[in] controllerId The controller ID to enumerate
/// @param[in] type [optional] Type to filter by, or @ref JOYSTICK_FEATURE_TYPE_UNKNOWN
/// for all features
/// @return The number of features matching the request parameters
///
unsigned int FeatureCount(const std::string& controllerId,
JOYSTICK_FEATURE_TYPE type = JOYSTICK_FEATURE_TYPE_UNKNOWN)
{
return m_instanceData->toKodi->feature_count(m_instanceData->toKodi->kodiInstance,
controllerId.c_str(), type);
}
//----------------------------------------------------------------------------
//============================================================================
/// @brief Return the type of the feature.
///
/// @param[in] controllerId The controller ID to check
/// @param[in] featureName The feature to check
/// @return The type of the specified feature, or @ref JOYSTICK_FEATURE_TYPE_UNKNOWN
/// if unknown
///
JOYSTICK_FEATURE_TYPE FeatureType(const std::string& controllerId, const std::string& featureName)
{
return m_instanceData->toKodi->feature_type(m_instanceData->toKodi->kodiInstance,
controllerId.c_str(), featureName.c_str());
}
//----------------------------------------------------------------------------
///@}
private:
void SetAddonStruct(KODI_HANDLE instance)
{
if (instance == nullptr)
throw std::logic_error("kodi::addon::CInstancePeripheral: Creation with empty addon "
"structure not allowed, table must be given from Kodi!");
m_instanceData = static_cast(instance);
m_instanceData->toAddon->addonInstance = this;
m_instanceData->toAddon->get_capabilities = ADDON_GetCapabilities;
m_instanceData->toAddon->perform_device_scan = ADDON_PerformDeviceScan;
m_instanceData->toAddon->free_scan_results = ADDON_FreeScanResults;
m_instanceData->toAddon->get_events = ADDON_GetEvents;
m_instanceData->toAddon->free_events = ADDON_FreeEvents;
m_instanceData->toAddon->send_event = ADDON_SendEvent;
m_instanceData->toAddon->get_joystick_info = ADDON_GetJoystickInfo;
m_instanceData->toAddon->free_joystick_info = ADDON_FreeJoystickInfo;
m_instanceData->toAddon->get_features = ADDON_GetFeatures;
m_instanceData->toAddon->free_features = ADDON_FreeFeatures;
m_instanceData->toAddon->map_features = ADDON_MapFeatures;
m_instanceData->toAddon->get_ignored_primitives = ADDON_GetIgnoredPrimitives;
m_instanceData->toAddon->free_primitives = ADDON_FreePrimitives;
m_instanceData->toAddon->set_ignored_primitives = ADDON_SetIgnoredPrimitives;
m_instanceData->toAddon->save_button_map = ADDON_SaveButtonMap;
m_instanceData->toAddon->revert_button_map = ADDON_RevertButtonMap;
m_instanceData->toAddon->reset_button_map = ADDON_ResetButtonMap;
m_instanceData->toAddon->power_off_joystick = ADDON_PowerOffJoystick;
}
inline static void ADDON_GetCapabilities(const AddonInstance_Peripheral* addonInstance,
PERIPHERAL_CAPABILITIES* capabilities)
{
if (!addonInstance || !capabilities)
return;
kodi::addon::PeripheralCapabilities peripheralCapabilities(capabilities);
static_cast(addonInstance->toAddon->addonInstance)
->GetCapabilities(peripheralCapabilities);
}
inline static PERIPHERAL_ERROR ADDON_PerformDeviceScan(
const AddonInstance_Peripheral* addonInstance,
unsigned int* peripheral_count,
PERIPHERAL_INFO** scan_results)
{
if (!addonInstance || !peripheral_count || !scan_results)
return PERIPHERAL_ERROR_INVALID_PARAMETERS;
std::vector> peripherals;
PERIPHERAL_ERROR err = static_cast(addonInstance->toAddon->addonInstance)
->PerformDeviceScan(peripherals);
if (err == PERIPHERAL_NO_ERROR)
{
*peripheral_count = static_cast(peripherals.size());
kodi::addon::Peripherals::ToStructs(peripherals, scan_results);
}
return err;
}
inline static void ADDON_FreeScanResults(const AddonInstance_Peripheral* addonInstance,
unsigned int peripheral_count,
PERIPHERAL_INFO* scan_results)
{
if (!addonInstance)
return;
kodi::addon::Peripherals::FreeStructs(peripheral_count, scan_results);
}
inline static PERIPHERAL_ERROR ADDON_GetEvents(const AddonInstance_Peripheral* addonInstance,
unsigned int* event_count,
PERIPHERAL_EVENT** events)
{
if (!addonInstance || !event_count || !events)
return PERIPHERAL_ERROR_INVALID_PARAMETERS;
std::vector peripheralEvents;
PERIPHERAL_ERROR err = static_cast(addonInstance->toAddon->addonInstance)
->GetEvents(peripheralEvents);
if (err == PERIPHERAL_NO_ERROR)
{
*event_count = static_cast(peripheralEvents.size());
kodi::addon::PeripheralEvents::ToStructs(peripheralEvents, events);
}
return err;
}
inline static void ADDON_FreeEvents(const AddonInstance_Peripheral* addonInstance,
unsigned int event_count,
PERIPHERAL_EVENT* events)
{
if (!addonInstance)
return;
kodi::addon::PeripheralEvents::FreeStructs(event_count, events);
}
inline static bool ADDON_SendEvent(const AddonInstance_Peripheral* addonInstance,
const PERIPHERAL_EVENT* event)
{
if (!addonInstance || !event)
return false;
return static_cast(addonInstance->toAddon->addonInstance)
->SendEvent(kodi::addon::PeripheralEvent(*event));
}
inline static PERIPHERAL_ERROR ADDON_GetJoystickInfo(
const AddonInstance_Peripheral* addonInstance, unsigned int index, JOYSTICK_INFO* info)
{
if (!addonInstance || !info)
return PERIPHERAL_ERROR_INVALID_PARAMETERS;
kodi::addon::Joystick addonInfo;
PERIPHERAL_ERROR err = static_cast(addonInstance->toAddon->addonInstance)
->GetJoystickInfo(index, addonInfo);
if (err == PERIPHERAL_NO_ERROR)
{
addonInfo.ToStruct(*info);
}
return err;
}
inline static void ADDON_FreeJoystickInfo(const AddonInstance_Peripheral* addonInstance,
JOYSTICK_INFO* info)
{
if (!addonInstance)
return;
kodi::addon::Joystick::FreeStruct(*info);
}
inline static PERIPHERAL_ERROR ADDON_GetFeatures(const AddonInstance_Peripheral* addonInstance,
const JOYSTICK_INFO* joystick,
const char* controller_id,
unsigned int* feature_count,
JOYSTICK_FEATURE** features)
{
if (!addonInstance || !joystick || !controller_id || !feature_count || !features)
return PERIPHERAL_ERROR_INVALID_PARAMETERS;
kodi::addon::Joystick addonJoystick(*joystick);
std::vector featuresVector;
PERIPHERAL_ERROR err = static_cast(addonInstance->toAddon->addonInstance)
->GetFeatures(addonJoystick, controller_id, featuresVector);
if (err == PERIPHERAL_NO_ERROR)
{
*feature_count = static_cast(featuresVector.size());
kodi::addon::JoystickFeatures::ToStructs(featuresVector, features);
}
return err;
}
inline static void ADDON_FreeFeatures(const AddonInstance_Peripheral* addonInstance,
unsigned int feature_count,
JOYSTICK_FEATURE* features)
{
if (!addonInstance)
return;
kodi::addon::JoystickFeatures::FreeStructs(feature_count, features);
}
inline static PERIPHERAL_ERROR ADDON_MapFeatures(const AddonInstance_Peripheral* addonInstance,
const JOYSTICK_INFO* joystick,
const char* controller_id,
unsigned int feature_count,
const JOYSTICK_FEATURE* features)
{
if (!addonInstance || !joystick || !controller_id || (feature_count > 0 && !features))
return PERIPHERAL_ERROR_INVALID_PARAMETERS;
kodi::addon::Joystick addonJoystick(*joystick);
std::vector primitiveVector;
for (unsigned int i = 0; i < feature_count; i++)
primitiveVector.emplace_back(*(features + i));
return static_cast(addonInstance->toAddon->addonInstance)
->MapFeatures(addonJoystick, controller_id, primitiveVector);
}
inline static PERIPHERAL_ERROR ADDON_GetIgnoredPrimitives(
const AddonInstance_Peripheral* addonInstance,
const JOYSTICK_INFO* joystick,
unsigned int* primitive_count,
JOYSTICK_DRIVER_PRIMITIVE** primitives)
{
if (!addonInstance || !joystick || !primitive_count || !primitives)
return PERIPHERAL_ERROR_INVALID_PARAMETERS;
kodi::addon::Joystick addonJoystick(*joystick);
std::vector primitiveVector;
PERIPHERAL_ERROR err = static_cast(addonInstance->toAddon->addonInstance)
->GetIgnoredPrimitives(addonJoystick, primitiveVector);
if (err == PERIPHERAL_NO_ERROR)
{
*primitive_count = static_cast(primitiveVector.size());
kodi::addon::DriverPrimitives::ToStructs(primitiveVector, primitives);
}
return err;
}
inline static void ADDON_FreePrimitives(const AddonInstance_Peripheral* addonInstance,
unsigned int primitive_count,
JOYSTICK_DRIVER_PRIMITIVE* primitives)
{
if (!addonInstance)
return;
kodi::addon::DriverPrimitives::FreeStructs(primitive_count, primitives);
}
inline static PERIPHERAL_ERROR ADDON_SetIgnoredPrimitives(
const AddonInstance_Peripheral* addonInstance,
const JOYSTICK_INFO* joystick,
unsigned int primitive_count,
const JOYSTICK_DRIVER_PRIMITIVE* primitives)
{
if (!addonInstance || !joystick || (primitive_count > 0 && !primitives))
return PERIPHERAL_ERROR_INVALID_PARAMETERS;
kodi::addon::Joystick addonJoystick(*joystick);
std::vector primitiveVector;
for (unsigned int i = 0; i < primitive_count; i++)
primitiveVector.emplace_back(*(primitives + i));
return static_cast(addonInstance->toAddon->addonInstance)
->SetIgnoredPrimitives(addonJoystick, primitiveVector);
}
inline static void ADDON_SaveButtonMap(const AddonInstance_Peripheral* addonInstance,
const JOYSTICK_INFO* joystick)
{
if (!addonInstance || !joystick)
return;
kodi::addon::Joystick addonJoystick(*joystick);
static_cast(addonInstance->toAddon->addonInstance)
->SaveButtonMap(addonJoystick);
}
inline static void ADDON_RevertButtonMap(const AddonInstance_Peripheral* addonInstance,
const JOYSTICK_INFO* joystick)
{
if (!addonInstance || !joystick)
return;
kodi::addon::Joystick addonJoystick(*joystick);
static_cast(addonInstance->toAddon->addonInstance)
->RevertButtonMap(addonJoystick);
}
inline static void ADDON_ResetButtonMap(const AddonInstance_Peripheral* addonInstance,
const JOYSTICK_INFO* joystick,
const char* controller_id)
{
if (!addonInstance || !joystick || !controller_id)
return;
kodi::addon::Joystick addonJoystick(*joystick);
static_cast(addonInstance->toAddon->addonInstance)
->ResetButtonMap(addonJoystick, controller_id);
}
inline static void ADDON_PowerOffJoystick(const AddonInstance_Peripheral* addonInstance,
unsigned int index)
{
if (!addonInstance)
return;
static_cast(addonInstance->toAddon->addonInstance)
->PowerOffJoystick(index);
}
AddonInstance_Peripheral* m_instanceData;
};
} /* namespace addon */
} /* namespace kodi */
#endif /* __cplusplus */