Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort Pokemon and trainer sprite palettes, with Makefile-specified exceptions #1137

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 38 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,45 @@ gfx/pokemon/girafarig/front.animated.tilemap: gfx/pokemon/girafarig/front.2bpp g
tools/pokemon_animation_graphics --girafarig -t $@ $^


### Misc file-specific graphics rules
### Pokemon and trainer sprite rules

gfx/pokemon/%/back.2bpp: rgbgfx += --columns
gfx/pokemon/%/back.2bpp: gfx/pokemon/%/back.png gfx/pokemon/%/normal.gbcpal
$(RGBGFX) $(rgbgfx) --colors gbc:$(word 2,$^) -o $@ $<
gfx/pokemon/%/front.2bpp: gfx/pokemon/%/front.png gfx/pokemon/%/normal.gbcpal
$(RGBGFX) $(rgbgfx) --colors gbc:$(word 2,$^) -o $@ $<
gfx/pokemon/%/normal.gbcpal: gfx/pokemon/%/front.gbcpal gfx/pokemon/%/back.gbcpal
tools/gbcpal $(tools/gbcpal) $@ $^

gfx/trainers/%.2bpp: rgbgfx += --columns
gfx/trainers/%.2bpp: gfx/trainers/%.png gfx/trainers/%.gbcpal
$(RGBGFX) $(rgbgfx) --colors gbc:$(word 2,$^) -o $@ $<

# Egg does not have a back sprite, so it only uses front.gbcpal
gfx/pokemon/egg/front.2bpp: gfx/pokemon/egg/front.png gfx/pokemon/egg/front.gbcpal
gfx/pokemon/egg/front.2bpp: rgbgfx += --colors gbc:$(word 2,$^)
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved

gfx/pokemon/%/back.2bpp: rgbgfx += --columns --colors embedded
gfx/pokemon/%/front.2bpp: rgbgfx += --colors embedded
# Unown letters share one normal.pal, so they don't already build each normal.gbcpal
$(foreach png, $(wildcard gfx/pokemon/unown_*/front.png),\
$(eval $(png:.png=.2bpp): $(png) $(png:front.png=normal.gbcpal)))
gfx/pokemon/unown_%/front.2bpp: rgbgfx += --colors gbc:$(@:front.2bpp=normal.gbcpal)

gfx/trainers/%.2bpp: rgbgfx += --columns --colors embedded

### Misc file-specific graphics rules

gfx/pokemon/egg/unused_front.2bpp: rgbgfx += --columns

gfx/pokemon/spearow/normal.gbcpal: tools/gbcpal += --reverse
gfx/pokemon/fearow/normal.gbcpal: tools/gbcpal += --reverse
gfx/pokemon/farfetch_d/normal.gbcpal: tools/gbcpal += --reverse
gfx/pokemon/hitmonlee/normal.gbcpal: tools/gbcpal += --reverse
gfx/pokemon/scyther/normal.gbcpal: tools/gbcpal += --reverse
gfx/pokemon/jynx/normal.gbcpal: tools/gbcpal += --reverse
gfx/pokemon/porygon/normal.gbcpal: tools/gbcpal += --reverse
gfx/pokemon/porygon2/normal.gbcpal: tools/gbcpal += --reverse

gfx/trainers/swimmer_m.gbcpal: tools/gbcpal += --reverse

gfx/new_game/shrink1.2bpp: rgbgfx += --columns
gfx/new_game/shrink2.2bpp: rgbgfx += --columns

Expand Down Expand Up @@ -307,15 +337,16 @@ gfx/mobile/stadium2_n64.2bpp: tools/gfx += --trim-whitespace
%.2bpp: %.png
$(RGBGFX) $(rgbgfx) -o $@ $<
$(if $(tools/gfx),\
tools/gfx $(tools/gfx) -o $@ $@)
tools/gfx $(tools/gfx) -o $@ $@ || $$($(RM) $@ && false))

%.1bpp: %.png
$(RGBGFX) $(rgbgfx) --depth 1 -o $@ $<
$(if $(tools/gfx),\
tools/gfx $(tools/gfx) --depth 1 -o $@ $@)
tools/gfx $(tools/gfx) --depth 1 -o $@ $@ || $$($(RM) $@ && false))

%.gbcpal: %.png
$(RGBGFX) --colors embedded -p $@ $<
$(RGBGFX) -p $@ $<
tools/gbcpal $(tools/gbcpal) $@ $@ || $$($(RM) $@ && false)

%.dimensions: %.png
tools/png_dimensions $< $@
508 changes: 254 additions & 254 deletions data/pokemon/palettes.asm

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tools/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
gbcpal
gfx
lzcomp
make_patch
Expand Down
1 change: 1 addition & 0 deletions tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CC := gcc
CFLAGS := -O3 -flto -std=c11 -Wall -Wextra -pedantic

tools := \
gbcpal \
gfx \
lzcomp \
make_patch \
Expand Down
Binary file removed tools/gbcpal
Binary file not shown.
141 changes: 141 additions & 0 deletions tools/gbcpal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#define PROGRAM_NAME "gbcpal"
#define USAGE_OPTS "[-h|--help] [-r|--reverse] out.gbcpal in.gbcpal..."

#include "common.h"

bool reverse;

void parse_args(int argc, char *argv[]) {
struct option long_options[] = {
{"reverse", no_argument, 0, 'r'},
{"help", no_argument, 0, 'h'},
{0}
};
for (int opt; (opt = getopt_long(argc, argv, "rh", long_options)) != -1;) {
switch (opt) {
case 'r':
reverse = true;
break;
case 'h':
usage_exit(0);
break;
default:
usage_exit(1);
}
}
}

struct Color {
uint8_t r, g, b;
};

const struct Color BLACK = {0, 0, 0};
const struct Color WHITE = {31, 31, 31};

uint16_t pack_color(struct Color color) {
return (color.b << 10) | (color.g << 5) | color.r;
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
}

struct Color unpack_color(uint16_t gbc_color) {
return (struct Color){
.r = gbc_color & 0x1f,
.g = (gbc_color >> 5) & 0x1f,
.b = (gbc_color >> 10) & 0x1f,
};
}

double luminance(struct Color color) {
return 0.299 * color.r + 0.587 * color.g + 0.114 * color.b;
}

int compare_colors(const void *color1, const void *color2) {
double lum1 = luminance(*(const struct Color *)color1);
double lum2 = luminance(*(const struct Color *)color2);
// sort lightest to darkest, or darkest to lightest if reversed
return reverse ? (lum1 > lum2) - (lum1 < lum2) : (lum1 < lum2) - (lum1 > lum2);
}

void read_gbcpal(const char *filename, struct Color **colors, size_t *num_colors) {
long filesize;
uint8_t *bytes = read_u8(filename, &filesize);
if (filesize == 0) {
error_exit("%s: empty gbcpal file\n", filename);
}
if (filesize % 2) {
error_exit("%s: invalid gbcpal file\n", filename);
}

size_t new_colors = filesize / 2;
*colors = xrealloc(*colors, (sizeof **colors) * (*num_colors + new_colors));
for (size_t i = 0; i < new_colors; i++) {
uint16_t gbc_color = (bytes[i * 2 + 1] << 8) | bytes[i * 2];
(*colors)[*num_colors + i] = unpack_color(gbc_color);
}
*num_colors += new_colors;

free(bytes);
}

void filter_colors(struct Color *colors, size_t *num_colors) {
size_t num_filtered = 0;
// filter out black, white, and duplicate colors
for (size_t i = 0; i < *num_colors; i++) {
struct Color color = colors[i];
if (color.r == BLACK.r && color.g == BLACK.g && color.b == BLACK.b) {
continue;
}
if (color.r == WHITE.r && color.g == WHITE.g && color.b == WHITE.b) {
continue;
}
if (num_filtered > 0) {
struct Color last = colors[num_filtered - 1];
if (color.r == last.r && color.g == last.g && color.b == last.b) {
continue;
}
}
colors[num_filtered++] = color;
}
*num_colors = num_filtered;
}

int main(int argc, char *argv[]) {
parse_args(argc, argv);

argc -= optind;
argv += optind;
if (argc < 2) {
usage_exit(1);
}

const char *out_filename = argv[0];

struct Color *colors = NULL;
size_t num_colors = 0;
for (int i = 1; i < argc; i++) {
read_gbcpal(argv[i], &colors, &num_colors);
}

qsort(colors, num_colors, sizeof(*colors), compare_colors);
filter_colors(colors, &num_colors);

struct Color pal_colors[4] = {
WHITE,
num_colors > 0 ? colors[0] : WHITE,
num_colors > 1 ? colors[1] : num_colors > 0 ? colors[0] : BLACK,
BLACK,
};
if (num_colors > 2) {
error_exit("%s: more than 2 colors besides black and white (%zu)\n", out_filename, num_colors);
}

uint8_t bytes[COUNTOF(pal_colors) * 2] = {0};
for (size_t i = 0; i < COUNTOF(pal_colors); i++) {
uint16_t packed_color = pack_color(pal_colors[i]);
bytes[2 * i] = packed_color & 0xff;
bytes[2 * i + 1] = packed_color >> 8;
}
write_u8(out_filename, bytes, COUNTOF(bytes));

free(colors);
return 0;
}
2 changes: 1 addition & 1 deletion tools/make_patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ struct Buffer *process_template(const char *template_filename, const char *patch
int compare_patch(const void *patch1, const void *patch2) {
unsigned int offset1 = ((const struct Patch *)patch1)->offset;
unsigned int offset2 = ((const struct Patch *)patch2)->offset;
return offset1 > offset2 ? 1 : offset1 < offset2 ? -1 : 0;
return (offset1 > offset2) - (offset1 < offset2);
}

bool verify_completeness(FILE *restrict orig_rom, FILE *restrict new_rom, struct Buffer *patches) {
Expand Down
76 changes: 0 additions & 76 deletions tools/palfix.py

This file was deleted.

Loading