yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
screen_editor.cc
Go to the documentation of this file.
1#include "screen_editor.h"
2
3#include <fstream>
4#include <iostream>
5#include <string>
6
7#include "absl/strings/str_format.h"
8#include "absl/strings/string_view.h"
11#include "app/gfx/bitmap.h"
12#include "app/gfx/snes_tile.h"
13#include "app/gfx/tilesheet.h"
14#include "app/gui/canvas.h"
15#include "app/gui/color.h"
16#include "app/gui/icons.h"
17#include "app/gui/input.h"
18#include "imgui/imgui.h"
19#include "util/hex.h"
20#include "util/macro.h"
21
22namespace yaze {
23namespace editor {
24
25using core::Renderer;
26
27constexpr uint32_t kRedPen = 0xFF0000FF;
28
29absl::Status ScreenEditor::Update() {
30 if (ImGui::BeginTabBar("##ScreenEditorTabBar")) {
31 if (ImGui::BeginTabItem("Dungeon Maps")) {
32 if (rom()->is_loaded()) {
34 }
35 ImGui::EndTabItem();
36 }
41 ImGui::EndTabBar();
42 }
43 return status_;
44}
45
47 TAB_ITEM("Inventory Menu")
48
49 static bool create = false;
50 if (!create && rom()->is_loaded()) {
51 status_ = inventory_.Create();
52 palette_ = inventory_.Palette();
53 create = true;
54 }
55
57
58 if (ImGui::BeginTable("InventoryScreen", 3, ImGuiTableFlags_Resizable)) {
59 ImGui::TableSetupColumn("Canvas");
60 ImGui::TableSetupColumn("Tiles");
61 ImGui::TableSetupColumn("Palette");
62 ImGui::TableHeadersRow();
63
64 ImGui::TableNextColumn();
65 screen_canvas_.DrawBackground();
66 screen_canvas_.DrawContextMenu();
67 screen_canvas_.DrawBitmap(inventory_.Bitmap(), 2, create);
68 screen_canvas_.DrawGrid(32.0f);
69 screen_canvas_.DrawOverlay();
70
71 ImGui::TableNextColumn();
72 tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, (192 * 2) + 4));
73 tilesheet_canvas_.DrawContextMenu();
74 tilesheet_canvas_.DrawBitmap(inventory_.Tilesheet(), 2, create);
75 tilesheet_canvas_.DrawGrid(16.0f);
76 tilesheet_canvas_.DrawOverlay();
77
78 ImGui::TableNextColumn();
80
81 ImGui::EndTable();
82 }
83 ImGui::Separator();
85}
86
88 if (ImGui::BeginTable("InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit,
89 ImVec2(0, 0))) {
90 ImGui::TableSetupColumn("#drawTool");
91 ImGui::TableSetupColumn("#sep1");
92 ImGui::TableSetupColumn("#zoomOut");
93 ImGui::TableSetupColumn("#zoomIN");
94 ImGui::TableSetupColumn("#sep2");
95 ImGui::TableSetupColumn("#bg2Tool");
96 ImGui::TableSetupColumn("#bg3Tool");
97 ImGui::TableSetupColumn("#itemTool");
98
107
108 ImGui::EndTable();
109 }
110}
111
113 std::vector<std::array<uint8_t, 25>> current_floor_rooms_d;
114 std::vector<std::array<uint8_t, 25>> current_floor_gfx_d;
115 int total_floors_d;
116 uint8_t nbr_floor_d;
117 uint8_t nbr_basement_d;
118
119 for (int d = 0; d < 14; d++) {
120 current_floor_rooms_d.clear();
121 current_floor_gfx_d.clear();
122 ASSIGN_OR_RETURN(int ptr,
123 rom()->ReadWord(zelda3::kDungeonMapRoomsPtr + (d * 2)));
124 ASSIGN_OR_RETURN(int ptr_gfx,
125 rom()->ReadWord(zelda3::kDungeonMapGfxPtr + (d * 2)));
126 ptr |= 0x0A0000; // Add bank to the short ptr
127 ptr_gfx |= 0x0A0000; // Add bank to the short ptr
128 int pc_ptr = SnesToPc(ptr); // Contains data for the next 25 rooms
129 int pc_ptr_gfx =
130 SnesToPc(ptr_gfx); // Contains data for the next 25 rooms
131
132 ASSIGN_OR_RETURN(uint16_t boss_room_d,
133 rom()->ReadWord(zelda3::kDungeonMapBossRooms + (d * 2)));
134
135 ASSIGN_OR_RETURN(nbr_basement_d,
136 rom()->ReadByte(zelda3::kDungeonMapFloors + (d * 2)));
137 nbr_basement_d &= 0x0F;
138
139 ASSIGN_OR_RETURN(nbr_floor_d,
140 rom()->ReadByte(zelda3::kDungeonMapFloors + (d * 2)));
141 nbr_floor_d &= 0xF0;
142 nbr_floor_d = nbr_floor_d >> 4;
143
144 total_floors_d = nbr_basement_d + nbr_floor_d;
145
146 dungeon_map_labels_.emplace_back();
147
148 // for each floor in the dungeon
149 for (int i = 0; i < total_floors_d; i++) {
150 dungeon_map_labels_[d].emplace_back();
151
152 std::array<uint8_t, 25> rdata;
153 std::array<uint8_t, 25> gdata;
154
155 // for each room on the floor
156 for (int j = 0; j < 25; j++) {
157 gdata[j] = 0xFF;
158 rdata[j] = rom()->data()[pc_ptr + j + (i * 25)]; // Set the rooms
159
160 if (rdata[j] == 0x0F) {
161 gdata[j] = 0xFF;
162 } else {
163 gdata[j] = rom()->data()[pc_ptr_gfx++];
164 }
165
166 std::string label = util::HexByte(rdata[j]);
167 dungeon_map_labels_[d][i][j] = label;
168 }
169
170 current_floor_gfx_d.push_back(gdata); // Add new floor gfx data
171 current_floor_rooms_d.push_back(rdata); // Add new floor data
172 }
173
174 dungeon_maps_.emplace_back(boss_room_d, nbr_floor_d, nbr_basement_d,
175 current_floor_rooms_d, current_floor_gfx_d);
176 }
177
178 return absl::OkStatus();
179}
180
182 for (int d = 0; d < 14; d++) {
183 int ptr = zelda3::kDungeonMapRoomsPtr + (d * 2);
184 int ptr_gfx = zelda3::kDungeonMapGfxPtr + (d * 2);
185 int pc_ptr = SnesToPc(ptr);
186 int pc_ptr_gfx = SnesToPc(ptr_gfx);
187
188 const int nbr_floors = dungeon_maps_[d].nbr_of_floor;
189 const int nbr_basements = dungeon_maps_[d].nbr_of_basement;
190 for (int i = 0; i < nbr_floors + nbr_basements; i++) {
191 for (int j = 0; j < 25; j++) {
192 RETURN_IF_ERROR(rom()->WriteByte(pc_ptr + j + (i * 25),
193 dungeon_maps_[d].floor_rooms[i][j]));
194 RETURN_IF_ERROR(rom()->WriteByte(pc_ptr_gfx + j + (i * 25),
195 dungeon_maps_[d].floor_gfx[i][j]));
196 pc_ptr_gfx++;
197 }
198 }
199 }
200
201 return absl::OkStatus();
202}
203
205 const std::vector<uint8_t> &gfx_data, bool bin_mode) {
206 tile16_sheet_.Init(256, 192, gfx::TileType::Tile16);
207
208 for (int i = 0; i < 186; i++) {
209 int addr = zelda3::kDungeonMapTile16;
210 if (rom()->data()[zelda3::kDungeonMapExpCheck] != 0xB9) {
212 }
213
214 ASSIGN_OR_RETURN(auto tl, rom()->ReadWord(addr + (i * 8)));
215 gfx::TileInfo t1 = gfx::WordToTileInfo(tl); // Top left
216
217 ASSIGN_OR_RETURN(auto tr, rom()->ReadWord(addr + 2 + (i * 8)));
218 gfx::TileInfo t2 = gfx::WordToTileInfo(tr); // Top right
219
220 ASSIGN_OR_RETURN(auto bl, rom()->ReadWord(addr + 4 + (i * 8)));
221 gfx::TileInfo t3 = gfx::WordToTileInfo(bl); // Bottom left
222
223 ASSIGN_OR_RETURN(auto br, rom()->ReadWord(addr + 6 + (i * 8)));
224 gfx::TileInfo t4 = gfx::WordToTileInfo(br); // Bottom right
225
226 int sheet_offset = 212;
227 if (bin_mode) {
228 sheet_offset = 0;
229 }
230 tile16_sheet_.ComposeTile16(gfx_data, t1, t2, t3, t4, sheet_offset);
231 }
232
233 RETURN_IF_ERROR(tile16_sheet_.mutable_bitmap()->ApplyPalette(
234 *rom()->mutable_dungeon_palette(3)));
235 Renderer::GetInstance().RenderBitmap(&*tile16_sheet_.mutable_bitmap().get());
236
237 for (int i = 0; i < tile16_sheet_.num_tiles(); ++i) {
238 auto tile = tile16_sheet_.GetTile16(i);
239 tile16_individual_[i] = tile;
241 tile16_individual_[i].ApplyPalette(*rom()->mutable_dungeon_palette(3)));
243 }
244
245 return absl::OkStatus();
246}
247
249 for (int i = 0; i < 186; i++) {
250 int addr = zelda3::kDungeonMapTile16;
251 if (rom()->data()[zelda3::kDungeonMapExpCheck] != 0xB9) {
253 }
254
255 gfx::TileInfo t1 = tile16_sheet_.tile_info()[i].tiles[0];
256 gfx::TileInfo t2 = tile16_sheet_.tile_info()[i].tiles[1];
257 gfx::TileInfo t3 = tile16_sheet_.tile_info()[i].tiles[2];
258 gfx::TileInfo t4 = tile16_sheet_.tile_info()[i].tiles[3];
259
260 auto tl = gfx::TileInfoToWord(t1);
261 RETURN_IF_ERROR(rom()->WriteWord(addr + (i * 8), tl));
262
263 auto tr = gfx::TileInfoToWord(t2);
264 RETURN_IF_ERROR(rom()->WriteWord(addr + 2 + (i * 8), tr));
265
266 auto bl = gfx::TileInfoToWord(t3);
267 RETURN_IF_ERROR(rom()->WriteWord(addr + 4 + (i * 8), bl));
268
269 auto br = gfx::TileInfoToWord(t4);
270 RETURN_IF_ERROR(rom()->WriteWord(addr + 6 + (i * 8), br));
271 }
272 return absl::OkStatus();
273}
274
276 auto &current_dungeon = dungeon_maps_[selected_dungeon];
277 if (ImGui::BeginTabBar("##DungeonMapTabs")) {
278 auto nbr_floors =
279 current_dungeon.nbr_of_floor + current_dungeon.nbr_of_basement;
280 for (int i = 0; i < nbr_floors; i++) {
281 int basement_num = current_dungeon.nbr_of_basement - i;
282 std::string tab_name = absl::StrFormat("Basement %d", basement_num);
283 if (i >= current_dungeon.nbr_of_basement) {
284 tab_name = absl::StrFormat("Floor %d",
285 i - current_dungeon.nbr_of_basement + 1);
286 }
287
288 if (ImGui::BeginTabItem(tab_name.c_str())) {
289 floor_number = i;
290 screen_canvas_.DrawBackground(ImVec2(325, 325));
291 screen_canvas_.DrawTileSelector(64.f);
292
293 auto boss_room = current_dungeon.boss_room;
294 for (int j = 0; j < 25; j++) {
295 if (current_dungeon.floor_rooms[floor_number][j] != 0x0F) {
296 int tile16_id = current_dungeon.floor_gfx[floor_number][j];
297 int posX = ((j % 5) * 32);
298 int posY = ((j / 5) * 32);
299
300 if (tile16_individual_.count(tile16_id) == 0) {
301 tile16_individual_[tile16_id] =
302 tile16_sheet_.GetTile16(tile16_id);
304 &tile16_individual_[tile16_id]);
305 }
306 screen_canvas_.DrawBitmap(tile16_individual_[tile16_id], (posX * 2),
307 (posY * 2), 4.0f);
308
309 if (current_dungeon.floor_rooms[floor_number][j] == boss_room) {
310 screen_canvas_.DrawOutlineWithColor((posX * 2), (posY * 2), 64,
311 64, kRedPen);
312 }
313
314 std::string label =
316 screen_canvas_.DrawText(label, (posX * 2), (posY * 2));
317 std::string gfx_id = util::HexByte(tile16_id);
318 screen_canvas_.DrawText(gfx_id, (posX * 2), (posY * 2) + 16);
319 }
320 }
321
322 screen_canvas_.DrawGrid(64.f, 5);
323 screen_canvas_.DrawOverlay();
324
325 if (!screen_canvas_.points().empty()) {
326 int x = screen_canvas_.points().front().x / 64;
327 int y = screen_canvas_.points().front().y / 64;
328 selected_room = x + (y * 5);
329 }
330 ImGui::EndTabItem();
331 }
332 }
333 ImGui::EndTabBar();
334 }
335
337 "Selected Room",
338 &current_dungeon.floor_rooms[floor_number].at(selected_room));
339
340 gui::InputHexWord("Boss Room", &current_dungeon.boss_room);
341
342 const ImVec2 button_size = ImVec2(130, 0);
343
344 // Add Floor Button
345 if (ImGui::Button("Add Floor", button_size) &&
346 current_dungeon.nbr_of_floor < 8) {
347 current_dungeon.nbr_of_floor++;
349 }
350 ImGui::SameLine();
351 if (ImGui::Button("Remove Floor", button_size) &&
352 current_dungeon.nbr_of_floor > 0) {
353 current_dungeon.nbr_of_floor--;
355 }
356
357 // Add Basement Button
358 if (ImGui::Button("Add Basement", button_size) &&
359 current_dungeon.nbr_of_basement < 8) {
360 current_dungeon.nbr_of_basement++;
362 }
363 ImGui::SameLine();
364 if (ImGui::Button("Remove Basement", button_size) &&
365 current_dungeon.nbr_of_basement > 0) {
366 current_dungeon.nbr_of_basement--;
368 }
369
370 if (ImGui::Button("Copy Floor", button_size)) {
371 copy_button_pressed = true;
372 }
373 ImGui::SameLine();
374 if (ImGui::Button("Paste Floor", button_size)) {
376 }
377}
378
380 if (ImGui::BeginChild("##DungeonMapTiles", ImVec2(0, 0), true)) {
381 tilesheet_canvas_.DrawBackground(ImVec2((256 * 2) + 2, (192 * 2) + 4));
382 tilesheet_canvas_.DrawContextMenu();
383 tilesheet_canvas_.DrawTileSelector(32.f);
384 tilesheet_canvas_.DrawBitmap(*tile16_sheet_.bitmap(), 2, true);
385 tilesheet_canvas_.DrawGrid(32.f);
386 tilesheet_canvas_.DrawOverlay();
387
388 if (!tilesheet_canvas_.points().empty()) {
389 selected_tile16_ = tilesheet_canvas_.points().front().x / 32 +
390 (tilesheet_canvas_.points().front().y / 32) * 16;
392
393 // Draw the selected tile
394 if (!screen_canvas_.points().empty()) {
397 tilesheet_canvas_.mutable_points()->clear();
398 }
399 }
400
401 ImGui::Separator();
402 current_tile_canvas_.DrawBackground(); // ImVec2(64 * 2 + 2, 64 * 2 + 4));
403 current_tile_canvas_.DrawContextMenu();
405 16)) {
406 // Modify the tile16 based on the selected tile and current_tile16_info
407 }
409 4.0f);
410 current_tile_canvas_.DrawGrid(16.f);
411 current_tile_canvas_.DrawOverlay();
412
414 ImGui::SameLine();
417 ImGui::SameLine();
419
420 if (ImGui::Button("Modify Tile16")) {
421 tile16_sheet_.ModifyTile16(
422 rom()->graphics_buffer(), current_tile16_info.tiles[0],
423 current_tile16_info.tiles[1], current_tile16_info.tiles[2],
428 *rom()->mutable_dungeon_palette(3)));
431 }
432 }
433 ImGui::EndChild();
434}
435
438 if (!LoadDungeonMaps().ok()) {
439 ImGui::Text("Failed to load dungeon maps");
440 }
441
442 if (LoadDungeonMapTile16(rom()->graphics_buffer()).ok()) {
443 // TODO: Load roomset gfx based on dungeon ID
444 sheets_.emplace(0, GraphicsSheetManager::GetInstance().gfx_sheets()[212]);
445 sheets_.emplace(1, GraphicsSheetManager::GetInstance().gfx_sheets()[213]);
446 sheets_.emplace(2, GraphicsSheetManager::GetInstance().gfx_sheets()[214]);
447 sheets_.emplace(3, GraphicsSheetManager::GetInstance().gfx_sheets()[215]);
448 int current_tile8 = 0;
449 int tile_data_offset = 0;
450 for (int i = 0; i < 4; ++i) {
451 for (int j = 0; j < 32; j++) {
452 std::vector<uint8_t> tile_data(64, 0); // 8x8 tile (64 bytes
453 int tile_index = current_tile8 + j;
454 int x = (j % 8) * 8;
455 int y = (j / 8) * 8;
456 sheets_[i].Get8x8Tile(tile_index, 0, 0, tile_data, tile_data_offset);
457 tile8_individual_.emplace_back(gfx::Bitmap(8, 8, 4, tile_data));
458 RETURN_VOID_IF_ERROR(tile8_individual_.back().ApplyPalette(
459 *rom()->mutable_dungeon_palette(3)));
461 }
462 tile_data_offset = 0;
463 }
465 } else {
466 ImGui::Text("Failed to load dungeon map tile16");
467 }
468 }
469
470 if (ImGui::BeginTable("##DungeonMapToolset", 2,
471 ImGuiTableFlags_SizingFixedFit)) {
472 ImGui::TableSetupColumn("Draw Mode");
473 ImGui::TableSetupColumn("Edit Mode");
474
475 ImGui::TableNextColumn();
476 if (ImGui::Button(ICON_MD_DRAW)) {
478 }
479
480 ImGui::TableNextColumn();
481 if (ImGui::Button(ICON_MD_EDIT)) {
483 }
484
485 ImGui::EndTable();
486 }
487
488 static std::vector<std::string> dungeon_names = {
489 "Sewers/Sanctuary", "Hyrule Castle", "Eastern Palace",
490 "Desert Palace", "Tower of Hera", "Agahnim's Tower",
491 "Palace of Darkness", "Swamp Palace", "Skull Woods",
492 "Thieves' Town", "Ice Palace", "Misery Mire",
493 "Turtle Rock", "Ganon's Tower"};
494
495 if (ImGui::BeginTable("DungeonMapsTable", 4,
496 ImGuiTableFlags_Resizable |
497 ImGuiTableFlags_Reorderable |
498 ImGuiTableFlags_Hideable)) {
499 ImGui::TableSetupColumn("Dungeon");
500 ImGui::TableSetupColumn("Map");
501 ImGui::TableSetupColumn("Rooms Gfx");
502 ImGui::TableSetupColumn("Tiles Gfx");
503 ImGui::TableHeadersRow();
504
505 ImGui::TableNextColumn();
506 for (int i = 0; i < dungeon_names.size(); i++) {
507 rom()->resource_label()->SelectableLabelWithNameEdit(
508 selected_dungeon == i, "Dungeon Names", absl::StrFormat("%d", i),
509 dungeon_names[i]);
510 if (ImGui::IsItemClicked()) {
512 }
513 }
514
515 ImGui::TableNextColumn();
517
518 ImGui::TableNextColumn();
520
521 ImGui::TableNextColumn();
522 tilemap_canvas_.DrawBackground();
523 tilemap_canvas_.DrawContextMenu();
524 if (tilemap_canvas_.DrawTileSelector(16.f)) {
525 // Get the tile8 ID to use for the tile16 drawing above
526 selected_tile8_ = tilemap_canvas_.GetTileIdFromMousePos();
527 }
528 tilemap_canvas_.DrawBitmapTable(sheets_);
529 tilemap_canvas_.DrawGrid();
530 tilemap_canvas_.DrawOverlay();
531
532 ImGui::Text("Selected tile8: %d", selected_tile8_);
533 ImGui::Separator();
534 ImGui::Text("For use with custom inserted graphics assembly patches.");
535 if (ImGui::Button("Load GFX from BIN file")) LoadBinaryGfx();
536
537 ImGui::EndTable();
538 }
539}
540
542 std::string bin_file = core::FileDialogWrapper::ShowOpenFileDialog();
543 if (!bin_file.empty()) {
544 std::ifstream file(bin_file, std::ios::binary);
545 if (file.is_open()) {
546 // Read the gfx data into a buffer
547 std::vector<uint8_t> bin_data((std::istreambuf_iterator<char>(file)),
548 std::istreambuf_iterator<char>());
549 auto converted_bin = gfx::SnesTo8bppSheet(bin_data, 4, 4);
550 gfx_bin_data_ = converted_bin;
551 tile16_sheet_.clear();
552 if (LoadDungeonMapTile16(converted_bin, true).ok()) {
553 sheets_.clear();
554 std::vector<std::vector<uint8_t>> gfx_sheets;
555 for (int i = 0; i < 4; i++) {
556 gfx_sheets.emplace_back(converted_bin.begin() + (i * 0x1000),
557 converted_bin.begin() + ((i + 1) * 0x1000));
558 sheets_.emplace(i, gfx::Bitmap(128, 32, 8, gfx_sheets[i]));
559 status_ = sheets_[i].ApplyPalette(*rom()->mutable_dungeon_palette(3));
560 if (status_.ok()) {
562 }
563 }
564 binary_gfx_loaded_ = true;
565 } else {
566 status_ = absl::InternalError("Failed to load dungeon map tile16");
567 }
568 file.close();
569 }
570 }
571}
572
574 if (ImGui::BeginTabItem("Title Screen")) {
575 ImGui::EndTabItem();
576 }
577}
578
580 if (ImGui::BeginTabItem("Naming Screen")) {
581 ImGui::EndTabItem();
582 }
583}
584
586 if (ImGui::BeginTabItem("Overworld Map")) {
587 ImGui::EndTabItem();
588 }
589}
590
592 static bool show_bg1 = true;
593 static bool show_bg2 = true;
594 static bool show_bg3 = true;
595
596 static bool drawing_bg1 = true;
597 static bool drawing_bg2 = false;
598 static bool drawing_bg3 = false;
599
600 ImGui::Checkbox("Show BG1", &show_bg1);
601 ImGui::SameLine();
602 ImGui::Checkbox("Show BG2", &show_bg2);
603
604 ImGui::Checkbox("Draw BG1", &drawing_bg1);
605 ImGui::SameLine();
606 ImGui::Checkbox("Draw BG2", &drawing_bg2);
607 ImGui::SameLine();
608 ImGui::Checkbox("Draw BG3", &drawing_bg3);
609}
610
611} // namespace editor
612} // namespace yaze
static GraphicsSheetManager & GetInstance()
Definition rom.h:271
auto rom()
Definition rom.h:383
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath.
void RenderBitmap(gfx::Bitmap *bitmap)
Used to render a bitmap to the screen.
Definition renderer.h:48
static Renderer & GetInstance()
Definition renderer.h:26
absl::Status LoadDungeonMapTile16(const std::vector< uint8_t > &gfx_data, bool bin_mode=false)
std::vector< gfx::Bitmap > tile8_individual_
absl::Status SaveDungeonMapTile16()
absl::Status Update() override
std::vector< uint8_t > gfx_bin_data_
std::vector< std::vector< std::array< std::string, 25 > > > dungeon_map_labels_
zelda3::Inventory inventory_
std::vector< zelda3::DungeonMap > dungeon_maps_
std::unordered_map< int, gfx::Bitmap > tile16_individual_
gfx::InternalTile16 current_tile16_info
Represents a bitmap image.
Definition bitmap.h:66
SNES 16-bit tile metadata container.
Definition snes_tile.h:49
#define ICON_MD_MORE_VERT
Definition icons.h:1241
#define ICON_MD_DRAW
Definition icons.h:623
#define ICON_MD_ZOOM_OUT
Definition icons.h:2191
#define ICON_MD_REDO
Definition icons.h:1568
#define ICON_MD_EDIT
Definition icons.h:643
#define ICON_MD_BUILD
Definition icons.h:326
#define ICON_MD_ZOOM_IN
Definition icons.h:2189
#define ICON_MD_UNDO
Definition icons.h:2034
#define RETURN_IF_ERROR(expression)
Definition macro.h:62
#define END_TAB_ITEM()
Definition macro.h:5
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:70
#define TEXT_COLUMN(w)
Definition macro.h:16
#define TAB_ITEM(w)
Definition macro.h:4
#define RETURN_VOID_IF_ERROR(expression)
Definition macro.h:53
#define BUTTON_COLUMN(w)
Definition macro.h:12
Editors are the view controllers for the application.
constexpr uint32_t kRedPen
uint16_t TileInfoToWord(TileInfo tile_info)
Definition snes_tile.cc:313
TileInfo WordToTileInfo(uint16_t word)
Definition snes_tile.cc:330
std::vector< uint8_t > SnesTo8bppSheet(const std::vector< uint8_t > &sheet, int bpp, int num_sheets)
Definition snes_tile.cc:151
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
Definition input.cc:153
bool InputTileInfo(const char *label, gfx::TileInfo *tile_info)
Definition input.cc:242
absl::Status DisplayPalette(gfx::SnesPalette &palette, bool loaded)
Definition color.cc:50
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
Definition input.cc:167
std::string HexByte(uint8_t byte, HexStringParams params)
Definition hex.cc:33
constexpr int kDungeonMapExpCheck
Definition dungeon_map.h:23
constexpr int kDungeonMapFloors
Definition dungeon_map.h:15
constexpr int kDungeonMapTile16
Definition dungeon_map.h:24
constexpr int kDungeonMapTile16Expanded
Definition dungeon_map.h:25
constexpr int kDungeonMapBossRooms
Definition dungeon_map.h:28
constexpr int kDungeonMapRoomsPtr
Definition dungeon_map.h:14
constexpr int kDungeonMapGfxPtr
Definition dungeon_map.h:17
Main namespace for the application.
Definition controller.cc:18
uint32_t SnesToPc(uint32_t addr) noexcept
Definition rom.h:328