11 #include "../AddonBase.h" 12 #include "../c-api/addon-instance/game.h" 46 class GameControllerLayout
50 explicit GameControllerLayout() =
default;
51 GameControllerLayout(
const game_controller_layout& layout) : controller_id(layout.controller_id)
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;
957 virtual GAME_ERROR SetRetroAchievementsCredentials(
const std::string& username,
958 const std::string& token)
960 return GAME_ERROR_NOT_IMPLEMENTED;
979 virtual GAME_ERROR RCPostRichPresenceUrl(std::string& url,
980 std::string& postData,
981 const std::string& username,
982 const std::string& token,
984 const std::string& richPresence)
986 return GAME_ERROR_NOT_IMPLEMENTED;
996 virtual GAME_ERROR RCEnableRichPresence(
const std::string& script)
998 return GAME_ERROR_NOT_IMPLEMENTED;
1014 virtual GAME_ERROR RCGetRichPresenceEvaluation(std::string& evaluation,
unsigned int consoleID)
1016 return GAME_ERROR_NOT_IMPLEMENTED;
1027 virtual GAME_ERROR ActivateAchievement(
unsigned cheevoId,
const char* memaddr)
1029 return GAME_ERROR_NOT_IMPLEMENTED;
1039 virtual GAME_ERROR GetCheevo_URL_ID(
void (*callback)(
const char* achievementUrl,
1042 return GAME_ERROR_NOT_IMPLEMENTED;
1052 virtual GAME_ERROR RCResetRuntime() {
return GAME_ERROR_NOT_IMPLEMENTED; }
1061 instance->hdl =
this;
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;
1073 instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
1074 instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
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;
1085 instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
1086 instance->game->toAddon->Serialize = ADDON_Serialize;
1087 instance->game->toAddon->Deserialize = ADDON_Deserialize;
1089 instance->game->toAddon->CheatReset = ADDON_CheatReset;
1090 instance->game->toAddon->GetMemory = ADDON_GetMemory;
1091 instance->game->toAddon->SetCheat = ADDON_SetCheat;
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;
1105 instance->game->toAddon->FreeString = ADDON_FreeString;
1107 m_instanceData = instance->game;
1108 m_instanceData->toAddon->addonInstance =
this;
1115 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadGame(url);
1123 std::vector<std::string> urlList;
1124 for (
size_t i = 0; i < urlCount; ++i)
1126 if (urls[i] !=
nullptr)
1127 urlList.emplace_back(urls[i]);
1130 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1131 ->LoadGameSpecial(type, urlList);
1136 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->LoadStandalone();
1141 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->UnloadGame();
1147 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1148 ->GetGameTiming(*timing_info);
1153 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->GetRegion();
1158 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RequiresGameLoop();
1163 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RunFrame();
1168 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Reset();
1175 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextReset();
1180 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->HwContextDestroy();
1186 const char* controller_id,
1187 const char* feature_name)
1189 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1190 ->HasFeature(controller_id, feature_name);
1195 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->GetTopology();
1201 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->FreeTopology(topology);
1205 const game_controller_layout* controllers,
1206 unsigned int controller_count)
1208 if (controllers ==
nullptr)
1211 std::vector<GameControllerLayout> controllerList;
1212 for (
unsigned int i = 0; i < controller_count; ++i)
1213 controllerList.emplace_back(controllers[i]);
1215 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1216 ->SetControllerLayouts(controllerList);
1221 const char* controller_id)
1223 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1224 ->EnableKeyboard(enable, controller_id);
1229 const char* controller_id)
1231 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1232 ->EnableMouse(enable, controller_id);
1237 const char* port_address,
1238 const char* controller_id)
1240 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1241 ->ConnectController(connect, port_address, controller_id);
1247 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->InputEvent(*event);
1254 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->SerializeSize();
1261 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Serialize(data, size);
1265 const uint8_t* data,
1268 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->Deserialize(data, size);
1275 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->CheatReset();
1283 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1284 ->GetMemory(type, *data, *size);
1292 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1293 ->SetCheat(index, enabled, code);
1296 inline static GAME_ERROR ADDON_RCGenerateHashFromFile(
const AddonInstance_Game* instance,
1298 unsigned int consoleID,
1299 const char* filePath)
1301 std::string cppHash;
1303 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1304 ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
1305 if (!cppHash.empty() && hash)
1307 *hash =
new char[cppHash.size() + 1];
1308 std::copy(cppHash.begin(), cppHash.end(), *hash);
1309 (*hash)[cppHash.size()] =
'\0';
1320 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
1321 if (!cppUrl.empty() && url)
1323 *url =
new char[cppUrl.size() + 1];
1324 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1325 (*url)[cppUrl.size()] =
'\0';
1332 const char* username,
1334 unsigned int gameID)
1338 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1339 ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
1340 if (!cppUrl.empty() && url)
1342 *url =
new char[cppUrl.size() + 1];
1343 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1344 (*url)[cppUrl.size()] =
'\0';
1349 inline static GAME_ERROR ADDON_SetRetroAchievementsCredentials(
const AddonInstance_Game* instance,
1350 const char* username,
1353 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1354 ->SetRetroAchievementsCredentials(username, token);
1357 inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(
const AddonInstance_Game* instance,
1360 const char* username,
1362 unsigned int gameID,
1363 const char* richPresence)
1366 std::string cppPostData;
1368 static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1369 ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
1370 if (!cppUrl.empty())
1372 *url =
new char[cppUrl.size() + 1];
1373 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1374 (*url)[cppUrl.size()] =
'\0';
1376 if (!cppPostData.empty())
1378 *postData =
new char[cppPostData.size() + 1];
1379 std::copy(cppPostData.begin(), cppPostData.end(), *postData);
1380 (*postData)[cppPostData.size()] =
'\0';
1386 inline static GAME_ERROR ADDON_RCEnableRichPresence(
const AddonInstance_Game* instance,
1389 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1390 ->RCEnableRichPresence(script);
1393 inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(
const AddonInstance_Game* instance,
1395 unsigned int consoleID)
1397 std::string cppEvaluation;
1398 GAME_ERROR ret =
static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1399 ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
1400 if (!cppEvaluation.empty())
1402 *evaluation =
new char[cppEvaluation.size() + 1];
1403 std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
1404 (*evaluation)[cppEvaluation.size()] =
'\0';
1410 inline static GAME_ERROR ADDON_ActivateAchievement(
const AddonInstance_Game* instance,
1412 const char* memaddr)
1414 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1415 ->ActivateAchievement(cheevoId, memaddr);
1419 void (*callback)(
const char* achievementUrl,
1422 return static_cast<CInstanceGame*
>(instance->toAddon->addonInstance)
1423 ->GetCheevo_URL_ID(callback);
1428 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:1137
SPECIAL_GAME_TYPE
**Special game types passed into game_load_game_special().
Definition: game.h:580
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
Immutable stream metadata
Definition: game.h:482
Game region unknown.
Definition: game.h:565
Game system timing.
Definition: game.h:1056