Implement base palette ID

This commit is contained in:
Rangi42
2025-07-04 02:14:20 -04:00
committed by Eldred Habert
parent d7b1569ee6
commit 185a3b29e6
11 changed files with 36 additions and 12 deletions

View File

@@ -113,7 +113,7 @@ void Options::verbosePrint(uint8_t level, char const *fmt, ...) const {
}
// Short options
static char const *optstring = "-Aa:B:b:Cc:d:hi:L:mN:n:Oo:Pp:Qq:r:s:Tt:U:uVvXx:YZ";
static char const *optstring = "-Aa:B:b:Cc:d:hi:L:l:mN:n:Oo:Pp:Qq:r:s:Tt:U:uVvXx:YZ";
// Equivalent long options
// Please keep in the same order as short opts.
@@ -133,6 +133,7 @@ static option const longopts[] = {
{"help", no_argument, nullptr, 'h'},
{"input-tileset", required_argument, nullptr, 'i'},
{"slice", required_argument, nullptr, 'L'},
{"base-palette", required_argument, nullptr, 'l'},
{"mirror-tiles", no_argument, nullptr, 'm'},
{"nb-tiles", required_argument, nullptr, 'N'},
{"nb-palettes", required_argument, nullptr, 'n'},
@@ -162,9 +163,9 @@ static void printUsage() {
fputs(
"Usage: rgbgfx [-r stride] [-ChmOuVXYZ] [-v [-v ...]] [-a <attr_map> | -A]\n"
" [-b <base_ids>] [-c <colors>] [-d <depth>] [-i <tileset_file>]\n"
" [-L <slice>] [-N <nb_tiles>] [-n <nb_pals>] [-o <out_file>]\n"
" [-p <pal_file> | -P] [-q <pal_map> | -Q] [-s <nb_colors>]\n"
" [-t <tile_map> | -T] [-x <nb_tiles>] <file>\n"
" [-L <slice>] [-l <base_pal>] [-N <nb_tiles>] [-n <nb_pals>]\n"
" [-o <out_file>] [-p <pal_file> | -P] [-q <pal_map> | -Q]\n"
" [-s <nb_colors>] [-t <tile_map> | -T] [-x <nb_tiles>] <file>\n"
"Useful options:\n"
" -m, --mirror-tiles optimize out mirrored tiles\n"
" -o, --output <path> output the tile data to this path\n"
@@ -481,6 +482,16 @@ static char *parseArgv(int argc, char *argv[]) {
error("Unexpected extra characters after slice spec in \"%s\"", musl_optarg);
}
break;
case 'l':
number = parseNumber(arg, "Base palette ID", 0);
if (*arg != '\0') {
error("Base palette ID must be a valid number, not \"%s\"", musl_optarg);
} else if (number >= 256) {
error("Base palette ID must be below 256");
} else {
options.basePalID = number;
}
break;
case 'm':
options.allowMirroringX = true; // Imply `-X`
options.allowMirroringY = true; // Imply `-Y`
@@ -876,6 +887,7 @@ int main(int argc, char *argv[]) {
options.baseTileIDs[0],
options.baseTileIDs[1]
);
fprintf(stderr, "\tBase palette ID: %" PRIu8 "\n", options.basePalID);
fprintf(
stderr,
"\tMaximum %" PRIu16 " tiles in bank 0, %" PRIu16 " in bank 1\n",

View File

@@ -928,9 +928,9 @@ static void outputUnoptimizedMaps(
(*tilemapOutput)
->sputc((attr.isBackgroundTile() ? 0 : tileID) + options.baseTileIDs[bank]);
}
uint8_t palID = attr.getPalID(mappings);
uint8_t palID = attr.getPalID(mappings) + options.basePalID;
if (attrmapOutput.has_value()) {
(*attrmapOutput)->sputc((palID & 7) | bank << 3); // The other flags are all 0
(*attrmapOutput)->sputc((palID & 0b111) | bank << 3); // The other flags are all 0
}
if (palmapOutput.has_value()) {
(*palmapOutput)->sputc(palID);
@@ -1112,7 +1112,7 @@ static void outputAttrmap(
for (AttrmapEntry const &entry : attrmap) {
uint8_t attr = entry.xFlip << 5 | entry.yFlip << 6;
attr |= entry.bank << 3;
attr |= entry.getPalID(mappings) & 7;
attr |= (entry.getPalID(mappings) + options.basePalID) & 0b111;
output->sputc(attr);
}
}
@@ -1128,7 +1128,7 @@ static void outputPalmap(
}
for (AttrmapEntry const &entry : attrmap) {
output->sputc(entry.getPalID(mappings));
output->sputc(entry.getPalID(mappings) + options.basePalID);
}
}

View File

@@ -289,10 +289,10 @@ void reverse() {
uint8_t attr = (*attrmap)[index];
size_t tx = index % width, ty = index / width;
if ((attr & 0b111) > palettes.size()) {
if (uint8_t palID = (attr & 0b111) - options.basePalID; palID > palettes.size()) {
error(
"Attribute map references palette #%u at (%zu, %zu), but there are only %zu!",
attr & 0b111,
palID,
tx,
ty,
palettes.size()
@@ -356,7 +356,7 @@ void reverse() {
size_t tx = index % width, ty = index / width;
uint8_t tileID = (*tilemap)[index];
uint8_t attr = (*attrmap)[index];
bool bank = attr & 0x08;
bool bank = attr & 0b1000;
if (uint8_t tileOfs = tileID - options.baseTileIDs[bank];
tileOfs >= options.maxNbTiles[bank]) {
@@ -511,7 +511,7 @@ void reverse() {
: index;
// This should have been enforced by the earlier checking.
assume(tileOfs < nbTiles + options.trim);
size_t palID = palmap ? (*palmap)[index] : attribute & 0b111;
size_t palID = (palmap ? (*palmap)[index] : attribute & 0b111) - options.basePalID;
assume(palID < palettes.size()); // Should be ensured on data read
// We do not have data for tiles trimmed with `-x`, so assume they are "blank"