Nick Siakas

Save state manager for RetroPlayer -
GSoC 2020

20/8/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


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:

RetroPlayer Save state manager

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.

RetroPlayer in-game save state manager

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:

typedef unsigned (*rc_peek_t)(unsigned address, unsigned num_bytes, void* ud);
which is used to read from the emulated system's memory. At first I was implementing this (and the whole code that dealt with rcheevos) in Kodi's codebase, but it was reading invalid memory. After a lot of debugging on Kodi and RetroArch I figured out that this code should go in game.libretro codebase.

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.

Kodi settings login to RetroAchievements
Finally I had to display the caption to the user. For now I just used the save state manager's label field. New UI!
RetroPlayer Save state manager
RetroPlayer Save state manager
The rich presence caption is also displayed to RetroAchievements.
Kodi settings login to RetroAchievements


Bugs


Future Work

Important

Nice-to-have


Acknowledgements

I'd like to thank:


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.