mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Properly detect tiles with more than 4 colours
Fixes #1127, which was caused by a dumb logic error. Duh me.
This commit is contained in:
@@ -15,15 +15,20 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
class ProtoPalette {
|
class ProtoPalette {
|
||||||
|
public:
|
||||||
|
static constexpr size_t capacity = 4;
|
||||||
|
|
||||||
|
private:
|
||||||
// Up to 4 colors, sorted, and where SIZE_MAX means the slot is empty
|
// Up to 4 colors, sorted, and where SIZE_MAX means the slot is empty
|
||||||
// (OK because it's not a valid color index)
|
// (OK because it's not a valid color index)
|
||||||
// Sorting is done on the raw numerical values to lessen `compare`'s complexity
|
// Sorting is done on the raw numerical values to lessen `compare`'s complexity
|
||||||
std::array<uint16_t, 4> _colorIndices{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
std::array<uint16_t, capacity> _colorIndices{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
* Adds the specified color to the set
|
* Adds the specified color to the set, or **silently drops it** if the set is full.
|
||||||
* Returns false if the set is full
|
*
|
||||||
|
* Returns whether the color was unique.
|
||||||
*/
|
*/
|
||||||
bool add(uint16_t color);
|
bool add(uint16_t color);
|
||||||
|
|
||||||
|
|||||||
@@ -986,12 +986,16 @@ void process() {
|
|||||||
for (auto tile : png.visitAsTiles()) {
|
for (auto tile : png.visitAsTiles()) {
|
||||||
ProtoPalette tileColors;
|
ProtoPalette tileColors;
|
||||||
AttrmapEntry &attrs = attrmap.emplace_back();
|
AttrmapEntry &attrs = attrmap.emplace_back();
|
||||||
|
uint8_t nbColorsInTile = 0;
|
||||||
|
|
||||||
for (uint32_t y = 0; y < 8; ++y) {
|
for (uint32_t y = 0; y < 8; ++y) {
|
||||||
for (uint32_t x = 0; x < 8; ++x) {
|
for (uint32_t x = 0; x < 8; ++x) {
|
||||||
Rgba color = tile.pixel(x, y);
|
Rgba color = tile.pixel(x, y);
|
||||||
if (!color.isTransparent()) { // Do not count transparency in for packing
|
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 "!",
|
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();
|
attrs.protoPaletteID = protoPalettes.size();
|
||||||
|
|||||||
@@ -17,24 +17,29 @@
|
|||||||
bool ProtoPalette::add(uint16_t color) {
|
bool ProtoPalette::add(uint16_t color) {
|
||||||
size_t i = 0;
|
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,
|
// (A linear search is better because we don't store the array size,
|
||||||
// and there are very few slots anyway)
|
// and there are very few slots anyway)
|
||||||
while (_colorIndices[i] < color) {
|
while (_colorIndices[i] < color) {
|
||||||
++i;
|
++i;
|
||||||
if (i == _colorIndices.size())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
// If we found ourselves, great!
|
|
||||||
if (_colorIndices[i] == color)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Swap entries until the end
|
// Swap entries until the end
|
||||||
while (_colorIndices[i] != UINT16_MAX) {
|
while (_colorIndices[i] != UINT16_MAX) {
|
||||||
std::swap(_colorIndices[i], color);
|
std::swap(_colorIndices[i], color);
|
||||||
++i;
|
++i;
|
||||||
if (i == _colorIndices.size())
|
if (i == _colorIndices.size()) {
|
||||||
return false; // Oh well
|
// The set is full, but doesn't include the new color.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Write that last one into the new slot
|
// Write that last one into the new slot
|
||||||
_colorIndices[i] = color;
|
_colorIndices[i] = color;
|
||||||
|
|||||||
Reference in New Issue
Block a user