shonumi / gbe-plus

DMG/GBC/GBA emulator and experimental NDS emulator.
GNU General Public License v2.0
501 stars 79 forks source link

[Request] Indexed color support for CGFX #71

Open frozenLake opened 6 years ago

frozenLake commented 6 years ago

This probably can be saved for after PNG support is implemented, but there is also indexed color for BMP, so I'll just continue.

Anyway, by having indexed color support, we could have something like

MegamanSheet.bmp 00s = 000000, 000000, 0070E8, 00E8D8, F8E0A0, F8F8F8, 00FF00 00o = A80010, 000000, 0070E8, 00E8D8, F8E0A0, F8F8F8, 00FF00 00k = E00058, 000000, 0070E8, 00E8D8, F8E0A0, F8F8F8, 00FF00 00g = F870B0, 000000, 0070E8, 00E8D8, F8E0A0, F8F8F8, 00FF00 01w = 5890F8, 000000, 0070E8, 00E8D8, F8E0A0, F8F8F8, 00FF00 02Q = 00E8D8, 000000, 000000, 0070E8, F8E0A0, F8F8F8, 00FF00 038 = 0070E8, 000000, 00E8D8, 000000, F8E0A0, F8F8F8, 00FF00

instead of having seven different files for each palette swap while charging.

shonumi commented 6 years ago

I do not think this would be a good approach due to the complexity it adds to parsing BMPs (essentially having 2 code paths, 1 for normal 24-bit color images, and another for indexed color ones).

Instead, what you want is something I've experimented with called the EXT_AUTO_PAL option, which would be another option users could enable like the EXT_AUTO_VRAM_ADDR and EXT_AUTO_BRIGHT. It uses an algorithm to automatically swap colors when the same tile uses different palettes. That feature is still WIP though.

At any rate, this is the preferred solution since it's relatively easy on the codebase and still requires users to dump only 1 version of their graphics (as long as they enable the option). It also has the benefit of working on any image format, since it's basically post-processing. It would require a new manifest file format going forward, but I've working on making a new format for a while now, so that change is inevitable.

The issue of DMG palette changes has been a known thorn in my side for quite some time though. It greatly affects other games (e.g. games that change the palette when paused, and dozens of Pokemon attacks like Night Shade), so it's very much something I'm trying to fix.

frozenLake commented 6 years ago

Actually, couldn't we encode what colors are the "indexes" in a line? For instance, have the default colors be for 00o, and then remap color matches from that, so that we have...

0=A80010 1=0070E8 2=00E8D8

Note that I am only picking specific colors to be indexed, as the others don't get remapped when charging. However, it might come up if we are dealing with colors when fading, so, one might need to index those anyway.

but yeah, changing specific hex values to other hex values, maybe?

shonumi commented 6 years ago

It's possible to do something like that, but let me explain the future EXT_AUTO_PAL option a bit more and why a particular method of handling palette changes is necessary for DMG games (the games that are most affected by this problem).

For DMG games, the graphical palette swaps are designed around swapping different levels of brightness rather than different colors. That is to say, something like the palette swapping done to Mario when he gets a star to make him invincible in Super Mario Land 1 or 2 is different from Super Mario Bros. DX. In the former, the game is changing different shades of gray, making certain parts darker or lighter. In the latter, colors are actually changing (sometimes not even using the same palette) instead of re-arranging the same 4 shades. We'll leave GBC palette swaps out of this example for now since the way I plan to handle them is a bit different from DMG palette swaps.

At any rate, the original effect in DMG games is about changing perceived levels of brightness (luminosity), since the LCD only deals with shades of gray (or green technically on the oldest Game Boys). EXT_AUTO_PAL approaches this by automatically looking up the original palette (which is encoded in the hash), comparing that palette to the current one, and adjusting the level of brightness depending on what changed. It maintains a more consistent look that mimics what palette swapping really did on the DMG, something simply shuffling and remapping colors doesn't quite get right. Color swapping works better for GBC graphics that swap out 4 different colors for tiles, so indexed image files would be a better fit there (EXT_AUTO_PAL is going to handle the color changing automatically, however).

So it's not that I don't think indexed image files themselves are a bad idea, it's just that the approach isn't a good fit. It adds more code to image parsing and adds yet another layer of difficulty for end-users, especially beginners. I.e. users would have to be the ones manually deciding which hashes need to be associated with specific indexed images (that's just not something GBE+ can detect on its own). It's just not as efficient as checking another checkbox and letting GBE+ handle all the color manipulation on its own. I keep looking at the logistics, but I'm not convinced in the long-term indexed images are a better option than what I have planned for EXT_AUTO_PAL.

frozenLake commented 6 years ago

So with the way EXT_AUTO_PAL is described, it seems that I won't be able to duplicate the NES Megaman charging for the gameboy games.

It also seems that using this with having more colors than the original gameboy color palette will be... weird. Either way, both are cases that would take duplicating the image to solve.

Its a shame that the end user can't define custom palettes for palettes, but completely understandable from a coding perspective.

EXT_AUTO_PAL does seem like something that will be fun to play around with, though!