Save state manager for RetroPlayer -
GSoC 2020
Introduction
RetroPlayer is a new player core for Kodi Entertainment Center. It is similar to the video and audio players, but it plays games instead of movies and music.
Kodi excels at managing large movie, music, and (with add-ons) game libraries. However, save states are simply stored next to the ROM or in a hard-coded folder. My project for the summer of 2020 was to create a save state manager for RetroPlayer. As a stretch goal, I had to implement automatic saved game captioning that gives saves a description of what the player is currently doing in their game.
You can find my work in the following links:
Challenges
- The biggest challenge I faced was building Kodi addons because I didn't know how to use cmake.
- The save state's thumbnail also got me stuck for a few days, more on this later.
- Another big challenge was that I had to modify existing code that I had never seen before.
Work
Save state Manager
I started by replacing the current dialog that was displaying when the user selected a rom, that was asking to select the game client that you want to use and deleted your save when you selected a different game client than the one which created the save state, with a dialog that displays all the saves from the selected game and extracted the game client's id from the selected save.
Next I had to change how save states were saved, because the current way saved them next to the rom with the same name. In a conversation I had with Nick Renieris (velocity), my mentor, we decided not to use a database for the save states but use the filesystem to organize them. Now when the user launches a new game (rom) a subfolder with the rom's name will be created in a subfolder for saves in Kodi's home folder.
At this point I had a working demo next step was to save the games current frame to use it as a thumbnail in the manager. This was the first challenge I faced, my first implementation took me about a week and it seemed to be working but then I found out it was working only with specific game clients, those that are using AV_PIX_FMT_BGR0 pixel format. Thankfully velocity came in with a solution to change the output pixel format in the ffmpeg SwsContext when we scale the image.
The last week of June the manager looked like this (I was using the dialog for the game clients):
The next step was to change the UI. Here is how the dialog looks now:
In-game save state manager
While I was working on the save state manager I had a talk with Garrett Brown (garbear) about creating an in-game manager that looks like the video filter dialog. When I woke up the next day I found a branch whith the UI for the in-game manager ready from Garrett. Now I had to populate the item list with the save states for the game and load a save state when you click on it.
Save state auto-captioning
To generate captions for save states I used the RetroAchievements API, which besides achievements also returns a rich presence script. To generate the caption from the script I used RetroAchievements rcheevos library. Here is where I faced my biggest challenge of the summer, building game.libretro
I started by adding rcheevos as a dependency to game.libretro, then I had to implement the environment callback RETRO_ENVIRONMENT_SET_MEMORY_MAPS, which is called from the game client code but wasn't doing anything until now, this was needed to calculate the real address from the offsets that RetroAchievements returns.
To evaluate the rich presence string you have to implement a callback function with the signature:
Next I had to add a way for the user to login to their RetroAchievements account, because that is needed in order to get the game data from the API.
Bugs
- The save state manager sometimes caches the save's thumbnail despite the fact that the thumbnail has been overwritten and displays the previous one.
Because the save states are saved using flatbuffers and they are read-only, so to rename a save state I had to copy the whole file and overwrite the old one, this means that when the manager sorts the saves it will place this save first.
Future Work
Important
- Garrett released my save state manager for testers so I will be fixing any bugs they find for the next months.
-
A new way to display the rich presence evaluation is needed.Done!
Nice-to-have
- Since we have the rich presence data a nice feature that I want to implement is to display that text to discord.
Acknowledgements
I'd like to thank:
- My mentors, Nick Renieris (velocity) and Kostas Andrianos (gusandrianos), for not only giving me the opportunity to work with them on Kodi but also for answering me every question I had.
- Garrett Brown (garbear) for helping me when I was stuck with the auto-captioning feature even thought he had his own students to mentor.
Closing thoughts
This was the first time that I contribute to an open-source software. I can say that this experience was awesome, I've learned a ton in just 3 months. I really liked the project and it's safe to say I will continue to contribute to Kodi.