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.