mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Add proper error message for bad manual palettes
This commit is contained in:
@@ -67,8 +67,21 @@ struct Options {
|
|||||||
|
|
||||||
extern Options options;
|
extern Options options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the error count, and exits with failure
|
||||||
|
*/
|
||||||
|
[[noreturn]] void giveUp();
|
||||||
|
/**
|
||||||
|
* Prints a warning, and does not change the error count
|
||||||
|
*/
|
||||||
void warning(char const *fmt, ...);
|
void warning(char const *fmt, ...);
|
||||||
|
/**
|
||||||
|
* Prints an error, and increments the error count
|
||||||
|
*/
|
||||||
void error(char const *fmt, ...);
|
void error(char const *fmt, ...);
|
||||||
|
/**
|
||||||
|
* Prints a fatal error, increments the error count, and gives up
|
||||||
|
*/
|
||||||
[[noreturn]] void fatal(char const *fmt, ...);
|
[[noreturn]] void fatal(char const *fmt, ...);
|
||||||
|
|
||||||
struct Palette {
|
struct Palette {
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ Options options;
|
|||||||
char const *externalPalSpec = nullptr;
|
char const *externalPalSpec = nullptr;
|
||||||
static uintmax_t nbErrors;
|
static uintmax_t nbErrors;
|
||||||
|
|
||||||
|
[[noreturn]] void giveUp() {
|
||||||
|
fprintf(stderr, "Conversion aborted after %ju error%s\n", nbErrors, nbErrors == 1 ? "" : "s");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
void warning(char const *fmt, ...) {
|
void warning(char const *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@@ -72,8 +77,7 @@ void error(char const *fmt, ...) {
|
|||||||
if (nbErrors != std::numeric_limits<decltype(nbErrors)>::max())
|
if (nbErrors != std::numeric_limits<decltype(nbErrors)>::max())
|
||||||
nbErrors++;
|
nbErrors++;
|
||||||
|
|
||||||
fprintf(stderr, "Conversion aborted after %ju error%s\n", nbErrors, nbErrors == 1 ? "" : "s");
|
giveUp();
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Options::verbosePrint(uint8_t level, char const *fmt, ...) const {
|
void Options::verbosePrint(uint8_t level, char const *fmt, ...) const {
|
||||||
@@ -718,9 +722,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// Do not do anything if option parsing went wrong
|
// Do not do anything if option parsing went wrong
|
||||||
if (nbErrors) {
|
if (nbErrors) {
|
||||||
fprintf(stderr, "Conversion aborted after %ju error%s\n", nbErrors,
|
giveUp();
|
||||||
nbErrors == 1 ? "" : "s");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.reverse()) {
|
if (options.reverse()) {
|
||||||
@@ -730,9 +732,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nbErrors) {
|
if (nbErrors) {
|
||||||
fprintf(stderr, "Conversion aborted after %ju error%s\n", nbErrors,
|
giveUp();
|
||||||
nbErrors == 1 ? "" : "s");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <cstdio>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -557,8 +558,6 @@ static std::tuple<DefaultInitVec<size_t>, std::vector<Palette>>
|
|||||||
// Fill in the palette spec
|
// Fill in the palette spec
|
||||||
options.palSpec.emplace_back(); // A single palette, with `#00000000`s (transparent)
|
options.palSpec.emplace_back(); // A single palette, with `#00000000`s (transparent)
|
||||||
assert(options.palSpec.size() == 1);
|
assert(options.palSpec.size() == 1);
|
||||||
// TODO: abort if ignored colors are being used; do it now for a friendlier error
|
|
||||||
// message
|
|
||||||
if (embPalSize > options.maxOpaqueColors()) { // Ignore extraneous colors if they are unused
|
if (embPalSize > options.maxOpaqueColors()) { // Ignore extraneous colors if they are unused
|
||||||
embPalSize = options.maxOpaqueColors();
|
embPalSize = options.maxOpaqueColors();
|
||||||
}
|
}
|
||||||
@@ -571,13 +570,24 @@ static std::tuple<DefaultInitVec<size_t>, std::vector<Palette>>
|
|||||||
// Convert the palette spec to actual palettes
|
// Convert the palette spec to actual palettes
|
||||||
std::vector<Palette> palettes(options.palSpec.size());
|
std::vector<Palette> palettes(options.palSpec.size());
|
||||||
for (auto [spec, pal] : zip(options.palSpec, palettes)) {
|
for (auto [spec, pal] : zip(options.palSpec, palettes)) {
|
||||||
for (size_t i = 0; i < options.nbColorsPerPal; ++i) {
|
for (size_t i = 0; i < options.nbColorsPerPal && spec[i].isOpaque(); ++i) {
|
||||||
pal[i] = spec[i].cgbColor();
|
pal[i] = spec[i].cgbColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto listColors = [](auto const &list) {
|
||||||
|
static char buf[sizeof(", $XXXX, $XXXX, $XXXX, $XXXX")];
|
||||||
|
char *ptr = buf;
|
||||||
|
for (uint16_t cgbColor : list) {
|
||||||
|
sprintf(ptr, ", $%04x", cgbColor);
|
||||||
|
ptr += 7;
|
||||||
|
}
|
||||||
|
return &buf[2];
|
||||||
|
};
|
||||||
|
|
||||||
// Iterate through proto-palettes, and try mapping them to the specified palettes
|
// Iterate through proto-palettes, and try mapping them to the specified palettes
|
||||||
DefaultInitVec<size_t> mappings(protoPalettes.size());
|
DefaultInitVec<size_t> mappings(protoPalettes.size());
|
||||||
|
bool bad = false;
|
||||||
for (size_t i = 0; i < protoPalettes.size(); ++i) {
|
for (size_t i = 0; i < protoPalettes.size(); ++i) {
|
||||||
ProtoPalette const &protoPal = protoPalettes[i];
|
ProtoPalette const &protoPal = protoPalettes[i];
|
||||||
// Find the palette...
|
// Find the palette...
|
||||||
@@ -587,8 +597,21 @@ static std::tuple<DefaultInitVec<size_t>, std::vector<Palette>>
|
|||||||
return std::find(pal.begin(), pal.end(), color) != pal.end();
|
return std::find(pal.begin(), pal.end(), color) != pal.end();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
assert(iter != palettes.end()); // TODO: produce a proper error message
|
|
||||||
mappings[i] = iter - palettes.begin();
|
if (iter == palettes.end()) {
|
||||||
|
assert(!protoPal.empty());
|
||||||
|
error("Could not fit tile colors [%s] in specified palettes", listColors(protoPal));
|
||||||
|
bad = true;
|
||||||
|
}
|
||||||
|
mappings[i] = iter - palettes.begin(); // Bogus value, but whatever
|
||||||
|
}
|
||||||
|
if (bad) {
|
||||||
|
fprintf(stderr, "note: The following palette%s specified:\n",
|
||||||
|
palettes.size() == 1 ? " was" : "s were");
|
||||||
|
for (Palette const &pal : palettes) {
|
||||||
|
fprintf(stderr, " [%s]\n", listColors(pal));
|
||||||
|
}
|
||||||
|
giveUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {mappings, palettes};
|
return {mappings, palettes};
|
||||||
|
|||||||
6
test/gfx/bad_manual_pals.err
Normal file
6
test/gfx/bad_manual_pals.err
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
error: Could not fit tile colors [$6c8a, $7f55, $7fff] in specified palettes
|
||||||
|
error: Could not fit tile colors [$6c8a, $7f55] in specified palettes
|
||||||
|
note: The following palettes were specified:
|
||||||
|
[$7fff, $7f55]
|
||||||
|
[$7fff, $6c8a]
|
||||||
|
Conversion aborted after 2 errors
|
||||||
1
test/gfx/bad_manual_pals.flags
Normal file
1
test/gfx/bad_manual_pals.flags
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-c #fff,#a9d4fe:#fff,#5721d9
|
||||||
BIN
test/gfx/bad_manual_pals.png
Normal file
BIN
test/gfx/bad_manual_pals.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 712 B |
Reference in New Issue
Block a user