git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-support/png2asset/palettes.cpp

      1 #include <vector>
      2 #include <string>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <set>
      6 #include <stdio.h>
      7 #include <fstream>
      8 #include <cstdint>
      9 
     10 #include "lodepng.h"
     11 #include "mttile.h"
     12 #include "export.h"
     13 #include "map_attributes.h"
     14 #include "palettes.h"
     15 
     16 #include "cmp_int_color.h"
     17 
     18 using namespace std;
     19 
     20 #include "png2asset.h"
     21 #include "image_utils.h"
     22 #include "maps.h"
     23 #include "metasprites.h"
     24 
     25 
     26 unsigned int PaletteCountApplyMaxLimit(unsigned int max_palettes, unsigned int cur_palette_size)
     27 {
     28     if(cur_palette_size > max_palettes)
     29     {
     30         printf("Warning: %d palettes found, truncating to %d (-max_palettes)\n", (unsigned int)cur_palette_size, (unsigned int)max_palettes);
     31         return max_palettes;
     32     }
     33     else
     34         return cur_palette_size;
     35 }
     36 
     37 int FindOrCreateSubPalette(const SetPal& pal, vector< SetPal >& palettes, size_t colors_per_pal)
     38 {
     39     // Return -1 if colors can't even fit in sub-palette hardware limit
     40     if(pal.size() > colors_per_pal)
     41     {
     42         return -1;
     43     }
     44     //Check if it matches any palettes or create a new one
     45     int i;
     46     for(i = 0; i < (int)palettes.size(); ++i)
     47     {
     48         //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)
     49         SetPal merged(palettes[i]);
     50         merged.insert(pal.begin(), pal.end());
     51         if(merged.size() <= colors_per_pal)
     52         {
     53             if(palettes[i].size() <= colors_per_pal)
     54                 palettes[i] = merged; //Increase colors with this palette (it has less than 4 colors)
     55             return i; //Found palette
     56         }
     57     }
     58 
     59     if(i == (int)palettes.size())
     60     {
     61         //Palette not found, add a new one
     62         palettes.push_back(pal);
     63     }
     64     return i;
     65 }
     66 
     67 
     68 
     69 //
     70 // Builds palettes and palette-per-tile (attributes) for an image
     71 //
     72 // Inputs:
     73 //   image32         : Input image in RGBA32 format
     74 //   palettes        : Palettes for image. Will be added-to / merged with new palettes.
     75 //   half_resolution : If true, attributes will follow a constraint of every 2x2 cell having the same attribute.
     76 //
     77 // Returns: array of attributes. This always has *per-tile* dimensions, even when half_resolution is true.
     78 //
     79 int* BuildPalettesAndAttributes(const PNGImage& image32, PNG2AssetData* assetData)
     80 {
     81     bool half_resolution = assetData->args->use_2x2_map_attributes;
     82     vector< SetPal >& palettes = assetData->palettes;
     83 
     84     int* palettes_per_tile = new int[(image32.w / image32.tile_w) * (image32.h / image32.tile_h)];
     85     int sx = half_resolution ? 2 : 1;
     86     int sy = half_resolution ? 2 : 1;
     87     for(unsigned int y = 0; y < image32.h; y += image32.tile_h * sy)
     88     {
     89         for(unsigned int x = 0; x < image32.w; x += image32.tile_w * sx)
     90         {
     91             // Get palette colors on (x, y, image32.tile_w, image32.tile_h)
     92             const bool isPackModeSGB = assetData->args->pack_mode == Tile::SGB;
     93             SetPal pal = GetPaletteColors(image32, isPackModeSGB, (x / sx) * sx, (y / sy) * sy, sx * image32.tile_w, sy * image32.tile_h);
     94 
     95             int subPalIndex = FindOrCreateSubPalette(pal, palettes, image32.colors_per_pal);
     96             if(subPalIndex < 0)
     97             {
     98                 printf("Error: more than %d colors found in tile at x:%d, y:%d of size w:%d, h:%d\n",
     99                     (unsigned int)image32.colors_per_pal,
    100                     (x / sx) * sx,
    101                     (y / sy) * sy,
    102                     sx * image32.tile_w,
    103                     sy * image32.tile_h);
    104                 subPalIndex = 0; // Force to sub-palette 0, to allow getting a partially-incorrect output image
    105             }
    106             // Assign single or multiple entries in palettes_per_tile, to keep it independent of
    107             // of half_resolution parameter
    108             int dx = ((x / image32.tile_w) / sx) * sx;
    109             int dy = ((y / image32.tile_h) / sy) * sy;
    110             int w = (image32.w / image32.tile_w);
    111             for(int yy = 0; yy < sy; yy++)
    112             {
    113                 for(int xx = 0; xx < sx; xx++)
    114                 {
    115                     palettes_per_tile[(dy + yy) * w + dx + xx] = subPalIndex;
    116                 }
    117             }
    118         }
    119     }
    120     return palettes_per_tile;
    121 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.