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.