2D accuracy: it's a rabbit hole too
Yeah. I've been wanting to fix mosaic support in melonDS, and, well, got sidetracked (I know I still have to release the JIT and DSi betas).

Anyway, mosaic is a typical feature of old consoles with 2D engines, including the DS. It basically applies a pixelation effect to graphics, as shown here:

The basic idea is that the screen is split in a grid, whose dimensions are variable (configured by register 0x0400x04C on the DS). For each 'cell' in the grid, all the pixels are colored the same as the first (top-left) pixel. In reality, it's a bit more complex, as on the DS the effect can be applied per-layer and per-sprite, and you can even specify different grid sizes for BG layers and sprites, but fundamentally it's more or less the same thing, it pixelates shit.

Sounds simple enough, right?

It's a bit tricky to implement when you're trying to write a performant renderer, though. Which is more or less why blargSNES never supported it.

As far as melonDS is concerned, mosaic was implemented in version 0.5, but (among other silly bugs) it never worked quite right as far as sprites were concerned, especially when those use rotation/scaling. But, at the time, I didn't do much past the original implementation, mostly because I don't know of a lot of games that use the mosaic effect. The lack of test cases meant it stayed supbar.

Until, well, now.

First thing to do is to write some test cases for sprite mosaic. BG mosaic seems quite simple, even though I would still have to probe it extensively for edge cases, but sprite mosaic is a bit more oddball, as seen here:

Those snapshots were taken from Grey, my capture-card DS. This isn't some weird buggy emulator, sprite mosaic really is that weird.

The sprite being mosaic'd is a simple ball sprite. The cyan sprite behind doesn't have mosaic applied to it, but both share the same size and rotscale parameters. The sprites on the left have double-size mode enabled, which merely doubles the bounding box of rotscaled sprites.

I have yet to work out all the oddities, but, from what I have observed, it seems that sprite mosaic doesn't work as we thought. If vertical mosaic is simply done by adjusting the source Y coordinate when rendering BG layers or sprites, horizontal mosaic is a different topic. As far as sprites are concerned:

* horizontal mosaic is restrained to the sprite's bounding box (vertical mosaic is too, but only in one direction)
* seeing how it is affected by the presence of neighbor sprites, horizontal mosaic seems to be applied after all the sprites are rendered
* it seems to keep track of which pixels belong to each sprite, even when said pixels are transparent

As of now, none of the existing DS emulators get sprite mosaic right. Probably, none of the GBA emulators get it right either, since the GBA uses a similar renderer, and it doesn't look like anybody has ever figured out the mystery of sprite mosaic.

I wanted to be able to check my mosaic implementation against hardware for correctness in many situations, to make sure I'd gotten the logic right. But constantly dumping frames from Grey and hand-comparing them against melonDS would be tedious. I wanted to have a better tool.

So, I set to work. I opened ds_capture.exe in IDA, opened up the Linux DS-capture code example and WinUSB documentation, and set to work. And, in one evening, MelonCap was born.

This is pretty simple. Left screen is the output from melonDS, middle is what is captured from Grey, right is a color-coded visualization of the differences.

The precision isn't exactly optimal though: melonDS outputs RGB666 color, like the DS does, but the capture card degrades it to RGB565 due to technical constraints. Well, this is atleast better than RGB555.

This is pretty much made for graphical testing in specific use cases, as there's no synchronization mechanism, one has to ensure that both melonDS and the DS are rendering the same things.

Anyway, the example in the screenshot above shows something interesting. There's been all that effort put towards pixel-perfect 3D, but our 2D engine isn't pixel-perfect (neither is the 3D one, but... yeah). We figured pixel perfection with the 2D engine would be a given, and, yet... here we are.

The bottom screen has BLDCNT configured so that all layers/sprites will be dimmed, with BLDY=1. This is hardly noticeable, and is likely an oversight. However, the colors generated by melonDS in this situation don't quite match hardware output.

The function for the brightness-down effect is described by GBAtek as:

out = in - ((in * EVY) / 16);

However, a quick hardware test tends to show that the actual function is:

out = in - (((in * EVY) + 7) / 16);

There's probably more of this shit everywhere, so the 2D engine will have to be heavily tested for accuracy. Fun shit ahead.
ari says:
Sep 16th 2019
Thanks for the replies. So it's not an issue related to this, but I still feel the need to bring it up on the topic of 2d. Below is an image of the issue. Left is Melonds and right is Desmume. Not sure if Desmume just adds some blur, if it's anti aliasing or something else, but 2d sprites in Melonds look really blocky. I can test with other 2d games later if you want.
poudink says:
Sep 17th 2019
it's probably a filter. tbh I think it makes the game look worse.
Arisotura says:
Sep 17th 2019
melonDS also has filtering if you wish, but it only works if you're not using OpenGL display.
AsPika2219 says:
Sep 17th 2019
Nice smooth pixels!
Ari says:
Sep 17th 2019
Aristotura, IT DOES. That's just plain impressive! (I was waiting for this because it obsoletes desmume forever)
asd says:
Sep 22nd 2019
Nice to see the progress and some insight into how it is to work on the emulator :)
AUDIO says:
Oct 1st 2019

Little Timmy says:
Oct 2nd 2019
Does this mean we can play Mario now?
poudink says:
Oct 2nd 2019
we could play Mario since 0.1
Little Timmy says:
Oct 3rd 2019
Teach me how to play mister and give me games
MelonMan says:
Oct 3rd 2019
Little Timmy: I don't think we can give rom links. If you have a copy, you can dump it from your DS/DSi and then you have it as a .nds file.
kevincrans says:
Oct 5th 2019
I really like there is being cared about the details! Also nice to hear that you're still gonna release the MelonDSi Beta, even better with hearing JIT is in good progress. Of course I understand that this and heavy testing might take a while, so I will stay tuned!
Little Timmy says:
Oct 6th 2019
You don't understand me mister I want games not roms and what do you mean dump? I want to play Mario
PeeJay Bonobo says:
Oct 6th 2019
Obvious troll is obvious.

Anyways, even with MUGEN creation, the road to source accuracy is a tough one.
Little Timmy says:
Oct 7th 2019
What? Give me Mario game
Post a comment