diff --git a/include/gfx/main.h b/include/gfx/main.h index a5919b99..0fef433d 100644 --- a/include/gfx/main.h +++ b/include/gfx/main.h @@ -23,6 +23,7 @@ struct Options { bool horizontal; bool mirror; bool unique; + bool colorcurve; int trim; char *tilemapfile; bool tilemapout; diff --git a/src/gfx/gb.c b/src/gfx/gb.c index 0e92d576..2ff66aed 100644 --- a/src/gfx/gb.c +++ b/src/gfx/gb.c @@ -285,6 +285,30 @@ void output_attrmap_file(const struct Options *opts, free(opts->attrmapfile); } +/* + * based on the Gaussian-like curve used by SameBoy since commit + * 65dd02cc52f531dbbd3a7e6014e99d5b24e71a4c (Oct 2017) + * with ties resolved by comparing the difference of the squares. + */ +static int reverse_curve[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, + 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, + 26, 27, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 30, 30, 31, +}; + void output_palette_file(const struct Options *opts, const struct RawIndexedImage *raw_image) { @@ -297,10 +321,25 @@ void output_palette_file(const struct Options *opts, err(1, "Opening palette file '%s' failed", opts->palfile); for (i = 0; i < raw_image->num_colors; i++) { - color = - raw_image->palette[i].blue >> 3 << 10 | - raw_image->palette[i].green >> 3 << 5 | - raw_image->palette[i].red >> 3; + int r = raw_image->palette[i].red; + int g = raw_image->palette[i].green; + int b = raw_image->palette[i].blue; + + if (opts->colorcurve) { + g = (g * 4 - b) / 3; + if (g < 0) + g = 0; + + r = reverse_curve[r]; + g = reverse_curve[g]; + b = reverse_curve[b]; + } else { + r >>= 3; + g >>= 3; + b >>= 3; + } + + color = b << 10 | g << 5 | r; cur_bytes[0] = color & 0xFF; cur_bytes[1] = color >> 8; fwrite(cur_bytes, 2, 1, f); diff --git a/src/gfx/main.c b/src/gfx/main.c index 7ca526dc..06ba0eac 100644 --- a/src/gfx/main.c +++ b/src/gfx/main.c @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) depth = 2; - while ((ch = getopt(argc, argv, "Aa:Dd:Ffhmo:Tt:uPp:Vvx:")) != -1) { + while ((ch = getopt(argc, argv, "Aa:CDd:Ffhmo:Tt:uPp:Vvx:")) != -1) { switch (ch) { case 'A': opts.attrmapout = true; @@ -53,6 +53,9 @@ int main(int argc, char *argv[]) case 'a': opts.attrmapfile = optarg; break; + case 'C': + opts.colorcurve = true; + break; case 'D': opts.debug = true; break; diff --git a/src/gfx/rgbgfx.1 b/src/gfx/rgbgfx.1 index 635206c1..b5898163 100644 --- a/src/gfx/rgbgfx.1 +++ b/src/gfx/rgbgfx.1 @@ -61,6 +61,8 @@ Same as but the attrmap file output name is made by taking the input filename, removing the file extension, and appending .Pa .attrmap . +.It Fl C +Use the color curve of the Game Boy Color when generating palettes. .It Fl D Debug features are enabled. .It Fl f