diff options
Diffstat (limited to 'xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h')
| -rw-r--r-- | xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h | 1190 |
1 files changed, 1190 insertions, 0 deletions
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h new file mode 100644 index 0000000..3dca94d --- /dev/null +++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/Game.h | |||
| @@ -0,0 +1,1190 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014-2018 Team Kodi | ||
| 3 | * This file is part of Kodi - https://kodi.tv | ||
| 4 | * | ||
| 5 | * SPDX-License-Identifier: GPL-2.0-or-later | ||
| 6 | * See LICENSES/README.md for more information. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #pragma once | ||
| 10 | |||
| 11 | #include "../AddonBase.h" | ||
| 12 | #include "../c-api/addon-instance/game.h" | ||
| 13 | |||
| 14 | #ifdef __cplusplus | ||
| 15 | |||
| 16 | namespace kodi | ||
| 17 | { | ||
| 18 | namespace addon | ||
| 19 | { | ||
| 20 | |||
| 21 | //============================================================================== | ||
| 22 | /// @addtogroup cpp_kodi_addon_game | ||
| 23 | /// | ||
| 24 | /// To use on Libretro and for stand-alone games or emulators that does not use | ||
| 25 | /// the Libretro API. | ||
| 26 | /// | ||
| 27 | /// Possible examples could be, Nvidia GameStream via Limelight or WINE capture | ||
| 28 | /// could possible through the Game API. | ||
| 29 | /// | ||
| 30 | |||
| 31 | //============================================================================== | ||
| 32 | /// @defgroup cpp_kodi_addon_game_Defs Definitions, structures and enumerators | ||
| 33 | /// @ingroup cpp_kodi_addon_game | ||
| 34 | /// @brief **Game add-on instance definition values** | ||
| 35 | /// | ||
| 36 | |||
| 37 | //============================================================================== | ||
| 38 | /// @defgroup cpp_kodi_addon_game_Defs_InputTypes_GameControllerLayout class GameControllerLayout | ||
| 39 | /// @ingroup cpp_kodi_addon_game_Defs_InputTypes | ||
| 40 | /// @brief Data of layouts for known controllers. | ||
| 41 | /// | ||
| 42 | /// Used on @ref kodi::addon::CInstanceGame::SetControllerLayouts(). | ||
| 43 | ///@{ | ||
| 44 | class GameControllerLayout | ||
| 45 | { | ||
| 46 | public: | ||
| 47 | /*! @cond PRIVATE */ | ||
| 48 | explicit GameControllerLayout() = default; | ||
| 49 | GameControllerLayout(const game_controller_layout& layout) | ||
| 50 | { | ||
| 51 | controller_id = layout.controller_id; | ||
| 52 | provides_input = layout.provides_input; | ||
| 53 | for (unsigned int i = 0; i < layout.digital_button_count; ++i) | ||
| 54 | digital_buttons.push_back(layout.digital_buttons[i]); | ||
| 55 | for (unsigned int i = 0; i < layout.analog_button_count; ++i) | ||
| 56 | analog_buttons.push_back(layout.analog_buttons[i]); | ||
| 57 | for (unsigned int i = 0; i < layout.analog_stick_count; ++i) | ||
| 58 | analog_sticks.push_back(layout.analog_sticks[i]); | ||
| 59 | for (unsigned int i = 0; i < layout.accelerometer_count; ++i) | ||
| 60 | accelerometers.push_back(layout.accelerometers[i]); | ||
| 61 | for (unsigned int i = 0; i < layout.key_count; ++i) | ||
| 62 | keys.push_back(layout.keys[i]); | ||
| 63 | for (unsigned int i = 0; i < layout.rel_pointer_count; ++i) | ||
| 64 | rel_pointers.push_back(layout.rel_pointers[i]); | ||
| 65 | for (unsigned int i = 0; i < layout.abs_pointer_count; ++i) | ||
| 66 | abs_pointers.push_back(layout.abs_pointers[i]); | ||
| 67 | for (unsigned int i = 0; i < layout.motor_count; ++i) | ||
| 68 | motors.push_back(layout.motors[i]); | ||
| 69 | } | ||
| 70 | /*! @endcond */ | ||
| 71 | |||
| 72 | /// @brief Controller identifier. | ||
| 73 | std::string controller_id; | ||
| 74 | |||
| 75 | /// @brief Provides input. | ||
| 76 | /// | ||
| 77 | /// False for multitaps | ||
| 78 | bool provides_input; | ||
| 79 | |||
| 80 | /// @brief Digital buttons. | ||
| 81 | std::vector<std::string> digital_buttons; | ||
| 82 | |||
| 83 | /// @brief Analog buttons. | ||
| 84 | std::vector<std::string> analog_buttons; | ||
| 85 | |||
| 86 | /// @brief Analog sticks. | ||
| 87 | std::vector<std::string> analog_sticks; | ||
| 88 | |||
| 89 | /// @brief Accelerometers. | ||
| 90 | std::vector<std::string> accelerometers; | ||
| 91 | |||
| 92 | /// @brief Keys. | ||
| 93 | std::vector<std::string> keys; | ||
| 94 | |||
| 95 | /// @brief Relative pointers. | ||
| 96 | std::vector<std::string> rel_pointers; | ||
| 97 | |||
| 98 | /// @brief Absolute pointers. | ||
| 99 | std::vector<std::string> abs_pointers; | ||
| 100 | |||
| 101 | /// @brief Motors. | ||
| 102 | std::vector<std::string> motors; | ||
| 103 | }; | ||
| 104 | ///@} | ||
| 105 | //------------------------------------------------------------------------------ | ||
| 106 | |||
| 107 | //============================================================================== | ||
| 108 | /// @addtogroup cpp_kodi_addon_game | ||
| 109 | /// @brief @cpp_class{ kodi::addon::CInstanceGame } | ||
| 110 | /// **Game add-on instance**\n | ||
| 111 | /// This class provides the basic game processing system for use as an add-on in | ||
| 112 | /// Kodi. | ||
| 113 | /// | ||
| 114 | /// This class is created at addon by Kodi. | ||
| 115 | /// | ||
| 116 | class ATTRIBUTE_HIDDEN CInstanceGame : public IAddonInstance | ||
| 117 | { | ||
| 118 | public: | ||
| 119 | //============================================================================ | ||
| 120 | /// @defgroup cpp_kodi_addon_game_Base 1. Basic functions | ||
| 121 | /// @ingroup cpp_kodi_addon_game | ||
| 122 | /// @brief **Functions to manage the addon and get basic information about it** | ||
| 123 | /// | ||
| 124 | ///@{ | ||
| 125 | |||
| 126 | //============================================================================ | ||
| 127 | /// @brief Game class constructor | ||
| 128 | /// | ||
| 129 | /// Used by an add-on that only supports only Game and only in one instance. | ||
| 130 | /// | ||
| 131 | /// This class is created at addon by Kodi. | ||
| 132 | /// | ||
| 133 | /// | ||
| 134 | /// -------------------------------------------------------------------------- | ||
| 135 | /// | ||
| 136 | /// | ||
| 137 | /// **Here's example about the use of this:** | ||
| 138 | /// ~~~~~~~~~~~~~{.cpp} | ||
| 139 | /// #include <kodi/addon-instance/Game.h> | ||
| 140 | /// ... | ||
| 141 | /// | ||
| 142 | /// class ATTRIBUTE_HIDDEN CGameExample | ||
| 143 | /// : public kodi::addon::CAddonBase, | ||
| 144 | /// public kodi::addon::CInstanceGame | ||
| 145 | /// { | ||
| 146 | /// public: | ||
| 147 | /// CGameExample() | ||
| 148 | /// { | ||
| 149 | /// } | ||
| 150 | /// | ||
| 151 | /// virtual ~CGameExample(); | ||
| 152 | /// { | ||
| 153 | /// } | ||
| 154 | /// | ||
| 155 | /// ... | ||
| 156 | /// }; | ||
| 157 | /// | ||
| 158 | /// ADDONCREATOR(CGameExample) | ||
| 159 | /// ~~~~~~~~~~~~~ | ||
| 160 | /// | ||
| 161 | CInstanceGame() : IAddonInstance(ADDON_INSTANCE_GAME, GetKodiTypeVersion(ADDON_INSTANCE_GAME)) | ||
| 162 | { | ||
| 163 | if (CAddonBase::m_interface->globalSingleInstance != nullptr) | ||
| 164 | throw std::logic_error("kodi::addon::CInstanceGame: Creation of more as one in single " | ||
| 165 | "instance way is not allowed!"); | ||
| 166 | |||
| 167 | SetAddonStruct(CAddonBase::m_interface->firstKodiInstance); | ||
| 168 | CAddonBase::m_interface->globalSingleInstance = this; | ||
| 169 | } | ||
| 170 | //---------------------------------------------------------------------------- | ||
| 171 | |||
| 172 | //============================================================================ | ||
| 173 | /// @brief Destructor | ||
| 174 | /// | ||
| 175 | ~CInstanceGame() override = default; | ||
| 176 | //---------------------------------------------------------------------------- | ||
| 177 | |||
| 178 | //============================================================================ | ||
| 179 | /// @brief **Callback to Kodi Function**\n | ||
| 180 | /// The path of the game client being loaded. | ||
| 181 | /// | ||
| 182 | /// @return the used game client Dll path | ||
| 183 | /// | ||
| 184 | /// @remarks Only called from addon itself | ||
| 185 | /// | ||
| 186 | std::string GameClientDllPath() const { return m_instanceData->props->game_client_dll_path; } | ||
| 187 | //---------------------------------------------------------------------------- | ||
| 188 | |||
| 189 | //============================================================================ | ||
| 190 | /// @brief **Callback to Kodi Function**\n | ||
| 191 | /// Paths to proxy DLLs used to load the game client. | ||
| 192 | /// | ||
| 193 | /// @param[out] paths vector list to store available dll paths | ||
| 194 | /// @return true if success and dll paths present | ||
| 195 | /// | ||
| 196 | /// @remarks Only called from addon itself | ||
| 197 | /// | ||
| 198 | bool ProxyDllPaths(std::vector<std::string>& paths) | ||
| 199 | { | ||
| 200 | for (unsigned int i = 0; i < m_instanceData->props->proxy_dll_count; ++i) | ||
| 201 | { | ||
| 202 | if (m_instanceData->props->proxy_dll_paths[i] != nullptr) | ||
| 203 | paths.push_back(m_instanceData->props->proxy_dll_paths[i]); | ||
| 204 | } | ||
| 205 | return !paths.empty(); | ||
| 206 | } | ||
| 207 | //---------------------------------------------------------------------------- | ||
| 208 | |||
| 209 | //============================================================================ | ||
| 210 | /// @brief **Callback to Kodi Function**\n | ||
| 211 | /// The "system" directories of the frontend. | ||
| 212 | /// | ||
| 213 | /// These directories can be used to store system-specific ROMs such as | ||
| 214 | /// BIOSes, configuration data, etc. | ||
| 215 | /// | ||
| 216 | /// @return the used resource directory | ||
| 217 | /// | ||
| 218 | /// @remarks Only called from addon itself | ||
| 219 | /// | ||
| 220 | bool ResourceDirectories(std::vector<std::string>& dirs) | ||
| 221 | { | ||
| 222 | for (unsigned int i = 0; i < m_instanceData->props->resource_directory_count; ++i) | ||
| 223 | { | ||
| 224 | if (m_instanceData->props->resource_directories[i] != nullptr) | ||
| 225 | dirs.push_back(m_instanceData->props->resource_directories[i]); | ||
| 226 | } | ||
| 227 | return !dirs.empty(); | ||
| 228 | } | ||
| 229 | //---------------------------------------------------------------------------- | ||
| 230 | |||
| 231 | //============================================================================ | ||
| 232 | /// @brief **Callback to Kodi Function**\n | ||
| 233 | /// The writable directory of the frontend. | ||
| 234 | /// | ||
| 235 | /// This directory can be used to store SRAM, memory cards, high scores, | ||
| 236 | /// etc, if the game client cannot use the regular memory interface, | ||
| 237 | /// GetMemoryData(). | ||
| 238 | /// | ||
| 239 | /// @return the used profile directory | ||
| 240 | /// | ||
| 241 | /// @remarks Only called from addon itself | ||
| 242 | /// | ||
| 243 | std::string ProfileDirectory() const { return m_instanceData->props->profile_directory; } | ||
| 244 | //---------------------------------------------------------------------------- | ||
| 245 | |||
| 246 | //============================================================================ | ||
| 247 | /// @brief **Callback to Kodi Function**\n | ||
| 248 | /// The value of the <supports_vfs> property from addon.xml. | ||
| 249 | /// | ||
| 250 | /// @return true if VFS is supported | ||
| 251 | /// | ||
| 252 | /// @remarks Only called from addon itself | ||
| 253 | /// | ||
| 254 | bool SupportsVFS() const { return m_instanceData->props->supports_vfs; } | ||
| 255 | //---------------------------------------------------------------------------- | ||
| 256 | |||
| 257 | //============================================================================ | ||
| 258 | /// @brief **Callback to Kodi Function**\n | ||
| 259 | /// The extensions in the <extensions> property from addon.xml. | ||
| 260 | /// | ||
| 261 | /// @param[out] extensions vector list to store available extension | ||
| 262 | /// @return true if success and extensions present | ||
| 263 | /// | ||
| 264 | /// @remarks Only called from addon itself | ||
| 265 | /// | ||
| 266 | bool Extensions(std::vector<std::string>& extensions) | ||
| 267 | { | ||
| 268 | for (unsigned int i = 0; i < m_instanceData->props->extension_count; ++i) | ||
| 269 | { | ||
| 270 | if (m_instanceData->props->extensions[i] != nullptr) | ||
| 271 | extensions.push_back(m_instanceData->props->extensions[i]); | ||
| 272 | } | ||
| 273 | return !extensions.empty(); | ||
| 274 | } | ||
| 275 | //---------------------------------------------------------------------------- | ||
| 276 | |||
| 277 | ///@} | ||
| 278 | |||
| 279 | //--==----==----==----==----==----==----==----==----==----==----==----==----==-- | ||
| 280 | |||
| 281 | //============================================================================ | ||
| 282 | /// | ||
| 283 | /// @defgroup cpp_kodi_addon_game_Operation 2. Game operations | ||
| 284 | /// @ingroup cpp_kodi_addon_game | ||
| 285 | /// @brief **Game operations** | ||
| 286 | /// | ||
| 287 | /// These are mandatory functions for using this addon to get the available | ||
| 288 | /// channels. | ||
| 289 | /// | ||
| 290 | /// | ||
| 291 | ///--------------------------------------------------------------------------- | ||
| 292 | /// | ||
| 293 | /// **Game operation parts in interface:**\n | ||
| 294 | /// Copy this to your project and extend with your parts or leave functions | ||
| 295 | /// complete away where not used or supported. | ||
| 296 | /// | ||
| 297 | /// @copydetails cpp_kodi_addon_game_Operation_header_addon_auto_check | ||
| 298 | /// @copydetails cpp_kodi_addon_game_Operation_source_addon_auto_check | ||
| 299 | /// | ||
| 300 | ///@{ | ||
| 301 | |||
| 302 | //============================================================================ | ||
| 303 | /// @brief Load a game | ||
| 304 | /// | ||
| 305 | /// @param[in] url The URL to load | ||
| 306 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was loaded | ||
| 307 | /// | ||
| 308 | virtual GAME_ERROR LoadGame(const std::string& url) | ||
| 309 | { | ||
| 310 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 311 | } | ||
| 312 | //---------------------------------------------------------------------------- | ||
| 313 | |||
| 314 | //============================================================================ | ||
| 315 | /// @brief Load a game that requires multiple files | ||
| 316 | /// | ||
| 317 | /// @param[in] type The game type | ||
| 318 | /// @param[in] urls An array of urls | ||
| 319 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was loaded | ||
| 320 | /// | ||
| 321 | virtual GAME_ERROR LoadGameSpecial(SPECIAL_GAME_TYPE type, const std::vector<std::string>& urls) | ||
| 322 | { | ||
| 323 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 324 | } | ||
| 325 | //---------------------------------------------------------------------------- | ||
| 326 | |||
| 327 | //============================================================================ | ||
| 328 | /// @brief Begin playing without a game file | ||
| 329 | /// | ||
| 330 | /// If the add-on supports standalone mode, it must add the <supports_standalone> | ||
| 331 | /// tag to the extension point in addon.xml: | ||
| 332 | /// | ||
| 333 | /// <supports_no_game>false</supports_no_game> | ||
| 334 | /// | ||
| 335 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game add-on was loaded | ||
| 336 | /// | ||
| 337 | virtual GAME_ERROR LoadStandalone() | ||
| 338 | { | ||
| 339 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 340 | } | ||
| 341 | //---------------------------------------------------------------------------- | ||
| 342 | |||
| 343 | //============================================================================ | ||
| 344 | /// @brief Unload the current game | ||
| 345 | /// | ||
| 346 | /// Unloads a currently loaded game | ||
| 347 | /// | ||
| 348 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was unloaded | ||
| 349 | /// | ||
| 350 | virtual GAME_ERROR UnloadGame() | ||
| 351 | { | ||
| 352 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 353 | } | ||
| 354 | //---------------------------------------------------------------------------- | ||
| 355 | |||
| 356 | //============================================================================ | ||
| 357 | /// @brief Get timing information about the loaded game | ||
| 358 | /// | ||
| 359 | /// @param[out] timing_info The info structure to fill | ||
| 360 | /// | ||
| 361 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if info was filled | ||
| 362 | /// | ||
| 363 | virtual GAME_ERROR GetGameTiming(game_system_timing& timing_info) | ||
| 364 | { | ||
| 365 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 366 | } | ||
| 367 | //---------------------------------------------------------------------------- | ||
| 368 | |||
| 369 | //============================================================================ | ||
| 370 | /// @brief Get region of the loaded game | ||
| 371 | /// | ||
| 372 | /// @return the region, or @ref GAME_REGION_UNKNOWN if unknown or no game is loaded | ||
| 373 | /// | ||
| 374 | virtual GAME_REGION GetRegion() | ||
| 375 | { | ||
| 376 | return GAME_REGION_UNKNOWN; | ||
| 377 | } | ||
| 378 | //---------------------------------------------------------------------------- | ||
| 379 | |||
| 380 | //============================================================================ | ||
| 381 | /// @brief Return true if the client requires the frontend to provide a game loop | ||
| 382 | /// | ||
| 383 | /// The game loop is a thread that calls RunFrame() in a loop at a rate | ||
| 384 | /// determined by the playback speed and the client's FPS. | ||
| 385 | /// | ||
| 386 | /// @return true if the frontend should provide a game loop, false otherwise | ||
| 387 | /// | ||
| 388 | virtual bool RequiresGameLoop() | ||
| 389 | { | ||
| 390 | return false; | ||
| 391 | } | ||
| 392 | //---------------------------------------------------------------------------- | ||
| 393 | |||
| 394 | //============================================================================ | ||
| 395 | /// @brief Run a single frame for add-ons that use a game loop | ||
| 396 | /// | ||
| 397 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if there was no error | ||
| 398 | /// | ||
| 399 | virtual GAME_ERROR RunFrame() | ||
| 400 | { | ||
| 401 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 402 | } | ||
| 403 | //---------------------------------------------------------------------------- | ||
| 404 | |||
| 405 | //============================================================================ | ||
| 406 | /// @brief Reset the current game | ||
| 407 | /// | ||
| 408 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was reset | ||
| 409 | /// | ||
| 410 | virtual GAME_ERROR Reset() | ||
| 411 | { | ||
| 412 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 413 | } | ||
| 414 | //---------------------------------------------------------------------------- | ||
| 415 | |||
| 416 | //========================================================================== | ||
| 417 | /// @brief **Callback to Kodi Function**\n | ||
| 418 | /// Requests the frontend to stop the current game | ||
| 419 | /// | ||
| 420 | /// @remarks Only called from addon itself | ||
| 421 | /// | ||
| 422 | void CloseGame(void) { m_instanceData->toKodi->CloseGame(m_instanceData->toKodi->kodiInstance); } | ||
| 423 | //---------------------------------------------------------------------------- | ||
| 424 | |||
| 425 | //============================================================================ | ||
| 426 | /// @defgroup cpp_kodi_addon_game_Operation_CStream Class: CStream | ||
| 427 | /// @ingroup cpp_kodi_addon_game_Operation | ||
| 428 | /// @brief @cpp_class{ kodi::addon::CInstanceGame::CStream } | ||
| 429 | /// **Game stream handler** | ||
| 430 | /// | ||
| 431 | /// This class will be integrated into the addon, which can then open it if | ||
| 432 | /// necessary for the processing of an audio or video stream. | ||
| 433 | /// | ||
| 434 | /// | ||
| 435 | /// @note Callback to Kodi class | ||
| 436 | ///@{ | ||
| 437 | class CStream | ||
| 438 | { | ||
| 439 | public: | ||
| 440 | CStream() = default; | ||
| 441 | |||
| 442 | CStream(const game_stream_properties& properties) | ||
| 443 | { | ||
| 444 | Open(properties); | ||
| 445 | } | ||
| 446 | |||
| 447 | ~CStream() | ||
| 448 | { | ||
| 449 | Close(); | ||
| 450 | } | ||
| 451 | |||
| 452 | //========================================================================== | ||
| 453 | /// @ingroup cpp_kodi_addon_game_Operation_CStream | ||
| 454 | /// @brief Create a stream for gameplay data | ||
| 455 | /// | ||
| 456 | /// @param[in] properties The stream properties | ||
| 457 | /// @return A stream handle, or `nullptr` on failure | ||
| 458 | /// | ||
| 459 | /// @remarks Only called from addon itself | ||
| 460 | /// | ||
| 461 | bool Open(const game_stream_properties& properties) | ||
| 462 | { | ||
| 463 | if (!CAddonBase::m_interface->globalSingleInstance) | ||
| 464 | return false; | ||
| 465 | |||
| 466 | if (m_handle) | ||
| 467 | { | ||
| 468 | kodi::Log(ADDON_LOG_INFO, "kodi::addon::CInstanceGame::CStream already becomes reopened"); | ||
| 469 | Close(); | ||
| 470 | } | ||
| 471 | |||
| 472 | AddonToKodiFuncTable_Game& cb = | ||
| 473 | *static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance) | ||
| 474 | ->m_instanceData->toKodi; | ||
| 475 | m_handle = cb.OpenStream(cb.kodiInstance, &properties); | ||
| 476 | return m_handle != nullptr; | ||
| 477 | } | ||
| 478 | //-------------------------------------------------------------------------- | ||
| 479 | |||
| 480 | //========================================================================== | ||
| 481 | /// @ingroup cpp_kodi_addon_game_Operation_CStream | ||
| 482 | /// @brief Free the specified stream | ||
| 483 | /// | ||
| 484 | /// @remarks Only called from addon itself | ||
| 485 | /// | ||
| 486 | void Close() | ||
| 487 | { | ||
| 488 | if (!m_handle || !CAddonBase::m_interface->globalSingleInstance) | ||
| 489 | return; | ||
| 490 | |||
| 491 | AddonToKodiFuncTable_Game& cb = | ||
| 492 | *static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance) | ||
| 493 | ->m_instanceData->toKodi; | ||
| 494 | cb.CloseStream(cb.kodiInstance, m_handle); | ||
| 495 | m_handle = nullptr; | ||
| 496 | } | ||
| 497 | //-------------------------------------------------------------------------- | ||
| 498 | |||
| 499 | //========================================================================== | ||
| 500 | /// @ingroup cpp_kodi_addon_game_Operation_CStream | ||
| 501 | /// @brief Get a buffer for zero-copy stream data | ||
| 502 | /// | ||
| 503 | /// @param[in] width The framebuffer width, or 0 for no width specified | ||
| 504 | /// @param[in] height The framebuffer height, or 0 for no height specified | ||
| 505 | /// @param[out] buffer The buffer, or unmodified if false is returned | ||
| 506 | /// @return True if buffer was set, false otherwise | ||
| 507 | /// | ||
| 508 | /// @note If this returns true, buffer must be freed using @ref ReleaseBuffer(). | ||
| 509 | /// | ||
| 510 | /// @remarks Only called from addon itself | ||
| 511 | /// | ||
| 512 | bool GetBuffer(unsigned int width, unsigned int height, game_stream_buffer& buffer) | ||
| 513 | { | ||
| 514 | if (!m_handle || !CAddonBase::m_interface->globalSingleInstance) | ||
| 515 | return false; | ||
| 516 | |||
| 517 | AddonToKodiFuncTable_Game& cb = | ||
| 518 | *static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance) | ||
| 519 | ->m_instanceData->toKodi; | ||
| 520 | return cb.GetStreamBuffer(cb.kodiInstance, m_handle, width, height, &buffer); | ||
| 521 | } | ||
| 522 | //-------------------------------------------------------------------------- | ||
| 523 | |||
| 524 | //========================================================================== | ||
| 525 | /// @ingroup cpp_kodi_addon_game_Operation_CStream | ||
| 526 | /// @brief Add a data packet to a stream | ||
| 527 | /// | ||
| 528 | /// @param[in] packet The data packet | ||
| 529 | /// | ||
| 530 | /// @remarks Only called from addon itself | ||
| 531 | /// | ||
| 532 | void AddData(const game_stream_packet& packet) | ||
| 533 | { | ||
| 534 | if (!m_handle || !CAddonBase::m_interface->globalSingleInstance) | ||
| 535 | return; | ||
| 536 | |||
| 537 | AddonToKodiFuncTable_Game& cb = | ||
| 538 | *static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance) | ||
| 539 | ->m_instanceData->toKodi; | ||
| 540 | cb.AddStreamData(cb.kodiInstance, m_handle, &packet); | ||
| 541 | } | ||
| 542 | //-------------------------------------------------------------------------- | ||
| 543 | |||
| 544 | //========================================================================== | ||
| 545 | /// @ingroup cpp_kodi_addon_game_Operation_CStream | ||
| 546 | /// @brief Free an allocated buffer | ||
| 547 | /// | ||
| 548 | /// @param[in] buffer The buffer returned from GetStreamBuffer() | ||
| 549 | /// | ||
| 550 | /// @remarks Only called from addon itself | ||
| 551 | /// | ||
| 552 | void ReleaseBuffer(game_stream_buffer& buffer) | ||
| 553 | { | ||
| 554 | if (!m_handle || !CAddonBase::m_interface->globalSingleInstance) | ||
| 555 | return; | ||
| 556 | |||
| 557 | AddonToKodiFuncTable_Game& cb = | ||
| 558 | *static_cast<CInstanceGame*>(CAddonBase::m_interface->globalSingleInstance) | ||
| 559 | ->m_instanceData->toKodi; | ||
| 560 | cb.ReleaseStreamBuffer(cb.kodiInstance, m_handle, &buffer); | ||
| 561 | } | ||
| 562 | //-------------------------------------------------------------------------- | ||
| 563 | |||
| 564 | //========================================================================== | ||
| 565 | /// @ingroup cpp_kodi_addon_game_Operation_CStream | ||
| 566 | /// @brief To check stream open was OK, e.g. after use of constructor | ||
| 567 | /// | ||
| 568 | /// @return true if stream was successfully opened | ||
| 569 | /// | ||
| 570 | /// @remarks Only called from addon itself | ||
| 571 | /// | ||
| 572 | bool IsOpen() const { return m_handle != nullptr; } | ||
| 573 | //-------------------------------------------------------------------------- | ||
| 574 | |||
| 575 | private: | ||
| 576 | KODI_GAME_STREAM_HANDLE m_handle = nullptr; | ||
| 577 | }; | ||
| 578 | ///@} | ||
| 579 | |||
| 580 | ///@} | ||
| 581 | |||
| 582 | //--==----==----==----==----==----==----==----==----==----==----==----==----==-- | ||
| 583 | |||
| 584 | //============================================================================ | ||
| 585 | /// | ||
| 586 | /// @defgroup cpp_kodi_addon_game_HardwareRendering 3. Hardware rendering operations | ||
| 587 | /// @ingroup cpp_kodi_addon_game | ||
| 588 | /// @brief **Hardware rendering operations** | ||
| 589 | /// | ||
| 590 | /// | ||
| 591 | ///--------------------------------------------------------------------------- | ||
| 592 | /// | ||
| 593 | /// **Hardware rendering operation parts in interface:**\n | ||
| 594 | /// Copy this to your project and extend with your parts or leave functions | ||
| 595 | /// complete away where not used or supported. | ||
| 596 | /// | ||
| 597 | /// @copydetails cpp_kodi_addon_game_HardwareRendering_header_addon_auto_check | ||
| 598 | /// @copydetails cpp_kodi_addon_game_HardwareRendering_source_addon_auto_check | ||
| 599 | /// | ||
| 600 | ///@{ | ||
| 601 | |||
| 602 | //============================================================================ | ||
| 603 | /// @brief Invalidates the current HW context and reinitializes GPU resources | ||
| 604 | /// | ||
| 605 | /// Any GL state is lost, and must not be deinitialized explicitly. | ||
| 606 | /// | ||
| 607 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the HW context was reset | ||
| 608 | /// | ||
| 609 | virtual GAME_ERROR HwContextReset() | ||
| 610 | { | ||
| 611 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 612 | } | ||
| 613 | //---------------------------------------------------------------------------- | ||
| 614 | |||
| 615 | //============================================================================ | ||
| 616 | /// @brief Called before the context is destroyed | ||
| 617 | /// | ||
| 618 | /// Resources can be deinitialized at this step. | ||
| 619 | /// | ||
| 620 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the HW context was destroyed | ||
| 621 | /// | ||
| 622 | virtual GAME_ERROR HwContextDestroy() | ||
| 623 | { | ||
| 624 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 625 | } | ||
| 626 | |||
| 627 | //============================================================================ | ||
| 628 | /// @brief **Callback to Kodi Function**<br>Get a symbol from the hardware context | ||
| 629 | /// | ||
| 630 | /// @param[in] sym The symbol's name | ||
| 631 | /// | ||
| 632 | /// @return A function pointer for the specified symbol | ||
| 633 | /// | ||
| 634 | /// @remarks Only called from addon itself | ||
| 635 | /// | ||
| 636 | game_proc_address_t HwGetProcAddress(const char* sym) | ||
| 637 | { | ||
| 638 | return m_instanceData->toKodi->HwGetProcAddress(m_instanceData->toKodi->kodiInstance, sym); | ||
| 639 | } | ||
| 640 | //---------------------------------------------------------------------------- | ||
| 641 | |||
| 642 | ///@} | ||
| 643 | |||
| 644 | //--==----==----==----==----==----==----==----==----==----==----==----==----==-- | ||
| 645 | |||
| 646 | //============================================================================ | ||
| 647 | /// @defgroup cpp_kodi_addon_game_InputOperations 4. Input operations | ||
| 648 | /// @ingroup cpp_kodi_addon_game | ||
| 649 | /// @brief **Input operations** | ||
| 650 | /// | ||
| 651 | /// | ||
| 652 | ///--------------------------------------------------------------------------- | ||
| 653 | /// | ||
| 654 | /// **Hardware rendering operation parts in interface:**\n | ||
| 655 | /// Copy this to your project and extend with your parts or leave functions | ||
| 656 | /// complete away where not used or supported. | ||
| 657 | /// | ||
| 658 | /// @copydetails cpp_kodi_addon_game_InputOperations_header_addon_auto_check | ||
| 659 | /// @copydetails cpp_kodi_addon_game_InputOperations_source_addon_auto_check | ||
| 660 | /// | ||
| 661 | ///@{ | ||
| 662 | |||
| 663 | //============================================================================ | ||
| 664 | /// @brief Check if input is accepted for a feature on the controller | ||
| 665 | /// | ||
| 666 | /// If only a subset of the controller profile is used, this can return false | ||
| 667 | /// for unsupported features to not absorb their input. | ||
| 668 | /// | ||
| 669 | /// If the entire controller profile is used, this should always return true. | ||
| 670 | /// | ||
| 671 | /// @param[in] controller_id The ID of the controller profile | ||
| 672 | /// @param[in] feature_name The name of a feature in that profile | ||
| 673 | /// @return true if input is accepted for the feature, false otherwise | ||
| 674 | /// | ||
| 675 | virtual bool HasFeature(const std::string& controller_id, const std::string& feature_name) | ||
| 676 | { | ||
| 677 | return false; | ||
| 678 | } | ||
| 679 | //---------------------------------------------------------------------------- | ||
| 680 | |||
| 681 | //============================================================================ | ||
| 682 | /// @brief Get the input topology that specifies which controllers can be connected | ||
| 683 | /// | ||
| 684 | /// @return The input topology, or null to use the default | ||
| 685 | /// | ||
| 686 | /// If this returns non-null, topology must be freed using FreeTopology(). | ||
| 687 | /// | ||
| 688 | /// If this returns null, the topology will default to a single port that can | ||
| 689 | /// accept all controllers imported by addon.xml. The port ID is set to | ||
| 690 | /// the @ref DEFAULT_PORT_ID constant. | ||
| 691 | /// | ||
| 692 | virtual game_input_topology* GetTopology() | ||
| 693 | { | ||
| 694 | return nullptr; | ||
| 695 | } | ||
| 696 | //---------------------------------------------------------------------------- | ||
| 697 | |||
| 698 | //============================================================================ | ||
| 699 | /// @brief Free the topology's resources | ||
| 700 | /// | ||
| 701 | /// @param[in] topology The topology returned by GetTopology() | ||
| 702 | /// | ||
| 703 | virtual void FreeTopology(game_input_topology* topology) | ||
| 704 | { | ||
| 705 | } | ||
| 706 | //---------------------------------------------------------------------------- | ||
| 707 | |||
| 708 | //============================================================================ | ||
| 709 | /// @brief Set the layouts for known controllers | ||
| 710 | /// | ||
| 711 | /// @param[in] controllers The controller layouts | ||
| 712 | /// | ||
| 713 | /// After loading the input topology, the frontend will call this with | ||
| 714 | /// controller layouts for all controllers discovered in the topology. | ||
| 715 | /// | ||
| 716 | virtual void SetControllerLayouts(const std::vector<kodi::addon::GameControllerLayout>& controllers) | ||
| 717 | { | ||
| 718 | } | ||
| 719 | //---------------------------------------------------------------------------- | ||
| 720 | |||
| 721 | //============================================================================ | ||
| 722 | /// @brief Enable/disable keyboard input using the specified controller | ||
| 723 | /// | ||
| 724 | /// @param[in] enable True to enable input, false otherwise | ||
| 725 | /// @param[in] controller_id The controller ID if enabling, or unused if disabling | ||
| 726 | /// | ||
| 727 | /// @return True if keyboard input was enabled, false otherwise | ||
| 728 | /// | ||
| 729 | virtual bool EnableKeyboard(bool enable, const std::string& controller_id) | ||
| 730 | { | ||
| 731 | return false; | ||
| 732 | } | ||
| 733 | //---------------------------------------------------------------------------- | ||
| 734 | |||
| 735 | //============================================================================ | ||
| 736 | /// @brief Enable/disable mouse input using the specified controller | ||
| 737 | /// | ||
| 738 | /// @param[in] enable True to enable input, false otherwise | ||
| 739 | /// @param[in] controller_id The controller ID if enabling, or unused if disabling | ||
| 740 | /// | ||
| 741 | /// @return True if mouse input was enabled, false otherwise | ||
| 742 | /// | ||
| 743 | virtual bool EnableMouse(bool enable, const std::string& controller_id) | ||
| 744 | { | ||
| 745 | return false; | ||
| 746 | } | ||
| 747 | //-------------------------------------------------------------------------- | ||
| 748 | |||
| 749 | //========================================================================== | ||
| 750 | /// @brief Connect/disconnect a controller to a port on the virtual game console | ||
| 751 | /// | ||
| 752 | /// @param[in] connect True to connect a controller, false to disconnect | ||
| 753 | /// @param[in] port_address The address of the port | ||
| 754 | /// @param[in] controller_id The controller ID if connecting, or unused if disconnecting | ||
| 755 | /// @return True if the \p controller was (dis-)connected to the port, false otherwise | ||
| 756 | /// | ||
| 757 | /// The address is a string that allows traversal of the controller topology. | ||
| 758 | /// It is formed by alternating port IDs and controller IDs separated by "/". | ||
| 759 | /// | ||
| 760 | /// For example, assume that the topology represented in XML for Snes9x is: | ||
| 761 | /// | ||
| 762 | /// ~~~~~~~~~~~~~{.xml} | ||
| 763 | /// <logicaltopology> | ||
| 764 | /// <port type="controller" id="1"> | ||
| 765 | /// <accepts controller="game.controller.snes"/> | ||
| 766 | /// <accepts controller="game.controller.snes.multitap"> | ||
| 767 | /// <port type="controller" id="1"> | ||
| 768 | /// <accepts controller="game.controller.snes"/> | ||
| 769 | /// </port> | ||
| 770 | /// <port type="controller" id="2"> | ||
| 771 | /// <accepts controller="game.controller.snes"/> | ||
| 772 | /// </port> | ||
| 773 | /// ... | ||
| 774 | /// </accepts> | ||
| 775 | /// </port> | ||
| 776 | /// </logicaltopology> | ||
| 777 | /// ~~~~~~~~~~~~~ | ||
| 778 | /// | ||
| 779 | /// To connect a multitap to the console's first port, the multitap's controller | ||
| 780 | /// info is set using the port address: | ||
| 781 | /// | ||
| 782 | /// 1 | ||
| 783 | /// | ||
| 784 | /// To connect a SNES controller to the second port of the multitap, the | ||
| 785 | /// controller info is next set using the address: | ||
| 786 | /// | ||
| 787 | /// 1/game.controller.multitap/2 | ||
| 788 | /// | ||
| 789 | /// Any attempts to connect a controller to a port on a disconnected multitap | ||
| 790 | /// will return false. | ||
| 791 | /// | ||
| 792 | virtual bool ConnectController(bool connect, | ||
| 793 | const std::string& port_address, | ||
| 794 | const std::string& controller_id) | ||
| 795 | { | ||
| 796 | return false; | ||
| 797 | } | ||
| 798 | //---------------------------------------------------------------------------- | ||
| 799 | |||
| 800 | //============================================================================ | ||
| 801 | /// @brief Notify the add-on of an input event | ||
| 802 | /// | ||
| 803 | /// @param[in] event The input event | ||
| 804 | /// | ||
| 805 | /// @return true if the event was handled, false otherwise | ||
| 806 | /// | ||
| 807 | virtual bool InputEvent(const game_input_event& event) | ||
| 808 | { | ||
| 809 | return false; | ||
| 810 | } | ||
| 811 | //---------------------------------------------------------------------------- | ||
| 812 | |||
| 813 | //============================================================================ | ||
| 814 | /// @brief **Callback to Kodi Function**<br>Notify the port of an input event | ||
| 815 | /// | ||
| 816 | /// @param[in] event The input event | ||
| 817 | /// @return true if the event was handled, false otherwise | ||
| 818 | /// | ||
| 819 | /// @note Input events can arrive for the following sources: | ||
| 820 | /// - @ref GAME_INPUT_EVENT_MOTOR | ||
| 821 | /// | ||
| 822 | /// @remarks Only called from addon itself | ||
| 823 | /// | ||
| 824 | bool KodiInputEvent(const game_input_event& event) | ||
| 825 | { | ||
| 826 | return m_instanceData->toKodi->InputEvent(m_instanceData->toKodi->kodiInstance, &event); | ||
| 827 | } | ||
| 828 | //---------------------------------------------------------------------------- | ||
| 829 | |||
| 830 | ///@} | ||
| 831 | |||
| 832 | //--==----==----==----==----==----==----==----==----==----==----==----==----==-- | ||
| 833 | |||
| 834 | //============================================================================ | ||
| 835 | /// @defgroup cpp_kodi_addon_game_SerializationOperations 5. Serialization operations | ||
| 836 | /// @ingroup cpp_kodi_addon_game | ||
| 837 | /// @brief **Serialization operations** | ||
| 838 | /// | ||
| 839 | /// | ||
| 840 | ///--------------------------------------------------------------------------- | ||
| 841 | /// | ||
| 842 | /// **Serialization operation parts in interface:**\n | ||
| 843 | /// Copy this to your project and extend with your parts or leave functions | ||
| 844 | /// complete away where not used or supported. | ||
| 845 | /// | ||
| 846 | /// @copydetails cpp_kodi_addon_game_SerializationOperations_header_addon_auto_check | ||
| 847 | /// @copydetails cpp_kodi_addon_game_SerializationOperations_source_addon_auto_check | ||
| 848 | /// | ||
| 849 | ///@{ | ||
| 850 | |||
| 851 | //============================================================================ | ||
| 852 | /// @brief Get the number of bytes required to serialize the game | ||
| 853 | /// | ||
| 854 | /// @return the number of bytes, or 0 if serialization is not supported | ||
| 855 | /// | ||
| 856 | virtual size_t SerializeSize() | ||
| 857 | { | ||
| 858 | return 0; | ||
| 859 | } | ||
| 860 | //---------------------------------------------------------------------------- | ||
| 861 | |||
| 862 | //============================================================================ | ||
| 863 | /// @brief Serialize the state of the game | ||
| 864 | /// | ||
| 865 | /// @param[in] data The buffer receiving the serialized game data | ||
| 866 | /// @param[in] size The size of the buffer | ||
| 867 | /// | ||
| 868 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game was serialized into the buffer | ||
| 869 | /// | ||
| 870 | virtual GAME_ERROR Serialize(uint8_t* data, size_t size) | ||
| 871 | { | ||
| 872 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 873 | } | ||
| 874 | //---------------------------------------------------------------------------- | ||
| 875 | |||
| 876 | //============================================================================ | ||
| 877 | /// @brief Deserialize the game from the given state | ||
| 878 | /// | ||
| 879 | /// @param[in] data A buffer containing the game's new state | ||
| 880 | /// @param[in] size The size of the buffer | ||
| 881 | /// | ||
| 882 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the game deserialized | ||
| 883 | /// | ||
| 884 | virtual GAME_ERROR Deserialize(const uint8_t* data, size_t size) | ||
| 885 | { | ||
| 886 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 887 | } | ||
| 888 | //---------------------------------------------------------------------------- | ||
| 889 | |||
| 890 | ///@} | ||
| 891 | |||
| 892 | //--==----==----==----==----==----==----==----==----==----==----==----==----==-- | ||
| 893 | |||
| 894 | //============================================================================ | ||
| 895 | /// @defgroup cpp_kodi_addon_game_CheatOperations 6. Cheat operations | ||
| 896 | /// @ingroup cpp_kodi_addon_game | ||
| 897 | /// @brief **Cheat operations** | ||
| 898 | /// | ||
| 899 | /// | ||
| 900 | ///--------------------------------------------------------------------------- | ||
| 901 | /// | ||
| 902 | /// **Cheat operation parts in interface:**\n | ||
| 903 | /// Copy this to your project and extend with your parts or leave functions | ||
| 904 | /// complete away where not used or supported. | ||
| 905 | /// | ||
| 906 | /// @copydetails cpp_kodi_addon_game_CheatOperations_header_addon_auto_check | ||
| 907 | /// @copydetails cpp_kodi_addon_game_CheatOperations_source_addon_auto_check | ||
| 908 | /// | ||
| 909 | ///@{ | ||
| 910 | |||
| 911 | //============================================================================ | ||
| 912 | /// @brief Reset the cheat system | ||
| 913 | /// | ||
| 914 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the cheat system was reset | ||
| 915 | /// | ||
| 916 | virtual GAME_ERROR CheatReset() | ||
| 917 | { | ||
| 918 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 919 | } | ||
| 920 | //---------------------------------------------------------------------------- | ||
| 921 | |||
| 922 | //============================================================================ | ||
| 923 | /// @brief Get a region of memory | ||
| 924 | /// | ||
| 925 | /// @param[in] type The type of memory to retrieve | ||
| 926 | /// @param[in] data Set to the region of memory; must remain valid until UnloadGame() is called | ||
| 927 | /// @param[in] size Set to the size of the region of memory | ||
| 928 | /// | ||
| 929 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if data was set to a valid buffer | ||
| 930 | /// | ||
| 931 | virtual GAME_ERROR GetMemory(GAME_MEMORY type, uint8_t*& data, size_t& size) | ||
| 932 | { | ||
| 933 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 934 | } | ||
| 935 | //---------------------------------------------------------------------------- | ||
| 936 | |||
| 937 | //============================================================================ | ||
| 938 | /// @brief Set a cheat code | ||
| 939 | /// | ||
| 940 | /// @param[in] index | ||
| 941 | /// @param[in] enabled | ||
| 942 | /// @param[in] code | ||
| 943 | /// | ||
| 944 | /// @return the error, or @ref GAME_ERROR_NO_ERROR if the cheat was set | ||
| 945 | /// | ||
| 946 | virtual GAME_ERROR SetCheat(unsigned int index, bool enabled, const std::string& code) | ||
| 947 | { | ||
| 948 | return GAME_ERROR_NOT_IMPLEMENTED; | ||
| 949 | } | ||
| 950 | //---------------------------------------------------------------------------- | ||
| 951 | |||
| 952 | ///@} | ||
| 953 | |||
| 954 | private: | ||
| 955 | void SetAddonStruct(KODI_HANDLE instance) | ||
| 956 | { | ||
| 957 | if (instance == nullptr) | ||
| 958 | throw std::logic_error("kodi::addon::CInstanceGame: Creation with empty addon structure not" | ||
| 959 | "allowed, table must be given from Kodi!"); | ||
| 960 | |||
| 961 | m_instanceData = static_cast<AddonInstance_Game*>(instance); | ||
| 962 | m_instanceData->toAddon->addonInstance = this; | ||
| 963 | |||
| 964 | m_instanceData->toAddon->LoadGame = ADDON_LoadGame; | ||
| 965 | m_instanceData->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial; | ||
| 966 | m_instanceData->toAddon->LoadStandalone = ADDON_LoadStandalone; | ||
| 967 | m_instanceData->toAddon->UnloadGame = ADDON_UnloadGame; | ||
| 968 | m_instanceData->toAddon->GetGameTiming = ADDON_GetGameTiming; | ||
| 969 | m_instanceData->toAddon->GetRegion = ADDON_GetRegion; | ||
| 970 | m_instanceData->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop; | ||
| 971 | m_instanceData->toAddon->RunFrame = ADDON_RunFrame; | ||
| 972 | m_instanceData->toAddon->Reset = ADDON_Reset; | ||
| 973 | |||
| 974 | m_instanceData->toAddon->HwContextReset = ADDON_HwContextReset; | ||
| 975 | m_instanceData->toAddon->HwContextDestroy = ADDON_HwContextDestroy; | ||
| 976 | |||
| 977 | m_instanceData->toAddon->HasFeature = ADDON_HasFeature; | ||
| 978 | m_instanceData->toAddon->GetTopology = ADDON_GetTopology; | ||
| 979 | m_instanceData->toAddon->FreeTopology = ADDON_FreeTopology; | ||
| 980 | m_instanceData->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts; | ||
| 981 | m_instanceData->toAddon->EnableKeyboard = ADDON_EnableKeyboard; | ||
| 982 | m_instanceData->toAddon->EnableMouse = ADDON_EnableMouse; | ||
| 983 | m_instanceData->toAddon->ConnectController = ADDON_ConnectController; | ||
| 984 | m_instanceData->toAddon->InputEvent = ADDON_InputEvent; | ||
| 985 | |||
| 986 | m_instanceData->toAddon->SerializeSize = ADDON_SerializeSize; | ||
| 987 | m_instanceData->toAddon->Serialize = ADDON_Serialize; | ||
| 988 | m_instanceData->toAddon->Deserialize = ADDON_Deserialize; | ||
| 989 | |||
| 990 | m_instanceData->toAddon->CheatReset = ADDON_CheatReset; | ||
| 991 | m_instanceData->toAddon->GetMemory = ADDON_GetMemory; | ||
| 992 | m_instanceData->toAddon->SetCheat = ADDON_SetCheat; | ||
| 993 | } | ||
| 994 | |||
| 995 | // --- Game operations --------------------------------------------------------- | ||
| 996 | |||
| 997 | inline static GAME_ERROR ADDON_LoadGame(const AddonInstance_Game* instance, const char* url) | ||
| 998 | { | ||
| 999 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadGame(url); | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | inline static GAME_ERROR ADDON_LoadGameSpecial(const AddonInstance_Game* instance, | ||
| 1003 | SPECIAL_GAME_TYPE type, | ||
| 1004 | const char** urls, | ||
| 1005 | size_t urlCount) | ||
| 1006 | { | ||
| 1007 | std::vector<std::string> urlList; | ||
| 1008 | for (size_t i = 0; i < urlCount; ++i) | ||
| 1009 | { | ||
| 1010 | if (urls[i] != nullptr) | ||
| 1011 | urlList.push_back(urls[i]); | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1015 | ->LoadGameSpecial(type, urlList); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | inline static GAME_ERROR ADDON_LoadStandalone(const AddonInstance_Game* instance) | ||
| 1019 | { | ||
| 1020 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadStandalone(); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | inline static GAME_ERROR ADDON_UnloadGame(const AddonInstance_Game* instance) | ||
| 1024 | { | ||
| 1025 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->UnloadGame(); | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | inline static GAME_ERROR ADDON_GetGameTiming(const AddonInstance_Game* instance, | ||
| 1029 | game_system_timing* timing_info) | ||
| 1030 | { | ||
| 1031 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1032 | ->GetGameTiming(*timing_info); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | inline static GAME_REGION ADDON_GetRegion(const AddonInstance_Game* instance) | ||
| 1036 | { | ||
| 1037 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetRegion(); | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | inline static bool ADDON_RequiresGameLoop(const AddonInstance_Game* instance) | ||
| 1041 | { | ||
| 1042 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RequiresGameLoop(); | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | inline static GAME_ERROR ADDON_RunFrame(const AddonInstance_Game* instance) | ||
| 1046 | { | ||
| 1047 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RunFrame(); | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | inline static GAME_ERROR ADDON_Reset(const AddonInstance_Game* instance) | ||
| 1051 | { | ||
| 1052 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Reset(); | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | |||
| 1056 | // --- Hardware rendering operations ------------------------------------------- | ||
| 1057 | |||
| 1058 | inline static GAME_ERROR ADDON_HwContextReset(const AddonInstance_Game* instance) | ||
| 1059 | { | ||
| 1060 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextReset(); | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | inline static GAME_ERROR ADDON_HwContextDestroy(const AddonInstance_Game* instance) | ||
| 1064 | { | ||
| 1065 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextDestroy(); | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | |||
| 1069 | // --- Input operations -------------------------------------------------------- | ||
| 1070 | |||
| 1071 | inline static bool ADDON_HasFeature(const AddonInstance_Game* instance, | ||
| 1072 | const char* controller_id, | ||
| 1073 | const char* feature_name) | ||
| 1074 | { | ||
| 1075 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1076 | ->HasFeature(controller_id, feature_name); | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | inline static game_input_topology* ADDON_GetTopology(const AddonInstance_Game* instance) | ||
| 1080 | { | ||
| 1081 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetTopology(); | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | inline static void ADDON_FreeTopology(const AddonInstance_Game* instance, | ||
| 1085 | game_input_topology* topology) | ||
| 1086 | { | ||
| 1087 | static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->FreeTopology(topology); | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | inline static void ADDON_SetControllerLayouts(const AddonInstance_Game* instance, | ||
| 1091 | const game_controller_layout* controllers, | ||
| 1092 | unsigned int controller_count) | ||
| 1093 | { | ||
| 1094 | if (controllers == nullptr) | ||
| 1095 | return; | ||
| 1096 | |||
| 1097 | std::vector<GameControllerLayout> controllerList; | ||
| 1098 | for (unsigned int i = 0; i < controller_count; ++i) | ||
| 1099 | controllerList.push_back(controllers[i]); | ||
| 1100 | |||
| 1101 | static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1102 | ->SetControllerLayouts(controllerList); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | inline static bool ADDON_EnableKeyboard(const AddonInstance_Game* instance, | ||
| 1106 | bool enable, | ||
| 1107 | const char* controller_id) | ||
| 1108 | { | ||
| 1109 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1110 | ->EnableKeyboard(enable, controller_id); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | inline static bool ADDON_EnableMouse(const AddonInstance_Game* instance, | ||
| 1114 | bool enable, | ||
| 1115 | const char* controller_id) | ||
| 1116 | { | ||
| 1117 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1118 | ->EnableMouse(enable, controller_id); | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | inline static bool ADDON_ConnectController(const AddonInstance_Game* instance, | ||
| 1122 | bool connect, | ||
| 1123 | const char* port_address, | ||
| 1124 | const char* controller_id) | ||
| 1125 | { | ||
| 1126 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1127 | ->ConnectController(connect, port_address, controller_id); | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | inline static bool ADDON_InputEvent(const AddonInstance_Game* instance, | ||
| 1131 | const game_input_event* event) | ||
| 1132 | { | ||
| 1133 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->InputEvent(*event); | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | |||
| 1137 | // --- Serialization operations ------------------------------------------------ | ||
| 1138 | |||
| 1139 | inline static size_t ADDON_SerializeSize(const AddonInstance_Game* instance) | ||
| 1140 | { | ||
| 1141 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->SerializeSize(); | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | inline static GAME_ERROR ADDON_Serialize(const AddonInstance_Game* instance, | ||
| 1145 | uint8_t* data, | ||
| 1146 | size_t size) | ||
| 1147 | { | ||
| 1148 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Serialize(data, size); | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | inline static GAME_ERROR ADDON_Deserialize(const AddonInstance_Game* instance, | ||
| 1152 | const uint8_t* data, | ||
| 1153 | size_t size) | ||
| 1154 | { | ||
| 1155 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Deserialize(data, size); | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | |||
| 1159 | // --- Cheat operations -------------------------------------------------------- | ||
| 1160 | |||
| 1161 | inline static GAME_ERROR ADDON_CheatReset(const AddonInstance_Game* instance) | ||
| 1162 | { | ||
| 1163 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->CheatReset(); | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | inline static GAME_ERROR ADDON_GetMemory(const AddonInstance_Game* instance, | ||
| 1167 | GAME_MEMORY type, | ||
| 1168 | uint8_t** data, | ||
| 1169 | size_t* size) | ||
| 1170 | { | ||
| 1171 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1172 | ->GetMemory(type, *data, *size); | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | inline static GAME_ERROR ADDON_SetCheat(const AddonInstance_Game* instance, | ||
| 1176 | unsigned int index, | ||
| 1177 | bool enabled, | ||
| 1178 | const char* code) | ||
| 1179 | { | ||
| 1180 | return static_cast<CInstanceGame*>(instance->toAddon->addonInstance) | ||
| 1181 | ->SetCheat(index, enabled, code); | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | AddonInstance_Game* m_instanceData; | ||
| 1185 | }; | ||
| 1186 | |||
| 1187 | } /* namespace addon */ | ||
| 1188 | } /* namespace kodi */ | ||
| 1189 | |||
| 1190 | #endif /* __cplusplus */ | ||
