11 #include "../AddonBase.h"    12 #include "../c-api/addon-instance/game.h"    46 class GameControllerLayout
    50   explicit GameControllerLayout() = 
default;
    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]);
    73   std::string controller_id;
    79   bool provides_input{
false};
    82   std::vector<std::string> digital_buttons;
    85   std::vector<std::string> analog_buttons;
    88   std::vector<std::string> analog_sticks;
    91   std::vector<std::string> accelerometers;
    94   std::vector<std::string> keys;
    97   std::vector<std::string> rel_pointers;
   100   std::vector<std::string> abs_pointers;
   103   std::vector<std::string> motors;
   117 class ATTR_DLL_LOCAL CInstanceGame : 
public IAddonInstance
   162   CInstanceGame() : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
   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!");
   168     SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
   169     CPrivateBase::m_interface->globalSingleInstance = 
this;
   176   ~CInstanceGame() 
override = 
default;
   187   std::string GameClientDllPath()
 const { 
return m_instanceData->props->game_client_dll_path; }
   199   bool ProxyDllPaths(std::vector<std::string>& paths)
   201     for (
unsigned int i = 0; i < m_instanceData->props->proxy_dll_count; ++i)
   203       if (m_instanceData->props->proxy_dll_paths[i] != 
nullptr)
   204         paths.emplace_back(m_instanceData->props->proxy_dll_paths[i]);
   206     return !paths.empty();
   221   bool ResourceDirectories(std::vector<std::string>& dirs)
   223     for (
unsigned int i = 0; i < m_instanceData->props->resource_directory_count; ++i)
   225       if (m_instanceData->props->resource_directories[i] != 
nullptr)
   226         dirs.emplace_back(m_instanceData->props->resource_directories[i]);
   228     return !dirs.empty();
   244   std::string ProfileDirectory()
 const { 
return m_instanceData->props->profile_directory; }
   255   bool SupportsVFS()
 const { 
return m_instanceData->props->supports_vfs; }
   267   bool Extensions(std::vector<std::string>& extensions)
   269     for (
unsigned int i = 0; i < m_instanceData->props->extension_count; ++i)
   271       if (m_instanceData->props->extensions[i] != 
nullptr)
   272         extensions.emplace_back(m_instanceData->props->extensions[i]);
   274     return !extensions.empty();
   309   virtual GAME_ERROR LoadGame(
const std::string& url) { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   319   virtual GAME_ERROR LoadGameSpecial(
SPECIAL_GAME_TYPE type, 
const std::vector<std::string>& urls)
   321     return GAME_ERROR_NOT_IMPLEMENTED;
   335   virtual GAME_ERROR LoadStandalone() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   345   virtual GAME_ERROR UnloadGame() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   357     return GAME_ERROR_NOT_IMPLEMENTED;
   377   virtual bool RequiresGameLoop() { 
return false; }
   385   virtual GAME_ERROR RunFrame() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   393   virtual GAME_ERROR Reset() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   402   void CloseGame(
void) { m_instanceData->toKodi->CloseGame(m_instanceData->toKodi->kodiInstance); }
   424     ~CStream() { Close(); }
   437       if (!CPrivateBase::m_interface->globalSingleInstance)
   442         kodi::Log(
ADDON_LOG_INFO, 
"kodi::addon::CInstanceGame::CStream already becomes reopened");
   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;
   462       if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
   466           *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
   467                ->m_instanceData->toKodi;
   468       cb.CloseStream(cb.kodiInstance, m_handle);
   488       if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
   492           *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
   493                ->m_instanceData->toKodi;
   494       return cb.GetStreamBuffer(cb.kodiInstance, m_handle, width, height, &buffer);
   508       if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
   512           *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
   513                ->m_instanceData->toKodi;
   514       cb.AddStreamData(cb.kodiInstance, m_handle, &packet);
   528       if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
   532           *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
   533                ->m_instanceData->toKodi;
   534       cb.ReleaseStreamBuffer(cb.kodiInstance, m_handle, &buffer);
   546     bool IsOpen()
 const { 
return m_handle != 
nullptr; }
   550     KODI_GAME_STREAM_HANDLE m_handle = 
nullptr;
   583   virtual GAME_ERROR HwContextReset() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   593   virtual GAME_ERROR HwContextDestroy() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   606     return m_instanceData->toKodi->HwGetProcAddress(m_instanceData->toKodi->kodiInstance, sym);
   643   virtual bool HasFeature(
const std::string& controller_id, 
const std::string& feature_name)
   679   virtual void SetControllerLayouts(
   680       const std::vector<kodi::addon::GameControllerLayout>& controllers)
   693   virtual bool EnableKeyboard(
bool enable, 
const std::string& controller_id) { 
return false; }
   704   virtual bool EnableMouse(
bool enable, 
const std::string& controller_id) { 
return false; }
   750   virtual bool ConnectController(
bool connect,
   751                                  const std::string& port_address,
   752                                  const std::string& controller_id)
   781     return m_instanceData->toKodi->InputEvent(m_instanceData->toKodi->kodiInstance, &event);
   811   virtual size_t SerializeSize() { 
return 0; }
   822   virtual GAME_ERROR Serialize(uint8_t* data, 
size_t size) { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   833   virtual GAME_ERROR Deserialize(
const uint8_t* data, 
size_t size)
   835     return GAME_ERROR_NOT_IMPLEMENTED;
   865   virtual GAME_ERROR CheatReset() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
   877   virtual GAME_ERROR GetMemory(
GAME_MEMORY type, uint8_t*& data, 
size_t& size)
   879     return GAME_ERROR_NOT_IMPLEMENTED;
   892   virtual GAME_ERROR SetCheat(
unsigned int index, 
bool enabled, 
const std::string& 
code)
   894     return GAME_ERROR_NOT_IMPLEMENTED;
   909   virtual GAME_ERROR RCGenerateHashFromFile(std::string& hash,
   910                                             unsigned int consoleID,
   911                                             const std::string& filePath)
   913     return GAME_ERROR_NOT_IMPLEMENTED;
   925   virtual GAME_ERROR RCGetGameIDUrl(std::string& url, 
const std::string& hash)
   927     return GAME_ERROR_NOT_IMPLEMENTED;
   941   virtual GAME_ERROR RCGetPatchFileUrl(std::string& url,
   942                                        const std::string& username,
   943                                        const std::string& token,
   946     return GAME_ERROR_NOT_IMPLEMENTED;
   965   virtual GAME_ERROR RCPostRichPresenceUrl(std::string& url,
   966                                            std::string& postData,
   967                                            const std::string& username,
   968                                            const std::string& token,
   970                                            const std::string& richPresence)
   972     return GAME_ERROR_NOT_IMPLEMENTED;
   982   virtual GAME_ERROR RCEnableRichPresence(
const std::string& script)
   984     return GAME_ERROR_NOT_IMPLEMENTED;
   999   virtual GAME_ERROR RCGetRichPresenceEvaluation(std::string& evaluation, 
unsigned int consoleID)
  1001     return GAME_ERROR_NOT_IMPLEMENTED;
  1011   virtual GAME_ERROR RCResetRuntime() { 
return GAME_ERROR_NOT_IMPLEMENTED; }
  1020     instance->hdl = 
this;
  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;
  1032     instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
  1033     instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
  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;
  1044     instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
  1045     instance->game->toAddon->Serialize = ADDON_Serialize;
  1046     instance->game->toAddon->Deserialize = ADDON_Deserialize;
  1048     instance->game->toAddon->CheatReset = ADDON_CheatReset;
  1049     instance->game->toAddon->GetMemory = ADDON_GetMemory;
  1050     instance->game->toAddon->SetCheat = ADDON_SetCheat;
  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;
  1060     instance->game->toAddon->FreeString = ADDON_FreeString;
  1062     m_instanceData = instance->game;
  1063     m_instanceData->toAddon->addonInstance = 
this;
  1070     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadGame(url);
  1078     std::vector<std::string> urlList;
  1079     for (
size_t i = 0; i < urlCount; ++i)
  1081       if (urls[i] != 
nullptr)
  1082         urlList.emplace_back(urls[i]);
  1085     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1086         ->LoadGameSpecial(type, urlList);
  1091     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadStandalone();
  1096     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->UnloadGame();
  1102     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1103         ->GetGameTiming(*timing_info);
  1108     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->GetRegion();
  1113     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RequiresGameLoop();
  1118     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RunFrame();
  1123     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Reset();
  1130     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextReset();
  1135     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextDestroy();
  1141                                       const char* controller_id,
  1142                                       const char* feature_name)
  1144     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1145         ->HasFeature(controller_id, feature_name);
  1150     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->GetTopology();
  1156     static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->FreeTopology(topology);
  1161                                                 unsigned int controller_count)
  1163     if (controllers == 
nullptr)
  1166     std::vector<GameControllerLayout> controllerList;
  1167     for (
unsigned int i = 0; i < controller_count; ++i)
  1168       controllerList.emplace_back(controllers[i]);
  1170     static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1171         ->SetControllerLayouts(controllerList);
  1176                                           const char* controller_id)
  1178     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1179         ->EnableKeyboard(enable, controller_id);
  1184                                        const char* controller_id)
  1186     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1187         ->EnableMouse(enable, controller_id);
  1192                                              const char* port_address,
  1193                                              const char* controller_id)
  1195     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1196         ->ConnectController(connect, port_address, controller_id);
  1202     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->InputEvent(*event);
  1209     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->SerializeSize();
  1216     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Serialize(data, size);
  1220                                              const uint8_t* data,
  1223     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Deserialize(data, size);
  1230     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->CheatReset();
  1238     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1239         ->GetMemory(type, *data, *size);
  1247     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1248         ->SetCheat(index, enabled, code);
  1251   inline static GAME_ERROR ADDON_RCGenerateHashFromFile(
const AddonInstance_Game* instance,
  1253                                                         unsigned int consoleID,
  1254                                                         const char* filePath)
  1256     std::string cppHash;
  1258     GAME_ERROR ret = 
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1259                          ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
  1260     if (!cppHash.empty() && hash)
  1262       *hash = 
new char[cppHash.size() + 1];
  1263       std::copy(cppHash.begin(), cppHash.end(), *hash);
  1264       (*hash)[cppHash.size()] = 
'\0';
  1275         static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
  1276     if (!cppUrl.empty() && url)
  1278       *url = 
new char[cppUrl.size() + 1];
  1279       std::copy(cppUrl.begin(), cppUrl.end(), *url);
  1280       (*url)[cppUrl.size()] = 
'\0';
  1287                                                    const char* username,
  1289                                                    unsigned int gameID)
  1293     GAME_ERROR ret = 
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1294                          ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
  1295     if (!cppUrl.empty() && url)
  1297       *url = 
new char[cppUrl.size() + 1];
  1298       std::copy(cppUrl.begin(), cppUrl.end(), *url);
  1299       (*url)[cppUrl.size()] = 
'\0';
  1304   inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(
const AddonInstance_Game* instance,
  1307                                                        const char* username,
  1309                                                        unsigned int gameID,
  1310                                                        const char* richPresence)
  1313     std::string cppPostData;
  1315         static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1316             ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
  1317     if (!cppUrl.empty())
  1319       *url = 
new char[cppUrl.size() + 1];
  1320       std::copy(cppUrl.begin(), cppUrl.end(), *url);
  1321       (*url)[cppUrl.size()] = 
'\0';
  1323     if (!cppPostData.empty())
  1325       *postData = 
new char[cppPostData.size() + 1];
  1326       std::copy(cppPostData.begin(), cppPostData.end(), *postData);
  1327       (*postData)[cppPostData.size()] = 
'\0';
  1333   inline static GAME_ERROR ADDON_RCEnableRichPresence(
const AddonInstance_Game* instance,
  1336     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1337         ->RCEnableRichPresence(script);
  1340   inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(
const AddonInstance_Game* instance,
  1342                                                              unsigned int consoleID)
  1344     std::string cppEvaluation;
  1345     GAME_ERROR ret = 
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
  1346                          ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
  1347     if (!cppEvaluation.empty())
  1349       *evaluation = 
new char[cppEvaluation.size() + 1];
  1350       std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
  1351       (*evaluation)[cppEvaluation.size()] = 
'\0';
  1359     return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RCResetRuntime();
 1 : To include information messages in the log file. 
Definition: addon_base.h:187
Game callbacks. 
Definition: game.h:1192
SPECIAL_GAME_TYPE
**Special game types passed into game_load_game_special(). 
Definition: game.h:577
"C" Game add-on controller layout. 
Definition: game.h:844
void(* game_proc_address_t)(void)
Hardware framebuffer process function address 
Definition: game.h:400
Stream packet and ephemeral metadata 
Definition: game.h:524
Definition: addon_base.h:267
GAME_MEMORY
Game Memory 
Definition: game.h:596
Stream buffers for hardware rendering and zero-copy support 
Definition: game.h:501
Definition: inftrees.h:24
GAME_REGION
Game region definition 
Definition: game.h:559
Game instance. 
Definition: game.h:1278
Immutable stream metadata 
Definition: game.h:476
Game region unknown. 
Definition: game.h:562
Game system timing. 
Definition: game.h:1107