diff --git a/include/gfx/rgba.hpp b/include/gfx/rgba.hpp index b86968b9..9693aa88 100644 --- a/include/gfx/rgba.hpp +++ b/include/gfx/rgba.hpp @@ -4,6 +4,9 @@ #define RGBDS_GFX_RGBA_HPP #include +#include + +#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(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 diff --git a/src/gfx/pal_packing.cpp b/src/gfx/pal_packing.cpp index 04d2b43b..b09bac62 100644 --- a/src/gfx/pal_packing.cpp +++ b/src/gfx/pal_packing.cpp @@ -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()); } diff --git a/src/gfx/process.cpp b/src/gfx/process.cpp index 54c28f12..7b13c92e 100644 --- a/src/gfx/process.cpp +++ b/src/gfx/process.cpp @@ -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> } } - 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 mappings(colorSets.size()); bool bad = false; @@ -435,7 +426,10 @@ static std::pair, std::vector> 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> 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 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 diff --git a/src/gfx/rgba.cpp b/src/gfx/rgba.cpp index ef37eace..1526e0fc 100644 --- a/src/gfx/rgba.cpp +++ b/src/gfx/rgba.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -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. diff --git a/test/gfx/alpha_embedded.err b/test/gfx/alpha_embedded.err index 8efb02a9..eb832e43 100644 --- a/test/gfx/alpha_embedded.err +++ b/test/gfx/alpha_embedded.err @@ -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 diff --git a/test/gfx/at-file-ref.err b/test/gfx/at-file-ref.err index f480fa6e..ec7edddf 100644 --- a/test/gfx/at-file-ref.err +++ b/test/gfx/at-file-ref.err @@ -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 diff --git a/test/gfx/bad_manual_pals.err b/test/gfx/bad_manual_pals.err index 0815a1ff..89c68717 100644 --- a/test/gfx/bad_manual_pals.err +++ b/test/gfx/bad_manual_pals.err @@ -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 diff --git a/test/gfx/bg_fuse.err b/test/gfx/bg_fuse.err index 439c4aa5..feb43b0d 100644 --- a/test/gfx/bg_fuse.err +++ b/test/gfx/bg_fuse.err @@ -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