Deeper than it seems
I've been wanting to work out the DS's color precision. Incoming colors (palettes, vertex colors...) are all 15-bit, but the screens actually output 18-bit color. The 3D engine is well documented in this regard, we know that the colors are converted to 18-bit before being blended together and even how they're converted. However, details on the 2D engines are at a loss. GBAtek doesn't say much, other than that master brightness is applied to 18-bit color.

For reference, GBAtek's diagram of the whole video system.

I first tested master brightness. The idea is to configure it in "brightness decrease" mode with a factor of 8, such that incoming colors are halved. Then, fill two parts of the screen with colors 0,2,0 and 0,3,0 respectively. If the colors are processed as 15-bit, they will come out the same, but if they're converted to 18-bit beforehand, there will be a difference. Noting that I picked green colors to make the difference as visible as possible, as the human eye sees green best.

The test reveals that there is a difference, subtle but visible. Which confirms that master brightness is applied to 18-bit color.

To find out where the color conversion takes place, I did the test again, using the "brightness decrease" special effect instead of master brightness. It works the same, but it's applied earlier than master brightness. The test also showed a difference, meaning that color special effects are applied to 18-bit color.

So now we know that colors are converted as soon as possible, but there is one remaining detail to work out: how they're converted.

We know that the 3D engine converts color components the following way:

if (in == 0) out = 0;
else out = in*2 + 1;

From there, the idea is to display identical colors from the 2D and 3D engines, side by side, and compare them. By doing it for each possible intensity (from 0 to 31), we can work out where they differ and infer how the 2D engine converts colors.

The result of this test is a little surprising. For all the intensities above 0, the colors differ.

out = in*2;

So this is how the 2D engine converts colors. Which means that it's impossible to reach full intensity, for example, white (31,31,31) will come out as 62,62,62 instead of 63,63,63. This also means that colors output by the 2D and 3D engines will be subtly different, atleast unless special effects are used.

I also checked the VRAM/FIFO display modes of 2D engine A, and they convert colors the same way as the 2D engine. However, the white displayed by a disabled screen is 63,63,63.
SpiffyJUNIOR says:
Feb 9th 2017
Nice progress so far,high hopes for this emulator in time,cheers!
Crono says:
Feb 9th 2017
Do you intend on doing a MelonDS Libretro core on the(probably far) future?
Arisotura says:
Feb 13th 2017

Eventually, yeah!
Crono says:
Feb 14th 2017
Happy to hear that!
Post a comment