xbmc
Game.h
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 #include <algorithm>
15 
16 #ifdef __cplusplus
17 
18 namespace kodi
19 {
20 namespace addon
21 {
22 
23 //==============================================================================
32 
33 //==============================================================================
38 
39 //==============================================================================
46 class GameControllerLayout
47 {
48 public:
50  explicit GameControllerLayout() = default;
51  GameControllerLayout(const game_controller_layout& layout) : controller_id(layout.controller_id)
52  {
53  provides_input = layout.provides_input;
54  for (unsigned int i = 0; i < layout.digital_button_count; ++i)
55  digital_buttons.emplace_back(layout.digital_buttons[i]);
56  for (unsigned int i = 0; i < layout.analog_button_count; ++i)
57  analog_buttons.emplace_back(layout.analog_buttons[i]);
58  for (unsigned int i = 0; i < layout.analog_stick_count; ++i)
59  analog_sticks.emplace_back(layout.analog_sticks[i]);
60  for (unsigned int i = 0; i < layout.accelerometer_count; ++i)
61  accelerometers.emplace_back(layout.accelerometers[i]);
62  for (unsigned int i = 0; i < layout.key_count; ++i)
63  keys.emplace_back(layout.keys[i]);
64  for (unsigned int i = 0; i < layout.rel_pointer_count; ++i)
65  rel_pointers.emplace_back(layout.rel_pointers[i]);
66  for (unsigned int i = 0; i < layout.abs_pointer_count; ++i)
67  abs_pointers.emplace_back(layout.abs_pointers[i]);
68  for (unsigned int i = 0; i < layout.motor_count; ++i)
69  motors.emplace_back(layout.motors[i]);
70  }
73  std::string controller_id;
75 
79  bool provides_input{false};
80 
82  std::vector<std::string> digital_buttons;
83 
85  std::vector<std::string> analog_buttons;
86 
88  std::vector<std::string> analog_sticks;
89 
91  std::vector<std::string> accelerometers;
92 
94  std::vector<std::string> keys;
95 
97  std::vector<std::string> rel_pointers;
98 
100  std::vector<std::string> abs_pointers;
101 
103  std::vector<std::string> motors;
104 };
106 //------------------------------------------------------------------------------
107 
108 //==============================================================================
117 class ATTR_DLL_LOCAL CInstanceGame : public IAddonInstance
118 {
119 public:
120  //============================================================================
126 
127  //============================================================================
162  CInstanceGame() : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
163  {
164  if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
165  throw std::logic_error("kodi::addon::CInstanceGame: Creation of more as one in single "
166  "instance way is not allowed!");
167 
168  SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
169  CPrivateBase::m_interface->globalSingleInstance = this;
170  }
171  //----------------------------------------------------------------------------
172 
173  //============================================================================
176  ~CInstanceGame() override = default;
177  //----------------------------------------------------------------------------
178 
179  //============================================================================
187  std::string GameClientDllPath() const { return m_instanceData->props->game_client_dll_path; }
188  //----------------------------------------------------------------------------
189 
190  //============================================================================
199  bool ProxyDllPaths(std::vector<std::string>& paths)
200  {
201  for (unsigned int i = 0; i < m_instanceData->props->proxy_dll_count; ++i)
202  {
203  if (m_instanceData->props->proxy_dll_paths[i] != nullptr)
204  paths.emplace_back(m_instanceData->props->proxy_dll_paths[i]);
205  }
206  return !paths.empty();
207  }
208  //----------------------------------------------------------------------------
209 
210  //============================================================================
221  bool ResourceDirectories(std::vector<std::string>& dirs)
222  {
223  for (unsigned int i = 0; i < m_instanceData->props->resource_directory_count; ++i)
224  {
225  if (m_instanceData->props->resource_directories[i] != nullptr)
226  dirs.emplace_back(m_instanceData->props->resource_directories[i]);
227  }
228  return !dirs.empty();
229  }
230  //----------------------------------------------------------------------------
231 
232  //============================================================================
244  std::string ProfileDirectory() const { return m_instanceData->props->profile_directory; }
245  //----------------------------------------------------------------------------
246 
247  //============================================================================
255  bool SupportsVFS() const { return m_instanceData->props->supports_vfs; }
256  //----------------------------------------------------------------------------
257 
258  //============================================================================
267  bool Extensions(std::vector<std::string>& extensions)
268  {
269  for (unsigned int i = 0; i < m_instanceData->props->extension_count; ++i)
270  {
271  if (m_instanceData->props->extensions[i] != nullptr)
272  extensions.emplace_back(m_instanceData->props->extensions[i]);
273  }
274  return !extensions.empty();
275  }
276  //----------------------------------------------------------------------------
277 
279 
280  //--==----==----==----==----==----==----==----==----==----==----==----==----==--
281 
282  //============================================================================
302 
303  //============================================================================
309  virtual GAME_ERROR LoadGame(const std::string& url) { return GAME_ERROR_NOT_IMPLEMENTED; }
310  //----------------------------------------------------------------------------
311 
312  //============================================================================
319  virtual GAME_ERROR LoadGameSpecial(SPECIAL_GAME_TYPE type, const std::vector<std::string>& urls)
320  {
321  return GAME_ERROR_NOT_IMPLEMENTED;
322  }
323  //----------------------------------------------------------------------------
324 
325  //============================================================================
335  virtual GAME_ERROR LoadStandalone() { return GAME_ERROR_NOT_IMPLEMENTED; }
336  //----------------------------------------------------------------------------
337 
338  //============================================================================
345  virtual GAME_ERROR UnloadGame() { return GAME_ERROR_NOT_IMPLEMENTED; }
346  //----------------------------------------------------------------------------
347 
348  //============================================================================
355  virtual GAME_ERROR GetGameTiming(game_system_timing& timing_info)
356  {
357  return GAME_ERROR_NOT_IMPLEMENTED;
358  }
359  //----------------------------------------------------------------------------
360 
361  //============================================================================
366  virtual GAME_REGION GetRegion() { return GAME_REGION_UNKNOWN; }
367  //----------------------------------------------------------------------------
368 
369  //============================================================================
377  virtual bool RequiresGameLoop() { return false; }
378  //----------------------------------------------------------------------------
379 
380  //============================================================================
385  virtual GAME_ERROR RunFrame() { return GAME_ERROR_NOT_IMPLEMENTED; }
386  //----------------------------------------------------------------------------
387 
388  //============================================================================
393  virtual GAME_ERROR Reset() { return GAME_ERROR_NOT_IMPLEMENTED; }
394  //----------------------------------------------------------------------------
395 
396  //==========================================================================
402  void CloseGame(void) { m_instanceData->toKodi->CloseGame(m_instanceData->toKodi->kodiInstance); }
403  //----------------------------------------------------------------------------
404 
405  //============================================================================
417  class CStream
418  {
419  public:
420  CStream() = default;
421 
422  CStream(const game_stream_properties& properties) { Open(properties); }
423 
424  ~CStream() { Close(); }
425 
426  //==========================================================================
435  bool Open(const game_stream_properties& properties)
436  {
437  if (!CPrivateBase::m_interface->globalSingleInstance)
438  return false;
439 
440  if (m_handle)
441  {
442  kodi::Log(ADDON_LOG_INFO, "kodi::addon::CInstanceGame::CStream already becomes reopened");
443  Close();
444  }
445 
447  *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
448  ->m_instanceData->toKodi;
449  m_handle = cb.OpenStream(cb.kodiInstance, &properties);
450  return m_handle != nullptr;
451  }
452  //--------------------------------------------------------------------------
453 
454  //==========================================================================
460  void Close()
461  {
462  if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
463  return;
464 
466  *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
467  ->m_instanceData->toKodi;
468  cb.CloseStream(cb.kodiInstance, m_handle);
469  m_handle = nullptr;
470  }
471  //--------------------------------------------------------------------------
472 
473  //==========================================================================
486  bool GetBuffer(unsigned int width, unsigned int height, game_stream_buffer& buffer)
487  {
488  if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
489  return false;
490 
492  *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
493  ->m_instanceData->toKodi;
494  return cb.GetStreamBuffer(cb.kodiInstance, m_handle, width, height, &buffer);
495  }
496  //--------------------------------------------------------------------------
497 
498  //==========================================================================
506  void AddData(const game_stream_packet& packet)
507  {
508  if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
509  return;
510 
512  *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
513  ->m_instanceData->toKodi;
514  cb.AddStreamData(cb.kodiInstance, m_handle, &packet);
515  }
516  //--------------------------------------------------------------------------
517 
518  //==========================================================================
526  void ReleaseBuffer(game_stream_buffer& buffer)
527  {
528  if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
529  return;
530 
532  *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
533  ->m_instanceData->toKodi;
534  cb.ReleaseStreamBuffer(cb.kodiInstance, m_handle, &buffer);
535  }
536  //--------------------------------------------------------------------------
537 
538  //==========================================================================
546  bool IsOpen() const { return m_handle != nullptr; }
547  //--------------------------------------------------------------------------
548 
549  private:
550  KODI_GAME_STREAM_HANDLE m_handle = nullptr;
551  };
553 
555 
556  //--==----==----==----==----==----==----==----==----==----==----==----==----==--
557 
558  //============================================================================
575 
576  //============================================================================
583  virtual GAME_ERROR HwContextReset() { return GAME_ERROR_NOT_IMPLEMENTED; }
584  //----------------------------------------------------------------------------
585 
586  //============================================================================
593  virtual GAME_ERROR HwContextDestroy() { return GAME_ERROR_NOT_IMPLEMENTED; }
594 
595  //============================================================================
604  game_proc_address_t HwGetProcAddress(const char* sym)
605  {
606  return m_instanceData->toKodi->HwGetProcAddress(m_instanceData->toKodi->kodiInstance, sym);
607  }
608  //----------------------------------------------------------------------------
609 
611 
612  //--==----==----==----==----==----==----==----==----==----==----==----==----==--
613 
614  //============================================================================
630 
631  //============================================================================
643  virtual bool HasFeature(const std::string& controller_id, const std::string& feature_name)
644  {
645  return false;
646  }
647  //----------------------------------------------------------------------------
648 
649  //============================================================================
660  virtual game_input_topology* GetTopology() { return nullptr; }
661  //----------------------------------------------------------------------------
662 
663  //============================================================================
668  virtual void FreeTopology(game_input_topology* topology) {}
669  //----------------------------------------------------------------------------
670 
671  //============================================================================
679  virtual void SetControllerLayouts(
680  const std::vector<kodi::addon::GameControllerLayout>& controllers)
681  {
682  }
683  //----------------------------------------------------------------------------
684 
685  //============================================================================
693  virtual bool EnableKeyboard(bool enable, const std::string& controller_id) { return false; }
694  //----------------------------------------------------------------------------
695 
696  //============================================================================
704  virtual bool EnableMouse(bool enable, const std::string& controller_id) { return false; }
705  //--------------------------------------------------------------------------
706 
707  //==========================================================================
750  virtual bool ConnectController(bool connect,
751  const std::string& port_address,
752  const std::string& controller_id)
753  {
754  return false;
755  }
756  //----------------------------------------------------------------------------
757 
758  //============================================================================
765  virtual bool InputEvent(const game_input_event& event) { return false; }
766  //----------------------------------------------------------------------------
767 
768  //============================================================================
779  bool KodiInputEvent(const game_input_event& event)
780  {
781  return m_instanceData->toKodi->InputEvent(m_instanceData->toKodi->kodiInstance, &event);
782  }
783  //----------------------------------------------------------------------------
784 
786 
787  //--==----==----==----==----==----==----==----==----==----==----==----==----==--
788 
789  //============================================================================
805 
806  //============================================================================
811  virtual size_t SerializeSize() { return 0; }
812  //----------------------------------------------------------------------------
813 
814  //============================================================================
822  virtual GAME_ERROR Serialize(uint8_t* data, size_t size) { return GAME_ERROR_NOT_IMPLEMENTED; }
823  //----------------------------------------------------------------------------
824 
825  //============================================================================
833  virtual GAME_ERROR Deserialize(const uint8_t* data, size_t size)
834  {
835  return GAME_ERROR_NOT_IMPLEMENTED;
836  }
837  //----------------------------------------------------------------------------
838 
840 
841  //--==----==----==----==----==----==----==----==----==----==----==----==----==--
842 
843  //============================================================================
859 
860  //============================================================================
865  virtual GAME_ERROR CheatReset() { return GAME_ERROR_NOT_IMPLEMENTED; }
866  //----------------------------------------------------------------------------
867 
868  //============================================================================
877  virtual GAME_ERROR GetMemory(GAME_MEMORY type, uint8_t*& data, size_t& size)
878  {
879  return GAME_ERROR_NOT_IMPLEMENTED;
880  }
881  //----------------------------------------------------------------------------
882 
883  //============================================================================
892  virtual GAME_ERROR SetCheat(unsigned int index, bool enabled, const std::string& code)
893  {
894  return GAME_ERROR_NOT_IMPLEMENTED;
895  }
896 
897  //============================================================================
909  virtual GAME_ERROR RCGenerateHashFromFile(std::string& hash,
910  unsigned int consoleID,
911  const std::string& filePath)
912  {
913  return GAME_ERROR_NOT_IMPLEMENTED;
914  }
915 
916  //============================================================================
925  virtual GAME_ERROR RCGetGameIDUrl(std::string& url, const std::string& hash)
926  {
927  return GAME_ERROR_NOT_IMPLEMENTED;
928  }
929 
930  //============================================================================
941  virtual GAME_ERROR RCGetPatchFileUrl(std::string& url,
942  const std::string& username,
943  const std::string& token,
944  unsigned int gameID)
945  {
946  return GAME_ERROR_NOT_IMPLEMENTED;
947  }
948 
949  //============================================================================
957  virtual GAME_ERROR SetRetroAchievementsCredentials(const std::string& username,
958  const std::string& token)
959  {
960  return GAME_ERROR_NOT_IMPLEMENTED;
961  }
962 
963  //============================================================================
979  virtual GAME_ERROR RCPostRichPresenceUrl(std::string& url,
980  std::string& postData,
981  const std::string& username,
982  const std::string& token,
983  unsigned int gameID,
984  const std::string& richPresence)
985  {
986  return GAME_ERROR_NOT_IMPLEMENTED;
987  }
988 
989  //============================================================================
996  virtual GAME_ERROR RCEnableRichPresence(const std::string& script)
997  {
998  return GAME_ERROR_NOT_IMPLEMENTED;
999  }
1000 
1001  //============================================================================
1014  virtual GAME_ERROR RCGetRichPresenceEvaluation(std::string& evaluation, unsigned int consoleID)
1015  {
1016  return GAME_ERROR_NOT_IMPLEMENTED;
1017  }
1018 
1019  //============================================================================
1027  virtual GAME_ERROR ActivateAchievement(unsigned cheevoId, const char* memaddr)
1028  {
1029  return GAME_ERROR_NOT_IMPLEMENTED;
1030  }
1031 
1032  //============================================================================
1039  virtual GAME_ERROR GetCheevo_URL_ID(void (*callback)(const char* achievementUrl,
1040  unsigned cheevoId))
1041  {
1042  return GAME_ERROR_NOT_IMPLEMENTED;
1043  }
1044 
1045  //============================================================================
1052  virtual GAME_ERROR RCResetRuntime() { return GAME_ERROR_NOT_IMPLEMENTED; }
1053 
1054  //----------------------------------------------------------------------------
1055 
1057 
1058 private:
1059  void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
1060  {
1061  instance->hdl = this;
1062 
1063  instance->game->toAddon->LoadGame = ADDON_LoadGame;
1064  instance->game->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial;
1065  instance->game->toAddon->LoadStandalone = ADDON_LoadStandalone;
1066  instance->game->toAddon->UnloadGame = ADDON_UnloadGame;
1067  instance->game->toAddon->GetGameTiming = ADDON_GetGameTiming;
1068  instance->game->toAddon->GetRegion = ADDON_GetRegion;
1069  instance->game->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop;
1070  instance->game->toAddon->RunFrame = ADDON_RunFrame;
1071  instance->game->toAddon->Reset = ADDON_Reset;
1072 
1073  instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
1074  instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
1075 
1076  instance->game->toAddon->HasFeature = ADDON_HasFeature;
1077  instance->game->toAddon->GetTopology = ADDON_GetTopology;
1078  instance->game->toAddon->FreeTopology = ADDON_FreeTopology;
1079  instance->game->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts;
1080  instance->game->toAddon->EnableKeyboard = ADDON_EnableKeyboard;
1081  instance->game->toAddon->EnableMouse = ADDON_EnableMouse;
1082  instance->game->toAddon->ConnectController = ADDON_ConnectController;
1083  instance->game->toAddon->InputEvent = ADDON_InputEvent;
1084 
1085  instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
1086  instance->game->toAddon->Serialize = ADDON_Serialize;
1087  instance->game->toAddon->Deserialize = ADDON_Deserialize;
1088 
1089  instance->game->toAddon->CheatReset = ADDON_CheatReset;
1090  instance->game->toAddon->GetMemory = ADDON_GetMemory;
1091  instance->game->toAddon->SetCheat = ADDON_SetCheat;
1092 
1093  instance->game->toAddon->RCGenerateHashFromFile = ADDON_RCGenerateHashFromFile;
1094  instance->game->toAddon->RCGetGameIDUrl = ADDON_RCGetGameIDUrl;
1095  instance->game->toAddon->RCGetPatchFileUrl = ADDON_RCGetPatchFileUrl;
1096  instance->game->toAddon->SetRetroAchievementsCredentials =
1097  ADDON_SetRetroAchievementsCredentials;
1098  instance->game->toAddon->RCPostRichPresenceUrl = ADDON_RCPostRichPresenceUrl;
1099  instance->game->toAddon->RCEnableRichPresence = ADDON_RCEnableRichPresence;
1100  instance->game->toAddon->RCGetRichPresenceEvaluation = ADDON_RCGetRichPresenceEvaluation;
1101  instance->game->toAddon->ActivateAchievement = ADDON_ActivateAchievement;
1102  instance->game->toAddon->GetCheevo_URL_ID = ADDON_GetCheevo_URL_ID;
1103  instance->game->toAddon->RCResetRuntime = ADDON_RCResetRuntime;
1104 
1105  instance->game->toAddon->FreeString = ADDON_FreeString;
1106 
1107  m_instanceData = instance->game;
1108  m_instanceData->toAddon->addonInstance = this;
1109  }
1110 
1111  // --- Game operations ---------------------------------------------------------
1112 
1113  inline static GAME_ERROR ADDON_LoadGame(const AddonInstance_Game* instance, const char* url)
1114  {
1115  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadGame(url);
1116  }
1117 
1118  inline static GAME_ERROR ADDON_LoadGameSpecial(const AddonInstance_Game* instance,
1119  SPECIAL_GAME_TYPE type,
1120  const char** urls,
1121  size_t urlCount)
1122  {
1123  std::vector<std::string> urlList;
1124  for (size_t i = 0; i < urlCount; ++i)
1125  {
1126  if (urls[i] != nullptr)
1127  urlList.emplace_back(urls[i]);
1128  }
1129 
1130  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1131  ->LoadGameSpecial(type, urlList);
1132  }
1133 
1134  inline static GAME_ERROR ADDON_LoadStandalone(const AddonInstance_Game* instance)
1135  {
1136  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadStandalone();
1137  }
1138 
1139  inline static GAME_ERROR ADDON_UnloadGame(const AddonInstance_Game* instance)
1140  {
1141  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->UnloadGame();
1142  }
1143 
1144  inline static GAME_ERROR ADDON_GetGameTiming(const AddonInstance_Game* instance,
1145  game_system_timing* timing_info)
1146  {
1147  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1148  ->GetGameTiming(*timing_info);
1149  }
1150 
1151  inline static GAME_REGION ADDON_GetRegion(const AddonInstance_Game* instance)
1152  {
1153  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetRegion();
1154  }
1155 
1156  inline static bool ADDON_RequiresGameLoop(const AddonInstance_Game* instance)
1157  {
1158  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RequiresGameLoop();
1159  }
1160 
1161  inline static GAME_ERROR ADDON_RunFrame(const AddonInstance_Game* instance)
1162  {
1163  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RunFrame();
1164  }
1165 
1166  inline static GAME_ERROR ADDON_Reset(const AddonInstance_Game* instance)
1167  {
1168  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Reset();
1169  }
1170 
1171  // --- Hardware rendering operations -------------------------------------------
1172 
1173  inline static GAME_ERROR ADDON_HwContextReset(const AddonInstance_Game* instance)
1174  {
1175  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextReset();
1176  }
1177 
1178  inline static GAME_ERROR ADDON_HwContextDestroy(const AddonInstance_Game* instance)
1179  {
1180  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextDestroy();
1181  }
1182 
1183  // --- Input operations --------------------------------------------------------
1184 
1185  inline static bool ADDON_HasFeature(const AddonInstance_Game* instance,
1186  const char* controller_id,
1187  const char* feature_name)
1188  {
1189  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1190  ->HasFeature(controller_id, feature_name);
1191  }
1192 
1193  inline static game_input_topology* ADDON_GetTopology(const AddonInstance_Game* instance)
1194  {
1195  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetTopology();
1196  }
1197 
1198  inline static void ADDON_FreeTopology(const AddonInstance_Game* instance,
1199  game_input_topology* topology)
1200  {
1201  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->FreeTopology(topology);
1202  }
1203 
1204  inline static void ADDON_SetControllerLayouts(const AddonInstance_Game* instance,
1205  const game_controller_layout* controllers,
1206  unsigned int controller_count)
1207  {
1208  if (controllers == nullptr)
1209  return;
1210 
1211  std::vector<GameControllerLayout> controllerList;
1212  for (unsigned int i = 0; i < controller_count; ++i)
1213  controllerList.emplace_back(controllers[i]);
1214 
1215  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1216  ->SetControllerLayouts(controllerList);
1217  }
1218 
1219  inline static bool ADDON_EnableKeyboard(const AddonInstance_Game* instance,
1220  bool enable,
1221  const char* controller_id)
1222  {
1223  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1224  ->EnableKeyboard(enable, controller_id);
1225  }
1226 
1227  inline static bool ADDON_EnableMouse(const AddonInstance_Game* instance,
1228  bool enable,
1229  const char* controller_id)
1230  {
1231  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1232  ->EnableMouse(enable, controller_id);
1233  }
1234 
1235  inline static bool ADDON_ConnectController(const AddonInstance_Game* instance,
1236  bool connect,
1237  const char* port_address,
1238  const char* controller_id)
1239  {
1240  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1241  ->ConnectController(connect, port_address, controller_id);
1242  }
1243 
1244  inline static bool ADDON_InputEvent(const AddonInstance_Game* instance,
1245  const game_input_event* event)
1246  {
1247  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->InputEvent(*event);
1248  }
1249 
1250  // --- Serialization operations ------------------------------------------------
1251 
1252  inline static size_t ADDON_SerializeSize(const AddonInstance_Game* instance)
1253  {
1254  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->SerializeSize();
1255  }
1256 
1257  inline static GAME_ERROR ADDON_Serialize(const AddonInstance_Game* instance,
1258  uint8_t* data,
1259  size_t size)
1260  {
1261  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Serialize(data, size);
1262  }
1263 
1264  inline static GAME_ERROR ADDON_Deserialize(const AddonInstance_Game* instance,
1265  const uint8_t* data,
1266  size_t size)
1267  {
1268  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Deserialize(data, size);
1269  }
1270 
1271  // --- Cheat operations --------------------------------------------------------
1272 
1273  inline static GAME_ERROR ADDON_CheatReset(const AddonInstance_Game* instance)
1274  {
1275  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->CheatReset();
1276  }
1277 
1278  inline static GAME_ERROR ADDON_GetMemory(const AddonInstance_Game* instance,
1279  GAME_MEMORY type,
1280  uint8_t** data,
1281  size_t* size)
1282  {
1283  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1284  ->GetMemory(type, *data, *size);
1285  }
1286 
1287  inline static GAME_ERROR ADDON_SetCheat(const AddonInstance_Game* instance,
1288  unsigned int index,
1289  bool enabled,
1290  const char* code)
1291  {
1292  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1293  ->SetCheat(index, enabled, code);
1294  }
1295 
1296  inline static GAME_ERROR ADDON_RCGenerateHashFromFile(const AddonInstance_Game* instance,
1297  char** hash,
1298  unsigned int consoleID,
1299  const char* filePath)
1300  {
1301  std::string cppHash;
1302 
1303  GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1304  ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
1305  if (!cppHash.empty() && hash)
1306  {
1307  *hash = new char[cppHash.size() + 1];
1308  std::copy(cppHash.begin(), cppHash.end(), *hash);
1309  (*hash)[cppHash.size()] = '\0';
1310  }
1311  return ret;
1312  }
1313 
1314  inline static GAME_ERROR ADDON_RCGetGameIDUrl(const AddonInstance_Game* instance,
1315  char** url,
1316  const char* hash)
1317  {
1318  std::string cppUrl;
1319  GAME_ERROR ret =
1320  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
1321  if (!cppUrl.empty() && url)
1322  {
1323  *url = new char[cppUrl.size() + 1];
1324  std::copy(cppUrl.begin(), cppUrl.end(), *url);
1325  (*url)[cppUrl.size()] = '\0';
1326  }
1327  return ret;
1328  }
1329 
1330  inline static GAME_ERROR ADDON_RCGetPatchFileUrl(const AddonInstance_Game* instance,
1331  char** url,
1332  const char* username,
1333  const char* token,
1334  unsigned int gameID)
1335  {
1336  std::string cppUrl;
1337 
1338  GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1339  ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
1340  if (!cppUrl.empty() && url)
1341  {
1342  *url = new char[cppUrl.size() + 1];
1343  std::copy(cppUrl.begin(), cppUrl.end(), *url);
1344  (*url)[cppUrl.size()] = '\0';
1345  }
1346  return ret;
1347  }
1348 
1349  inline static GAME_ERROR ADDON_SetRetroAchievementsCredentials(const AddonInstance_Game* instance,
1350  const char* username,
1351  const char* token)
1352  {
1353  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1354  ->SetRetroAchievementsCredentials(username, token);
1355  }
1356 
1357  inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(const AddonInstance_Game* instance,
1358  char** url,
1359  char** postData,
1360  const char* username,
1361  const char* token,
1362  unsigned int gameID,
1363  const char* richPresence)
1364  {
1365  std::string cppUrl;
1366  std::string cppPostData;
1367  GAME_ERROR ret =
1368  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1369  ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
1370  if (!cppUrl.empty())
1371  {
1372  *url = new char[cppUrl.size() + 1];
1373  std::copy(cppUrl.begin(), cppUrl.end(), *url);
1374  (*url)[cppUrl.size()] = '\0';
1375  }
1376  if (!cppPostData.empty())
1377  {
1378  *postData = new char[cppPostData.size() + 1];
1379  std::copy(cppPostData.begin(), cppPostData.end(), *postData);
1380  (*postData)[cppPostData.size()] = '\0';
1381  }
1382 
1383  return ret;
1384  }
1385 
1386  inline static GAME_ERROR ADDON_RCEnableRichPresence(const AddonInstance_Game* instance,
1387  const char* script)
1388  {
1389  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1390  ->RCEnableRichPresence(script);
1391  }
1392 
1393  inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(const AddonInstance_Game* instance,
1394  char** evaluation,
1395  unsigned int consoleID)
1396  {
1397  std::string cppEvaluation;
1398  GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1399  ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
1400  if (!cppEvaluation.empty())
1401  {
1402  *evaluation = new char[cppEvaluation.size() + 1];
1403  std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
1404  (*evaluation)[cppEvaluation.size()] = '\0';
1405  }
1406 
1407  return ret;
1408  }
1409 
1410  inline static GAME_ERROR ADDON_ActivateAchievement(const AddonInstance_Game* instance,
1411  unsigned cheevoId,
1412  const char* memaddr)
1413  {
1414  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1415  ->ActivateAchievement(cheevoId, memaddr);
1416  }
1417 
1418  inline static GAME_ERROR ADDON_GetCheevo_URL_ID(const AddonInstance_Game* instance,
1419  void (*callback)(const char* achievementUrl,
1420  unsigned cheevoId))
1421  {
1422  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1423  ->GetCheevo_URL_ID(callback);
1424  }
1425 
1426  inline static GAME_ERROR ADDON_RCResetRuntime(const AddonInstance_Game* instance)
1427  {
1428  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCResetRuntime();
1429  }
1430 
1431  inline static void ADDON_FreeString(const AddonInstance_Game* instance, char* str)
1432  {
1433  delete[] str;
1434  }
1435 
1436  AddonInstance_Game* m_instanceData;
1437 };
1438 
1439 } /* namespace addon */
1440 } /* namespace kodi */
1441 
1442 #endif /* __cplusplus */
1 : To include information messages in the log file.
Definition: addon_base.h:187
Game callbacks.
Definition: game.h:1137
SPECIAL_GAME_TYPE
**Special game types passed into game_load_game_special().
Definition: game.h:580
The input topology is the possible ways to connect input devices.
Definition: game.h:872
void(* game_proc_address_t)(void)
Hardware framebuffer process function address
Definition: game.h:406
Stream packet and ephemeral metadata
Definition: game.h:528
Definition: addon_base.h:267
GAME_MEMORY
Game Memory
Definition: game.h:599
Stream buffers for hardware rendering and zero-copy support
Definition: game.h:506
Definition: inftrees.h:24
GAME_REGION
Game region definition
Definition: game.h:562
Game instance.
Definition: game.h:1228
Definition: game.h:996
Immutable stream metadata
Definition: game.h:482
Game region unknown.
Definition: game.h:565
Game system timing.
Definition: game.h:1056