libretro / RetroArch

Cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.
http://www.libretro.com
GNU General Public License v3.0
10.27k stars 1.83k forks source link

[Feature Request] tvOS auto copy ROMs & BIOS files when tvOS decides to clean caches #15885

Open fellowgeek opened 11 months ago

fellowgeek commented 11 months ago

Warning: The tvOS port of RetroArch comes with the following important notice:

tvOS does not provide apps with a persistent storage area; instead, it allows for up to 500kb meant for configuration data. The disk space shown through the web UI is a cache space. If the OS needs to reclaim disk space, it will delete files from that cache space without warning. This includes state and saves! When this happens, you will immediately see that the appearance of RetroArch is wrong, as the assets will need to be re-downloaded.

I came up with an idea to streamline the process by embedding ROMs into the build itself and implementing a small hack to copy the files from the App Bundle to the cache folder if they are not already there. You can find the code in the following gist. This solution works as expected and saves time from having to upload ROMs every time you reboot the Apple TV.

I'm interested in getting feedback from more experienced developers who can potentially turn this into a built-in feature for the tvOS build. I've attached my hack to the WebServer initialization code.

https://gist.github.com/fellowgeek/65c536d2aebc5531649ac32a62ebd632

warmenhoven commented 11 months ago

I'm very glad someone else is thinking about this as well. Thanks for the suggestion. I need to think about it more, it's something I hadn't considered.

It doesn't suit my personal use case at all. For comparison, the current RetroArch tvOS IPA is about 310MB (when all the cores are building correctly). That's compressed, and includes all of the cores. My compressed system directory for the cores I use most often is 612MB. So now you're asking me to triple the size of my IPA, and force me to re-upload all the BIOSes every time the binary changes. And that's just the system folder; my roms folder for the cores that work on tvOS is 16GB (most of that comes from flycast and ppsspp). And then you're talking about making a second copy of them on a disk that is probably only 64GB or might even be only 32GB.

The way I've worked around the disappearing cache problem for myself so far is to put all of my BIOSes and ROMs on S3 in a way that mimics the libretro buildbot file heirarchy, and then override core_updater_buildbot_assets_url to point to that store. Then when the files inevitably get deleted from cache, I can download just the ones I want in that moment, direct from the RetroArch UI without needing to go through the WebServer. Definitely not something I'd recommend to the general population but I find it's highly effective.

The other thing that's not sitting right with me about this approach is that it is not approachable. In order for it to work you have to put the BIOS and ROM files into the IPA, and most people aren't really going to want to have to learn how to modify an IPA file or where to put the files in the IPA file (yes I know this part is easy, people still won't do it). That or they're going to have to build it for themselves, which is asking way more of them. So I'm concerned it doesn't work for heavy users like myself, nor more casual users who are used to things on Apple products being easier.

Now, all that said, I do think there's likely a set of goldilocks users where this approach would work well for them. And for everyone else, the code doesn't hurt. So it's maybe worth including?

Or, maybe there's an even better solution that's more broadly applicable, and we just need to think about this some more.

fellowgeek commented 11 months ago

Thank you for the insightful points. I've observed that installing a 3.5 GB app on my Apple TV via Xcode was quite time-consuming. While this might address my immediate retro gaming and emulation requirements, I'm more inclined towards the concept of utilizing an S3 Bucket or a remote server that can be easily configured with ROMs and BIOS files. If I find the opportunity, I'm considering creating a solution for this, albeit with the possibility of seeking assistance from the community to ensure a proper implementation via a pull request. I'll keep you updated on my progress should I decide to pursue this path.

fellowgeek commented 11 months ago

@warmenhoven, appreciate your input! I've incorporated the feature to synchronize game libraries and BIOS files from an external server. You can check out the implementation details at (https://github.com/fellowgeek/RetroArch/commit/ff1057358dc00799453eeb972de2688ef55f6ee5) if you're curious.

The server functionality is implemented through a straightforward PHP file available here: https://gist.github.com/fellowgeek/3628f2b3a74dce8d0ea265e8ed492bfb. While the code might benefit from some refinement, I've managed to address occasional upload failures by introducing a 100ms delay between uploads.

On a personal note, everything runs smoothly on my AppleTV. While I'm considering creating a pull request in the future, I'm also open to the possibility that a more adept contributor might step in. Cheers!

Sample JSON:

{
    "files": [
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/amiga500\/Prince of Persia.adf",
            "remote_path": "\/ROMs\/amiga500"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/amiga500\/Turrican (USA).ipf",
            "remote_path": "\/ROMs\/amiga500"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/amiga500\/Workbench v1.3 (Extras).adf",
            "remote_path": "\/ROMs\/amiga500"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/amiga500\/Workbench v1.3.adf",
            "remote_path": "\/ROMs\/amiga500"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/atari2600\/2Pak Black - Challenge - Surfing.bin",
            "remote_path": "\/ROMs\/atari2600"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/atari2600\/2Pak Green - Hoppy - Alien Force.bin",
            "remote_path": "\/ROMs\/atari2600"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/atari2600\/2Pak Yellow - Star Warrior - Frogger.bin",
            "remote_path": "\/ROMs\/atari2600"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/atari2600\/32-in-1 (PAL).bin",
            "remote_path": "\/ROMs\/atari2600"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/atari2600\/3D Tic-Tac-Toe (1).bin",
            "remote_path": "\/ROMs\/atari2600"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/ROMs\/atari2600\/3D Tic-Tac-Toe (2).bin",
            "remote_path": "\/ROMs\/atari2600"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/BIOS\/capsimg.so",
            "remote_path": "\/RetroArch\/system\/"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/BIOS\/kick34005.A500",
            "remote_path": "\/RetroArch\/system\/"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/BIOS\/kick40063.A600",
            "remote_path": "\/RetroArch\/system\/"
        },
        {
            "download_url": "http:\/\/192.168.0.100\/retroarch\/BIOS\/kick40068.A1200",
            "remote_path": "\/RetroArch\/system\/"
        }
    ]
}