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/map_attributes.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 
     13 #include "cmp_int_color.h"
     14 
     15 using namespace std;
     16 
     17 #include "png2asset.h"
     18 #include "image_utils.h"
     19 #include "process_arguments.h"
     20 
     21 unsigned char GetMapAttribute(size_t x, size_t y,PNG2AssetData* assetData)
     22 {
     23     if(x < assetData->args->map_attributes_size.width && y < assetData->args->map_attributes_size.height)
     24         return assetData->map_attributes[y * assetData->args->map_attributes_size.width + x];
     25     else
     26         return 0;
     27 }
     28 
     29 void ReduceMapAttributes2x2(PNG2AssetData* assetData)
     30 {
     31     size_t w = (assetData->args->map_attributes_size.width + 1) / 2;
     32     size_t h = (assetData->args->map_attributes_size.height + 1) / 2;
     33     vector< unsigned char > map_attributes_2x2;
     34     map_attributes_2x2.resize(w * h);
     35     for(size_t y = 0; y < h; y++)
     36     {
     37         for(size_t x = 0; x < w; x++)
     38         {
     39             // Use only Top-left attribute, ignoring the other three as they should now be identical
     40             map_attributes_2x2[y * w + x] = GetMapAttribute(2 * x, 2 * y,assetData);
     41         }
     42     }
     43     // Overwrite old attributes
     44     assetData->args->map_attributes_size.width = w;
     45     assetData->args->map_attributes_size.height = h;
     46     assetData->map_attributes = map_attributes_2x2;
     47 }
     48 
     49 //
     50 // Aligns map attribute data to be aligned properly for NES and set_bkg_submap_attributes
     51 // Namely:
     52 // * Width aligned to multiples of 2 to reflect the NES's packed attribute table
     53 // * Every 16th row is blank to reflect the unused row in the NES's packed attribute table
     54 //
     55 void AlignMapAttributes(PNG2AssetData* assetData)
     56 {
     57     const size_t ATTRIBUTE_HEIGHT = 15;
     58     const size_t ATTRIBUTE_ALIGNED_HEIGHT = 16;
     59     vector< unsigned char > map_attributes_aligned;
     60     size_t map_attributes_aligned_width = 2 * ((assetData->args->map_attributes_size.width + 1) / 2);
     61     size_t num_vertical_nametables = (assetData->args->map_attributes_size.height + ATTRIBUTE_HEIGHT - 1) / ATTRIBUTE_HEIGHT;
     62     map_attributes_aligned.resize(map_attributes_aligned_width * (num_vertical_nametables * ATTRIBUTE_ALIGNED_HEIGHT));
     63     for(size_t i = 0; i < num_vertical_nametables; i++)
     64     {
     65         bool last_nametable = (i == num_vertical_nametables - 1);
     66         size_t height = last_nametable ? (assetData->args->map_attributes_size.height - i * ATTRIBUTE_HEIGHT) : ATTRIBUTE_HEIGHT;
     67         for(size_t y = 0; y < height; y++)
     68         {
     69             for(size_t x = 0; x < assetData->args->map_attributes_size.width; x++)
     70             {
     71                 map_attributes_aligned[(i * ATTRIBUTE_ALIGNED_HEIGHT + y) * map_attributes_aligned_width + x] =
     72                     assetData->map_attributes[(i * ATTRIBUTE_HEIGHT + y) * assetData->args->map_attributes_size.width + x];
     73             }
     74         }
     75     }
     76     // Overwrite old attributes
     77     assetData->args->map_attributes_size.width = map_attributes_aligned_width;
     78     assetData->args->map_attributes_size.height = num_vertical_nametables * ATTRIBUTE_ALIGNED_HEIGHT;
     79     assetData->map_attributes = map_attributes_aligned;
     80 }
     81 
     82 //
     83 // Pack map attributes
     84 // (NES packs multiple 2-bit entries into one byte)
     85 //
     86 void PackMapAttributes(PNG2AssetData *assetData)
     87 {
     88     vector< unsigned char > map_attributes_packed;
     89     assetData->args->map_attributes_packed_size.width = (assetData->args->map_attributes_size.width + 1) / 2;
     90     assetData->args->map_attributes_packed_size.height = (assetData->args->map_attributes_size.height + 1) / 2;
     91     map_attributes_packed.resize(assetData->args->map_attributes_packed_size.width * assetData->args->map_attributes_packed_size.height);
     92     for(size_t y = 0; y < assetData->args->map_attributes_packed_size.height; y++)
     93     {
     94         for(size_t x = 0; x < assetData->args->map_attributes_packed_size.width; x++)
     95         {
     96             unsigned char a_tl = GetMapAttribute(2 * x + 0, 2 * y + 0, assetData);
     97             unsigned char a_tr = GetMapAttribute(2 * x + 1, 2 * y + 0, assetData);
     98             unsigned char a_bl = GetMapAttribute(2 * x + 0, 2 * y + 1, assetData);
     99             unsigned char a_br = GetMapAttribute(2 * x + 1, 2 * y + 1, assetData);
    100             unsigned char packed_bits = (a_br << 6) | (a_bl << 4) | (a_tr << 2) | (a_tl << 0);
    101             map_attributes_packed[assetData->args->map_attributes_packed_size.width * y + x] = packed_bits;
    102         }
    103     }
    104     // Overwrite old attributes
    105     assetData->map_attributes = map_attributes_packed;
    106 }
    107 
    108 void HandleMapAttributes(PNG2AssetData* assetData) {
    109     assetData->args->map_attributes_size.width = assetData->image.w / 8;
    110     assetData->args->map_attributes_size.height = assetData->image.h / 8;
    111 
    112     // Optionally perform 2x2 reduction on attributes (NES attribute table has this format)
    113     if(assetData->args->use_2x2_map_attributes)
    114     {
    115         // NES attribute map dimensions are half-resolution 
    116         ReduceMapAttributes2x2(assetData);
    117     }
    118     // Optionally align and pack map attributes into NES PPU format
    119     if(assetData->args->pack_map_attributes)
    120     {
    121         AlignMapAttributes(assetData);
    122         PackMapAttributes(assetData);
    123     }
    124     else
    125     {
    126         // Use original attribute dimensions for packed
    127         assetData->args->map_attributes_packed_size.width = assetData->args->map_attributes_size.width;
    128         assetData->args->map_attributes_packed_size.height = assetData->args->map_attributes_size.height;
    129     }
    130 }

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