yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
tilemap.cc
Go to the documentation of this file.
1#include "app/gfx/tilemap.h"
2
3#include <vector>
4
6#include "app/gfx/bitmap.h"
7#include "app/gfx/snes_tile.h"
8
9namespace yaze {
10namespace gfx {
11
12Tilemap CreateTilemap(std::vector<uint8_t> &data, int width, int height,
13 int tile_size, int num_tiles, SnesPalette &palette) {
14 Tilemap tilemap;
15 tilemap.tile_size.x = tile_size;
16 tilemap.tile_size.y = tile_size;
17 tilemap.map_size.x = num_tiles;
18 tilemap.map_size.y = num_tiles;
19 tilemap.atlas = Bitmap(width, height, 8, data);
20 tilemap.atlas.SetPalette(palette);
22 return tilemap;
23}
24
25void UpdateTilemap(Tilemap &tilemap, const std::vector<uint8_t> &data) {
26 tilemap.atlas.set_data(data);
28}
29
30void RenderTile(Tilemap &tilemap, int tile_id) {
31 if (tilemap.tile_bitmaps.find(tile_id) == tilemap.tile_bitmaps.end()) {
32 tilemap.tile_bitmaps[tile_id] =
33 Bitmap(tilemap.tile_size.x, tilemap.tile_size.y, 8,
34 GetTilemapData(tilemap, tile_id), tilemap.atlas.palette());
35 auto bitmap_ptr = &tilemap.tile_bitmaps[tile_id];
37 } else {
39 }
40}
41
42void RenderTile16(Tilemap &tilemap, int tile_id) {
43 if (tilemap.tile_bitmaps.find(tile_id) == tilemap.tile_bitmaps.end()) {
44 int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x;
45 int tile_x = (tile_id % tiles_per_row) * tilemap.tile_size.x;
46 int tile_y = (tile_id / tiles_per_row) * tilemap.tile_size.y;
47 std::vector<uint8_t> tile_data(tilemap.tile_size.x * tilemap.tile_size.y,
48 0x00);
49 int tile_data_offset = 0;
50 tilemap.atlas.Get16x16Tile(tile_x, tile_y, tile_data, tile_data_offset);
51 tilemap.tile_bitmaps[tile_id] =
52 Bitmap(tilemap.tile_size.x, tilemap.tile_size.y, 8, tile_data,
53 tilemap.atlas.palette());
54 auto bitmap_ptr = &tilemap.tile_bitmaps[tile_id];
56 }
57}
58
59void UpdateTile16(Tilemap &tilemap, int tile_id) {
60 int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x;
61 int tile_x = (tile_id % tiles_per_row) * tilemap.tile_size.x;
62 int tile_y = (tile_id / tiles_per_row) * tilemap.tile_size.y;
63 std::vector<uint8_t> tile_data(tilemap.tile_size.x * tilemap.tile_size.y,
64 0x00);
65 int tile_data_offset = 0;
66 tilemap.atlas.Get16x16Tile(tile_x, tile_y, tile_data, tile_data_offset);
67 tilemap.tile_bitmaps[tile_id].set_data(tile_data);
69}
70
72 const std::vector<uint8_t> &data, int tile_id, int sheet_offset) {
73 const int tile_width = 8;
74 const int tile_height = 8;
75 const int buffer_width = 128;
76 const int sheet_height = 32;
77
78 const int tiles_per_row = buffer_width / tile_width;
79 const int rows_per_sheet = sheet_height / tile_height;
80 const int tiles_per_sheet = tiles_per_row * rows_per_sheet;
81
82 int sheet = (tile_id / tiles_per_sheet) % 4 + sheet_offset;
83 int position_in_sheet = tile_id % tiles_per_sheet;
84 int row_in_sheet = position_in_sheet / tiles_per_row;
85 int column_in_sheet = position_in_sheet % tiles_per_row;
86
87 assert(sheet >= sheet_offset && sheet <= sheet_offset + 3);
88
89 std::vector<uint8_t> tile_data(tile_width * tile_height);
90 for (int y = 0; y < tile_height; ++y) {
91 for (int x = 0; x < tile_width; ++x) {
92 int src_x = column_in_sheet * tile_width + x;
93 int src_y = (sheet * sheet_height) + (row_in_sheet * tile_height) + y;
94
95 int src_index = (src_y * buffer_width) + src_x;
96 int dest_index = y * tile_width + x;
97 tile_data[dest_index] = data[src_index];
98 }
99 }
100 return tile_data;
101}
102
103namespace {
104
105void MirrorTileDataVertically(std::vector<uint8_t> &tile_data) {
106 for (int y = 0; y < 4; ++y) {
107 for (int x = 0; x < 8; ++x) {
108 std::swap(tile_data[y * 8 + x], tile_data[(7 - y) * 8 + x]);
109 }
110 }
111}
112
113void MirrorTileDataHorizontally(std::vector<uint8_t> &tile_data) {
114 for (int y = 0; y < 8; ++y) {
115 for (int x = 0; x < 4; ++x) {
116 std::swap(tile_data[y * 8 + x], tile_data[y * 8 + (7 - x)]);
117 }
118 }
119}
120
121void ComposeAndPlaceTilePart(Tilemap &tilemap, const std::vector<uint8_t> &data,
122 const TileInfo &tile_info, int base_x, int base_y,
123 int sheet_offset) {
124 std::vector<uint8_t> tile_data =
125 FetchTileDataFromGraphicsBuffer(data, tile_info.id_, sheet_offset);
126
127 if (tile_info.vertical_mirror_) {
128 MirrorTileDataVertically(tile_data);
129 }
130 if (tile_info.horizontal_mirror_) {
132 }
133
134 for (int y = 0; y < 8; ++y) {
135 for (int x = 0; x < 8; ++x) {
136 int src_index = y * 8 + x;
137 int dest_x = base_x + x;
138 int dest_y = base_y + y;
139 int dest_index = (dest_y * tilemap.atlas.width()) + dest_x;
140 tilemap.atlas.WriteToPixel(dest_index, tile_data[src_index]);
141 }
142 };
143}
144} // namespace
145
146void ModifyTile16(Tilemap &tilemap, const std::vector<uint8_t> &data,
147 const TileInfo &top_left, const TileInfo &top_right,
148 const TileInfo &bottom_left, const TileInfo &bottom_right,
149 int sheet_offset, int tile_id) {
150 // Calculate the base position for this Tile16 in the full-size bitmap
151 int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x;
152 int tile16_row = tile_id / tiles_per_row;
153 int tile16_column = tile_id % tiles_per_row;
154 int base_x = tile16_column * tilemap.tile_size.x;
155 int base_y = tile16_row * tilemap.tile_size.y;
156
157 // Compose and place each part of the Tile16
158 ComposeAndPlaceTilePart(tilemap, data, top_left, base_x, base_y,
159 sheet_offset);
160 ComposeAndPlaceTilePart(tilemap, data, top_right, base_x + 8, base_y,
161 sheet_offset);
162 ComposeAndPlaceTilePart(tilemap, data, bottom_left, base_x, base_y + 8,
163 sheet_offset);
164 ComposeAndPlaceTilePart(tilemap, data, bottom_right, base_x + 8, base_y + 8,
165 sheet_offset);
166
167 tilemap.tile_info[tile_id] = {top_left, top_right, bottom_left, bottom_right};
168}
169
170void ComposeTile16(Tilemap &tilemap, const std::vector<uint8_t> &data,
171 const TileInfo &top_left, const TileInfo &top_right,
172 const TileInfo &bottom_left, const TileInfo &bottom_right,
173 int sheet_offset) {
174 int num_tiles = tilemap.tile_info.size();
175 int tiles_per_row = tilemap.atlas.width() / tilemap.tile_size.x;
176 int tile16_row = num_tiles / tiles_per_row;
177 int tile16_column = num_tiles % tiles_per_row;
178 int base_x = tile16_column * tilemap.tile_size.x;
179 int base_y = tile16_row * tilemap.tile_size.y;
180
181 ComposeAndPlaceTilePart(tilemap, data, top_left, base_x, base_y,
182 sheet_offset);
183 ComposeAndPlaceTilePart(tilemap, data, top_right, base_x + 8, base_y,
184 sheet_offset);
185 ComposeAndPlaceTilePart(tilemap, data, bottom_left, base_x, base_y + 8,
186 sheet_offset);
187 ComposeAndPlaceTilePart(tilemap, data, bottom_right, base_x + 8, base_y + 8,
188 sheet_offset);
189
190 tilemap.tile_info.push_back({top_left, top_right, bottom_left, bottom_right});
191}
192
193std::vector<uint8_t> GetTilemapData(Tilemap &tilemap, int tile_id) {
194 int tile_size = tilemap.tile_size.x;
195 std::vector<uint8_t> data(tile_size * tile_size);
196 int num_tiles = tilemap.map_size.x;
197 int index = tile_id * tile_size * tile_size;
198 int width = tilemap.atlas.width();
199
200 for (int ty = 0; ty < tile_size; ty++) {
201 for (int tx = 0; tx < tile_size; tx++) {
202 uint8_t value =
203 tilemap.atlas
204 .vector()[(tile_id % 8 * tile_size) +
205 (tile_id / 8 * tile_size * width) + ty * width + tx];
206 data[ty * tile_size + tx] = value;
207 }
208 }
209
210 return data;
211}
212
213} // namespace gfx
214} // namespace yaze
void UpdateBitmap(gfx::Bitmap *bitmap)
Definition renderer.h:49
static Renderer & Get()
Definition renderer.h:26
void RenderBitmap(gfx::Bitmap *bitmap)
Definition renderer.h:45
Represents a bitmap image.
Definition bitmap.h:59
const SnesPalette & palette() const
Definition bitmap.h:149
void WriteToPixel(int position, uint8_t value)
Write a value to a pixel at the given position.
Definition bitmap.cc:383
const std::vector< uint8_t > & vector() const
Definition bitmap.h:159
void set_data(const std::vector< uint8_t > &data)
Definition bitmap.h:164
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap.
Definition bitmap.cc:307
int width() const
Definition bitmap.h:151
void Get16x16Tile(int tile_x, int tile_y, std::vector< uint8_t > &tile_data, int &tile_data_offset)
Extract a 16x16 tile from the bitmap.
Definition bitmap.cc:427
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
SNES 16-bit tile metadata container.
Definition snes_tile.h:50
void ComposeAndPlaceTilePart(Tilemap &tilemap, const std::vector< uint8_t > &data, const TileInfo &tile_info, int base_x, int base_y, int sheet_offset)
Definition tilemap.cc:121
void MirrorTileDataVertically(std::vector< uint8_t > &tile_data)
Definition tilemap.cc:105
void MirrorTileDataHorizontally(std::vector< uint8_t > &tile_data)
Definition tilemap.cc:113
Contains classes for handling graphical data.
Definition arena.cc:8
Tilemap CreateTilemap(std::vector< uint8_t > &data, int width, int height, int tile_size, int num_tiles, SnesPalette &palette)
Definition tilemap.cc:12
void UpdateTilemap(Tilemap &tilemap, const std::vector< uint8_t > &data)
Definition tilemap.cc:25
void ModifyTile16(Tilemap &tilemap, const std::vector< uint8_t > &data, const TileInfo &top_left, const TileInfo &top_right, const TileInfo &bottom_left, const TileInfo &bottom_right, int sheet_offset, int tile_id)
Definition tilemap.cc:146
void UpdateTile16(Tilemap &tilemap, int tile_id)
Definition tilemap.cc:59
void RenderTile16(Tilemap &tilemap, int tile_id)
Definition tilemap.cc:42
std::vector< uint8_t > GetTilemapData(Tilemap &tilemap, int tile_id)
Definition tilemap.cc:193
std::vector< uint8_t > FetchTileDataFromGraphicsBuffer(const std::vector< uint8_t > &data, int tile_id, int sheet_offset)
Definition tilemap.cc:71
void RenderTile(Tilemap &tilemap, int tile_id)
Definition tilemap.cc:30
void ComposeTile16(Tilemap &tilemap, const std::vector< uint8_t > &data, const TileInfo &top_left, const TileInfo &top_right, const TileInfo &bottom_left, const TileInfo &bottom_right, int sheet_offset)
Definition tilemap.cc:170
Main namespace for the application.
Definition controller.cc:18
absl::flat_hash_map< int, Bitmap > tile_bitmaps
Definition tilemap.h:18
std::vector< std::array< gfx::TileInfo, 4 > > tile_info
Definition tilemap.h:19