diff --git a/include/gfx/proto_palette.hpp b/include/gfx/proto_palette.hpp index b2cc4433..f634c12b 100644 --- a/include/gfx/proto_palette.hpp +++ b/include/gfx/proto_palette.hpp @@ -15,15 +15,20 @@ #include class ProtoPalette { +public: + static constexpr size_t capacity = 4; + +private: // Up to 4 colors, sorted, and where SIZE_MAX means the slot is empty // (OK because it's not a valid color index) // Sorting is done on the raw numerical values to lessen `compare`'s complexity - std::array _colorIndices{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX}; + std::array _colorIndices{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX}; public: /* - * Adds the specified color to the set - * Returns false if the set is full + * Adds the specified color to the set, or **silently drops it** if the set is full. + * + * Returns whether the color was unique. */ bool add(uint16_t color); diff --git a/src/gfx/process.cpp b/src/gfx/process.cpp index 94b1fe1d..fda630d0 100644 --- a/src/gfx/process.cpp +++ b/src/gfx/process.cpp @@ -986,12 +986,16 @@ void process() { for (auto tile : png.visitAsTiles()) { ProtoPalette tileColors; AttrmapEntry &attrs = attrmap.emplace_back(); + uint8_t nbColorsInTile = 0; for (uint32_t y = 0; y < 8; ++y) { for (uint32_t x = 0; x < 8; ++x) { Rgba color = tile.pixel(x, y); if (!color.isTransparent()) { // Do not count transparency in for packing - tileColors.add(color.cgbColor()); + // Add the color to the proto-pal (if not full), and count it if it was unique. + if (tileColors.add(color.cgbColor())) { + ++nbColorsInTile; + } } } } @@ -1033,9 +1037,9 @@ void process() { } } - if (tileColors.size() > options.maxOpaqueColors()) { + if (nbColorsInTile > options.maxOpaqueColors()) { fatal("Tile at (%" PRIu32 ", %" PRIu32 ") has %zu opaque colors, more than %" PRIu8 "!", - tile.x, tile.y, tileColors.size(), options.maxOpaqueColors()); + tile.x, tile.y, nbColorsInTile, options.maxOpaqueColors()); } attrs.protoPaletteID = protoPalettes.size(); diff --git a/src/gfx/proto_palette.cpp b/src/gfx/proto_palette.cpp index 641406be..d67db291 100644 --- a/src/gfx/proto_palette.cpp +++ b/src/gfx/proto_palette.cpp @@ -17,24 +17,29 @@ bool ProtoPalette::add(uint16_t color) { size_t i = 0; - // Seek the first slot greater than our color + // Seek the first slot greater than the new color // (A linear search is better because we don't store the array size, // and there are very few slots anyway) while (_colorIndices[i] < color) { ++i; - if (i == _colorIndices.size()) - return false; + if (i == _colorIndices.size()) { + // We reached the end of the array without finding the color, so it's a new one. + return true; + } + } + // If we found it, great! Nothing else to do. + if (_colorIndices[i] == color) { + return false; } - // If we found ourselves, great! - if (_colorIndices[i] == color) - return true; // Swap entries until the end while (_colorIndices[i] != UINT16_MAX) { std::swap(_colorIndices[i], color); ++i; - if (i == _colorIndices.size()) - return false; // Oh well + if (i == _colorIndices.size()) { + // The set is full, but doesn't include the new color. + return true; + } } // Write that last one into the new slot _colorIndices[i] = color;