Kodi Development 22.0
for Binary and Script based Add-Ons
 
Loading...
Searching...
No Matches
Game.h
1/*
2 * Copyright (C) 2014-2025 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#pragma once
10
11#include "../AddonBase.h"
12#include "../c-api/addon-instance/game.h"
13
14#include <algorithm>
15#include <functional>
16
17#ifdef __cplusplus
18
19namespace kodi
20{
21namespace addon
22{
23
24//==============================================================================
33
34//==============================================================================
39
40//==============================================================================
48{
49public:
51 explicit GameControllerLayout() = default;
52 GameControllerLayout(const game_controller_layout& layout) : controller_id(layout.controller_id)
53 {
54 provides_input = layout.provides_input;
55 for (unsigned int i = 0; i < layout.digital_button_count; ++i)
56 digital_buttons.emplace_back(layout.digital_buttons[i]);
57 for (unsigned int i = 0; i < layout.analog_button_count; ++i)
58 analog_buttons.emplace_back(layout.analog_buttons[i]);
59 for (unsigned int i = 0; i < layout.analog_stick_count; ++i)
60 analog_sticks.emplace_back(layout.analog_sticks[i]);
61 for (unsigned int i = 0; i < layout.accelerometer_count; ++i)
62 accelerometers.emplace_back(layout.accelerometers[i]);
63 for (unsigned int i = 0; i < layout.key_count; ++i)
64 keys.emplace_back(layout.keys[i]);
65 for (unsigned int i = 0; i < layout.rel_pointer_count; ++i)
66 rel_pointers.emplace_back(layout.rel_pointers[i]);
67 for (unsigned int i = 0; i < layout.abs_pointer_count; ++i)
68 abs_pointers.emplace_back(layout.abs_pointers[i]);
69 for (unsigned int i = 0; i < layout.motor_count; ++i)
70 motors.emplace_back(layout.motors[i]);
71 }
75 std::string controller_id;
76
80 bool provides_input{false};
81
83 std::vector<std::string> digital_buttons;
84
86 std::vector<std::string> analog_buttons;
87
89 std::vector<std::string> analog_sticks;
90
92 std::vector<std::string> accelerometers;
93
95 std::vector<std::string> keys;
96
98 std::vector<std::string> rel_pointers;
99
101 std::vector<std::string> abs_pointers;
102
104 std::vector<std::string> motors;
105};
107//------------------------------------------------------------------------------
108
109//==============================================================================
118class ATTR_DLL_LOCAL CInstanceGame : public IAddonInstance
119{
120public:
121 //============================================================================
127
128 //============================================================================
161 CInstanceGame() : IAddonInstance(IInstanceInfo(CPrivateBase::m_interface->firstKodiInstance))
162 {
163 if (CPrivateBase::m_interface->globalSingleInstance != nullptr)
164 {
165 throw std::logic_error(
166 "kodi::addon::CInstanceGame: Cannot create more than one game instance!");
167 }
168 SetAddonStruct(CPrivateBase::m_interface->firstKodiInstance);
169 CPrivateBase::m_interface->globalSingleInstance = this;
170 }
171 //----------------------------------------------------------------------------
172
173 //============================================================================
176 ~CInstanceGame() override = default;
177 //----------------------------------------------------------------------------
178
179 //============================================================================
187 std::string GameClientDllPath() const { return m_instanceData->props->game_client_dll_path; }
188 //----------------------------------------------------------------------------
189
190 //============================================================================
200 bool ProxyDllPaths(std::vector<std::string>& paths)
201 {
202 for (unsigned int i = 0; i < m_instanceData->props->proxy_dll_count; ++i)
203 {
204 if (m_instanceData->props->proxy_dll_paths[i] != nullptr)
205 paths.emplace_back(m_instanceData->props->proxy_dll_paths[i]);
206 }
207 return !paths.empty();
208 }
209 //----------------------------------------------------------------------------
210
211 //============================================================================
224 bool ResourceDirectories(std::vector<std::string>& dirs)
225 {
226 for (unsigned int i = 0; i < m_instanceData->props->resource_directory_count; ++i)
227 {
228 if (m_instanceData->props->resource_directories[i] != nullptr)
229 dirs.emplace_back(m_instanceData->props->resource_directories[i]);
230 }
231 return !dirs.empty();
232 }
233 //----------------------------------------------------------------------------
234
235 //============================================================================
247 std::string ProfileDirectory() const { return m_instanceData->props->profile_directory; }
248 //----------------------------------------------------------------------------
249
250 //============================================================================
258 bool SupportsVFS() const { return m_instanceData->props->supports_vfs; }
259 //----------------------------------------------------------------------------
260
261 //============================================================================
271 bool Extensions(std::vector<std::string>& extensions)
272 {
273 for (unsigned int i = 0; i < m_instanceData->props->extension_count; ++i)
274 {
275 if (m_instanceData->props->extensions[i] != nullptr)
276 extensions.emplace_back(m_instanceData->props->extensions[i]);
277 }
278 return !extensions.empty();
279 }
280 //----------------------------------------------------------------------------
281
283
284 //--==----==----==----==----==----==----==----==----==----==----==----==----==--
285
286 //============================================================================
305
306 //============================================================================
313 virtual GAME_ERROR LoadGame(const std::string& url) { return GAME_ERROR_NOT_IMPLEMENTED; }
314 //----------------------------------------------------------------------------
315
316 //============================================================================
324 virtual GAME_ERROR LoadGameSpecial(SPECIAL_GAME_TYPE type, const std::vector<std::string>& urls)
325 {
327 }
328 //----------------------------------------------------------------------------
329
330 //============================================================================
341 //----------------------------------------------------------------------------
342
343 //============================================================================
351 //----------------------------------------------------------------------------
352
353 //============================================================================
361 {
363 }
364 //----------------------------------------------------------------------------
365
366 //============================================================================
372 //----------------------------------------------------------------------------
373
374 //============================================================================
382 virtual bool RequiresGameLoop() { return false; }
383 //----------------------------------------------------------------------------
384
385 //============================================================================
391 //----------------------------------------------------------------------------
392
393 //============================================================================
399 //----------------------------------------------------------------------------
400
401 //==========================================================================
407 void CloseGame(void) { m_instanceData->toKodi->CloseGame(m_instanceData->toKodi->kodiInstance); }
408 //----------------------------------------------------------------------------
409
410 //============================================================================
422 {
423 public:
424 CStream() = default;
425
426 CStream(const game_stream_properties& properties) { Open(properties); }
427
428 ~CStream() { Close(); }
429
430 //==========================================================================
440 bool Open(const game_stream_properties& properties)
441 {
442 if (!CPrivateBase::m_interface->globalSingleInstance)
443 return false;
444
445 if (m_handle)
446 {
447 kodi::Log(ADDON_LOG_INFO, "kodi::addon::CInstanceGame::CStream already reopened");
448 Close();
449 }
450
452 *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
453 ->m_instanceData->toKodi;
454 m_handle = cb.OpenStream(cb.kodiInstance, &properties);
455 return m_handle != nullptr;
456 }
457 //--------------------------------------------------------------------------
458
459 //==========================================================================
465 void Close()
466 {
467 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
468 return;
469
471 *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
472 ->m_instanceData->toKodi;
473 cb.CloseStream(cb.kodiInstance, m_handle);
474 m_handle = nullptr;
475 }
476 //--------------------------------------------------------------------------
477
478 //==========================================================================
492 bool GetBuffer(unsigned int width, unsigned int height, game_stream_buffer& buffer)
493 {
494 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
495 return false;
496
498 *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
499 ->m_instanceData->toKodi;
500 return cb.GetStreamBuffer(cb.kodiInstance, m_handle, width, height, &buffer);
501 }
502 //--------------------------------------------------------------------------
503
504 //==========================================================================
512 void AddData(const game_stream_packet& packet)
513 {
514 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
515 return;
516
518 *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
519 ->m_instanceData->toKodi;
520 cb.AddStreamData(cb.kodiInstance, m_handle, &packet);
521 }
522 //--------------------------------------------------------------------------
523
524 //==========================================================================
533 {
534 if (!m_handle || !CPrivateBase::m_interface->globalSingleInstance)
535 return;
536
538 *static_cast<CInstanceGame*>(CPrivateBase::m_interface->globalSingleInstance)
539 ->m_instanceData->toKodi;
540 cb.ReleaseStreamBuffer(cb.kodiInstance, m_handle, &buffer);
541 }
542 //--------------------------------------------------------------------------
543
544 //==========================================================================
552 bool IsOpen() const { return m_handle != nullptr; }
553 //--------------------------------------------------------------------------
554
555 private:
556 KODI_GAME_STREAM_HANDLE m_handle = nullptr;
557 };
559
561
562 //--==----==----==----==----==----==----==----==----==----==----==----==----==--
563
564 //============================================================================
580
581 //==========================================================================
590 {
591 return m_instanceData->toKodi->EnableHardwareRendering(m_instanceData->toKodi->kodiInstance,
592 &properties);
593 }
594 //----------------------------------------------------------------------------
595
596 //============================================================================
604 //----------------------------------------------------------------------------
605
606 //============================================================================
614
615 //============================================================================
625 {
626 return m_instanceData->toKodi->HwGetProcAddress(m_instanceData->toKodi->kodiInstance, sym);
627 }
628 //----------------------------------------------------------------------------
629
631
632 //--==----==----==----==----==----==----==----==----==----==----==----==----==--
633
634 //============================================================================
649
650 //============================================================================
662 virtual bool HasFeature(const std::string& controller_id, const std::string& feature_name)
663 {
664 return false;
665 }
666 //----------------------------------------------------------------------------
667
668 //============================================================================
679 virtual game_input_topology* GetTopology() { return nullptr; }
680 //----------------------------------------------------------------------------
681
682 //============================================================================
687 virtual void FreeTopology(game_input_topology* topology) {}
688 //----------------------------------------------------------------------------
689
690 //============================================================================
699 const std::vector<kodi::addon::GameControllerLayout>& controllers)
700 {
701 }
702 //----------------------------------------------------------------------------
703
704 //============================================================================
712 virtual bool EnableKeyboard(bool enable, const std::string& controller_id) { return false; }
713 //----------------------------------------------------------------------------
714
715 //============================================================================
723 virtual bool EnableMouse(bool enable, const std::string& controller_id) { return false; }
724 //--------------------------------------------------------------------------
725
726 //==========================================================================
770 virtual bool ConnectController(bool connect,
771 const std::string& port_address,
772 const std::string& controller_id)
773 {
774 return false;
775 }
776 //----------------------------------------------------------------------------
777
778 //============================================================================
785 virtual bool InputEvent(const game_input_event& event) { return false; }
786 //----------------------------------------------------------------------------
787
788 //============================================================================
801 {
802 return m_instanceData->toKodi->InputEvent(m_instanceData->toKodi->kodiInstance, &event);
803 }
804 //----------------------------------------------------------------------------
805
807
808 //--==----==----==----==----==----==----==----==----==----==----==----==----==--
809
810 //============================================================================
825
826 //============================================================================
831 virtual size_t SerializeSize() { return 0; }
832 //----------------------------------------------------------------------------
833
834 //============================================================================
842 virtual GAME_ERROR Serialize(uint8_t* data, size_t size) { return GAME_ERROR_NOT_IMPLEMENTED; }
843 //----------------------------------------------------------------------------
844
845 //============================================================================
853 virtual GAME_ERROR Deserialize(const uint8_t* data, size_t size)
854 {
856 }
857 //----------------------------------------------------------------------------
858
860
861 //--==----==----==----==----==----==----==----==----==----==----==----==----==--
862
863 //============================================================================
879
880 //============================================================================
886 //----------------------------------------------------------------------------
887
888 //============================================================================
897 virtual GAME_ERROR GetMemory(GAME_MEMORY type, uint8_t*& data, size_t& size)
898 {
900 }
901 //----------------------------------------------------------------------------
902
903 //============================================================================
912 virtual GAME_ERROR SetCheat(unsigned int index, bool enabled, const std::string& code)
913 {
915 }
916
917 //============================================================================
929 virtual GAME_ERROR RCGenerateHashFromFile(std::string& hash,
930 unsigned int consoleID,
931 const std::string& filePath)
932 {
934 }
935
936 //============================================================================
944 virtual GAME_ERROR RCGetGameIDUrl(std::string& url, const std::string& hash)
945 {
947 }
948
949 //============================================================================
959 virtual GAME_ERROR RCGetPatchFileUrl(std::string& url,
960 const std::string& username,
961 const std::string& token,
962 unsigned int gameID)
963 {
965 }
966
967 //============================================================================
975 virtual GAME_ERROR SetRetroAchievementsCredentials(const std::string& username,
976 const std::string& token)
977 {
979 }
980
981 //============================================================================
995 virtual GAME_ERROR RCPostRichPresenceUrl(std::string& url,
996 std::string& postData,
997 const std::string& username,
998 const std::string& token,
999 unsigned int gameID,
1000 const std::string& richPresence)
1001 {
1003 }
1004
1005 //============================================================================
1012 virtual GAME_ERROR RCEnableRichPresence(const std::string& script)
1013 {
1015 }
1016
1017 //============================================================================
1029 virtual GAME_ERROR RCGetRichPresenceEvaluation(std::string& evaluation, unsigned int consoleID)
1030 {
1032 }
1033
1034 //============================================================================
1043 virtual GAME_ERROR ActivateAchievement(unsigned int cheevoId,
1044 const std::string& memAddrExpression)
1045 {
1047 }
1048
1049 //============================================================================
1062 const std::function<void(const std::string& achievementUrl, unsigned int cheevoId)>& callback)
1063 {
1065 }
1066
1067 //============================================================================
1075
1076 //----------------------------------------------------------------------------
1077
1079
1080 //--==----==----==----==----==----==----==----==----==----==----==----==----==--
1081
1082 //============================================================================
1097
1098 //============================================================================
1106 virtual bool GetEjectState() { return false; }
1107 //----------------------------------------------------------------------------
1108
1109 //============================================================================
1119 virtual GAME_ERROR SetEjectState(bool ejected) { return GAME_ERROR_NOT_IMPLEMENTED; }
1120 //----------------------------------------------------------------------------
1121
1122 //============================================================================
1128 virtual unsigned int GetImageIndex() { return 0; }
1129 //----------------------------------------------------------------------------
1130
1131 //============================================================================
1140 virtual GAME_ERROR SetImageIndex(unsigned int imageIndex) { return GAME_ERROR_NOT_IMPLEMENTED; }
1141 //----------------------------------------------------------------------------
1142
1143 //============================================================================
1148 virtual unsigned int GetImageCount() { return 0; }
1149 //----------------------------------------------------------------------------
1150
1151 //============================================================================
1158 //----------------------------------------------------------------------------
1159
1160 //============================================================================
1170 virtual GAME_ERROR ReplaceImageIndex(unsigned int imageIndex, const std::string& filePath)
1171 {
1173 }
1174 //----------------------------------------------------------------------------
1175
1176 //============================================================================
1185 virtual GAME_ERROR RemoveImageIndex(unsigned int imageIndex)
1186 {
1188 }
1189 //----------------------------------------------------------------------------
1190
1191 //============================================================================
1200 virtual GAME_ERROR SetInitialImage(unsigned int imageIndex, const std::string& filePath)
1201 {
1203 }
1204 //----------------------------------------------------------------------------
1205
1206 //============================================================================
1213 virtual std::string GetImagePath(unsigned int imageIndex) { return ""; }
1214 //----------------------------------------------------------------------------
1215
1216 //============================================================================
1223 virtual std::string GetImageLabel(unsigned int imageIndex) { return ""; }
1224 //----------------------------------------------------------------------------
1225
1227
1228private:
1229 void SetAddonStruct(KODI_ADDON_INSTANCE_STRUCT* instance)
1230 {
1231 instance->hdl = this;
1232
1233 instance->game->toAddon->LoadGame = ADDON_LoadGame;
1234 instance->game->toAddon->LoadGameSpecial = ADDON_LoadGameSpecial;
1235 instance->game->toAddon->LoadStandalone = ADDON_LoadStandalone;
1236 instance->game->toAddon->UnloadGame = ADDON_UnloadGame;
1237 instance->game->toAddon->GetGameTiming = ADDON_GetGameTiming;
1238 instance->game->toAddon->GetRegion = ADDON_GetRegion;
1239 instance->game->toAddon->RequiresGameLoop = ADDON_RequiresGameLoop;
1240 instance->game->toAddon->RunFrame = ADDON_RunFrame;
1241 instance->game->toAddon->Reset = ADDON_Reset;
1242
1243 instance->game->toAddon->HwContextReset = ADDON_HwContextReset;
1244 instance->game->toAddon->HwContextDestroy = ADDON_HwContextDestroy;
1245
1246 instance->game->toAddon->HasFeature = ADDON_HasFeature;
1247 instance->game->toAddon->GetTopology = ADDON_GetTopology;
1248 instance->game->toAddon->FreeTopology = ADDON_FreeTopology;
1249 instance->game->toAddon->SetControllerLayouts = ADDON_SetControllerLayouts;
1250 instance->game->toAddon->EnableKeyboard = ADDON_EnableKeyboard;
1251 instance->game->toAddon->EnableMouse = ADDON_EnableMouse;
1252 instance->game->toAddon->ConnectController = ADDON_ConnectController;
1253 instance->game->toAddon->InputEvent = ADDON_InputEvent;
1254
1255 instance->game->toAddon->SerializeSize = ADDON_SerializeSize;
1256 instance->game->toAddon->Serialize = ADDON_Serialize;
1257 instance->game->toAddon->Deserialize = ADDON_Deserialize;
1258
1259 instance->game->toAddon->CheatReset = ADDON_CheatReset;
1260 instance->game->toAddon->GetMemory = ADDON_GetMemory;
1261 instance->game->toAddon->SetCheat = ADDON_SetCheat;
1262
1263 instance->game->toAddon->RCGenerateHashFromFile = ADDON_RCGenerateHashFromFile;
1264 instance->game->toAddon->RCGetGameIDUrl = ADDON_RCGetGameIDUrl;
1265 instance->game->toAddon->RCGetPatchFileUrl = ADDON_RCGetPatchFileUrl;
1266 instance->game->toAddon->SetRetroAchievementsCredentials =
1267 ADDON_SetRetroAchievementsCredentials;
1268 instance->game->toAddon->RCPostRichPresenceUrl = ADDON_RCPostRichPresenceUrl;
1269 instance->game->toAddon->RCEnableRichPresence = ADDON_RCEnableRichPresence;
1270 instance->game->toAddon->RCGetRichPresenceEvaluation = ADDON_RCGetRichPresenceEvaluation;
1271 instance->game->toAddon->ActivateAchievement = ADDON_ActivateAchievement;
1272 instance->game->toAddon->GetCheevoUrlId = ADDON_GetCheevoUrlId;
1273 instance->game->toAddon->RCResetRuntime = ADDON_RCResetRuntime;
1274
1275 instance->game->toAddon->GetEjectState = ADDON_GetEjectState;
1276 instance->game->toAddon->SetEjectState = ADDON_SetEjectState;
1277 instance->game->toAddon->GetImageIndex = ADDON_GetImageIndex;
1278 instance->game->toAddon->SetImageIndex = ADDON_SetImageIndex;
1279 instance->game->toAddon->GetImageCount = ADDON_GetImageCount;
1280 instance->game->toAddon->AddImageIndex = ADDON_AddImageIndex;
1281 instance->game->toAddon->ReplaceImageIndex = ADDON_ReplaceImageIndex;
1282 instance->game->toAddon->RemoveImageIndex = ADDON_RemoveImageIndex;
1283 instance->game->toAddon->SetInitialImage = ADDON_SetInitialImage;
1284 instance->game->toAddon->GetImagePath = ADDON_GetImagePath;
1285 instance->game->toAddon->GetImageLabel = ADDON_GetImageLabel;
1286
1287 instance->game->toAddon->FreeString = ADDON_FreeString;
1288
1289 m_instanceData = instance->game;
1290 m_instanceData->toAddon->addonInstance = this;
1291 }
1292
1293 // --- Game operations ---------------------------------------------------------
1294
1295 inline static GAME_ERROR ADDON_LoadGame(const AddonInstance_Game* instance, const char* url)
1296 {
1297 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadGame(url);
1298 }
1299
1300 inline static GAME_ERROR ADDON_LoadGameSpecial(const AddonInstance_Game* instance,
1301 SPECIAL_GAME_TYPE type,
1302 const char** urls,
1303 size_t urlCount)
1304 {
1305 std::vector<std::string> urlList;
1306 for (size_t i = 0; i < urlCount; ++i)
1307 {
1308 if (urls[i] != nullptr)
1309 urlList.emplace_back(urls[i]);
1310 }
1311
1312 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1313 ->LoadGameSpecial(type, urlList);
1314 }
1315
1316 inline static GAME_ERROR ADDON_LoadStandalone(const AddonInstance_Game* instance)
1317 {
1318 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->LoadStandalone();
1319 }
1320
1321 inline static GAME_ERROR ADDON_UnloadGame(const AddonInstance_Game* instance)
1322 {
1323 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->UnloadGame();
1324 }
1325
1326 inline static GAME_ERROR ADDON_GetGameTiming(const AddonInstance_Game* instance,
1327 game_system_timing* timing_info)
1328 {
1329 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1330 ->GetGameTiming(*timing_info);
1331 }
1332
1333 inline static GAME_REGION ADDON_GetRegion(const AddonInstance_Game* instance)
1334 {
1335 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetRegion();
1336 }
1337
1338 inline static bool ADDON_RequiresGameLoop(const AddonInstance_Game* instance)
1339 {
1340 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RequiresGameLoop();
1341 }
1342
1343 inline static GAME_ERROR ADDON_RunFrame(const AddonInstance_Game* instance)
1344 {
1345 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RunFrame();
1346 }
1347
1348 inline static GAME_ERROR ADDON_Reset(const AddonInstance_Game* instance)
1349 {
1350 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Reset();
1351 }
1352
1353 // --- Hardware rendering operations -------------------------------------------
1354
1355 inline static GAME_ERROR ADDON_HwContextReset(const AddonInstance_Game* instance)
1356 {
1357 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextReset();
1358 }
1359
1360 inline static GAME_ERROR ADDON_HwContextDestroy(const AddonInstance_Game* instance)
1361 {
1362 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->HwContextDestroy();
1363 }
1364
1365 // --- Input operations --------------------------------------------------------
1366
1367 inline static bool ADDON_HasFeature(const AddonInstance_Game* instance,
1368 const char* controller_id,
1369 const char* feature_name)
1370 {
1371 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1372 ->HasFeature(controller_id, feature_name);
1373 }
1374
1375 inline static game_input_topology* ADDON_GetTopology(const AddonInstance_Game* instance)
1376 {
1377 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetTopology();
1378 }
1379
1380 inline static void ADDON_FreeTopology(const AddonInstance_Game* instance,
1381 game_input_topology* topology)
1382 {
1383 static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->FreeTopology(topology);
1384 }
1385
1386 inline static void ADDON_SetControllerLayouts(const AddonInstance_Game* instance,
1387 const game_controller_layout* controllers,
1388 unsigned int controller_count)
1389 {
1390 if (controllers == nullptr)
1391 return;
1392
1393 std::vector<GameControllerLayout> controllerList;
1394 controllerList.reserve(controller_count);
1395 for (unsigned int i = 0; i < controller_count; ++i)
1396 controllerList.emplace_back(controllers[i]);
1397
1398 static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1399 ->SetControllerLayouts(controllerList);
1400 }
1401
1402 inline static bool ADDON_EnableKeyboard(const AddonInstance_Game* instance,
1403 bool enable,
1404 const char* controller_id)
1405 {
1406 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1407 ->EnableKeyboard(enable, controller_id);
1408 }
1409
1410 inline static bool ADDON_EnableMouse(const AddonInstance_Game* instance,
1411 bool enable,
1412 const char* controller_id)
1413 {
1414 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1415 ->EnableMouse(enable, controller_id);
1416 }
1417
1418 inline static bool ADDON_ConnectController(const AddonInstance_Game* instance,
1419 bool connect,
1420 const char* port_address,
1421 const char* controller_id)
1422 {
1423 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1424 ->ConnectController(connect, port_address, controller_id);
1425 }
1426
1427 inline static bool ADDON_InputEvent(const AddonInstance_Game* instance,
1428 const game_input_event* event)
1429 {
1430 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->InputEvent(*event);
1431 }
1432
1433 // --- Serialization operations ------------------------------------------------
1434
1435 inline static size_t ADDON_SerializeSize(const AddonInstance_Game* instance)
1436 {
1437 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->SerializeSize();
1438 }
1439
1440 inline static GAME_ERROR ADDON_Serialize(const AddonInstance_Game* instance,
1441 uint8_t* data,
1442 size_t size)
1443 {
1444 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Serialize(data, size);
1445 }
1446
1447 inline static GAME_ERROR ADDON_Deserialize(const AddonInstance_Game* instance,
1448 const uint8_t* data,
1449 size_t size)
1450 {
1451 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->Deserialize(data, size);
1452 }
1453
1454 // --- Cheat operations --------------------------------------------------------
1455
1456 inline static GAME_ERROR ADDON_CheatReset(const AddonInstance_Game* instance)
1457 {
1458 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->CheatReset();
1459 }
1460
1461 inline static GAME_ERROR ADDON_GetMemory(const AddonInstance_Game* instance,
1462 GAME_MEMORY type,
1463 uint8_t** data,
1464 size_t* size)
1465 {
1466 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1467 ->GetMemory(type, *data, *size);
1468 }
1469
1470 inline static GAME_ERROR ADDON_SetCheat(const AddonInstance_Game* instance,
1471 unsigned int index,
1472 bool enabled,
1473 const char* code)
1474 {
1475 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1476 ->SetCheat(index, enabled, code);
1477 }
1478
1479 inline static GAME_ERROR ADDON_RCGenerateHashFromFile(const AddonInstance_Game* instance,
1480 char** hash,
1481 unsigned int consoleID,
1482 const char* filePath)
1483 {
1484 if (hash == nullptr || filePath == nullptr)
1486
1487 *hash = nullptr;
1488
1489 std::string cppHash;
1490
1491 GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1492 ->RCGenerateHashFromFile(cppHash, consoleID, filePath);
1493
1494 if (ret == GAME_ERROR_NO_ERROR)
1495 {
1496 *hash = new char[cppHash.size() + 1];
1497 std::copy(cppHash.begin(), cppHash.end(), *hash);
1498 (*hash)[cppHash.size()] = '\0';
1499 }
1500
1501 return ret;
1502 }
1503
1504 inline static GAME_ERROR ADDON_RCGetGameIDUrl(const AddonInstance_Game* instance,
1505 char** url,
1506 const char* hash)
1507 {
1508 if (url == nullptr || hash == nullptr)
1510
1511 *url = nullptr;
1512
1513 std::string cppUrl;
1514 GAME_ERROR ret =
1515 static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCGetGameIDUrl(cppUrl, hash);
1516
1517 if (ret == GAME_ERROR_NO_ERROR)
1518 {
1519 *url = new char[cppUrl.size() + 1];
1520 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1521 (*url)[cppUrl.size()] = '\0';
1522 }
1523
1524 return ret;
1525 }
1526
1527 inline static GAME_ERROR ADDON_RCGetPatchFileUrl(const AddonInstance_Game* instance,
1528 char** url,
1529 const char* username,
1530 const char* token,
1531 unsigned int gameID)
1532 {
1533 if (url == nullptr || username == nullptr || token == nullptr)
1535
1536 *url = nullptr;
1537
1538 std::string cppUrl;
1539
1540 GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1541 ->RCGetPatchFileUrl(cppUrl, username, token, gameID);
1542
1543 if (ret == GAME_ERROR_NO_ERROR)
1544 {
1545 *url = new char[cppUrl.size() + 1];
1546 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1547 (*url)[cppUrl.size()] = '\0';
1548 }
1549
1550 return ret;
1551 }
1552
1553 inline static GAME_ERROR ADDON_SetRetroAchievementsCredentials(const AddonInstance_Game* instance,
1554 const char* username,
1555 const char* token)
1556 {
1557 if (username == nullptr || token == nullptr)
1559
1560 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1561 ->SetRetroAchievementsCredentials(username, token);
1562 }
1563
1564 inline static GAME_ERROR ADDON_RCPostRichPresenceUrl(const AddonInstance_Game* instance,
1565 char** url,
1566 char** postData,
1567 const char* username,
1568 const char* token,
1569 unsigned int gameID,
1570 const char* richPresence)
1571 {
1572 if (url == nullptr || postData == nullptr || username == nullptr || token == nullptr ||
1573 richPresence == nullptr)
1575
1576 *url = nullptr;
1577 *postData = nullptr;
1578
1579 std::string cppUrl;
1580 std::string cppPostData;
1581
1582 GAME_ERROR ret =
1583 static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1584 ->RCPostRichPresenceUrl(cppUrl, cppPostData, username, token, gameID, richPresence);
1585
1586 if (ret == GAME_ERROR_NO_ERROR)
1587 {
1588 *url = new char[cppUrl.size() + 1];
1589 std::copy(cppUrl.begin(), cppUrl.end(), *url);
1590 (*url)[cppUrl.size()] = '\0';
1591
1592 *postData = new char[cppPostData.size() + 1];
1593 std::copy(cppPostData.begin(), cppPostData.end(), *postData);
1594 (*postData)[cppPostData.size()] = '\0';
1595 }
1596
1597 return ret;
1598 }
1599
1600 inline static GAME_ERROR ADDON_RCEnableRichPresence(const AddonInstance_Game* instance,
1601 const char* script)
1602 {
1603 if (script == nullptr)
1605
1606 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1607 ->RCEnableRichPresence(script);
1608 }
1609
1610 inline static GAME_ERROR ADDON_RCGetRichPresenceEvaluation(const AddonInstance_Game* instance,
1611 char** evaluation,
1612 unsigned int consoleID)
1613 {
1614 if (evaluation == nullptr)
1616
1617 *evaluation = nullptr;
1618
1619 std::string cppEvaluation;
1620 GAME_ERROR ret = static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1621 ->RCGetRichPresenceEvaluation(cppEvaluation, consoleID);
1622
1623 if (ret == GAME_ERROR_NO_ERROR)
1624 {
1625 *evaluation = new char[cppEvaluation.size() + 1];
1626 std::copy(cppEvaluation.begin(), cppEvaluation.end(), *evaluation);
1627 (*evaluation)[cppEvaluation.size()] = '\0';
1628 }
1629
1630 return ret;
1631 }
1632
1633 inline static GAME_ERROR ADDON_ActivateAchievement(const AddonInstance_Game* instance,
1634 unsigned int cheevoId,
1635 const char* memAddrExpression)
1636 {
1637 if (memAddrExpression == nullptr)
1639
1640 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1641 ->ActivateAchievement(cheevoId, memAddrExpression);
1642 }
1643
1644 inline static GAME_ERROR ADDON_GetCheevoUrlId(const AddonInstance_Game* instance,
1645 void(__cdecl* callback)(const void* context,
1646 const char* achievementUrl,
1647 unsigned int cheevoId),
1648 const void* context)
1649 {
1650 if (callback == nullptr)
1652
1653 const auto cppCallback =
1654 [callback, context](const std::string& achievementUrl, unsigned int cheevoId)
1655 { callback(context, achievementUrl.c_str(), cheevoId); };
1656
1657 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1658 ->GetCheevoUrlId(cppCallback);
1659 }
1660
1661 inline static GAME_ERROR ADDON_RCResetRuntime(const AddonInstance_Game* instance)
1662 {
1663 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->RCResetRuntime();
1664 }
1665
1666 inline static bool ADDON_GetEjectState(const AddonInstance_Game* instance)
1667 {
1668 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetEjectState();
1669 }
1670
1671 inline static GAME_ERROR ADDON_SetEjectState(const AddonInstance_Game* instance, bool ejected)
1672 {
1673 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->SetEjectState(ejected);
1674 }
1675
1676 inline static unsigned int ADDON_GetImageIndex(const AddonInstance_Game* instance)
1677 {
1678 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetImageIndex();
1679 }
1680
1681 inline static GAME_ERROR ADDON_SetImageIndex(const AddonInstance_Game* instance,
1682 unsigned int imageIndex)
1683 {
1684 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->SetImageIndex(imageIndex);
1685 }
1686
1687 inline static unsigned int ADDON_GetImageCount(const AddonInstance_Game* instance)
1688 {
1689 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetImageCount();
1690 }
1691
1692 inline static GAME_ERROR ADDON_AddImageIndex(const AddonInstance_Game* instance)
1693 {
1694 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->AddImageIndex();
1695 }
1696
1697 inline static GAME_ERROR ADDON_ReplaceImageIndex(const AddonInstance_Game* instance,
1698 unsigned int imageIndex,
1699 const char* filePath)
1700 {
1701 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1702 ->ReplaceImageIndex(imageIndex, filePath ? filePath : "");
1703 }
1704
1705 inline static GAME_ERROR ADDON_RemoveImageIndex(const AddonInstance_Game* instance,
1706 unsigned int imageIndex)
1707 {
1708 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1709 ->RemoveImageIndex(imageIndex);
1710 }
1711
1712 inline static GAME_ERROR ADDON_SetInitialImage(const AddonInstance_Game* instance,
1713 unsigned int imageIndex,
1714 const char* filePath)
1715 {
1716 return static_cast<CInstanceGame*>(instance->toAddon->addonInstance)
1717 ->SetInitialImage(imageIndex, filePath ? filePath : "");
1718 }
1719
1720 inline static char* ADDON_GetImagePath(const AddonInstance_Game* instance,
1721 unsigned int imageIndex)
1722 {
1723 std::string cppPath =
1724 static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetImagePath(imageIndex);
1725 if (cppPath.empty())
1726 return nullptr;
1727
1728 char* path = new char[cppPath.size() + 1];
1729 std::copy(cppPath.begin(), cppPath.end(), path);
1730 path[cppPath.size()] = '\0';
1731 return path;
1732 }
1733
1734 inline static char* ADDON_GetImageLabel(const AddonInstance_Game* instance,
1735 unsigned int imageIndex)
1736 {
1737 std::string cppLabel =
1738 static_cast<CInstanceGame*>(instance->toAddon->addonInstance)->GetImageLabel(imageIndex);
1739 if (cppLabel.empty())
1740 return nullptr;
1741
1742 char* label = new char[cppLabel.size() + 1];
1743 std::copy(cppLabel.begin(), cppLabel.end(), label);
1744 label[cppLabel.size()] = '\0';
1745 return label;
1746 }
1747
1748 inline static void ADDON_FreeString(const AddonInstance_Game* instance, char* str)
1749 {
1750 delete[] str;
1751 }
1752
1753 AddonInstance_Game* m_instanceData;
1754};
1755
1756} /* namespace addon */
1757} /* namespace kodi */
1758
1759#endif /* __cplusplus */
Definition Game.h:119
Definition AddonBase.h:566
Definition AddonBase.h:502
@ ADDON_LOG_INFO
1 : To include information messages in the log file.
Definition addon_base.h:188
CInstanceGame()
Game class constructor.
Definition Game.h:161
std::string GameClientDllPath() const
Callback to Kodi Function The path of the game client being loaded.
Definition Game.h:187
bool ProxyDllPaths(std::vector< std::string > &paths)
Callback to Kodi Function Paths to proxy DLLs used to load the game client.
Definition Game.h:200
bool ResourceDirectories(std::vector< std::string > &dirs)
Callback to Kodi Function The "system" directories of the frontend.
Definition Game.h:224
std::string ProfileDirectory() const
Callback to Kodi Function The writable directory of the frontend.
Definition Game.h:247
bool SupportsVFS() const
Callback to Kodi Function The value of the <supports_vfs> property from addon.xml.
Definition Game.h:258
~CInstanceGame() override=default
Destructor.
bool Extensions(std::vector< std::string > &extensions)
Callback to Kodi Function The extensions in the <extensions> property from addon.xml.
Definition Game.h:271
virtual GAME_ERROR RCGetRichPresenceEvaluation(std::string &evaluation, unsigned int consoleID)
Gets the rich presence evaluation for the current frame. Rich presence must be enabled first or this ...
Definition Game.h:1029
virtual GAME_ERROR RCGetPatchFileUrl(std::string &url, const std::string &username, const std::string &token, unsigned int gameID)
Gets a URL to the endpoint that returns the patch file.
Definition Game.h:959
virtual GAME_ERROR RCGenerateHashFromFile(std::string &hash, unsigned int consoleID, const std::string &filePath)
Generates a RetroAchievements hash for a given game that can be used to identify the game by RetroAch...
Definition Game.h:929
virtual GAME_ERROR ActivateAchievement(unsigned int cheevoId, const std::string &memAddrExpression)
Activate an achievement.
Definition Game.h:1043
virtual GAME_ERROR RCPostRichPresenceUrl(std::string &url, std::string &postData, const std::string &username, const std::string &token, unsigned int gameID, const std::string &richPresence)
Gets a URL to the endpoint that updates the rich presence in the user's RetroAchievements profile.
Definition Game.h:995
virtual GAME_ERROR RCGetGameIDUrl(std::string &url, const std::string &hash)
Gets a URL to the endpoint that returns the game ID.
Definition Game.h:944
virtual GAME_ERROR RCEnableRichPresence(const std::string &script)
Enables rich presence.
Definition Game.h:1012
virtual GAME_ERROR RCResetRuntime()
Resets the runtime. Must be called each time a new rom is starting and when the savestate is changed.
Definition Game.h:1074
virtual GAME_ERROR SetRetroAchievementsCredentials(const std::string &username, const std::string &token)
Set the credentials of the RetroAchievements user.
Definition Game.h:975
virtual GAME_ERROR GetCheevoUrlId(const std::function< void(const std::string &achievementUrl, unsigned int cheevoId)> &callback)
Get triggered achievement URL and ID pairs.
Definition Game.h:1061
virtual GAME_ERROR CheatReset()
Reset the cheat system.
Definition Game.h:885
virtual GAME_ERROR GetMemory(GAME_MEMORY type, uint8_t *&data, size_t &size)
Get a region of memory.
Definition Game.h:897
virtual GAME_ERROR SetCheat(unsigned int index, bool enabled, const std::string &code)
Set a cheat code.
Definition Game.h:912
Game system timing.
Definition game.h:1140
GAME_REGION
Game region definition
Definition game.h:585
SPECIAL_GAME_TYPE
Special game types passed into game_load_game_special().
Definition game.h:603
GAME_MEMORY
Game Memory
Definition game.h:622
@ GAME_REGION_UNKNOWN
Game region unknown.
Definition game.h:587
void(* game_proc_address_t)(void)
Hardware framebuffer process function address
Definition game.h:425
Hardware rendering properties
Definition game.h:337
std::vector< std::string > analog_buttons
Analog buttons.
Definition Game.h:86
std::vector< std::string > accelerometers
Accelerometers.
Definition Game.h:92
bool provides_input
Provides input.
Definition Game.h:80
std::vector< std::string > digital_buttons
Digital buttons.
Definition Game.h:83
std::vector< std::string > abs_pointers
Absolute pointers.
Definition Game.h:101
std::vector< std::string > motors
Motors.
Definition Game.h:104
std::string controller_id
Controller identifier.
Definition Game.h:75
std::vector< std::string > rel_pointers
Relative pointers.
Definition Game.h:98
std::vector< std::string > keys
Keys.
Definition Game.h:95
std::vector< std::string > analog_sticks
Analog sticks.
Definition Game.h:89
"C" Game add-on controller layout.
Definition game.h:870
An input event.
Definition game.h:1079
The input topology is the possible ways to connect input devices.
Definition game.h:951
Stream buffers for hardware rendering and zero-copy support
Definition game.h:527
Stream packet and ephemeral metadata
Definition game.h:550
Immutable stream metadata
Definition game.h:502
GAME_ERROR
Game add-on error codes
Definition game.h:28
@ GAME_ERROR_INVALID_PARAMETERS
The parameters of the called method are invalid for this operation.
Definition game.h:42
@ GAME_ERROR_NO_ERROR
No error occurred.
Definition game.h:30
@ GAME_ERROR_NOT_IMPLEMENTED
The method called by the frontend is not implemented.
Definition game.h:36
virtual GAME_ERROR SetImageIndex(unsigned int imageIndex)
Inserts the disk image at the given index.
Definition Game.h:1140
virtual unsigned int GetImageCount()
Gets the number of available disk images.
Definition Game.h:1148
virtual std::string GetImageLabel(unsigned int imageIndex)
Gets a user-friendly label for a disk image.
Definition Game.h:1223
virtual GAME_ERROR ReplaceImageIndex(unsigned int imageIndex, const std::string &filePath)
Replaces the disk image at the given index.
Definition Game.h:1170
virtual GAME_ERROR RemoveImageIndex(unsigned int imageIndex)
Removes the disk image at the given index.
Definition Game.h:1185
virtual std::string GetImagePath(unsigned int imageIndex)
Gets the full path of a disk image.
Definition Game.h:1213
virtual unsigned int GetImageIndex()
Gets the index of the currently inserted disk image.
Definition Game.h:1128
virtual GAME_ERROR SetInitialImage(unsigned int imageIndex, const std::string &filePath)
Sets which image should be initially inserted on load.
Definition Game.h:1200
virtual GAME_ERROR SetEjectState(bool ejected)
Opens or closes the virtual disk tray.
Definition Game.h:1119
virtual GAME_ERROR AddImageIndex()
Adds a new disk image slot.
Definition Game.h:1157
virtual bool GetEjectState()
Returns whether the virtual disk tray is currently ejected.
Definition Game.h:1106
virtual GAME_ERROR HwContextDestroy()
Called before the context is destroyed.
Definition Game.h:613
virtual GAME_ERROR HwContextReset()
Invalidates the current HW context and reinitializes GPU resources.
Definition Game.h:603
bool EnableHardwareRendering(const game_hw_rendering_properties &properties)
Callback to Kodi Function Enable hardware rendering functionality
Definition Game.h:589
game_proc_address_t HwGetProcAddress(const char *sym)
Callback to Kodi Function Get a symbol from the hardware context
Definition Game.h:624
virtual bool HasFeature(const std::string &controller_id, const std::string &feature_name)
Check if input is accepted for a feature on the controller.
Definition Game.h:662
virtual bool InputEvent(const game_input_event &event)
Notify the add-on of an input event.
Definition Game.h:785
virtual void FreeTopology(game_input_topology *topology)
Free the topology's resources.
Definition Game.h:687
virtual bool ConnectController(bool connect, const std::string &port_address, const std::string &controller_id)
Connect/disconnect a controller to a port on the virtual game console.
Definition Game.h:770
virtual void SetControllerLayouts(const std::vector< kodi::addon::GameControllerLayout > &controllers)
Set the layouts for known controllers.
Definition Game.h:698
virtual bool EnableMouse(bool enable, const std::string &controller_id)
Enable/disable mouse input using the specified controller.
Definition Game.h:723
virtual bool EnableKeyboard(bool enable, const std::string &controller_id)
Enable/disable keyboard input using the specified controller.
Definition Game.h:712
bool KodiInputEvent(const game_input_event &event)
Callback to Kodi Function Notify the port of an input event
Definition Game.h:800
virtual game_input_topology * GetTopology()
Get the input topology that specifies which controllers can be connected.
Definition Game.h:679
bool IsOpen() const
Check if the stream opened correctly, e.g. after calling the constructor.
Definition Game.h:552
void ReleaseBuffer(game_stream_buffer &buffer)
Free an allocated buffer.
Definition Game.h:532
void Close()
Free the specified stream.
Definition Game.h:465
bool GetBuffer(unsigned int width, unsigned int height, game_stream_buffer &buffer)
Get a buffer for zero-copy stream data.
Definition Game.h:492
void AddData(const game_stream_packet &packet)
Add a data packet to a stream.
Definition Game.h:512
bool Open(const game_stream_properties &properties)
Create a stream for gameplay data.
Definition Game.h:440
virtual GAME_ERROR LoadGameSpecial(SPECIAL_GAME_TYPE type, const std::vector< std::string > &urls)
Load a game that requires multiple files.
Definition Game.h:324
virtual GAME_ERROR UnloadGame()
Unload the current game.
Definition Game.h:350
virtual GAME_ERROR GetGameTiming(game_system_timing &timing_info)
Get timing information about the loaded game.
Definition Game.h:360
virtual GAME_ERROR RunFrame()
Run a single frame for add-ons that use a game loop.
Definition Game.h:390
virtual bool RequiresGameLoop()
Return true if the client requires the frontend to provide a game loop.
Definition Game.h:382
virtual GAME_ERROR Reset()
Reset the current game.
Definition Game.h:398
virtual GAME_ERROR LoadStandalone()
Begin playing without a game file.
Definition Game.h:340
void CloseGame(void)
Callback to Kodi Function Requests the frontend to stop the current game
Definition Game.h:407
virtual GAME_ERROR LoadGame(const std::string &url)
Load a game.
Definition Game.h:313
virtual GAME_REGION GetRegion()
Get region of the loaded game.
Definition Game.h:371
virtual GAME_ERROR Deserialize(const uint8_t *data, size_t size)
Deserialize the game from the given state.
Definition Game.h:853
virtual GAME_ERROR Serialize(uint8_t *data, size_t size)
Serialize the state of the game.
Definition Game.h:842
virtual size_t SerializeSize()
Get the number of bytes required to serialize the game.
Definition Game.h:831
void ATTR_DLL_LOCAL Log(const ADDON_LOG loglevel, const char *format,...)
Add a message to Kodi's log.
Definition AddonBase.h:1939
std::string ATTR_DLL_LOCAL GetRegion(const std::string &id)
Returns your regions setting as a string for the specified id.
Definition General.h:331
Game instance.
Definition game.h:1330
Game callbacks.
Definition game.h:1225
Definition addon_base.h:269
Internal used structure to have stored C API data above and available for everything below.
Definition AddonBase.h:73