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.push_back(layout.digital_buttons[i]);
56  for (unsigned int i = 0; i < layout.analog_button_count; ++i)
57  analog_buttons.push_back(layout.analog_buttons[i]);
58  for (unsigned int i = 0; i < layout.analog_stick_count; ++i)
59  analog_sticks.push_back(layout.analog_sticks[i]);
60  for (unsigned int i = 0; i < layout.accelerometer_count; ++i)
61  accelerometers.push_back(layout.accelerometers[i]);
62  for (unsigned int i = 0; i < layout.key_count; ++i)
63  keys.push_back(layout.keys[i]);
64  for (unsigned int i = 0; i < layout.rel_pointer_count; ++i)
65  rel_pointers.push_back(layout.rel_pointers[i]);
66  for (unsigned int i = 0; i < layout.abs_pointer_count; ++i)
67  abs_pointers.push_back(layout.abs_pointers[i]);
68  for (unsigned int i = 0; i < layout.motor_count; ++i)
69  motors.push_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.push_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.push_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.push_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  //============================================================================
965  virtual GAME_ERROR RCPostRichPresenceUrl(std::string& url,
966  std::string& postData,
967  const std::string& username,
968  const std::string& token,
969  unsigned int gameID,
970  const std::string& richPresence)
971  {
972  return GAME_ERROR_NOT_IMPLEMENTED;
973  }
974 
975  //============================================================================
982  virtual GAME_ERROR RCEnableRichPresence(const std::string& script)
983  {
984  return GAME_ERROR_NOT_IMPLEMENTED;
985  }
986 
987  //============================================================================
999  virtual GAME_ERROR RCGetRichPresenceEvaluation(std::string& evaluation, unsigned int consoleID)
1000  {
1001  return GAME_ERROR_NOT_IMPLEMENTED;
1002  }
1003 
1004  //============================================================================
1011  virtual GAME_ERROR RCResetRuntime() { return GAME_ERROR_NOT_IMPLEMENTED; }
1012 
1013  //----------------------------------------------------------------------------
1014 
1016 
1017 private:
1018  void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
1019  {
1020  instance->hdl = this;
1021 
1022  instance->game->toAddon->LoadGame = ADDON_LoadGame;
1023  instance->game->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial;
1024  instance->game->toAddon->LoadStandalone = ADDON_LoadStandalone;
1025  instance->game->toAddon->UnloadGame = ADDON_UnloadGame;
1026  instance->game->toAddon->GetGameTiming = ADDON_GetGameTiming;
1027  instance->game->toAddon->GetRegion = ADDON_GetRegion;
1028  instance->game->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop;
1029  instance->game->toAddon->RunFrame = ADDON_RunFrame;
1030  instance->game->toAddon->Reset = ADDON_Reset;
1031 
1032  instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
1033  instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
1034 
1035  instance->game->toAddon->HasFeature = ADDON_HasFeature;
1036  instance->game->toAddon->GetTopology = ADDON_GetTopology;
1037  instance->game->toAddon->FreeTopology = ADDON_FreeTopology;
1038  instance->game->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts;
1039  instance->game->toAddon->EnableKeyboard = ADDON_EnableKeyboard;
1040  instance->game->toAddon->EnableMouse = ADDON_EnableMouse;
1041  instance->game->toAddon->ConnectController = ADDON_ConnectController;
1042  instance->game->toAddon->InputEvent = ADDON_InputEvent;
1043 
1044  instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
1045  instance->game->toAddon->Serialize = ADDON_Serialize;
1046  instance->game->toAddon->Deserialize = ADDON_Deserialize;
1047 
1048  instance->game->toAddon->CheatReset = ADDON_CheatReset;
1049  instance->game->toAddon->GetMemory = ADDON_GetMemory;
1050  instance->game->toAddon->SetCheat = ADDON_SetCheat;
1051 
1052  instance->game->toAddon->RCGenerateHashFromFile = ADDON_RCGenerateHashFromFile;
1053  instance->game->toAddon->RCGetGameIDUrl = ADDON_RCGetGameIDUrl;
1054  instance->game->toAddon->RCGetPatchFileUrl = ADDON_RCGetPatchFileUrl;
1055  instance->game->toAddon->RCPostRichPresenceUrl = ADDON_RCPostRichPresenceUrl;
1056  instance->game->toAddon->RCEnableRichPresence = ADDON_RCEnableRichPresence;
1057  instance->game->toAddon->RCGetRichPresenceEvaluation = ADDON_RCGetRichPresenceEvaluation;
1058  instance->game->toAddon->RCResetRuntime = ADDON_RCResetRuntime;
1059 
1060  instance->game->toAddon->FreeString = ADDON_FreeString;
1061 
1062  m_instanceData = instance->game;
1063  m_instanceData->toAddon->addonInstance = this;
1064  }
1065 
1066  // --- Game operations ---------------------------------------------------------
1067 
1068  inline static GAME_ERROR ADDON_LoadGame(const AddonInstance_Game* instance, const char* url)
1069  {
1070  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadGame(url);
1071  }
1072 
1073  inline static GAME_ERROR ADDON_LoadGameSpecial(const AddonInstance_Game* instance,
1074  SPECIAL_GAME_TYPE type,
1075  const char** urls,
1076  size_t urlCount)
1077  {
1078  std::vector<std::string> urlList;
1079  for (size_t i = 0; i < urlCount; ++i)
1080  {
1081  if (urls[i] != nullptr)
1082  urlList.push_back(urls[i]);
1083  }
1084 
1085  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1086  ->LoadGameSpecial(type, urlList);
1087  }
1088 
1089  inline static GAME_ERROR ADDON_LoadStandalone(const AddonInstance_Game* instance)
1090  {
1091  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadStandalone();
1092  }
1093 
1094  inline static GAME_ERROR ADDON_UnloadGame(const AddonInstance_Game* instance)
1095  {
1096  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->UnloadGame();
1097  }
1098 
1099  inline static GAME_ERROR ADDON_GetGameTiming(const AddonInstance_Game* instance,
1100  game_system_timing* timing_info)
1101  {
1102  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1103  ->GetGameTiming(*timing_info);
1104  }
1105 
1106  inline static GAME_REGION ADDON_GetRegion(const AddonInstance_Game* instance)
1107  {
1108  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetRegion();
1109  }
1110 
1111  inline static bool ADDON_RequiresGameLoop(const AddonInstance_Game* instance)
1112  {
1113  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RequiresGameLoop();
1114  }
1115 
1116  inline static GAME_ERROR ADDON_RunFrame(const AddonInstance_Game* instance)
1117  {
1118  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RunFrame();
1119  }
1120 
1121  inline static GAME_ERROR ADDON_Reset(const AddonInstance_Game* instance)
1122  {
1123  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Reset();
1124  }
1125 
1126  // --- Hardware rendering operations -------------------------------------------
1127 
1128  inline static GAME_ERROR ADDON_HwContextReset(const AddonInstance_Game* instance)
1129  {
1130  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextReset();
1131  }
1132 
1133  inline static GAME_ERROR ADDON_HwContextDestroy(const AddonInstance_Game* instance)
1134  {
1135  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextDestroy();
1136  }
1137 
1138  // --- Input operations --------------------------------------------------------
1139 
1140  inline static bool ADDON_HasFeature(const AddonInstance_Game* instance,
1141  const char* controller_id,
1142  const char* feature_name)
1143  {
1144  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1145  ->HasFeature(controller_id, feature_name);
1146  }
1147 
1148  inline static game_input_topology* ADDON_GetTopology(const AddonInstance_Game* instance)
1149  {
1150  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetTopology();
1151  }
1152 
1153  inline static void ADDON_FreeTopology(const AddonInstance_Game* instance,
1154  game_input_topology* topology)
1155  {
1156  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->FreeTopology(topology);
1157  }
1158 
1159  inline static void ADDON_SetControllerLayouts(const AddonInstance_Game* instance,
1160  const game_controller_layout* controllers,
1161  unsigned int controller_count)
1162  {
1163  if (controllers == nullptr)
1164  return;
1165 
1166  std::vector<GameControllerLayout> controllerList;
1167  for (unsigned int i = 0; i < controller_count; ++i)
1168  controllerList.push_back(controllers[i]);
1169 
1170  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1171  ->SetControllerLayouts(controllerList);
1172  }
1173 
1174  inline static bool ADDON_EnableKeyboard(const AddonInstance_Game* instance,
1175  bool enable,
1176  const char* controller_id)
1177  {
1178  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1179  ->EnableKeyboard(enable, controller_id);
1180  }
1181 
1182  inline static bool ADDON_EnableMouse(const AddonInstance_Game* instance,
1183  bool enable,
1184  const char* controller_id)
1185  {
1186  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1187  ->EnableMouse(enable, controller_id);
1188  }
1189 
1190  inline static bool ADDON_ConnectController(const AddonInstance_Game* instance,
1191  bool connect,
1192  const char* port_address,
1193  const char* controller_id)
1194  {
1195  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1196  ->ConnectController(connect, port_address, controller_id);
1197  }
1198 
1199  inline static bool ADDON_InputEvent(const AddonInstance_Game* instance,
1200  const game_input_event* event)
1201  {
1202  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->InputEvent(*event);
1203  }
1204 
1205  // --- Serialization operations ------------------------------------------------
1206 
1207  inline static size_t ADDON_SerializeSize(const AddonInstance_Game* instance)
1208  {
1209  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->SerializeSize();
1210  }
1211 
1212  inline static GAME_ERROR ADDON_Serialize(const AddonInstance_Game* instance,
1213  uint8_t* data,
1214  size_t size)
1215  {
1216  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Serialize(data, size);
1217  }
1218 
1219  inline static GAME_ERROR ADDON_Deserialize(const AddonInstance_Game* instance,
1220  const uint8_t* data,
1221  size_t size)
1222  {
1223  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Deserialize(data, size);
1224  }
1225 
1226  // --- Cheat operations --------------------------------------------------------
1227 
1228  inline static GAME_ERROR ADDON_CheatReset(const AddonInstance_Game* instance)
1229  {
1230  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->CheatReset();
1231  }
1232 
1233  inline static GAME_ERROR ADDON_GetMemory(const AddonInstance_Game* instance,
1234  GAME_MEMORY type,
1235  uint8_t** data,
1236  size_t* size)
1237  {
1238  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1239  ->GetMemory(type, *data, *size);
1240  }
1241 
1242  inline static GAME_ERROR ADDON_SetCheat(const AddonInstance_Game* instance,
1243  unsigned int index,
1244  bool enabled,
1245  const char* code)
1246  {
1247  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1248  ->SetCheat(index, enabled, code);
1249  }
1250 
1251  inline static GAME_ERROR ADDON_RCGenerateHashFromFile(const AddonInstance_Game* instance,
1252  char** hash,
1253  unsigned int consoleID,
1254  const char* filePath)
1255  {
1256  std::string cppHash;
1257 
1258  GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1259  ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
1260  if (!cppHash.empty() && hash)
1261  {
1262  *hash = new char[cppHash.size() + 1];
1263  std::copy(cppHash.begin(), cppHash.end(), *hash);
1264  (*hash)[cppHash.size()] = '\0';
1265  }
1266  return ret;
1267  }
1268 
1269  inline static GAME_ERROR ADDON_RCGetGameIDUrl(const AddonInstance_Game* instance,
1270  char** url,
1271  const char* hash)
1272  {
1273  std::string cppUrl;
1274  GAME_ERROR ret =
1275  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
1276  if (!cppUrl.empty() && url)
1277  {
1278  *url = new char[cppUrl.size() + 1];
1279  std::copy(cppUrl.begin(), cppUrl.end(), *url);
1280  (*url)[cppUrl.size()] = '\0';
1281  }
1282  return ret;
1283  }
1284 
1285  inline static GAME_ERROR ADDON_RCGetPatchFileUrl(const AddonInstance_Game* instance,
1286  char** url,
1287  const char* username,
1288  const char* token,
1289  unsigned int gameID)
1290  {
1291  std::string cppUrl;
1292 
1293  GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1294  ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
1295  if (!cppUrl.empty() && url)
1296  {
1297  *url = new char[cppUrl.size() + 1];
1298  std::copy(cppUrl.begin(), cppUrl.end(), *url);
1299  (*url)[cppUrl.size()] = '\0';
1300  }
1301  return ret;
1302  }
1303 
1304  inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(const AddonInstance_Game* instance,
1305  char** url,
1306  char** postData,
1307  const char* username,
1308  const char* token,
1309  unsigned int gameID,
1310  const char* richPresence)
1311  {
1312  std::string cppUrl;
1313  std::string cppPostData;
1314  GAME_ERROR ret =
1315  static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1316  ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
1317  if (!cppUrl.empty())
1318  {
1319  *url = new char[cppUrl.size() + 1];
1320  std::copy(cppUrl.begin(), cppUrl.end(), *url);
1321  (*url)[cppUrl.size()] = '\0';
1322  }
1323  if (!cppPostData.empty())
1324  {
1325  *postData = new char[cppPostData.size() + 1];
1326  std::copy(cppPostData.begin(), cppPostData.end(), *postData);
1327  (*postData)[cppPostData.size()] = '\0';
1328  }
1329 
1330  return ret;
1331  }
1332 
1333  inline static GAME_ERROR ADDON_RCEnableRichPresence(const AddonInstance_Game* instance,
1334  const char* script)
1335  {
1336  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1337  ->RCEnableRichPresence(script);
1338  }
1339 
1340  inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(const AddonInstance_Game* instance,
1341  char** evaluation,
1342  unsigned int consoleID)
1343  {
1344  std::string cppEvaluation;
1345  GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1346  ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
1347  if (!cppEvaluation.empty())
1348  {
1349  *evaluation = new char[cppEvaluation.size() + 1];
1350  std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
1351  (*evaluation)[cppEvaluation.size()] = '\0';
1352  }
1353 
1354  return ret;
1355  }
1356 
1357  inline static GAME_ERROR ADDON_RCResetRuntime(const AddonInstance_Game* instance)
1358  {
1359  return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCResetRuntime();
1360  }
1361 
1362  inline static void ADDON_FreeString(const AddonInstance_Game* instance, char* str)
1363  {
1364  delete[] str;
1365  }
1366 
1367  AddonInstance_Game* m_instanceData;
1368 };
1369 
1370 } /* namespace addon */
1371 } /* namespace kodi */
1372 
1373 #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 reguin definition
Definition: game.h:562
Game instance.
Definition: game.h:1223
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