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.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]);
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.push_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.push_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.push_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.push_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);
1160 const game_controller_layout* controllers,
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.push_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: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 reguin definition
Definition: game.h:562
Game instance.
Definition: game.h:1223
Immutable stream metadata
Definition: game.h:482
Game region unknown.
Definition: game.h:565
Game system timing.
Definition: game.h:1056