diff --git a/tools/assets/build_from_png/build_from_png.c b/tools/assets/build_from_png/build_from_png.c index 2d4b5a8022..0af45ce06d 100644 --- a/tools/assets/build_from_png/build_from_png.c +++ b/tools/assets/build_from_png/build_from_png.c @@ -462,9 +462,8 @@ static bool handle_ci_shared_tlut(const char* png_p, const struct fmt_info* fmt, assert(tlut_elem_size == 8 || tlut_elem_size == 4); sprintf(pal_inc_c_p, "%s/%s.tlut.rgba16%s.inc.c", out_dir_p, tlut_name, tlut_elem_size == 8 ? "" : ".u32"); - const unsigned int max_colors = fmt->siz == G_IM_SIZ_4b ? 16 - : subfmt == SUBFMT_SPLIT_LO || subfmt == SUBFMT_SPLIT_HI ? 128 - : 256; + const bool is_split_palette = subfmt == SUBFMT_SPLIT_LO || subfmt == SUBFMT_SPLIT_HI; + const unsigned int max_colors = fmt->siz == G_IM_SIZ_4b ? 16 : is_split_palette ? 128 : 256; if (all_other_pngs_match_ref_img_pal && ref_img->pal->count <= max_colors) { // write matching palette, and matching color indices for all pngs @@ -472,6 +471,13 @@ static bool handle_ci_shared_tlut(const char* png_p, const struct fmt_info* fmt, fprintf(stderr, "Matching data detected!\n"); #endif + if (is_split_palette && ref_img->pal->count < max_colors) { + // split palettes must be exactly 128 colors, resize to full size + struct n64_palette* old_pal = ref_img->pal; + ref_img->pal = n64texconv_palette_resize(ref_img->pal, max_colors); + n64texconv_palette_free(old_pal); + } + // pass pad_to_8b=true to account for the case where this is in fact not matching data // (the png was silently palettized by n64texconv) // Note: this forces all palette sizes to be 8-aligned, even u32-element-typed ones @@ -537,6 +543,13 @@ static bool handle_ci_shared_tlut(const char* png_p, const struct fmt_info* fmt, fprintf(stderr, "Could not co-palettize images\n"); } + if (is_split_palette) { + for (size_t i = out_pal_count; i < max_colors; i++) { + out_pal[i] = (struct color){ .w = 0 }; + } + out_pal_count = max_colors; + } + // write palette to .inc.c struct n64_palette pal = { out_pal, G_IM_FMT_RGBA, out_pal_count }; if (success) { diff --git a/tools/assets/n64texconv/__init__.py b/tools/assets/n64texconv/__init__.py index 3952b19c8e..82c4c4a3db 100644 --- a/tools/assets/n64texconv/__init__.py +++ b/tools/assets/n64texconv/__init__.py @@ -245,6 +245,13 @@ class N64Palette(Structure): _object_refcount.add_ref(pal) return deref(pal) + def resize(self, new_count : int) -> Optional["N64Palette"]: + if new_count > 256: + raise ValueError("The largest possible palette size is 256") + pal = ln64texconv.n64texconv_palette_resize(byref(self), new_count) + _object_refcount.add_ref(pal) + return deref(pal) + @staticmethod def from_png(path : str, fmt : int) -> Optional["N64Palette"]: if fmt not in (G_IM_FMT_RGBA, G_IM_FMT_IA): @@ -306,6 +313,10 @@ ln64texconv.n64texconv_palette_copy.restype = POINTER(N64Palette) ln64texconv.n64texconv_palette_reformat.argtypes = [POINTER(N64Palette), c_int] ln64texconv.n64texconv_palette_reformat.restype = POINTER(N64Palette) +# struct n64_palette *n64texconv_palette_resize(struct n64_palette *pal, size_t new_count); +ln64texconv.n64texconv_palette_resize.argtypes = [POINTER(N64Palette), c_size_t] +ln64texconv.n64texconv_palette_resize.restype = POINTER(N64Palette) + # struct n64_palette *n64texconv_palette_from_png(const char *path, int fmt); ln64texconv.n64texconv_palette_from_png.argtypes = [c_char_p, c_int] ln64texconv.n64texconv_palette_from_png.restype = POINTER(N64Palette) diff --git a/tools/assets/n64texconv/src/libn64texconv/n64texconv.c b/tools/assets/n64texconv/src/libn64texconv/n64texconv.c index 61d7fbb8eb..6f533b0b49 100644 --- a/tools/assets/n64texconv/src/libn64texconv/n64texconv.c +++ b/tools/assets/n64texconv/src/libn64texconv/n64texconv.c @@ -590,6 +590,24 @@ n64texconv_palette_reformat(struct n64_palette *pal, int fmt) return new_pal; } +struct n64_palette * +n64texconv_palette_resize(struct n64_palette *pal, size_t new_count) +{ + assert(pal != NULL); + + struct n64_palette *new_pal = n64texconv_palette_new(new_count, pal->fmt); + + size_t min_count = (new_count < pal->count) ? new_count : pal->count; + + size_t i; + for (i = 0; i < min_count; i++) + new_pal->texels[i] = pal->texels[i]; + for (i = min_count; i < new_count; i++) + new_pal->texels[i] = (struct color){ .w = 0 }; + + return new_pal; +} + struct n64_palette * n64texconv_palette_from_png(const char *path, int fmt) { diff --git a/tools/assets/n64texconv/src/libn64texconv/n64texconv.h b/tools/assets/n64texconv/src/libn64texconv/n64texconv.h index 0c6476e3aa..85962f72a1 100644 --- a/tools/assets/n64texconv/src/libn64texconv/n64texconv.h +++ b/tools/assets/n64texconv/src/libn64texconv/n64texconv.h @@ -55,6 +55,9 @@ n64texconv_palette_copy(struct n64_palette *pal); struct n64_palette * n64texconv_palette_reformat(struct n64_palette *pal, int fmt); +struct n64_palette * +n64texconv_palette_resize(struct n64_palette *pal, size_t new_count); + struct n64_palette * n64texconv_palette_from_png(const char *path, int fmt);