|Home | Downloads | Screenshots | Forums | Source code | RSS | Donate|
|Register | Log in|
melonDS aims at providing fast and accurate Nintendo DS emulation. While it is still a work in progress, it has a pretty solid set of features:
• Nearly complete core (CPU, video, audio, ...)
• JIT recompiler for fast emulation
• OpenGL renderer, 3D upscaling
• RTC, microphone, lid close/open
• Joystick support
• Various display position/sizing/rotation modes
• (WIP) Wifi: local multiplayer, online connectivity
• (WIP) DSi emulation
• (WIP) GBA slot add-ons
• and more are planned!
If you're running into trouble: Howto/FAQ
Changes to the website
Oct 31st 2020, by Arisotura
This blog now uses the same user accounts as the forums. So if you have an account there, you can now use it to post comments here as well.
Of course, comments are also still open to guests.
There are more updates planned to this site, so, let me know asap if anything breaks.
|29 comments (last by Shreyansh) | Post a comment|
The DSi camera adventure
Oct 27th 2020, by Arisotura
I mentioned the DSi cameras in my previous post, and that's what I was working on lately. Mostly trying to get the cameras going on the DSi itself, so I could test the transfer hardware.
Well, it's not been that easy.
I had started work in the dsi_camera branch, but so far it was a large trainwreck. I couldn't really understand how camera transfers work and how everything interacts together. My attempt at a guessed implementation was getting nowhere, which meant it was time for some hardware research.
So I started work on a DSi camera test homebrew. I first went and implemented the initialization procedure found in GBAtek, only to be rewarded with a hang when trying to activate a camera. I tried many things, taking the init procedure from some open-source Aptina MT9V113 driver (the model of camera the DSi uses), reverse-engineering the DSi camera app to use its exact init procedure, all to no avail.
I felt stuck there. I even tried looking for existing examples using the DSi cameras, found this one by Epicpkmn11, but at the time it seemed to have the same issue I was having.
I eventually went out and asked for help on several places. A side effect is that I'm now found in some Discord servers. I also posted a thread at nesdev, knowing nocash hangs around there. The documentation in GBAtek implied he did get the cameras working, so I figured he'd be able to help. And he did, thanks there.
I first looked at the code he provided, checking for any meaningful differences in the init procedure, but it looked like I had all the essential stuff right. I was stumped.
It eventually occured to me that maybe I should try initializing both cameras simultaneously, like Nintendo does, rather than only initializing one camera. You know how it is, when you're desperate, anything can look like a valid solution. Anyway, that didn't cut it, but it revealed something interesting when I tried to read some registers from both cameras. Some reads were getting corrupted. So I knew something was up with the I2C code.
Looking at nocash's I2C code, I was able to spot and fix the issue. Turns out that during an I2C read, you don't raise an ack when reading the last byte. This fixed the corruption I was observing, and finally allowed the camera to activate successfully. At the same time, Epicpkmn11 happened to be in the same Discord server I was in, so they could fix their code too (turns out it did have the same issue as mine).
... read more
|31 comments (last by Woodcode) | Post a comment|
Sorry for the silence lately
Oct 11th 2020, by Arisotura
I know that since the 0.9 release, there hasn't been a lot of progress. On my side, things have been pretty rough, especially regarding depression. Under these circumstances, it's good to take a break.
Anyway, what can we attempt doing, at this point?
Besides dealing with the pull requests and issue reports?
One thing I was working on lately was DSi camera support, but I didn't get too far. I'm going to need hardware tests to figure out how the camera hardware works. Considering the lenghty initialization procedure for those, it's not quite something I look forward to. So I'll post more about this when I get further into it.
I have ideas for the OpenGL renderer, namely, a better method for rendering quads. It would need more work for an implementation though, but might be worth it.
But, one of my main concerns is about wifi, especially local multiplayer.
At this point, melonDS is mainly known as 'the wifi emulator'. It's a bit sad that, 3 years after we got it working, we're still telling people to disable their framerate limiter and pray. We can probably do better.
It's not like we haven't tried, though. You might have seen that branch named 'betterer_wifi' in the repo. I was hoping to run the wifi with more stable timing, but it was a trainwreck, it performed even worse than our current method.
The main issue with local multiplayer is that it requires tight synchronization to function. You might remember how finicky it was back in the old days, you would start lagging and disconnecting as soon as your friend was more than 10m away from you. Long story short, the protocol works by having the host repeatedly poll its clients, multiple times per frame, and each client is given a narrow window to respond (the time given is barely greater than what it takes to transfer the response frame).
... read more
|46 comments (last by AshleyGee) | Post a comment|
melonDS 0.9 is out!
Sep 4th 2020, by Arisotura
It's been forever, but, finally, here it is. melonDS 0.9.
And it's big.
So, what are the highlights of this release?
- JIT recompiler
Brought to you by Generic (aka RSDuck), the new JIT recompiler enables melonDS to run much faster, and quite often reach fullspeed even when emulating DSi titles!
There are a few settings you can try out to get the most out of this JIT. While it has been heavily tested and worked on, it's still imperfect.
- DSi emulation
This is the other flagship feature of this release: melonDS now emulates the DSi!
... read more
|88 comments (last by Grant) | Post a comment|
Sep 3rd 2020, by Arisotura
I'll let you guess ;)
|10 comments (last by ~.~) | Post a comment|
Messin' around with the GL renderer
Aug 19th 2020, by Arisotura
First of all, lil' status update. Things are nearly ready for the 0.9 release, we are mostly busy ironing out small issues here and there to ensure everything is good. Nobody would want something big like that 0.9 release to end up being a total flop.
Also, if you ever wondered why progress is slow: an emulator project is like a tree in that once you're done with the trunk, it branches off in a billion different directions. At this point, melonDS is too big to be a one-man show. There are a few people working on it now, but there's only so much we can do with our time and motivation.
Anyway, while Generic is busy polishing the JIT, I figured I'd go around and try fixing some of the issues on the issue tracker.
This one, Deformed floor textures in the Celestial Tower (Pokemon Black/White) (OpenGL only), is an interesting problem. The base issue is that, if you happen to remember, the DS can draw quads natively, while modern GPUs can't. Actually, it's even worse: clipping on the DS cuts through polygons but doesn't create more polygons, which means that you can end up with a maximum of 10 vertices per polygon. For example, a triangle that sticks out of the view volume can become a quad, a pentagon, or more.
The base issue here is faulty rendering of these polygons that have more than 3 vertices. The DS employs a scanline-based convex polygon renderer, so it doesn't care how many vertices your polygon has. Software renderers used in DS emulators use similar filling algorithms, so no problem there either. However, when you use OpenGL, it's another deal entirely -- modern OpenGL-compatible GPUs are very good at drawing triangles, but... that's about it.
So, what do you do when you need to render a quad? Easy, split it into two triangles!
Suppose the quad below.
All fine and dandy. Now we split this, like this:
... read more
|20 comments (last by Generic aka RSDuck) | Post a comment|
Jul 23rd 2020, by Arisotura
Sorry for the silence lately -- these times are getting pretty busy. melonDS wise, we're trying to perfect the JIT and the few other things we want for the 0.9 release. Real life wise, on my side, I'm starting the procedure to get my gender marker updated, which is going to be the last big thing for my transition.
Anyway, just yesterday, asie told me that maxmod's interpolated mode was broken in melonDS, which piqued my curiosity.
What's maxmod, you ask? It's a real fancy audio library for the GBA and DS. I don't know much about the GBA side of it, but on the DS, it supports three modes: hardware mode, interpolated mode, and extended mode. Hardware mode is fairly straightforward. Interpolated mode resamples audio on the fly, applying interpolation to make up for the lack of hardware interpolation. Extended mode does its own mixing, adding support for more channels than the hardware can offer.
In our case, interpolated mode was broken, outputting pretty much short high-pitched beeps and nothing else. I was curious to see if maxmod used any of the fancy audio capture/output modes that melonDS doesn't support (because no commercial game uses them, and my policy is to avoid implementing things until I have test cases). melonDS is set to report if any such features are being used, but in this case, it didn't report anything out of the ordinary. So this meant I'd have to dig further.
Quick regression testing showed that interpolated mode worked okay-ish on melonDS versions prior to 0.6. Well, it didn't sound as it should, but it was atleast reasonably close, instead of just being high-pitched beeps.
So apparently it was completely broken when sound FIFOs were implemented. The FIFO logic was fine, but the addition of that feature worsened the consequences of a bug that had always been there.
I logged what was going on during playback, to try and figure out where it failed. It appeared that the data being fed to the audio channels was fine, but, for whatever reason, the channels themselves failed to actually pull the data from memory. More logging revealed some strange things, like how certain things started at zero when they shouldn't. Notably, the channel timers started at zero, when they're supposed to start at the SOUNDxTMR reload value. But also, the FIFO level started at zero, causing it to immediately go negative and break the FIFO filling logic.
For a while, I scratched my head at all that, until it finally clicked.
In interpolated mode, maxmod will first disable the mixer, then sequentially initialize the channel registers, then enable the mixer, letting all channels start in perfect sync.
... read more
|41 comments (last by Arisotura) | Post a comment|
Jun 25th 2020, by Arisotura
|I got the surgery. I am alive and well. Thank y'all! :)|
|32 comments (last by Ammako) | Post a comment|
The new wifi adventure
Jun 21st 2020, by Arisotura
I'm doing this while waiting for my surgery, which will be in 3 days. So, a bit more about yesterday's screenshot.
Basically, it all started with a new branch called slirp. What's that, you ask, another of Arisotura's oddball noises?
Nah. If you followed the melonDS history, you know that a while back, support for internet connectivity was added. It was pretty similar to how DeSmuME did it back then: providing a basic emulated access point to connect to, then forwarding outgoing traffic via libpcap.
While it was straightforward, it had its lot of issues: it required installing libpcap (or any Windows equivalent), required admin/root privileges, and, more annoyingly, did not work over wifi connections, as explained here.
Eventually indirect mode (aka LANMAGIC) was developed to get around this. The basic idea was to emulate a local network and use simple BSD sockets to forward outgoing traffic to the host network. The idea was good, but the actual implementation was more or less a pile of hacks that never really worked right.
Enter the slirp branch. Basically, QEMU's libslirp does exactly what LANMAGIC clumsily tried to do.
So I reimplemented indirect mode using that. Took a while to figure out how to use libslirp, as it isn't really documented, but we got there, and it works beautifully.
More notably, this is how we like it. Unlike direct mode, it requires no setup, it Just Works™. Over any sort of connection, without any special privileges, ...
Then I got carried away and began implementing features of the DSi's new wifi device. From there, you can see how this ended.
... read more
|39 comments (last by Vijju123) | Post a comment|
Jun 20th 2020, by Arisotura
|13 comments (last by Max) | Post a comment|