mgba-emu / mgba

mGBA Game Boy Advance Emulator
https://mgba.io/
Mozilla Public License 2.0
5.67k stars 777 forks source link

Horizontal sprite mosaic is inaccurate #2933

Open fleroviux opened 1 year ago

fleroviux commented 1 year ago

I wrote a basic test ROM to figure out how horizontal sprite mosaic might work and currently it seems to be quite broken in mGBA.

image On the left side is mGBA and on the right side is what it looks like on hardware.

The mosaic algorithm implemented in hardware is a post-process effect done during the layer-merge step and seems to use an internal register to store the the sprite pixel that will actually be displayed. For each pixel at x-coordinate line_x in the scanline the PPU looks at the sprite pixel for the current x-coordinate and decides based on three conditions if the current sprite pixel should be latched into the register. The conditions are as follows:

  1. (line_x % mosaic_width) == 0 or
  2. the current sprite pixel has the mosaic-flag cleared or
  3. the latched sprite pixel has the mosaic-flag cleared

In essence the first condition (likely implemented with a counter) creates the classical pixelation effect while the last two conditions handle the transitions at the boundaries of sprites, i.e. from no-sprite to sprite-with-mosaic and sprite-without-mosaic to sprite-with-mosaic and vice versa.

Finally it should be noted that the PPU updates the mosaic-flag in the sprite buffer even for transparent pixels (like with the sprite priority bug) which likely matters for this test ROM. Also the object window test always uses the current sprite pixel and not the latched one.

endrift commented 1 year ago

Can you give me a raw screenshot of correct output? It'd be useful for setting up CInema.

fleroviux commented 1 year ago

Yes, here's the raw output. Generated from NBA, but from what I can tell it's pixel-identical to real hardware (I should really get a proper way to capture output from real hardware some day...).

output

profi200 commented 1 year ago

Here you have it dumped from a 3DS in GBA mode. Note that colors might not be accurate due to dithering and color correction. But the mosaic effect should be 1:1 accurate with GBA (SP) hardware.

sprite-hmosaic_3DS edit: Accidentally uploaded a 239 pixel screenshot. This one is correct.