mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Implement base palette ID
This commit is contained in:
@@ -43,6 +43,7 @@ struct Options {
|
|||||||
uint32_t right() const { return left + width * 8; }
|
uint32_t right() const { return left + width * 8; }
|
||||||
uint32_t bottom() const { return top + height * 8; }
|
uint32_t bottom() const { return top + height * 8; }
|
||||||
} inputSlice{0, 0, 0, 0}; // -L (margins in clockwise order, like CSS)
|
} inputSlice{0, 0, 0, 0}; // -L (margins in clockwise order, like CSS)
|
||||||
|
uint8_t basePalID = 0; // -l
|
||||||
std::array<uint16_t, 2> maxNbTiles{UINT16_MAX, 0}; // -N
|
std::array<uint16_t, 2> maxNbTiles{UINT16_MAX, 0}; // -N
|
||||||
uint16_t nbPalettes = 8; // -n
|
uint16_t nbPalettes = 8; // -n
|
||||||
std::string output{}; // -o
|
std::string output{}; // -o
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
.Op Fl d Ar depth
|
.Op Fl d Ar depth
|
||||||
.Op Fl i Ar input_tiles
|
.Op Fl i Ar input_tiles
|
||||||
.Op Fl L Ar slice
|
.Op Fl L Ar slice
|
||||||
|
.Op Fl l Ar base_pal
|
||||||
.Op Fl N Ar nb_tiles
|
.Op Fl N Ar nb_tiles
|
||||||
.Op Fl n Ar nb_pals
|
.Op Fl n Ar nb_pals
|
||||||
.Op Fl o Ar out_file
|
.Op Fl o Ar out_file
|
||||||
@@ -261,6 +262,11 @@ The first number pair specifies the X and Y coordinates of the top-left pixel th
|
|||||||
The second number pair specifies how many tiles to process horizontally and vertically, respectively.
|
The second number pair specifies how many tiles to process horizontally and vertically, respectively.
|
||||||
.Pp
|
.Pp
|
||||||
.Fl L Sy is ignored in reverse mode , No no padding is inserted .
|
.Fl L Sy is ignored in reverse mode , No no padding is inserted .
|
||||||
|
.It Fl l Ar base_pal , Fl \-base-palette Ar base_pal
|
||||||
|
Set the base ID for attribute map and palette map output.
|
||||||
|
.Ar base_pal
|
||||||
|
should be a number between 0 and 255.
|
||||||
|
It defaults to 0.
|
||||||
.It Fl m , Fl \-mirror-tiles
|
.It Fl m , Fl \-mirror-tiles
|
||||||
Deduplicate tiles that are horizontally and/or vertically symmetrical mirror images of each other.
|
Deduplicate tiles that are horizontally and/or vertically symmetrical mirror images of each other.
|
||||||
Only one of each unique tile will be saved in the tile data file, with mirror images counting as duplicates.
|
Only one of each unique tile will be saved in the tile data file, with mirror images counting as duplicates.
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ void Options::verbosePrint(uint8_t level, char const *fmt, ...) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Short options
|
// 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
|
// Equivalent long options
|
||||||
// Please keep in the same order as short opts.
|
// Please keep in the same order as short opts.
|
||||||
@@ -133,6 +133,7 @@ static option const longopts[] = {
|
|||||||
{"help", no_argument, nullptr, 'h'},
|
{"help", no_argument, nullptr, 'h'},
|
||||||
{"input-tileset", required_argument, nullptr, 'i'},
|
{"input-tileset", required_argument, nullptr, 'i'},
|
||||||
{"slice", required_argument, nullptr, 'L'},
|
{"slice", required_argument, nullptr, 'L'},
|
||||||
|
{"base-palette", required_argument, nullptr, 'l'},
|
||||||
{"mirror-tiles", no_argument, nullptr, 'm'},
|
{"mirror-tiles", no_argument, nullptr, 'm'},
|
||||||
{"nb-tiles", required_argument, nullptr, 'N'},
|
{"nb-tiles", required_argument, nullptr, 'N'},
|
||||||
{"nb-palettes", required_argument, nullptr, 'n'},
|
{"nb-palettes", required_argument, nullptr, 'n'},
|
||||||
@@ -162,9 +163,9 @@ static void printUsage() {
|
|||||||
fputs(
|
fputs(
|
||||||
"Usage: rgbgfx [-r stride] [-ChmOuVXYZ] [-v [-v ...]] [-a <attr_map> | -A]\n"
|
"Usage: rgbgfx [-r stride] [-ChmOuVXYZ] [-v [-v ...]] [-a <attr_map> | -A]\n"
|
||||||
" [-b <base_ids>] [-c <colors>] [-d <depth>] [-i <tileset_file>]\n"
|
" [-b <base_ids>] [-c <colors>] [-d <depth>] [-i <tileset_file>]\n"
|
||||||
" [-L <slice>] [-N <nb_tiles>] [-n <nb_pals>] [-o <out_file>]\n"
|
" [-L <slice>] [-l <base_pal>] [-N <nb_tiles>] [-n <nb_pals>]\n"
|
||||||
" [-p <pal_file> | -P] [-q <pal_map> | -Q] [-s <nb_colors>]\n"
|
" [-o <out_file>] [-p <pal_file> | -P] [-q <pal_map> | -Q]\n"
|
||||||
" [-t <tile_map> | -T] [-x <nb_tiles>] <file>\n"
|
" [-s <nb_colors>] [-t <tile_map> | -T] [-x <nb_tiles>] <file>\n"
|
||||||
"Useful options:\n"
|
"Useful options:\n"
|
||||||
" -m, --mirror-tiles optimize out mirrored tiles\n"
|
" -m, --mirror-tiles optimize out mirrored tiles\n"
|
||||||
" -o, --output <path> output the tile data to this path\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);
|
error("Unexpected extra characters after slice spec in \"%s\"", musl_optarg);
|
||||||
}
|
}
|
||||||
break;
|
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':
|
case 'm':
|
||||||
options.allowMirroringX = true; // Imply `-X`
|
options.allowMirroringX = true; // Imply `-X`
|
||||||
options.allowMirroringY = true; // Imply `-Y`
|
options.allowMirroringY = true; // Imply `-Y`
|
||||||
@@ -876,6 +887,7 @@ int main(int argc, char *argv[]) {
|
|||||||
options.baseTileIDs[0],
|
options.baseTileIDs[0],
|
||||||
options.baseTileIDs[1]
|
options.baseTileIDs[1]
|
||||||
);
|
);
|
||||||
|
fprintf(stderr, "\tBase palette ID: %" PRIu8 "\n", options.basePalID);
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
"\tMaximum %" PRIu16 " tiles in bank 0, %" PRIu16 " in bank 1\n",
|
"\tMaximum %" PRIu16 " tiles in bank 0, %" PRIu16 " in bank 1\n",
|
||||||
|
|||||||
@@ -928,9 +928,9 @@ static void outputUnoptimizedMaps(
|
|||||||
(*tilemapOutput)
|
(*tilemapOutput)
|
||||||
->sputc((attr.isBackgroundTile() ? 0 : tileID) + options.baseTileIDs[bank]);
|
->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()) {
|
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()) {
|
if (palmapOutput.has_value()) {
|
||||||
(*palmapOutput)->sputc(palID);
|
(*palmapOutput)->sputc(palID);
|
||||||
@@ -1112,7 +1112,7 @@ static void outputAttrmap(
|
|||||||
for (AttrmapEntry const &entry : attrmap) {
|
for (AttrmapEntry const &entry : attrmap) {
|
||||||
uint8_t attr = entry.xFlip << 5 | entry.yFlip << 6;
|
uint8_t attr = entry.xFlip << 5 | entry.yFlip << 6;
|
||||||
attr |= entry.bank << 3;
|
attr |= entry.bank << 3;
|
||||||
attr |= entry.getPalID(mappings) & 7;
|
attr |= (entry.getPalID(mappings) + options.basePalID) & 0b111;
|
||||||
output->sputc(attr);
|
output->sputc(attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1128,7 +1128,7 @@ static void outputPalmap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (AttrmapEntry const &entry : attrmap) {
|
for (AttrmapEntry const &entry : attrmap) {
|
||||||
output->sputc(entry.getPalID(mappings));
|
output->sputc(entry.getPalID(mappings) + options.basePalID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -289,10 +289,10 @@ void reverse() {
|
|||||||
uint8_t attr = (*attrmap)[index];
|
uint8_t attr = (*attrmap)[index];
|
||||||
size_t tx = index % width, ty = index / width;
|
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(
|
error(
|
||||||
"Attribute map references palette #%u at (%zu, %zu), but there are only %zu!",
|
"Attribute map references palette #%u at (%zu, %zu), but there are only %zu!",
|
||||||
attr & 0b111,
|
palID,
|
||||||
tx,
|
tx,
|
||||||
ty,
|
ty,
|
||||||
palettes.size()
|
palettes.size()
|
||||||
@@ -356,7 +356,7 @@ void reverse() {
|
|||||||
size_t tx = index % width, ty = index / width;
|
size_t tx = index % width, ty = index / width;
|
||||||
uint8_t tileID = (*tilemap)[index];
|
uint8_t tileID = (*tilemap)[index];
|
||||||
uint8_t attr = (*attrmap)[index];
|
uint8_t attr = (*attrmap)[index];
|
||||||
bool bank = attr & 0x08;
|
bool bank = attr & 0b1000;
|
||||||
|
|
||||||
if (uint8_t tileOfs = tileID - options.baseTileIDs[bank];
|
if (uint8_t tileOfs = tileID - options.baseTileIDs[bank];
|
||||||
tileOfs >= options.maxNbTiles[bank]) {
|
tileOfs >= options.maxNbTiles[bank]) {
|
||||||
@@ -511,7 +511,7 @@ void reverse() {
|
|||||||
: index;
|
: index;
|
||||||
// This should have been enforced by the earlier checking.
|
// This should have been enforced by the earlier checking.
|
||||||
assume(tileOfs < nbTiles + options.trim);
|
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
|
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"
|
// We do not have data for tiles trimmed with `-x`, so assume they are "blank"
|
||||||
|
|||||||
3
test/gfx/base_ids.flags
Normal file
3
test/gfx/base_ids.flags
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-b 15
|
||||||
|
-l 3
|
||||||
|
-m
|
||||||
BIN
test/gfx/base_ids.out.2bpp
Normal file
BIN
test/gfx/base_ids.out.2bpp
Normal file
Binary file not shown.
1
test/gfx/base_ids.out.attrmap
Normal file
1
test/gfx/base_ids.out.attrmap
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
BIN
test/gfx/base_ids.out.pal
Normal file
BIN
test/gfx/base_ids.out.pal
Normal file
Binary file not shown.
1
test/gfx/base_ids.out.tilemap
Normal file
1
test/gfx/base_ids.out.tilemap
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
BIN
test/gfx/base_ids.png
Normal file
BIN
test/gfx/base_ids.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 184 B |
Reference in New Issue
Block a user