summaryrefslogtreecommitdiffstats
path: root/xbmc/games/addons/GameClientInGameSaves.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/games/addons/GameClientInGameSaves.cpp')
-rw-r--r--xbmc/games/addons/GameClientInGameSaves.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/xbmc/games/addons/GameClientInGameSaves.cpp b/xbmc/games/addons/GameClientInGameSaves.cpp
new file mode 100644
index 0000000..802ebb7
--- /dev/null
+++ b/xbmc/games/addons/GameClientInGameSaves.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "GameClientInGameSaves.h"
+
+#include "GameClient.h"
+#include "GameClientTranslator.h"
+#include "ServiceBroker.h"
+#include "filesystem/Directory.h"
+#include "filesystem/File.h"
+#include "games/GameServices.h"
+#include "utils/URIUtils.h"
+#include "utils/log.h"
+
+#include <assert.h>
+
+using namespace KODI;
+using namespace GAME;
+
+#define INGAME_SAVES_DIRECTORY "InGameSaves"
+#define INGAME_SAVES_EXTENSION_SAVE_RAM ".sav"
+#define INGAME_SAVES_EXTENSION_RTC ".rtc"
+
+CGameClientInGameSaves::CGameClientInGameSaves(CGameClient* addon,
+ const AddonInstance_Game* dllStruct)
+ : m_gameClient(addon), m_dllStruct(dllStruct)
+{
+ assert(m_gameClient != nullptr);
+ assert(m_dllStruct != nullptr);
+}
+
+void CGameClientInGameSaves::Load()
+{
+ Load(GAME_MEMORY_SAVE_RAM);
+ Load(GAME_MEMORY_RTC);
+}
+
+void CGameClientInGameSaves::Save()
+{
+ Save(GAME_MEMORY_SAVE_RAM);
+ Save(GAME_MEMORY_RTC);
+}
+
+std::string CGameClientInGameSaves::GetPath(GAME_MEMORY memoryType)
+{
+ const CGameServices& gameServices = CServiceBroker::GetGameServices();
+ std::string path =
+ URIUtils::AddFileToFolder(gameServices.GetSavestatesFolder(), INGAME_SAVES_DIRECTORY);
+ if (!XFILE::CDirectory::Exists(path))
+ XFILE::CDirectory::Create(path);
+
+ // Append save game filename
+ std::string gamePath = URIUtils::GetFileName(m_gameClient->GetGamePath());
+ path = URIUtils::AddFileToFolder(path, gamePath.empty() ? m_gameClient->ID() : gamePath);
+
+ // Append file extension
+ switch (memoryType)
+ {
+ case GAME_MEMORY_SAVE_RAM:
+ return path + INGAME_SAVES_EXTENSION_SAVE_RAM;
+ case GAME_MEMORY_RTC:
+ return path + INGAME_SAVES_EXTENSION_RTC;
+ default:
+ break;
+ }
+ return std::string();
+}
+
+void CGameClientInGameSaves::Load(GAME_MEMORY memoryType)
+{
+ uint8_t* gameMemory = nullptr;
+ size_t size = 0;
+
+ try
+ {
+ m_dllStruct->toAddon->GetMemory(m_dllStruct, memoryType, &gameMemory, &size);
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "GAME: {}: Exception caught in GetMemory()", m_gameClient->ID());
+ }
+
+ const std::string path = GetPath(memoryType);
+ if (size > 0 && XFILE::CFile::Exists(path))
+ {
+ XFILE::CFile file;
+ if (file.Open(path))
+ {
+ ssize_t read = file.Read(gameMemory, size);
+ if (read == static_cast<ssize_t>(size))
+ {
+ CLog::Log(LOGINFO, "GAME: In-game saves ({}) loaded from {}",
+ CGameClientTranslator::ToString(memoryType), path);
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "GAME: Failed to read in-game saves ({}): {}/{} bytes read",
+ CGameClientTranslator::ToString(memoryType), read, size);
+ }
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "GAME: Unable to open in-game saves ({}) from file {}",
+ CGameClientTranslator::ToString(memoryType), path);
+ }
+ }
+ else
+ {
+ CLog::Log(LOGDEBUG, "GAME: No in-game saves ({}) to load",
+ CGameClientTranslator::ToString(memoryType));
+ }
+}
+
+void CGameClientInGameSaves::Save(GAME_MEMORY memoryType)
+{
+ uint8_t* gameMemory = nullptr;
+ size_t size = 0;
+
+ try
+ {
+ m_dllStruct->toAddon->GetMemory(m_dllStruct, memoryType, &gameMemory, &size);
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "GAME: {}: Exception caught in GetMemory()", m_gameClient->ID());
+ }
+
+ if (size > 0)
+ {
+ const std::string path = GetPath(memoryType);
+ XFILE::CFile file;
+ if (file.OpenForWrite(path, true))
+ {
+ ssize_t written = 0;
+ written = file.Write(gameMemory, size);
+ file.Close();
+ if (written == static_cast<ssize_t>(size))
+ {
+ CLog::Log(LOGINFO, "GAME: In-game saves ({}) written to {}",
+ CGameClientTranslator::ToString(memoryType), path);
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "GAME: Failed to write in-game saves ({}): {}/{} bytes written",
+ CGameClientTranslator::ToString(memoryType), written, size);
+ }
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "GAME: Unable to open in-game saves ({}) from file {}",
+ CGameClientTranslator::ToString(memoryType), path);
+ }
+ }
+ else
+ {
+ CLog::Log(LOGDEBUG, "GAME: No in-game saves ({}) to save",
+ CGameClientTranslator::ToString(memoryType));
+ }
+}