7#include "absl/strings/str_format.h"
8#include "absl/strings/string_view.h"
18#include "imgui/imgui.h"
29 if (ImGui::BeginTabBar(
"##ScreenEditorTabBar")) {
30 if (ImGui::BeginTabItem(
"Dungeon Maps")) {
31 if (
rom()->is_loaded()) {
48 static bool create =
false;
49 if (!create &&
rom()->is_loaded()) {
57 if (ImGui::BeginTable(
"InventoryScreen", 3, ImGuiTableFlags_Resizable)) {
58 ImGui::TableSetupColumn(
"Canvas");
59 ImGui::TableSetupColumn(
"Tiles");
60 ImGui::TableSetupColumn(
"Palette");
61 ImGui::TableHeadersRow();
63 ImGui::TableNextColumn();
70 ImGui::TableNextColumn();
77 ImGui::TableNextColumn();
87 if (ImGui::BeginTable(
"InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit,
89 ImGui::TableSetupColumn(
"#drawTool");
90 ImGui::TableSetupColumn(
"#sep1");
91 ImGui::TableSetupColumn(
"#zoomOut");
92 ImGui::TableSetupColumn(
"#zoomIN");
93 ImGui::TableSetupColumn(
"#sep2");
94 ImGui::TableSetupColumn(
"#bg2Tool");
95 ImGui::TableSetupColumn(
"#bg3Tool");
96 ImGui::TableSetupColumn(
"#itemTool");
112 std::vector<std::array<uint8_t, 25>> current_floor_rooms_d;
113 std::vector<std::array<uint8_t, 25>> current_floor_gfx_d;
116 uint8_t nbr_basement_d;
118 for (
int d = 0; d < 14; d++) {
119 current_floor_rooms_d.clear();
120 current_floor_gfx_d.clear();
140 nbr_basement_d &= 0x0F;
146 nbr_floor_d = nbr_floor_d >> 4;
148 total_floors_d = nbr_basement_d + nbr_floor_d;
153 for (
int i = 0; i < total_floors_d; i++) {
156 std::array<uint8_t, 25> rdata;
157 std::array<uint8_t, 25> gdata;
160 for (
int j = 0; j < 25; j++) {
162 rdata[j] =
rom()->data()[pc_ptr + j + (i * 25)];
164 if (rdata[j] == 0x0F) {
167 gdata[j] =
rom()->data()[pc_ptr_gfx++];
174 current_floor_gfx_d.push_back(gdata);
175 current_floor_rooms_d.push_back(rdata);
178 dungeon_maps_.emplace_back(boss_room_d, nbr_floor_d, nbr_basement_d,
179 current_floor_rooms_d, current_floor_gfx_d);
182 return absl::OkStatus();
186 for (
int d = 0; d < 14; d++) {
194 for (
int i = 0; i < nbr_floors + nbr_basements; i++) {
195 for (
int j = 0; j < 25; j++) {
205 return absl::OkStatus();
209 const std::vector<uint8_t>& gfx_data,
bool bin_mode) {
212 for (
int i = 0; i < 186; i++) {
230 int sheet_offset = 212;
238 *
rom()->mutable_dungeon_palette(3)));
249 return absl::OkStatus();
253 for (
int i = 0; i < 186; i++) {
276 return absl::OkStatus();
281 if (ImGui::BeginTabBar(
"##DungeonMapTabs")) {
283 current_dungeon.nbr_of_floor + current_dungeon.nbr_of_basement;
284 for (
int i = 0; i < nbr_floors; i++) {
285 int basement_num = current_dungeon.nbr_of_basement - i;
286 std::string tab_name = absl::StrFormat(
"Basement %d", basement_num);
287 if (i >= current_dungeon.nbr_of_basement) {
288 tab_name = absl::StrFormat(
"Floor %d",
289 i - current_dungeon.nbr_of_basement + 1);
292 if (ImGui::BeginTabItem(tab_name.c_str())) {
297 auto boss_room = current_dungeon.boss_room;
298 for (
int j = 0; j < 25; j++) {
299 if (current_dungeon.floor_rooms[
floor_number][j] != 0x0F) {
300 int tile16_id = current_dungeon.floor_gfx[
floor_number][j];
301 int posX = ((j % 5) * 32);
302 int posY = ((j / 5) * 32);
346 const ImVec2 button_size = ImVec2(130, 0);
349 if (ImGui::Button(
"Add Floor", button_size) &&
350 current_dungeon.nbr_of_floor < 8) {
351 current_dungeon.nbr_of_floor++;
355 if (ImGui::Button(
"Remove Floor", button_size) &&
356 current_dungeon.nbr_of_floor > 0) {
357 current_dungeon.nbr_of_floor--;
362 if (ImGui::Button(
"Add Basement", button_size) &&
363 current_dungeon.nbr_of_basement < 8) {
364 current_dungeon.nbr_of_basement++;
368 if (ImGui::Button(
"Remove Basement", button_size) &&
369 current_dungeon.nbr_of_basement > 0) {
370 current_dungeon.nbr_of_basement--;
374 if (ImGui::Button(
"Copy Floor", button_size)) {
378 if (ImGui::Button(
"Paste Floor", button_size)) {
386 ImGui::Text(
"Failed to load dungeon maps");
397 ImGui::Text(
"Failed to load dungeon map tile16");
401 if (ImGui::BeginTable(
"##DungeonMapToolset", 2, ImGuiTableFlags_SizingFixedFit)) {
402 ImGui::TableSetupColumn(
"Draw Mode");
403 ImGui::TableSetupColumn(
"Edit Mode");
405 ImGui::TableNextColumn();
410 ImGui::TableNextColumn();
418 static std::vector<std::string> dungeon_names = {
419 "Sewers/Sanctuary",
"Hyrule Castle",
"Eastern Palace",
420 "Desert Palace",
"Tower of Hera",
"Agahnim's Tower",
421 "Palace of Darkness",
"Swamp Palace",
"Skull Woods",
422 "Thieves' Town",
"Ice Palace",
"Misery Mire",
423 "Turtle Rock",
"Ganon's Tower"};
425 if (ImGui::BeginTable(
"DungeonMapsTable", 4,
426 ImGuiTableFlags_Resizable |
427 ImGuiTableFlags_Reorderable |
428 ImGuiTableFlags_Hideable)) {
429 ImGui::TableSetupColumn(
"Dungeon");
430 ImGui::TableSetupColumn(
"Map");
431 ImGui::TableSetupColumn(
"Rooms Gfx");
432 ImGui::TableSetupColumn(
"Tiles Gfx");
433 ImGui::TableHeadersRow();
436 ImGui::TableNextColumn();
437 for (
int i = 0; i < dungeon_names.size(); i++) {
438 rom()->resource_label()->SelectableLabelWithNameEdit(
441 if (ImGui::IsItemClicked()) {
447 ImGui::TableNextColumn();
450 ImGui::TableNextColumn();
451 if (ImGui::BeginChild(
"##DungeonMapTiles", ImVec2(0, 0),
true)) {
487 if (ImGui::Button(
"Modify Tile16")) {
495 *
rom()->mutable_dungeon_palette(3)));
502 ImGui::TableNextColumn();
516 ImGui::Text(
"For use with custom inserted graphics assembly patches.");
517 if (ImGui::Button(
"Load GFX from BIN file"))
LoadBinaryGfx();
525 if (!bin_file.empty()) {
526 std::ifstream file(bin_file, std::ios::binary);
527 if (file.is_open()) {
529 std::vector<uint8_t> bin_data((std::istreambuf_iterator<char>(file)),
530 std::istreambuf_iterator<char>());
536 std::vector<std::vector<uint8_t>> gfx_sheets;
537 for (
int i = 0; i < 4; i++) {
538 gfx_sheets.emplace_back(converted_bin.begin() + (i * 0x1000),
539 converted_bin.begin() + ((i + 1) * 0x1000));
541 sheets_[i].ApplyPalette(*
rom()->mutable_dungeon_palette(3));
546 status_ = absl::InternalError(
"Failed to load dungeon map tile16");
554 if (ImGui::BeginTabItem(
"Title Screen")) {
560 if (ImGui::BeginTabItem(
"Naming Screen")) {
566 if (ImGui::BeginTabItem(
"Overworld Map")) {
572 static bool show_bg1 =
true;
573 static bool show_bg2 =
true;
574 static bool show_bg3 =
true;
576 static bool drawing_bg1 =
true;
577 static bool drawing_bg2 =
false;
578 static bool drawing_bg3 =
false;
580 ImGui::Checkbox(
"Show BG1", &show_bg1);
582 ImGui::Checkbox(
"Show BG2", &show_bg2);
584 ImGui::Checkbox(
"Draw BG1", &drawing_bg1);
586 ImGui::Checkbox(
"Draw BG2", &drawing_bg2);
588 ImGui::Checkbox(
"Draw BG3", &drawing_bg3);
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath.
static Renderer & GetInstance()
void RenderBitmap(gfx::Bitmap *bitmap)
Used to render a bitmap to the screen.
gui::Canvas tilemap_canvas_
std::vector< std::vector< std::array< std::string, 25 > > > dungeon_map_labels_
void DrawInventoryMenuEditor()
absl::Status LoadDungeonMapTile16(const std::vector< uint8_t > &gfx_data, bool bin_mode=false)
gui::Canvas screen_canvas_
bool dungeon_maps_loaded_
absl::Status Update() override
gfx::Tilesheet tile16_sheet_
std::vector< uint8_t > gfx_bin_data_
zelda3::screen::Inventory inventory_
gfx::InternalTile16 current_tile16_info
void DrawTitleScreenEditor()
void DrawDungeonMapsEditor()
gui::Canvas current_tile_canvas_
absl::Status SaveDungeonMaps()
gfx::SnesPalette palette_
void DrawOverworldMapEditor()
bool paste_button_pressed
EditingMode current_mode_
void DrawDungeonMapsTabs()
absl::Status LoadDungeonMaps()
void DrawNamingScreenEditor()
gui::Canvas tilesheet_canvas_
void DrawInventoryToolset()
std::vector< zelda3::screen::DungeonMap > dungeon_maps_
std::unordered_map< int, gfx::Bitmap > tile16_individual_
absl::Status SaveDungeonMapTile16()
Represents a bitmap image.
SNES 16-bit tile metadata container.
void Init(int width, int height, TileType tile_type)
Bitmap GetTile16(int tile_id)
void ModifyTile16(const std::vector< uint8_t > &graphics_buffer, const TileInfo &top_left, const TileInfo &top_right, const TileInfo &bottom_left, const TileInfo &bottom_right, int tile_id, int sheet_offset=0)
void ComposeTile16(const std::vector< uint8_t > &graphics_buffer, const TileInfo &top_left, const TileInfo &top_right, const TileInfo &bottom_left, const TileInfo &bottom_right, int sheet_offset=0)
bool DrawTileSelector(int size)
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0), bool drag=false)
int GetTileIdFromMousePos()
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
void DrawText(std::string text, int x, int y)
void DrawBitmap(const Bitmap &bitmap, int border_offset=0, bool ready=true)
void DrawOutlineWithColor(int x, int y, int w, int h, ImVec4 color)
void DrawBitmapTable(const BitmapTable &gfx_bin)
void DrawContextMenu(gfx::Bitmap *bitmap=nullptr)
#define RETURN_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
#define RETURN_VOID_IF_ERROR(expression)
#define ICON_MD_MORE_VERT
uint32_t SnesToPc(uint32_t addr) noexcept
std::string UppercaseHexByte(uint8_t byte, bool leading)
constexpr uint32_t kRedPen
TileInfo WordToTileInfo(uint16_t word)
std::vector< uint8_t > SnesTo8bppSheet(const std::vector< uint8_t > &sheet, int bpp, int num_sheets)
uint16_t TileInfoToWord(TileInfo tile_info)
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
absl::Status DisplayPalette(app::gfx::SnesPalette &palette, bool loaded)
bool InputTileInfo(const char *label, gfx::TileInfo *tile_info)
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
constexpr int kDungeonMapTile16Expanded
constexpr int kDungeonMapGfxPtr
constexpr int kDungeonMapBossRooms
constexpr int kDungeonMapTile16
constexpr int kDungeonMapFloors
constexpr int kDungeonMapRoomsPtr
constexpr int kDungeonMapExpCheck
std::array< TileInfo, 4 > tiles