libretro / hatari

New rebasing of Hatari based on Mercurial upstream. Tries to be a shallow fork for easy upstreaming later on.
25 stars 41 forks source link

[Feature Request] Implement Netplay Support on Hatari Libretro core #54

Open salem-ok opened 4 years ago

salem-ok commented 4 years ago

Today the Doc (https://docs.libretro.com/library/hatari/) clearly states that Netplay is not supported. Some test using RetroArch 1.8.5 showed it was possible to start a Netplay server, and connect to it, even though the games were not playable due to lag. With further versions (1.8.9 was tested), it is not possible to start a Netplay server at all.

Thsi would be an amazing addition to the core to enable multiplayer over Netplay.

bbbradsmith commented 3 years ago

So, as far as I know Netplay isn't something that is directly "supported" by any core. It requires a number of things to work in the emulation, and with those things netplay should presumably "just work"? (See: https://docs.libretro.com/development/retroarch/netplay/ )

  1. Savestates. These have been in for a while, but with #66 they now happen in memory rather than going do disk and back, which might be necessary for effective netplay.

  2. Fast forwarding. The core was timing its own frames and sleeping rather than letting libretro request as many frames as it wants at its own pace. I got rid of that sleeping behaviour so with #65 this now works.

  3. Responds to controllers on more than one port. With #63 there is now actual 2 player support, which we couldn't do netplay without.

So... with these things in place, netplay is supposed to use savestates to rewind and fastforward as necessary to synchronize, and map the two connected players to different controller ports, and between those features, netplay should function.

I think most of the pieces are there, but it gets mysterious to me why it won't start. When I begin a netplay host, I think it's getting stuck with netplay_driver_ctl always indicating it's in "preframe" in retroarch.c::core_run? I don't know why this is happening, and I haven't been able to use a debugger to get much information about this yet. If we could solve that, it might start working?

A current issue with savestates... I'm not sure how the GUI will interact with the savestate rewinding. Currently savestates don't have a way to leave the GUI due to the way the hatari GUI is implemented to run in a co-thread, so there would probably be some janky behaviour if trying to use that during netplay until that's solved (other player might have to manually exit GUI?). I think one way to approach this would be to put up a "quit GUI" flag in hatari-mapper.c::gui_poll_events after co_switch that sends some event to the GUI that automatically closes it, but I haven't figured out a way to do this yet. (Edit: put in a way to exit GUI via savestate in #68 so this is maybe partly resolved... but I think there are subsequent issues like it taking an extra frame to exit the GUI.)

The other thing I'd be worried about is whether the savestates are really going back a single frame, or if there's a frame of "warm up" after a reload... if they don't just cleanly go back to a previous frame instantly, there might be more issues to resolve.

.

Anyway, that's as far as I got while trying to look into it, and my assessment of what still needs to be done to get it working. Not sure if I will be able to get to it myself, but if I don't maybe this explanation will be helpful to someone else that wants to try.

bbbradsmith commented 3 years ago

Realized I could test how smooth savestates are with the "run ahead to reduce latency" feature, which constantly uses savestates and fast-forward in the same way that netplay has to.

Verdict: this core cannot do netplay. (At least not currently.)

Unfortunately there is a huge hitch and gap every time a savestate is loaded. There is no way to do sensible netplay under this condition. It's possible this is a problem with our implementation, but it seems more likely to me that the problem is deeper than that, and Hatari just can't do clean frame-precise instant savestate loads.

Hatari's stand-alone version doesn't need to be able to do clean reloads like that, because it does not provide any features that depend on it (e.g. run-ahead, netplay, TAS). Considering its savestate implementation writes to disk only, I'd say it's just not built with this in mind at all.

Darknior commented 3 years ago

Maybe later @bbbradsmith ... You have made a fantastic work with this old emulator, to make it working fine as a modern core on libretro ! The old GUI was a pain, it was impossible to configure games by games because options was not in LR core options menu ... Now with all you do it is really better and we can use this emulator better than ever :) It will be perfect if one day all the video and sound options will be moved to core options to make them easier to use for users ... the old GUI menu must disappear i think ...

salem-ok commented 3 years ago

Thanks @bbbradsmith for looking into this, and thoroughly explaining your reasoning. It's a kind of a bummer that Hatari by design cannot perform savestates in a way that would enable Netplay, but as @Darknior said, maybe one day!

bbbradsmith commented 3 years ago

Even though I don't see a way to do it right now, it's probably worth keeping the issue open for future referemce. It's still a valid request, and something I'd like to see made possible too.

It could be that Hatari's savestate restore puts it into some kind of suspend for a frame, or maybe there's a Sleep or something involved that I haven't found yet. I tried just forcing an extra frame (or several) after the restore, but it didn't help. It should be possible to fix, but may require some serious debugging to find the cause.

Right now I can't devote the time to go deeper on either of those, but if we leave the issue open someone else might find the notes useful, and/or maybe I can get back to it in the future.

salem-ok commented 3 years ago

Thank you @bbbradsmith ! Hopefully somebody will pick this up, maybe you later if you find any time. I don't have skills to dive into the code, but will be more than happy to help with testing. Feature reopened.

Cogweasel commented 3 years ago

It's great to see to some updates being made to the Hatari libretro core, thank you @bbbradsmith ! Also hoping that someone will take a peek at getting multi-player working in the core. Sadly I am completely useless at coding, so can't help there. But just as my buddy @salem-ok I am up for helping with testing. crossing fingers :)