162 if (CPrivateBase::m_interface->globalSingleInstance !=
nullptr)
164 throw std::logic_error(
165 "kodi::addon::CInstanceGame: Cannot create more than one game instance!");
167 SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
168 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();
225 for (
unsigned int i = 0; i < m_instanceData->props->resource_directory_count; ++i)
227 if (m_instanceData->props->resource_directories[i] !=
nullptr)
228 dirs.emplace_back(m_instanceData->props->resource_directories[i]);
230 return !dirs.empty();
257 bool SupportsVFS()
const {
return m_instanceData->props->supports_vfs; }
272 for (
unsigned int i = 0; i < m_instanceData->props->extension_count; ++i)
274 if (m_instanceData->props->extensions[i] !=
nullptr)
275 extensions.emplace_back(m_instanceData->props->extensions[i]);
277 return !extensions.empty();
406 void CloseGame(
void) { m_instanceData->toKodi->CloseGame(m_instanceData->toKodi->kodiInstance); }
427 ~CStream() {
Close(); }
441 if (!CPrivateBase::m_interface->globalSingleInstance)
451 *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
452 ->m_instanceData->toKodi;
453 m_handle = cb.OpenStream(cb.kodiInstance, &properties);
454 return m_handle !=
nullptr;
466 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
470 *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
471 ->m_instanceData->toKodi;
472 cb.CloseStream(cb.kodiInstance, m_handle);
493 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
497 *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
498 ->m_instanceData->toKodi;
499 return cb.GetStreamBuffer(cb.kodiInstance, m_handle, width, height, &buffer);
513 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
517 *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
518 ->m_instanceData->toKodi;
519 cb.AddStreamData(cb.kodiInstance, m_handle, &packet);
533 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
537 *
static_cast<CInstanceGame*
>(CPrivateBase::m_interface->globalSingleInstance)
538 ->m_instanceData->toKodi;
539 cb.ReleaseStreamBuffer(cb.kodiInstance, m_handle, &buffer);
551 bool IsOpen()
const {
return m_handle !=
nullptr; }
555 KODI_GAME_STREAM_HANDLE m_handle =
nullptr;
590 return m_instanceData->toKodi->EnableHardwareRendering(m_instanceData->toKodi->kodiInstance,
625 return m_instanceData->toKodi->HwGetProcAddress(m_instanceData->toKodi->kodiInstance, sym);
661 virtual bool HasFeature(
const std::string& controller_id,
const std::string& feature_name)
661 virtual bool HasFeature(
const std::string& controller_id,
const std::string& feature_name) {
…}
698 const std::vector<kodi::addon::GameControllerLayout>& controllers)
711 virtual bool EnableKeyboard(
bool enable,
const std::string& controller_id) {
return false; }
722 virtual bool EnableMouse(
bool enable,
const std::string& controller_id) {
return false; }
770 const std::string& port_address,
771 const std::string& controller_id)
801 return m_instanceData->toKodi->InputEvent(m_instanceData->toKodi->kodiInstance, &event);
929 unsigned int consoleID,
930 const std::string& filePath)
961 const std::string& username,
962 const std::string& token,
985 std::string& postData,
986 const std::string& username,
987 const std::string& token,
989 const std::string& richPresence)
1040 instance->hdl =
this;
1042 instance->game->toAddon->LoadGame = ADDON_LoadGame;
1043 instance->game->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial;
1044 instance->game->toAddon->LoadStandalone = ADDON_LoadStandalone;
1045 instance->game->toAddon->UnloadGame = ADDON_UnloadGame;
1046 instance->game->toAddon->GetGameTiming = ADDON_GetGameTiming;
1047 instance->game->toAddon->GetRegion = ADDON_GetRegion;
1048 instance->game->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop;
1049 instance->game->toAddon->RunFrame = ADDON_RunFrame;
1050 instance->game->toAddon->Reset = ADDON_Reset;
1052 instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
1053 instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
1055 instance->game->toAddon->HasFeature = ADDON_HasFeature;
1056 instance->game->toAddon->GetTopology = ADDON_GetTopology;
1057 instance->game->toAddon->FreeTopology = ADDON_FreeTopology;
1058 instance->game->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts;
1059 instance->game->toAddon->EnableKeyboard = ADDON_EnableKeyboard;
1060 instance->game->toAddon->EnableMouse = ADDON_EnableMouse;
1061 instance->game->toAddon->ConnectController = ADDON_ConnectController;
1062 instance->game->toAddon->InputEvent = ADDON_InputEvent;
1064 instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
1065 instance->game->toAddon->Serialize = ADDON_Serialize;
1066 instance->game->toAddon->Deserialize = ADDON_Deserialize;
1068 instance->game->toAddon->CheatReset = ADDON_CheatReset;
1069 instance->game->toAddon->GetMemory = ADDON_GetMemory;
1070 instance->game->toAddon->SetCheat = ADDON_SetCheat;
1072 instance->game->toAddon->RCGenerateHashFromFile = ADDON_RCGenerateHashFromFile;
1073 instance->game->toAddon->RCGetGameIDUrl = ADDON_RCGetGameIDUrl;
1074 instance->game->toAddon->RCGetPatchFileUrl = ADDON_RCGetPatchFileUrl;
1075 instance->game->toAddon->RCPostRichPresenceUrl = ADDON_RCPostRichPresenceUrl;
1076 instance->game->toAddon->RCEnableRichPresence = ADDON_RCEnableRichPresence;
1077 instance->game->toAddon->RCGetRichPresenceEvaluation = ADDON_RCGetRichPresenceEvaluation;
1078 instance->game->toAddon->RCResetRuntime = ADDON_RCResetRuntime;
1080 instance->game->toAddon->FreeString = ADDON_FreeString;
1082 m_instanceData = instance->game;
1083 m_instanceData->toAddon->addonInstance =
this;
1090 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadGame(url);
1098 std::vector<std::string> urlList;
1099 for (
size_t i = 0; i < urlCount; ++i)
1101 if (urls[i] !=
nullptr)
1102 urlList.emplace_back(urls[i]);
1105 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1106 ->LoadGameSpecial(type, urlList);
1109 inline static GAME_ERROR ADDON_LoadStandalone(
const AddonInstance_Game* instance)
1111 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadStandalone();
1114 inline static GAME_ERROR ADDON_UnloadGame(
const AddonInstance_Game* instance)
1116 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->UnloadGame();
1119 inline static GAME_ERROR ADDON_GetGameTiming(
const AddonInstance_Game* instance,
1120 game_system_timing* timing_info)
1122 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1123 ->GetGameTiming(*timing_info);
1126 inline static GAME_REGION ADDON_GetRegion(
const AddonInstance_Game* instance)
1128 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->
GetRegion();
1131 inline static bool ADDON_RequiresGameLoop(
const AddonInstance_Game* instance)
1133 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RequiresGameLoop();
1136 inline static GAME_ERROR ADDON_RunFrame(
const AddonInstance_Game* instance)
1138 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RunFrame();
1141 inline static GAME_ERROR ADDON_Reset(
const AddonInstance_Game* instance)
1143 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Reset();
1148 inline static GAME_ERROR ADDON_HwContextReset(
const AddonInstance_Game* instance)
1150 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextReset();
1153 inline static GAME_ERROR ADDON_HwContextDestroy(
const AddonInstance_Game* instance)
1155 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextDestroy();
1160 inline static bool ADDON_HasFeature(
const AddonInstance_Game* instance,
1161 const char* controller_id,
1162 const char* feature_name)
1164 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1165 ->HasFeature(controller_id, feature_name);
1168 inline static game_input_topology* ADDON_GetTopology(
const AddonInstance_Game* instance)
1170 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->GetTopology();
1173 inline static void ADDON_FreeTopology(
const AddonInstance_Game* instance,
1174 game_input_topology* topology)
1176 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->FreeTopology(topology);
1179 inline static void ADDON_SetControllerLayouts(
const AddonInstance_Game* instance,
1180 const game_controller_layout* controllers,
1181 unsigned int controller_count)
1183 if (controllers ==
nullptr)
1186 std::vector<GameControllerLayout> controllerList;
1187 controllerList.reserve(controller_count);
1188 for (
unsigned int i = 0; i < controller_count; ++i)
1189 controllerList.emplace_back(controllers[i]);
1191 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1192 ->SetControllerLayouts(controllerList);
1195 inline static bool ADDON_EnableKeyboard(
const AddonInstance_Game* instance,
1197 const char* controller_id)
1199 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1200 ->EnableKeyboard(enable, controller_id);
1203 inline static bool ADDON_EnableMouse(
const AddonInstance_Game* instance,
1205 const char* controller_id)
1207 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1208 ->EnableMouse(enable, controller_id);
1211 inline static bool ADDON_ConnectController(
const AddonInstance_Game* instance,
1213 const char* port_address,
1214 const char* controller_id)
1216 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1217 ->ConnectController(connect, port_address, controller_id);
1220 inline static bool ADDON_InputEvent(
const AddonInstance_Game* instance,
1221 const game_input_event* event)
1223 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->InputEvent(*event);
1228 inline static size_t ADDON_SerializeSize(
const AddonInstance_Game* instance)
1230 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->SerializeSize();
1233 inline static GAME_ERROR ADDON_Serialize(
const AddonInstance_Game* instance,
1237 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Serialize(data, size);
1240 inline static GAME_ERROR ADDON_Deserialize(
const AddonInstance_Game* instance,
1241 const uint8_t* data,
1244 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Deserialize(data, size);
1249 inline static GAME_ERROR ADDON_CheatReset(
const AddonInstance_Game* instance)
1251 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->CheatReset();
1254 inline static GAME_ERROR ADDON_GetMemory(
const AddonInstance_Game* instance,
1259 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1260 ->GetMemory(type, *data, *size);
1263 inline static GAME_ERROR ADDON_SetCheat(
const AddonInstance_Game* instance,
1268 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1269 ->SetCheat(index, enabled, code);
1272 inline static GAME_ERROR ADDON_RCGenerateHashFromFile(
const AddonInstance_Game* instance,
1274 unsigned int consoleID,
1275 const char* filePath)
1277 std::string cppHash;
1279 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1280 ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
1281 if (!cppHash.empty() && hash)
1283 *hash =
new char[cppHash.size() + 1];
1284 std::copy(cppHash.begin(), cppHash.end(), *hash);
1285 (*hash)[cppHash.size()] =
'\0';
1290 inline static GAME_ERROR ADDON_RCGetGameIDUrl(
const AddonInstance_Game* instance,
1296 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
1297 if (!cppUrl.empty() && url)
1299 *url =
new char[cppUrl.size() + 1];
1300 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1301 (*url)[cppUrl.size()] =
'\0';
1306 inline static GAME_ERROR ADDON_RCGetPatchFileUrl(
const AddonInstance_Game* instance,
1308 const char* username,
1310 unsigned int gameID)
1314 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1315 ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
1316 if (!cppUrl.empty() && url)
1318 *url =
new char[cppUrl.size() + 1];
1319 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1320 (*url)[cppUrl.size()] =
'\0';
1325 inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(
const AddonInstance_Game* instance,
1328 const char* username,
1330 unsigned int gameID,
1331 const char* richPresence)
1334 std::string cppPostData;
1336 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1337 ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
1338 if (!cppUrl.empty())
1340 *url =
new char[cppUrl.size() + 1];
1341 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1342 (*url)[cppUrl.size()] =
'\0';
1344 if (!cppPostData.empty())
1346 *postData =
new char[cppPostData.size() + 1];
1347 std::copy(cppPostData.begin(), cppPostData.end(), *postData);
1348 (*postData)[cppPostData.size()] =
'\0';
1354 inline static GAME_ERROR ADDON_RCEnableRichPresence(
const AddonInstance_Game* instance,
1357 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1358 ->RCEnableRichPresence(script);
1361 inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(
const AddonInstance_Game* instance,
1363 unsigned int consoleID)
1365 std::string cppEvaluation;
1366 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1367 ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
1368 if (!cppEvaluation.empty())
1370 *evaluation =
new char[cppEvaluation.size() + 1];
1371 std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
1372 (*evaluation)[cppEvaluation.size()] =
'\0';
1378 inline static GAME_ERROR ADDON_RCResetRuntime(
const AddonInstance_Game* instance)
1380 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RCResetRuntime();
1383 inline static void ADDON_FreeString(
const AddonInstance_Game* instance,
char* str)
1388 AddonInstance_Game* m_instanceData;