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;
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();
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();
255 bool SupportsVFS()
const {
return m_instanceData->props->supports_vfs; }
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();
402 void CloseGame(
void) { m_instanceData->toKodi->CloseGame(m_instanceData->toKodi->kodiInstance); }
424 ~CStream() {
Close(); }
437 if (!CPrivateBase::m_interface->globalSingleInstance)
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;
586 return m_instanceData->toKodi->EnableHardwareRendering(m_instanceData->toKodi->kodiInstance,
621 return m_instanceData->toKodi->HwGetProcAddress(m_instanceData->toKodi->kodiInstance, sym);
658 virtual bool HasFeature(
const std::string& controller_id,
const std::string& feature_name)
695 const std::vector<kodi::addon::GameControllerLayout>& controllers)
708 virtual bool EnableKeyboard(
bool enable,
const std::string& controller_id) {
return false; }
719 virtual bool EnableMouse(
bool enable,
const std::string& controller_id) {
return false; }
766 const std::string& port_address,
767 const std::string& controller_id)
796 return m_instanceData->toKodi->InputEvent(m_instanceData->toKodi->kodiInstance, &event);
925 unsigned int consoleID,
926 const std::string& filePath)
957 const std::string& username,
958 const std::string& token,
981 std::string& postData,
982 const std::string& username,
983 const std::string& token,
985 const std::string& richPresence)
1035 instance->hdl =
this;
1037 instance->game->toAddon->LoadGame = ADDON_LoadGame;
1038 instance->game->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial;
1039 instance->game->toAddon->LoadStandalone = ADDON_LoadStandalone;
1040 instance->game->toAddon->UnloadGame = ADDON_UnloadGame;
1041 instance->game->toAddon->GetGameTiming = ADDON_GetGameTiming;
1042 instance->game->toAddon->GetRegion = ADDON_GetRegion;
1043 instance->game->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop;
1044 instance->game->toAddon->RunFrame = ADDON_RunFrame;
1045 instance->game->toAddon->Reset = ADDON_Reset;
1047 instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
1048 instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
1050 instance->game->toAddon->HasFeature = ADDON_HasFeature;
1051 instance->game->toAddon->GetTopology = ADDON_GetTopology;
1052 instance->game->toAddon->FreeTopology = ADDON_FreeTopology;
1053 instance->game->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts;
1054 instance->game->toAddon->EnableKeyboard = ADDON_EnableKeyboard;
1055 instance->game->toAddon->EnableMouse = ADDON_EnableMouse;
1056 instance->game->toAddon->ConnectController = ADDON_ConnectController;
1057 instance->game->toAddon->InputEvent = ADDON_InputEvent;
1059 instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
1060 instance->game->toAddon->Serialize = ADDON_Serialize;
1061 instance->game->toAddon->Deserialize = ADDON_Deserialize;
1063 instance->game->toAddon->CheatReset = ADDON_CheatReset;
1064 instance->game->toAddon->GetMemory = ADDON_GetMemory;
1065 instance->game->toAddon->SetCheat = ADDON_SetCheat;
1067 instance->game->toAddon->RCGenerateHashFromFile = ADDON_RCGenerateHashFromFile;
1068 instance->game->toAddon->RCGetGameIDUrl = ADDON_RCGetGameIDUrl;
1069 instance->game->toAddon->RCGetPatchFileUrl = ADDON_RCGetPatchFileUrl;
1070 instance->game->toAddon->RCPostRichPresenceUrl = ADDON_RCPostRichPresenceUrl;
1071 instance->game->toAddon->RCEnableRichPresence = ADDON_RCEnableRichPresence;
1072 instance->game->toAddon->RCGetRichPresenceEvaluation = ADDON_RCGetRichPresenceEvaluation;
1073 instance->game->toAddon->RCResetRuntime = ADDON_RCResetRuntime;
1075 instance->game->toAddon->FreeString = ADDON_FreeString;
1077 m_instanceData = instance->game;
1078 m_instanceData->toAddon->addonInstance =
this;
1085 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadGame(url);
1093 std::vector<std::string> urlList;
1094 for (
size_t i = 0; i < urlCount; ++i)
1096 if (urls[i] !=
nullptr)
1097 urlList.emplace_back(urls[i]);
1100 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1101 ->LoadGameSpecial(type, urlList);
1104 inline static GAME_ERROR ADDON_LoadStandalone(
const AddonInstance_Game* instance)
1106 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadStandalone();
1109 inline static GAME_ERROR ADDON_UnloadGame(
const AddonInstance_Game* instance)
1111 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->UnloadGame();
1114 inline static GAME_ERROR ADDON_GetGameTiming(
const AddonInstance_Game* instance,
1115 game_system_timing* timing_info)
1117 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1118 ->GetGameTiming(*timing_info);
1121 inline static GAME_REGION ADDON_GetRegion(
const AddonInstance_Game* instance)
1123 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->
GetRegion();
1126 inline static bool ADDON_RequiresGameLoop(
const AddonInstance_Game* instance)
1128 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RequiresGameLoop();
1131 inline static GAME_ERROR ADDON_RunFrame(
const AddonInstance_Game* instance)
1133 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RunFrame();
1136 inline static GAME_ERROR ADDON_Reset(
const AddonInstance_Game* instance)
1138 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Reset();
1143 inline static GAME_ERROR ADDON_HwContextReset(
const AddonInstance_Game* instance)
1145 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextReset();
1148 inline static GAME_ERROR ADDON_HwContextDestroy(
const AddonInstance_Game* instance)
1150 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextDestroy();
1155 inline static bool ADDON_HasFeature(
const AddonInstance_Game* instance,
1156 const char* controller_id,
1157 const char* feature_name)
1159 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1160 ->HasFeature(controller_id, feature_name);
1163 inline static game_input_topology* ADDON_GetTopology(
const AddonInstance_Game* instance)
1165 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->GetTopology();
1168 inline static void ADDON_FreeTopology(
const AddonInstance_Game* instance,
1169 game_input_topology* topology)
1171 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->FreeTopology(topology);
1174 inline static void ADDON_SetControllerLayouts(
const AddonInstance_Game* instance,
1175 const game_controller_layout* controllers,
1176 unsigned int controller_count)
1178 if (controllers ==
nullptr)
1181 std::vector<GameControllerLayout> controllerList;
1182 for (
unsigned int i = 0; i < controller_count; ++i)
1183 controllerList.emplace_back(controllers[i]);
1185 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1186 ->SetControllerLayouts(controllerList);
1189 inline static bool ADDON_EnableKeyboard(
const AddonInstance_Game* instance,
1191 const char* controller_id)
1193 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1194 ->EnableKeyboard(enable, controller_id);
1197 inline static bool ADDON_EnableMouse(
const AddonInstance_Game* instance,
1199 const char* controller_id)
1201 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1202 ->EnableMouse(enable, controller_id);
1205 inline static bool ADDON_ConnectController(
const AddonInstance_Game* instance,
1207 const char* port_address,
1208 const char* controller_id)
1210 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1211 ->ConnectController(connect, port_address, controller_id);
1214 inline static bool ADDON_InputEvent(
const AddonInstance_Game* instance,
1215 const game_input_event* event)
1217 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->InputEvent(*event);
1222 inline static size_t ADDON_SerializeSize(
const AddonInstance_Game* instance)
1224 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->SerializeSize();
1227 inline static GAME_ERROR ADDON_Serialize(
const AddonInstance_Game* instance,
1231 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Serialize(data, size);
1234 inline static GAME_ERROR ADDON_Deserialize(
const AddonInstance_Game* instance,
1235 const uint8_t* data,
1238 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Deserialize(data, size);
1243 inline static GAME_ERROR ADDON_CheatReset(
const AddonInstance_Game* instance)
1245 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->CheatReset();
1248 inline static GAME_ERROR ADDON_GetMemory(
const AddonInstance_Game* instance,
1253 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1254 ->GetMemory(type, *data, *size);
1257 inline static GAME_ERROR ADDON_SetCheat(
const AddonInstance_Game* instance,
1262 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1263 ->SetCheat(index, enabled, code);
1266 inline static GAME_ERROR ADDON_RCGenerateHashFromFile(
const AddonInstance_Game* instance,
1268 unsigned int consoleID,
1269 const char* filePath)
1271 std::string cppHash;
1273 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1274 ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
1275 if (!cppHash.empty() && hash)
1277 *hash =
new char[cppHash.size() + 1];
1278 std::copy(cppHash.begin(), cppHash.end(), *hash);
1279 (*hash)[cppHash.size()] =
'\0';
1284 inline static GAME_ERROR ADDON_RCGetGameIDUrl(
const AddonInstance_Game* instance,
1290 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
1291 if (!cppUrl.empty() && url)
1293 *url =
new char[cppUrl.size() + 1];
1294 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1295 (*url)[cppUrl.size()] =
'\0';
1300 inline static GAME_ERROR ADDON_RCGetPatchFileUrl(
const AddonInstance_Game* instance,
1302 const char* username,
1304 unsigned int gameID)
1308 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1309 ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
1310 if (!cppUrl.empty() && url)
1312 *url =
new char[cppUrl.size() + 1];
1313 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1314 (*url)[cppUrl.size()] =
'\0';
1319 inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(
const AddonInstance_Game* instance,
1322 const char* username,
1324 unsigned int gameID,
1325 const char* richPresence)
1328 std::string cppPostData;
1330 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1331 ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
1332 if (!cppUrl.empty())
1334 *url =
new char[cppUrl.size() + 1];
1335 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1336 (*url)[cppUrl.size()] =
'\0';
1338 if (!cppPostData.empty())
1340 *postData =
new char[cppPostData.size() + 1];
1341 std::copy(cppPostData.begin(), cppPostData.end(), *postData);
1342 (*postData)[cppPostData.size()] =
'\0';
1348 inline static GAME_ERROR ADDON_RCEnableRichPresence(
const AddonInstance_Game* instance,
1351 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1352 ->RCEnableRichPresence(script);
1355 inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(
const AddonInstance_Game* instance,
1357 unsigned int consoleID)
1359 std::string cppEvaluation;
1360 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1361 ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
1362 if (!cppEvaluation.empty())
1364 *evaluation =
new char[cppEvaluation.size() + 1];
1365 std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
1366 (*evaluation)[cppEvaluation.size()] =
'\0';
1372 inline static GAME_ERROR ADDON_RCResetRuntime(
const AddonInstance_Game* instance)
1374 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RCResetRuntime();
1377 inline static void ADDON_FreeString(
const AddonInstance_Game* instance,
char* str)
1382 AddonInstance_Game* m_instanceData;