New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[games] Implement in-game saves #11380
Conversation
@@ -161,6 +162,9 @@ class CGameClient : public ADDON::CAddonDll | |||
std::unique_ptr<IGameClientPlayback> m_playback; // Interface to control playback | |||
GAME_REGION m_region; // Region of the loaded game | |||
|
|||
// In-game saves | |||
std::unique_ptr<CGameClientInGameSaves> m_inGameSaves; |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
void CGameClientInGameSaves::Load() | ||
{ | ||
Load(GAME_MEMORY_SAVE_RAM); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
void CGameClientInGameSaves::Save() | ||
{ | ||
Save(GAME_MEMORY_SAVE_RAM); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
if (size > 0) | ||
{ | ||
const std::string path = GetPath(memoryType); | ||
|
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
/*! | ||
* \brief This class implements in-game saves. | ||
* | ||
* Some games do not implement state persistence on their own, but rely on the frontend for saving their current |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
(and it looks all good to me now). |
Change GetMemory to use a non-const pointer. This is necessary for in-game (SRAM) saves that need to write into the memory.
Thanks! Does it make sense to save periodically (maybe every minute)? We don't control cores and they might crash before we're able to stop a game. Guess that could easily be implemented with a CTimer in CGameClient and could even be reused later for savestates. If it makes sense this can however come in a separate PR. |
maybe, but then we'd definitely need to ping-pong on the sram file, or you may end up dumping corrupted data (either because the core has stomped ram, or because of timing, core may be busy updating sram). |
I would like to abstract the various software and hardware details of managing one's saved data. I think the best interface would be a "Saved game" concept associated with a single game/file. The saved game would include the player's current progress, including awards/achievements (scraped from a ROM achievements service) and a history of saved data. The saved data would include all forms of the game's storage at a point in time, and we could eventually allow more fine-grained memory management like loading/saving/importing/exporting SRAM saves (per-file) or savestates (per-emulator). |
|
||
#define INGAME_SAVES_DIRECTORY "InGameSaves" | ||
#define INGAME_SAVES_EXTENSION_SAVE_RAM ".sav" | ||
#define INGAME_SAVES_EXTENSION_RTC ".rtc" |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
@fetzerch is this ready to go in? |
@@ -276,6 +277,9 @@ bool CGameClient::OpenFile(const CFileItem& file, IGameAudioCallback* audio, IGa | |||
if (!InitializeGameplay(file.GetPath(), audio, video)) | |||
return false; | |||
|
|||
m_inGameSaves.reset(new CGameClientInGameSaves(this, &m_struct)); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
From my side it's ready - but I thought you don't want it in its current from (without the abstraction). Therefore: Your button, (needs a merge of kodi-game/game.libretro#10 as well). |
jenkins build this please |
Implement in-game (save ram) saves.
Description
This implements in-game saves where the frontend accesses the game's memory and saves/loads it to/from disk. This is mostly used in emulators for SRAM (battery backed up ram on cartridges) or memory cards.
For reference, these are the other ways how saving is implemented in the Game API:
Differences to save states:
Previously PRed to the retroplayer banch in garbear#73
API-Change: Merging has to be synced with kodi-game/game.libretro#10.
Motivation and Context
Save games.
How Has This Been Tested?
Best tested with 2048 or SNES/GBA emulators.
Types of change
Checklist: