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/maps.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 
     14 #include "cmp_int_color.h"
     15 #include "tiles.h"
     16 
     17 using namespace std;
     18 
     19 #include "png2asset.h"
     20 #include "image_utils.h"
     21 #include "map_attributes.h"
     22 #include "process_arguments.h"
     23 
     24 
     25 void ExtractTileset(PNG2AssetData* assetData, vector< Tile > & tileset, bool keep_duplicate_tiles) {
     26 
     27     // Placeholder vars needed for function call, they get discarded
     28     size_t idx;
     29     unsigned char props;
     30 
     31     for(int y = 0; y < (int)assetData->image.h; y += assetData->image.tile_h)
     32     {
     33         for(int x = 0; x < (int)assetData->image.w; x += assetData->image.tile_w)
     34         {
     35             // Get a tile from the image
     36             Tile tile(assetData->image.tile_w * assetData->image.tile_h);
     37             assetData->image.ExtractTile(x, y, tile, assetData->args->sprite_mode, assetData->args->export_as_map, assetData->args->use_map_attributes);
     38 
     39             if (keep_duplicate_tiles)
     40                 tileset.push_back(tile);
     41             else {
     42                 if (!FindTile(tile, idx, props, tileset, assetData))
     43                     tileset.push_back(tile);
     44             }
     45         }
     46     }
     47 }
     48 
     49 
     50 static void checkWarnMapTileLimits(PNG2AssetData* assetData) {
     51 
     52     unsigned int maxUsedTileCount = (assetData->tiles.size() + assetData->args->tile_origin);
     53     unsigned int maxTilesWarnLimit = 256; // 256 is default for GB, NES
     54 
     55     // GB + Map Attributes implies GBC which has a secondary tile bank
     56     if (((assetData->args->pack_mode == Tile::GB) && assetData->args->use_map_attributes) ||
     57          (assetData->args->pack_mode == Tile::SMS)) {
     58         maxTilesWarnLimit = 512;
     59     }
     60 
     61     if (maxUsedTileCount > maxTilesWarnLimit) {
     62         printf("Warning: Tile count (%d) + tile origin (%d) = %d exceeds limit %d\n",
     63                 (unsigned int)assetData->tiles.size(), (unsigned int)assetData->args->tile_origin,
     64                 maxUsedTileCount, maxTilesWarnLimit);
     65     }
     66 
     67     // If using GBC, notify user about extra requirements to use > 256 tiles
     68     if ((maxUsedTileCount > 256) && ((assetData->args->pack_mode == Tile::GB) && assetData->args->use_map_attributes)) {
     69         printf("Warning: On GBC more then 256 tiles may require use of alternate tile bank. Tile count (%d) + tile origin (%d) = %d\n",
     70                 (unsigned int)assetData->tiles.size(), (unsigned int)assetData->args->tile_origin, maxUsedTileCount);
     71     }
     72 }
     73 
     74 
     75 void GetMap(PNG2AssetData* assetData)
     76 {
     77     for(int y = 0; y < (int)assetData->image.h; y += assetData->image.tile_h)
     78     {
     79         for(int x = 0; x < (int)assetData->image.w; x += assetData->image.tile_w)
     80         {
     81             // Get a tile from the image
     82             Tile tile(assetData->image.tile_w * assetData->image.tile_h);
     83             assetData->image.ExtractTile(x, y, tile, assetData->args->sprite_mode, assetData->args->export_as_map, assetData->args->use_map_attributes);
     84 
     85             size_t idx;
     86             unsigned char props;
     87 
     88             // If there is an entity tileset then always check that for a matching tile first
     89             if (assetData->args->has_entity_tileset && FindTile(tile, idx, props, assetData->entity_tiles, assetData)) {
     90                 // Entity tilesets index counts from 255 down instead of 0 up,
     91                 // so invert the tile ID on the 8 bit boundary
     92                 idx = (256 - assetData->entity_tiles.size()) + idx;
     93                 props = assetData->args->props_default;
     94             }
     95             // When both -keep_duplicate_tiles and source tilesets are used then
     96             // keep_duplicate_tiles should only apply to source tilesets, not the main image.
     97             // (Since keeping duplicate tiles from the main image would
     98             //  cause the identical tiles in a source tileset to be ignored)
     99             else if ((assetData->args->keep_duplicate_tiles) && (assetData->args->has_source_tilesets == false)) {
    100                 // Save tile pattern data, don't try to deduplicate it
    101                 assetData->tiles.push_back(tile);
    102                 idx = assetData->tiles.size() - 1;
    103                 props = assetData->args->props_default;
    104             }
    105             else {
    106                 // Otherwise if the tile pattern has not been encountered before then save it
    107                 if (!FindTile(tile, idx, props, assetData->tiles, assetData))
    108                 {
    109                     if (assetData->args->has_source_tilesets) {
    110                         printf("found a tile not in the source tileset at %d,%d\n", x, y);
    111                         assetData->args->includeTileData = true;
    112                     }
    113                     assetData->tiles.push_back(tile);
    114                     idx = assetData->tiles.size() - 1;
    115                     props = assetData->args->props_default;
    116                 }
    117             }
    118 
    119 
    120             // Creating map tile id and attributes entries is only when processing the the main image.
    121             assetData->map.push_back((unsigned char)idx + assetData->args->tile_origin);
    122 
    123             if(assetData->args->use_map_attributes)
    124             {
    125                 unsigned char pal_idx = tile.pal;
    126                 if(assetData->args->pack_mode == Tile::SGB)
    127                 {
    128                     props = props << 1; //Mirror flags in SGB are on bit 7
    129                     props |= (pal_idx + 4) << 2; //Pals are in bits 2,3,4 and need to go from 4 to 7
    130                     assetData->map.push_back(props); //Also they are stored within the map tiles
    131                 }
    132                 else if(assetData->args->pack_mode == Tile::SMS)
    133                 {
    134                         props = (props >> 4) | ((pal_idx & 1) << 3);
    135                         if(idx > 255)
    136                             props |= 1;
    137                     if (assetData->args->use_structs) {
    138                         // put the attribute data in a separate array as with GBC
    139                         // for: -use_map_attributes + -use_structs[aka zgb] + SMS/GG
    140                         assetData->map_attributes.push_back(props);
    141                     } else {
    142                         assetData->map.push_back(props);
    143                     }
    144                 }
    145                 else
    146                 {
    147                     props |= pal_idx;
    148                      // If GBC and more than 256 tiles then add in tile bank num
    149                     if ((idx > 255) && (assetData->args->pack_mode == Tile::GB))
    150                         props |= CGB_BKGF_BANK1;
    151                     assetData->map_attributes.push_back(props);
    152                 }
    153             }
    154         }
    155     }
    156 
    157     checkWarnMapTileLimits(assetData);
    158     HandleMapAttributes(assetData);
    159 }
    160 

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