The local multiplayer saga, ep 5
It keeps going!

Lately, I have been working on faster IPC, so I could get a more accurate idea of how much it would take to emulate local multiplayer at acceptable speeds, and whether my ideas were feasible at all. First order was getting rid of the old inefficient BSD sockets.

Instead, I built a data exchange system based on shared memory. The idea is simple: have a large block of memory shared between all melonDS instances, where you have a FIFO buffer for exchanging wifi packets, another FIFO buffer for exchanging sync points, and a small header containing some useful status bits. Then each instance has a set of semaphores that other instances can use to signal when new packets or sync points are sent. All fine and dandy.

I figured this would be easily taken care of, with QSharedMemory and QSystemSemaphore. And I ran into my first issue: QSystemSemaphore sucks. Basically, it isn't possible to wait on a QSystemSemaphore with a timeout, which means that waiting on it will block until it is signaled. What if, for whatever reason, the other side isn't signaling the semaphore? That's a deadlock. In our situation (and probably many others), this is unacceptable. The problem has been reported to the Qt team in 2008 and they don't seem very interested in fixing it. So this basically means I had to code my own thing, directly using the OS's named semaphores. Currently, I have only coded it for Windows, so it will have to be ported to Linux and macOS.

On the other hand, QSharedMemory works like a charm, so there's that.

I also reworked the sync system some. It's currently not perfect, but atleast now I know I'm not being held back by faulty emulation: as long as no frames are being dropped or delayed, the communication should work fine.

Overall, this gives much better performance than the previous iteration: NSMB multiplayer reaches near-fullspeed on my laptop Crepe, and that's with the interpreter. There are still issues to iron out, but this gives me hope that we can pull off fun multiplayer features in melonDS.

Also worth noting that there is another candidate for optimization, which I haven't talked much about yet: the wifi module itself.

The wifi module, you say? What's worth optimizing in there?

The wifi module has a bunch of microsecond-precision timers, all sorts of fun status bits, and some parts of Nintendo's code relies on packet transmission/reception taking time and not being instant. And then you have local-multiplayer CMD/reply/ack exchanges and their tight timings. You guess the picture.

So currently, in melonDS, it is emulated at the microsecond level, which means it is run every 33 system cycles (not exactly one microsecond, but it works well enough for our purposes), and all the various counters and things are checked and updated every time. Which is less than optimal.

Compare this to the main emulation loop in melonDS: instead of checking on all the DS subsystems every CPU instruction or every clock cycle, melonDS uses an event scheduler. It is basically a way of planning hardware events in the future (like "VBlank needs to happen in 342 cycles") and keeping track of them. melonDS can then determine the next event to come and how many cycles are left before it needs to be run, the CPUs are run for that many cycles and the event is run. Rinse and repeat. Compared to checking everything per-instruction, this system offers much better performance while retaining decent accuracy.

So it would make sense to use a similar system to emulate the wifi module. The main issue is that it would require extra cleverness to emulate things like the timers, or W_RXTX_ADDR (wifi RAM pointer that is updated during transmission or reception to reflect which address the hardware is accessing). Nothing insurmontable, but it's a pretty big change and it has quite the potential to break things.

So, all in all, I'm hopeful we can get local multiplayer working and good. It will take time, but we will definitely get there for melonDS 1.0.
Peduls says:
Aug 20th 2022
I'm impressed at how fast you're working through the wifi stuff. Great work!
Saizo7 says:
Aug 20th 2022
melonDS the local multiplayer saga > Marvel the infinity saga
I wonder when is the endgame ;)
Burntham says:
Aug 20th 2022
I love this. I love the enthusiasm of this post. I love the pace at which this emulator is progressing.

All hail the Melon.
Nixel says:
Aug 20th 2022
I'm so glad your brain decided to focus on this, you're making progress towards tangible results that we'll all get to enjoy!
Trunks says:
Aug 21st 2022
I can't believe how good you are at this. I know how tight it has to be to avoid timeouts and the fact that you were able to figure everything out blows my mind. We are all lucky to have you working on this. You are making history!
Bless says:
Aug 21st 2022
Feel the urge to check out what's the latest update in MelonDs, from someone that doesn't and hasn't touched a ds game in months.
Bless says:
Aug 21st 2022
And all I can say is that I am witnessing history.
Jay says:
Aug 21st 2022
And the saga continues.
Sivecano says:
Aug 21st 2022
this is one of the coolest emulator projects I've seen.
Zebi says:
Sep 28th 2022
How do i get Wi-fi?
MBM says:
Dec 22nd 2022
I have the Ir-melon DS on reto-pie
When I load a DSI game I’m getting just a white screen
How am I to solve this ?
Generic aka RSDuck says:
Dec 26th 2022
we don't support versions of melonDS which have been repackaged a thousand times
Post a comment