Format CGB colors in error/verbose messages as "GB:rr,gg,bb"

These should be more debuggable than packed "$xxxx" format.
This commit is contained in:
Rangi
2026-07-14 10:34:27 -04:00
committed by Rangi
parent 7e2a3491a5
commit 9a15b723f2
8 changed files with 79 additions and 72 deletions
+20 -2
View File
@@ -4,6 +4,9 @@
#define RGBDS_GFX_RGBA_HPP
#include <stdint.h>
#include <string>
#include "helpers.hpp" // literal_strlen
struct Rgba {
uint8_t red;
@@ -30,8 +33,8 @@ struct Rgba {
};
}
// Returns this RGBA as a 32-bit number that can be printed in hex (`%08x`) to yield its CSS
// representation
// Returns this RGBA as a 32-bit number that can be printed in hex (`#%08x`)
// to yield its CSS representation (`#rrggbbaa`).
uint32_t toCSS() const {
constexpr auto shl = [](uint8_t val, unsigned shift) {
return static_cast<uint32_t>(val) << shift;
@@ -56,4 +59,19 @@ struct Rgba {
uint8_t grayIndex() const;
};
// Returns a CGB color as a rendered string "GB:rr,gg,bb" or "transparent".
std::string toCGB(uint16_t color);
std::string listCGBColors(auto const &list) {
std::string buf;
for (uint16_t color : list) {
buf += toCGB(color) + "; ";
}
static constexpr size_t n = literal_strlen("; ");
if (buf.size() >= n) {
buf.erase(buf.size() - n, n);
}
return buf;
}
#endif // RGBDS_GFX_RGBA_HPP
+7 -5
View File
@@ -260,12 +260,14 @@ static void verboseOutputAssignments(
) {
verboseDo(VERB_INFO, [&]() {
for (AssignedSets const &assignment : assignments) {
fputs("{ ", stderr);
fputs("- { ", stderr);
for (ColorSetAttrs const &attrs : assignment) {
fprintf(stderr, "[%zu] ", attrs.colorSetIndex);
for (uint16_t colorIndex : colorSets[attrs.colorSetIndex]) {
fprintf(stderr, "%04" PRIx16 ", ", colorIndex);
}
fprintf(
stderr,
"[%zu] %s ",
attrs.colorSetIndex,
listCGBColors(colorSets[attrs.colorSetIndex]).c_str()
);
}
fprintf(stderr, "} (volume = %zu)\n", assignment.volume());
}
+27 -53
View File
@@ -200,11 +200,11 @@ struct Image {
if (std::pair fused{color.toCSS(), other->toCSS()};
fusions.find(fused) == fusions.end()) {
warnx(
"Colors #%08x and #%08x both reduce to the same Game Boy color $%04x "
"Colors #%08x and #%08x both reduce to the same RGB555 color %s "
"(first seen at (%" PRIu32 ", %" PRIu32 "))",
fused.first,
fused.second,
color.cgbColor(),
toCGB(color.cgbColor()).c_str(),
x,
y
);
@@ -411,15 +411,6 @@ static std::pair<std::vector<size_t>, std::vector<Palette>>
}
}
auto listColors = [](auto const &list) {
static char buf[sizeof(", $xxxx, $xxxx, $xxxx, $xxxx")];
char *ptr = buf;
for (uint16_t color : list) {
ptr += snprintf(ptr, sizeof(", $xxxx"), ", $%04x", color);
}
return &buf[literal_strlen(", ")];
};
// Iterate through color sets, and try mapping them to the specified palettes
std::vector<size_t> mappings(colorSets.size());
bool bad = false;
@@ -435,7 +426,10 @@ static std::pair<std::vector<size_t>, std::vector<Palette>>
if (iter == palettes.end()) {
assume(!colorSet.empty());
error("Failed to fit tile colors [%s] in specified palettes", listColors(colorSet));
error(
"Failed to fit tile colors [%s] in specified palettes",
listCGBColors(colorSet).c_str()
);
bad = true;
}
mappings[i] = iter - palettes.begin(); // Bogus value, but whatever
@@ -447,7 +441,7 @@ static std::pair<std::vector<size_t>, std::vector<Palette>>
palettes.size() == 1 ? " was" : "s were"
);
for (Palette const &pal : palettes) {
fprintf(stderr, " [%s]\n", listColors(pal));
fprintf(stderr, " - [%s]\n", listCGBColors(pal).c_str());
}
giveUp();
}
@@ -459,11 +453,7 @@ static void outputPalettes(std::vector<Palette> const &palettes) {
// LCOV_EXCL_START
verboseDo(VERB_INFO, [&]() {
for (Palette const &palette : palettes) {
fputs("{ ", stderr);
for (uint16_t colorIndex : palette) {
fprintf(stderr, "%04" PRIx16 ", ", colorIndex);
}
fputs("}\n", stderr);
fprintf(stderr, "- { %s }\n", listCGBColors(palette).c_str());
}
});
// LCOV_EXCL_STOP
@@ -1048,23 +1038,16 @@ void process() {
case ColorSet::STRICT_SUPERSET:
// Override the previous color set that this one is a strict superset of
verboseDo(VERB_DEBUG, [&]() {
fprintf(
stderr,
"- Tile (%" PRIu32 ", %" PRIu32 ") overrides color set #%zu: [",
tile.x,
tile.y,
n
);
for (uint16_t color : colorSets[n]) {
fprintf(stderr, "$%04x, ", color);
}
fputs("] becomes [", stderr);
for (uint16_t color : colorSet) {
fprintf(stderr, "$%04x, ", color);
}
fputs("]\n", stderr);
});
verbosePrint(
VERB_DEBUG,
"- Tile (%" PRIu32 ", %" PRIu32
") overrides color set #%zu: [%s] becomes [%s]\n",
tile.x,
tile.y,
n,
listCGBColors(colorSets[n]).c_str(),
listCGBColors(colorSet).c_str()
);
colorSets[n] = colorSet;
// Remove any other color sets that we are also a strict superset of
@@ -1112,19 +1095,14 @@ void process() {
attrs.colorSetID = colorSets.size();
colorSets.push_back(colorSet);
verboseDo(VERB_DEBUG, [&]() {
fprintf(
stderr,
"- Tile (%" PRIu32 ", %" PRIu32 ") adds color set #%zu: [",
tile.x,
tile.y,
attrs.colorSetID
);
for (uint16_t color : colorSet) {
fprintf(stderr, "$%04x, ", color);
}
fputs("]\n", stderr);
});
verbosePrint(
VERB_DEBUG,
"- Tile (%" PRIu32 ", %" PRIu32 ") adds color set #%zu: [%s]\n",
tile.x,
tile.y,
attrs.colorSetID,
listCGBColors(colorSet).c_str()
);
continue_visiting_tiles:;
}
@@ -1138,11 +1116,7 @@ continue_visiting_tiles:;
// LCOV_EXCL_START
verboseDo(VERB_INFO, [&]() {
for (ColorSet const &colorSet : colorSets) {
fputs("[ ", stderr);
for (uint16_t color : colorSet) {
fprintf(stderr, "$%04x, ", color);
}
fputs("]\n", stderr);
fprintf(stderr, "- [%s]\n", listCGBColors(colorSet).c_str());
}
});
// LCOV_EXCL_STOP
+13
View File
@@ -4,6 +4,7 @@
#include <algorithm>
#include <array>
#include <inttypes.h>
#include <math.h>
#include <stdint.h>
@@ -11,6 +12,18 @@
#include "gfx/main.hpp" // options
std::string toCGB(uint16_t color) {
if (color == Rgba::transparent) {
return "transparent"; // same length as "GB:rr,gg,bb"
}
uint8_t red = color & 0b11111;
uint8_t green = color >> 5 & 0b11111;
uint8_t blue = color >> 10 & 0b11111;
char buf[sizeof("GB:rr,gg,bb")];
snprintf(buf, sizeof(buf), "GB:%02" PRIu8 ",%02" PRIu8 ",%02" PRIu8, red, green, blue);
return buf;
}
// Based on inverting the "Modern - Accurate" formula used by SameBoy
// since commit b5a611c5db46d6a0649d04d24d8d6339200f9ca1 (Dec 2020),
// with gaps in the scale curve filled by polynomial interpolation.
+2 -2
View File
@@ -1,4 +1,4 @@
error: Failed to fit tile colors [$1527, $15cc, $1ab4] in specified palettes
error: Failed to fit tile colors [GB:07,09,05; GB:12,14,05; GB:20,21,06] in specified palettes
note: The following palette was specified:
[$1ab4, $15cc]
- [GB:20,21,06; GB:12,14,05]
Conversion aborted after 1 error
+6 -6
View File
@@ -1,8 +1,8 @@
error: Failed to fit tile colors [$6c8a, $7f55, $7fff] in specified palettes
error: Failed to fit tile colors [GB:10,04,27; GB:21,26,31; GB:31,31,31] in specified palettes
note: The following palettes were specified:
[$5f77, $213d, $41a6, $40ee]
[$3f65, $36b3, $262a, $50b0]
[$53c3, $3f65, $36b3]
[$5f77, $267c, $41a6]
[$267c, $213d, $40ee]
- [GB:23,27,23; GB:29,09,08; GB:06,13,16; GB:14,07,16]
- [GB:05,27,15; GB:19,21,13; GB:10,17,09; GB:16,05,20]
- [GB:03,30,20; GB:05,27,15; GB:19,21,13]
- [GB:23,27,23; GB:28,19,09; GB:06,13,16]
- [GB:28,19,09; GB:29,09,08; GB:14,07,16]
Conversion aborted after 1 error
+3 -3
View File
@@ -1,5 +1,5 @@
error: Failed to fit tile colors [$6c8a, $7f55, $7fff] in specified palettes
error: Failed to fit tile colors [GB:10,04,27; GB:21,26,31; GB:31,31,31] in specified palettes
note: The following palettes were specified:
[$7fff, $7f55]
[$7fff, $6c8a]
- [GB:31,31,31; GB:21,26,31]
- [GB:31,31,31; GB:10,04,27]
Conversion aborted after 1 error
+1 -1
View File
@@ -1,3 +1,3 @@
warning: Colors #a9b9c9ff and #aabbccff both reduce to the same Game Boy color $66f5 (first seen at (1, 1))
warning: Colors #a9b9c9ff and #aabbccff both reduce to the same RGB555 color GB:21,23,25 (first seen at (1, 1))
FATAL: Tile (0, 0) contains the background color (#aabbccff)
Conversion aborted after 1 error