diff --git a/include/gfx/main.hpp b/include/gfx/main.hpp index 1a0fb6d5..15128aaa 100644 --- a/include/gfx/main.hpp +++ b/include/gfx/main.hpp @@ -73,6 +73,8 @@ struct Palette { decltype(colors)::iterator end(); decltype(colors)::const_iterator begin() const; decltype(colors)::const_iterator end() const; + + uint8_t size() const; }; #endif /* RGBDS_GFX_MAIN_HPP */ diff --git a/src/gfx/main.cpp b/src/gfx/main.cpp index c1dc3c29..d2ec1eb5 100644 --- a/src/gfx/main.cpp +++ b/src/gfx/main.cpp @@ -374,7 +374,7 @@ void Palette::addColor(uint16_t color) { } uint8_t Palette::indexOf(uint16_t color) const { - return std::distance(colors.begin(), std::find(colors.begin(), colors.end(), color)); + return std::find(colors.begin(), colors.end(), color) - colors.begin(); } auto Palette::begin() -> decltype(colors)::iterator { @@ -390,3 +390,7 @@ auto Palette::begin() const -> decltype(colors)::const_iterator { auto Palette::end() const -> decltype(colors)::const_iterator { return std::find(colors.begin(), colors.end(), UINT16_MAX); } + +uint8_t Palette::size() const { + return indexOf(UINT16_MAX); +} diff --git a/src/gfx/pal_sorting.cpp b/src/gfx/pal_sorting.cpp index 756746ee..0ce543fa 100644 --- a/src/gfx/pal_sorting.cpp +++ b/src/gfx/pal_sorting.cpp @@ -10,27 +10,56 @@ #include "gfx/convert.hpp" #include "gfx/main.hpp" +using std::swap; + namespace sorting { void indexed(std::vector &palettes, int palSize, png_color const *palRGB, png_byte *palAlpha) { options.verbosePrint("Sorting palettes using embedded palette...\n"); + auto pngToRgb = [&palRGB, &palAlpha](int index) { + auto const &c = palRGB[index]; + return Rgba(c.red, c.green, c.blue, palAlpha ? palAlpha[index] : 0xFF); + }; + + // HACK: for compatibility with old versions, add unused colors if: + // - there is only one palette, and + // - only some of the first N colors are being used + if (palettes.size() == 1) { + Palette &palette = palettes[0]; + // Build our candidate array of colors + decltype(palette.colors) colors{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX}; + for (int i = 0; i < options.maxPalSize(); ++i) { + colors[i] = pngToRgb(i).cgbColor(); + } + + // Check that the palette only uses those colors + if (std::all_of(palette.begin(), palette.end(), [&colors](uint16_t color) { + return std::find(colors.begin(), colors.end(), color) != colors.end(); + })) { + if (palette.size() != options.maxPalSize()) { + warning("Unused color in PNG embedded palette was re-added; please use `-c embedded` to get this in future versions"); + } + // Overwrite the palette, and return with that (it's already sorted) + palette.colors = colors; + return; + } + } + for (Palette &pal : palettes) { std::sort(pal.begin(), pal.end(), [&](uint16_t lhs, uint16_t rhs) { // Iterate through the PNG's palette, looking for either of the two for (int i = 0; i < palSize; ++i) { - auto const &c = palRGB[i]; - Rgba color(c.red, c.green, c.blue, palAlpha ? palAlpha[i] : 0xFF); - uint16_t cgbColor = color.cgbColor(); - if (cgbColor == Rgba::transparent) { + uint16_t color = pngToRgb(i).cgbColor(); + if (color == Rgba::transparent) { continue; } // Return whether lhs < rhs - if (cgbColor == rhs) { + if (color == rhs) { return false; } - if (cgbColor == lhs) { + if (color == lhs) { return true; } } diff --git a/test/pokecrystal.patch b/test/pokecrystal.patch deleted file mode 100644 index 6f85efb4..00000000 --- a/test/pokecrystal.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/Makefile b/Makefile -index ca08f23f..abd2e95c 100644 ---- a/Makefile -+++ b/Makefile -@@ -170,9 +170,9 @@ gfx/pokemon/girafarig/front.animated.tilemap: gfx/pokemon/girafarig/front.2bpp g - - ### Misc file-specific graphics rules - --gfx/pokemon/%/back.2bpp: rgbgfx += -h -+gfx/pokemon/%/back.2bpp: rgbgfx += -h -c embedded - --gfx/trainers/%.2bpp: rgbgfx += -h -+gfx/trainers/%.2bpp: rgbgfx += -h -c embedded - - gfx/pokemon/egg/unused_front.2bpp: rgbgfx += -h - diff --git a/test/run-tests.sh b/test/run-tests.sh index b0358da0..85953ade 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -30,8 +30,7 @@ if [ ! -d pokecrystal ]; then fi pushd pokecrystal git fetch -git checkout a3e31d6463e6313aed12ebc733b3f772f2fc78d7 -f -git apply ../pokecrystal.patch +git checkout a3e31d6463e6313aed12ebc733b3f772f2fc78d7 make clean make -j4 compare RGBDS=../../ popd