mirror of
https://github.com/gbdk-2020/gbdk-2020.git
synced 2026-02-20 00:32:21 +01:00
- For SGB palettes there is 1 transparent color (0) which should be the first and then 15 opaque colors. - In cases where more than SGB palette is generated, png2asset was failsing to force the transparent color as the first color for any additional palettes.
121 lines
4.1 KiB
C++
121 lines
4.1 KiB
C++
#include <vector>
|
|
#include <string>
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include <set>
|
|
#include <stdio.h>
|
|
#include <fstream>
|
|
#include <cstdint>
|
|
|
|
#include "lodepng.h"
|
|
#include "mttile.h"
|
|
#include "export.h"
|
|
#include "map_attributes.h"
|
|
#include "palettes.h"
|
|
|
|
#include "cmp_int_color.h"
|
|
|
|
using namespace std;
|
|
|
|
#include "png2asset.h"
|
|
#include "image_utils.h"
|
|
#include "maps.h"
|
|
#include "metasprites.h"
|
|
|
|
|
|
unsigned int PaletteCountApplyMaxLimit(unsigned int max_palettes, unsigned int cur_palette_size)
|
|
{
|
|
if(cur_palette_size > max_palettes)
|
|
{
|
|
printf("Warning: %d palettes found, truncating to %d (-max_palettes)\n", (unsigned int)cur_palette_size, (unsigned int)max_palettes);
|
|
return max_palettes;
|
|
}
|
|
else
|
|
return cur_palette_size;
|
|
}
|
|
|
|
int FindOrCreateSubPalette(const SetPal& pal, vector< SetPal >& palettes, size_t colors_per_pal)
|
|
{
|
|
// Return -1 if colors can't even fit in sub-palette hardware limit
|
|
if(pal.size() > colors_per_pal)
|
|
{
|
|
return -1;
|
|
}
|
|
//Check if it matches any palettes or create a new one
|
|
int i;
|
|
for(i = 0; i < (int)palettes.size(); ++i)
|
|
{
|
|
//Try to merge this palette with any of the palettes (checking if they are equal is not enough since the palettes can have less than 4 colors)
|
|
SetPal merged(palettes[i]);
|
|
merged.insert(pal.begin(), pal.end());
|
|
if(merged.size() <= colors_per_pal)
|
|
{
|
|
if(palettes[i].size() <= colors_per_pal)
|
|
palettes[i] = merged; //Increase colors with this palette (it has less than 4 colors)
|
|
return i; //Found palette
|
|
}
|
|
}
|
|
|
|
if(i == (int)palettes.size())
|
|
{
|
|
//Palette not found, add a new one
|
|
palettes.push_back(pal);
|
|
}
|
|
return i;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Builds palettes and palette-per-tile (attributes) for an image
|
|
//
|
|
// Inputs:
|
|
// image32 : Input image in RGBA32 format
|
|
// palettes : Palettes for image. Will be added-to / merged with new palettes.
|
|
// half_resolution : If true, attributes will follow a constraint of every 2x2 cell having the same attribute.
|
|
//
|
|
// Returns: array of attributes. This always has *per-tile* dimensions, even when half_resolution is true.
|
|
//
|
|
int* BuildPalettesAndAttributes(const PNGImage& image32, PNG2AssetData* assetData)
|
|
{
|
|
bool half_resolution = assetData->args->use_2x2_map_attributes;
|
|
vector< SetPal >& palettes = assetData->palettes;
|
|
|
|
int* palettes_per_tile = new int[(image32.w / image32.tile_w) * (image32.h / image32.tile_h)];
|
|
int sx = half_resolution ? 2 : 1;
|
|
int sy = half_resolution ? 2 : 1;
|
|
for(unsigned int y = 0; y < image32.h; y += image32.tile_h * sy)
|
|
{
|
|
for(unsigned int x = 0; x < image32.w; x += image32.tile_w * sx)
|
|
{
|
|
// Get palette colors on (x, y, image32.tile_w, image32.tile_h)
|
|
const bool isPackModeSGB = assetData->args->pack_mode == Tile::SGB;
|
|
SetPal pal = GetPaletteColors(image32, isPackModeSGB, (x / sx) * sx, (y / sy) * sy, sx * image32.tile_w, sy * image32.tile_h);
|
|
|
|
int subPalIndex = FindOrCreateSubPalette(pal, palettes, image32.colors_per_pal);
|
|
if(subPalIndex < 0)
|
|
{
|
|
printf("Error: more than %d colors found in tile at x:%d, y:%d of size w:%d, h:%d\n",
|
|
(unsigned int)image32.colors_per_pal,
|
|
(x / sx) * sx,
|
|
(y / sy) * sy,
|
|
sx * image32.tile_w,
|
|
sy * image32.tile_h);
|
|
subPalIndex = 0; // Force to sub-palette 0, to allow getting a partially-incorrect output image
|
|
}
|
|
// Assign single or multiple entries in palettes_per_tile, to keep it independent of
|
|
// of half_resolution parameter
|
|
int dx = ((x / image32.tile_w) / sx) * sx;
|
|
int dy = ((y / image32.tile_h) / sy) * sy;
|
|
int w = (image32.w / image32.tile_w);
|
|
for(int yy = 0; yy < sy; yy++)
|
|
{
|
|
for(int xx = 0; xx < sx; xx++)
|
|
{
|
|
palettes_per_tile[(dy + yy) * w + dx + xx] = subPalIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return palettes_per_tile;
|
|
} |