/* * 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 */