pret / pokecrystal

Disassembly of Pokémon Crystal
https://pret.github.io/pokecrystal/
2.07k stars 785 forks source link

Sort Pokemon and trainer sprite palettes from lightest to darkest, with Makefile-specified exceptions #1136

Open Rangi42 opened 2 weeks ago

Rangi42 commented 2 weeks ago

These sprites all use white, black, and two colors. The order of the two colors matters in some in-game contexts: examples include the Pokedex's monochrome green sprites, the PC's monochrome orange ones, or battle anims which cycle palettes to "lighten" or "darken" them.

Most of the time, the lighter color is first and the darker color is second. There are a few exceptions, like Farfetch'd, which can be specified in the Makefile.

We would use the colors from the PNG; verify that there are four of them and that two are white and black; and sort them lightest-first (or darkest-first with a flag in the Makefile).

This could be done by processing the .gbcpal file, so no need for a PNG library.

mid-kid commented 2 weeks ago

One important property of the color indexes is that they should be consistent across both front and back sprites: If one color is unused in either the front or the back sprite, the indexes used in the generated tileset should still represent the correct colors. With that in mind, I propose a procedure that works as follows:

  1. Read out the colors in both front.png and back.png (using rgbgfx?)
  2. Sort the colors from brightest to darkest and remove duplicates
  3. If there's less than four colors, append black to the list until there's four.
  4. Verify the colors
    1. There must be exactly four colors.
    2. The first color must be white.
    3. The last clolor must be black.
  5. Provide this new color selection as the input to rgbgfx, and use it to generate the tiles.

Of course, a flag would be used to reverse the color ordering for sprites which require this for matching.

Rangi42 commented 2 weeks ago

Yes, using rgbgfx to generate a .gbcpal file is the simplest way to do that. No need for a PNG library or text parsing.

mid-kid commented 2 weeks ago

The main problem with this solution: The order of the colors is unknown to the user until they're generated. This poses a problem when creating a shiny.pal, as the user won't know which color goes where.

I can only think of two solutions:

A color substitution map, say, for example 13,7,31 = 8,24,31, where the first color (in the original palette) is replaced with the second. Imo this kind of defeats the purpose of generating the colors in the first place...

Running the same procedure as above on equivalent shiny_front.png and shiny_back.png sprites, and verifying the generated tile data: If the the data matches, you have found the correct color order for the shiny, otherwise, try swapping the two middle colors and generating the tile data again, if that matches, then you have found the correct colors for the shiny. If neither matches, the pictures are different. (there may be better ways to approach this but I can't think of any simpler ones)

Of course, a third solution is just accepting that the shiny colors may end up the wrong way around if the normal colors are edited, and that the user is unlikely to change the colors of a pokemon significantly (such that they swap places in the brightness order) if they've already made a shiny palette.

Rangi42 commented 2 weeks ago

Of course, a third solution is just accepting that the shiny colors may end up the wrong way around if the normal colors are edited, and that the user is unlikely to change the colors of a pokemon significantly (such that they swap places in the brightness order) if they've already made a shiny palette.

I'd like to keep things simple and go with this option. Optimistically, it'll be easier for someone who's already edited shiny.pal to swap two lines of text when they notice the backwards colors. Realistically, they won't, but it'll be easier to tell them to do so than explain how to use palfix.py and its caveats.