7#include "absl/strings/str_format.h"
8#include "absl/strings/string_view.h"
18#include "imgui/imgui.h"
30 if (ImGui::BeginTabBar(
"##ScreenEditorTabBar")) {
31 if (ImGui::BeginTabItem(
"Dungeon Maps")) {
32 if (
rom()->is_loaded()) {
49 static bool create =
false;
50 if (!create &&
rom()->is_loaded()) {
58 if (ImGui::BeginTable(
"InventoryScreen", 3, ImGuiTableFlags_Resizable)) {
59 ImGui::TableSetupColumn(
"Canvas");
60 ImGui::TableSetupColumn(
"Tiles");
61 ImGui::TableSetupColumn(
"Palette");
62 ImGui::TableHeadersRow();
64 ImGui::TableNextColumn();
71 ImGui::TableNextColumn();
78 ImGui::TableNextColumn();
88 if (ImGui::BeginTable(
"InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit,
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");
113 std::vector<std::array<uint8_t, 25>> current_floor_rooms_d;
114 std::vector<std::array<uint8_t, 25>> current_floor_gfx_d;
117 uint8_t nbr_basement_d;
119 for (
int d = 0; d < 14; d++) {
120 current_floor_rooms_d.clear();
121 current_floor_gfx_d.clear();
137 nbr_basement_d &= 0x0F;
142 nbr_floor_d = nbr_floor_d >> 4;
144 total_floors_d = nbr_basement_d + nbr_floor_d;
149 for (
int i = 0; i < total_floors_d; i++) {
152 std::array<uint8_t, 25> rdata;
153 std::array<uint8_t, 25> gdata;
156 for (
int j = 0; j < 25; j++) {
158 rdata[j] =
rom()->data()[pc_ptr + j + (i * 25)];
160 if (rdata[j] == 0x0F) {
163 gdata[j] =
rom()->data()[pc_ptr_gfx++];
170 current_floor_gfx_d.push_back(gdata);
171 current_floor_rooms_d.push_back(rdata);
174 dungeon_maps_.emplace_back(boss_room_d, nbr_floor_d, nbr_basement_d,
175 current_floor_rooms_d, current_floor_gfx_d);
178 return absl::OkStatus();
182 for (
int d = 0; d < 14; d++) {
190 for (
int i = 0; i < nbr_floors + nbr_basements; i++) {
191 for (
int j = 0; j < 25; j++) {
201 return absl::OkStatus();
205 const std::vector<uint8_t> &gfx_data,
bool bin_mode) {
208 for (
int i = 0; i < 186; i++) {
226 int sheet_offset = 212;
230 tile16_sheet_.ComposeTile16(gfx_data, t1, t2, t3, t4, sheet_offset);
234 *
rom()->mutable_dungeon_palette(3)));
245 return absl::OkStatus();
249 for (
int i = 0; i < 186; i++) {
272 return absl::OkStatus();
277 if (ImGui::BeginTabBar(
"##DungeonMapTabs")) {
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);
288 if (ImGui::BeginTabItem(tab_name.c_str())) {
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);
342 const ImVec2 button_size = ImVec2(130, 0);
345 if (ImGui::Button(
"Add Floor", button_size) &&
346 current_dungeon.nbr_of_floor < 8) {
347 current_dungeon.nbr_of_floor++;
351 if (ImGui::Button(
"Remove Floor", button_size) &&
352 current_dungeon.nbr_of_floor > 0) {
353 current_dungeon.nbr_of_floor--;
358 if (ImGui::Button(
"Add Basement", button_size) &&
359 current_dungeon.nbr_of_basement < 8) {
360 current_dungeon.nbr_of_basement++;
364 if (ImGui::Button(
"Remove Basement", button_size) &&
365 current_dungeon.nbr_of_basement > 0) {
366 current_dungeon.nbr_of_basement--;
370 if (ImGui::Button(
"Copy Floor", button_size)) {
374 if (ImGui::Button(
"Paste Floor", button_size)) {
380 if (ImGui::BeginChild(
"##DungeonMapTiles", ImVec2(0, 0),
true)) {
420 if (ImGui::Button(
"Modify Tile16")) {
428 *
rom()->mutable_dungeon_palette(3)));
439 ImGui::Text(
"Failed to load dungeon maps");
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);
453 int tile_index = current_tile8 + j;
456 sheets_[i].Get8x8Tile(tile_index, 0, 0, tile_data, tile_data_offset);
459 *
rom()->mutable_dungeon_palette(3)));
462 tile_data_offset = 0;
466 ImGui::Text(
"Failed to load dungeon map tile16");
470 if (ImGui::BeginTable(
"##DungeonMapToolset", 2,
471 ImGuiTableFlags_SizingFixedFit)) {
472 ImGui::TableSetupColumn(
"Draw Mode");
473 ImGui::TableSetupColumn(
"Edit Mode");
475 ImGui::TableNextColumn();
480 ImGui::TableNextColumn();
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"};
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();
505 ImGui::TableNextColumn();
506 for (
int i = 0; i < dungeon_names.size(); i++) {
507 rom()->resource_label()->SelectableLabelWithNameEdit(
510 if (ImGui::IsItemClicked()) {
515 ImGui::TableNextColumn();
518 ImGui::TableNextColumn();
521 ImGui::TableNextColumn();
534 ImGui::Text(
"For use with custom inserted graphics assembly patches.");
535 if (ImGui::Button(
"Load GFX from BIN file"))
LoadBinaryGfx();
543 if (!bin_file.empty()) {
544 std::ifstream file(bin_file, std::ios::binary);
545 if (file.is_open()) {
547 std::vector<uint8_t> bin_data((std::istreambuf_iterator<char>(file)),
548 std::istreambuf_iterator<char>());
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));
566 status_ = absl::InternalError(
"Failed to load dungeon map tile16");
574 if (ImGui::BeginTabItem(
"Title Screen")) {
580 if (ImGui::BeginTabItem(
"Naming Screen")) {
586 if (ImGui::BeginTabItem(
"Overworld Map")) {
592 static bool show_bg1 =
true;
593 static bool show_bg2 =
true;
594 static bool show_bg3 =
true;
596 static bool drawing_bg1 =
true;
597 static bool drawing_bg2 =
false;
598 static bool drawing_bg3 =
false;
600 ImGui::Checkbox(
"Show BG1", &show_bg1);
602 ImGui::Checkbox(
"Show BG2", &show_bg2);
604 ImGui::Checkbox(
"Draw BG1", &drawing_bg1);
606 ImGui::Checkbox(
"Draw BG2", &drawing_bg2);
608 ImGui::Checkbox(
"Draw BG3", &drawing_bg3);
static GraphicsSheetManager & GetInstance()
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.
static Renderer & GetInstance()
void DrawTitleScreenEditor()
absl::Status LoadDungeonMapTile16(const std::vector< uint8_t > &gfx_data, bool bin_mode=false)
void DrawDungeonMapsRoomGfx()
std::vector< gfx::Bitmap > tile8_individual_
gfx::SnesPalette palette_
absl::Status SaveDungeonMapTile16()
absl::Status SaveDungeonMaps()
bool dungeon_maps_loaded_
gui::Canvas tilemap_canvas_
absl::Status Update() override
gui::Canvas screen_canvas_
absl::Status LoadDungeonMaps()
std::vector< uint8_t > gfx_bin_data_
gfx::Tilesheet tile16_sheet_
gui::Canvas current_tile_canvas_
void DrawDungeonMapsEditor()
void DrawInventoryToolset()
std::vector< std::vector< std::array< std::string, 25 > > > dungeon_map_labels_
void DrawOverworldMapEditor()
zelda3::Inventory inventory_
EditingMode current_mode_
bool paste_button_pressed
gui::Canvas tilesheet_canvas_
void DrawNamingScreenEditor()
void DrawDungeonMapsTabs()
std::vector< zelda3::DungeonMap > dungeon_maps_
std::unordered_map< int, gfx::Bitmap > tile16_individual_
void DrawInventoryMenuEditor()
gfx::InternalTile16 current_tile16_info
Represents a bitmap image.
SNES 16-bit tile metadata container.
#define ICON_MD_MORE_VERT
#define RETURN_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
#define RETURN_VOID_IF_ERROR(expression)
Editors are the view controllers for the application.
constexpr uint32_t kRedPen
uint16_t TileInfoToWord(TileInfo tile_info)
TileInfo WordToTileInfo(uint16_t word)
std::vector< uint8_t > SnesTo8bppSheet(const std::vector< uint8_t > &sheet, int bpp, int num_sheets)
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
bool InputTileInfo(const char *label, gfx::TileInfo *tile_info)
absl::Status DisplayPalette(gfx::SnesPalette &palette, bool loaded)
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
std::string HexByte(uint8_t byte, HexStringParams params)
constexpr int kDungeonMapExpCheck
constexpr int kDungeonMapFloors
constexpr int kDungeonMapTile16
constexpr int kDungeonMapTile16Expanded
constexpr int kDungeonMapBossRooms
constexpr int kDungeonMapRoomsPtr
constexpr int kDungeonMapGfxPtr
Main namespace for the application.
uint32_t SnesToPc(uint32_t addr) noexcept