7#include "absl/strings/str_format.h"
8#include "absl/strings/string_view.h"
22#include "imgui/imgui.h"
36 card_manager.RegisterCard({
37 .card_id =
"screen.dungeon_maps",
38 .display_name =
"Dungeon Maps",
41 .shortcut_hint =
"Alt+1",
46 card_manager.RegisterCard({
47 .card_id =
"screen.inventory_menu",
48 .display_name =
"Inventory Menu",
51 .shortcut_hint =
"Alt+2",
56 card_manager.RegisterCard({
57 .card_id =
"screen.overworld_map",
58 .display_name =
"Overworld Map",
61 .shortcut_hint =
"Alt+3",
66 card_manager.RegisterCard({
67 .card_id =
"screen.title_screen",
68 .display_name =
"Title Screen",
71 .shortcut_hint =
"Alt+4",
76 card_manager.RegisterCard({
77 .card_id =
"screen.naming_screen",
78 .display_name =
"Naming Screen",
81 .shortcut_hint =
"Alt+5",
118 return absl::OkStatus();
136 dungeon_maps_card.
End();
142 inventory_menu_card.
End();
148 overworld_map_card.
End();
154 title_screen_card.
End();
160 naming_screen_card.
End();
190 static bool create =
false;
191 if (!create &&
rom()->is_loaded()) {
199 if (ImGui::BeginTable(
"InventoryScreen", 3, ImGuiTableFlags_Resizable)) {
200 ImGui::TableSetupColumn(
"Canvas");
201 ImGui::TableSetupColumn(
"Tilesheet");
202 ImGui::TableSetupColumn(
"Palette");
203 ImGui::TableHeadersRow();
205 ImGui::TableNextColumn();
212 ImGui::TableNextColumn();
219 ImGui::TableNextColumn();
228 if (ImGui::BeginTable(
"InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit,
230 ImGui::TableSetupColumn(
"#drawTool");
231 ImGui::TableSetupColumn(
"#sep1");
232 ImGui::TableSetupColumn(
"#zoomOut");
233 ImGui::TableSetupColumn(
"#zoomIN");
234 ImGui::TableSetupColumn(
"#sep2");
235 ImGui::TableSetupColumn(
"#bg2Tool");
236 ImGui::TableSetupColumn(
"#bg3Tool");
237 ImGui::TableSetupColumn(
"#itemTool");
239 ImGui::TableNextColumn();
243 ImGui::TableNextColumn();
247 ImGui::TableNextColumn();
249 ImGui::TableNextColumn();
253 ImGui::TableNextColumn();
257 ImGui::TableNextColumn();
259 ImGui::TableNextColumn();
263 ImGui::TableNextColumn();
281 auto boss_room = current_dungeon.boss_room;
284 std::vector<int> tile_ids_to_render;
285 std::vector<ImVec2> tile_positions;
290 if (current_dungeon.floor_rooms[
floor_number][j] != 0x0F) {
291 int tile16_id = current_dungeon.floor_gfx[
floor_number][j];
292 int posX = ((j % 5) * 32);
293 int posY = ((j / 5) * 32);
296 tile_ids_to_render.push_back(tile16_id);
297 tile_positions.emplace_back(posX * 2, posY * 2);
302 for (
size_t idx = 0; idx < tile_ids_to_render.size(); ++idx) {
303 int tile16_id = tile_ids_to_render[idx];
304 ImVec2 pos = tile_positions[idx];
309 if (cached_tile && cached_tile->is_active()) {
311 if (!cached_tile->texture()) {
322 if (current_dungeon.floor_rooms[
floor_number][j] != 0x0F) {
323 int posX = ((j % 5) * 32);
324 int posY = ((j / 5) * 32);
326 if (current_dungeon.floor_rooms[
floor_number][j] == boss_room) {
352 if (ImGui::BeginTabBar(
"##DungeonMapTabs")) {
354 current_dungeon.nbr_of_floor + current_dungeon.nbr_of_basement;
355 for (
int i = 0; i < nbr_floors; i++) {
356 int basement_num = current_dungeon.nbr_of_basement - i;
357 std::string tab_name = absl::StrFormat(
"Basement %d", basement_num);
358 if (i >= current_dungeon.nbr_of_basement) {
359 tab_name = absl::StrFormat(
"Floor %d",
360 i - current_dungeon.nbr_of_basement + 1);
362 if (ImGui::BeginTabItem(tab_name.data())) {
376 const auto button_size = ImVec2(130, 0);
378 if (ImGui::Button(
"Add Floor", button_size) &&
379 current_dungeon.nbr_of_floor < 8) {
380 current_dungeon.nbr_of_floor++;
384 if (ImGui::Button(
"Remove Floor", button_size) &&
385 current_dungeon.nbr_of_floor > 0) {
386 current_dungeon.nbr_of_floor--;
390 if (ImGui::Button(
"Add Basement", button_size) &&
391 current_dungeon.nbr_of_basement < 8) {
392 current_dungeon.nbr_of_basement++;
396 if (ImGui::Button(
"Remove Basement", button_size) &&
397 current_dungeon.nbr_of_basement > 0) {
398 current_dungeon.nbr_of_basement--;
402 if (ImGui::Button(
"Copy Floor", button_size)) {
406 if (ImGui::Button(
"Paste Floor", button_size)) {
430 if (ImGui::BeginChild(
"##DungeonMapTiles", ImVec2(0, 0),
true)) {
471 if (selected_tile && selected_tile->is_active()) {
473 if (!selected_tile->texture()) {
490 if (ImGui::Button(
"Modify Tile16")) {
531 static std::vector<std::string> dungeon_names = {
532 "Sewers/Sanctuary",
"Hyrule Castle",
"Eastern Palace",
533 "Desert Palace",
"Tower of Hera",
"Agahnim's Tower",
534 "Palace of Darkness",
"Swamp Palace",
"Skull Woods",
535 "Thieves' Town",
"Ice Palace",
"Misery Mire",
536 "Turtle Rock",
"Ganon's Tower"};
538 if (ImGui::BeginTable(
"DungeonMapsTable", 4,
539 ImGuiTableFlags_Resizable |
540 ImGuiTableFlags_Reorderable |
541 ImGuiTableFlags_Hideable)) {
542 ImGui::TableSetupColumn(
"Dungeon");
543 ImGui::TableSetupColumn(
"Map");
544 ImGui::TableSetupColumn(
"Rooms Gfx");
545 ImGui::TableSetupColumn(
"Tiles Gfx");
546 ImGui::TableHeadersRow();
548 ImGui::TableNextColumn();
549 for (
int i = 0; i < dungeon_names.size(); i++) {
553 if (ImGui::IsItemClicked()) {
558 ImGui::TableNextColumn();
561 ImGui::TableNextColumn();
564 ImGui::TableNextColumn();
577 ImGui::Text(
"For use with custom inserted graphics assembly patches.");
578 if (ImGui::Button(
"Load GFX from BIN file"))
587 if (!bin_file.empty()) {
588 std::ifstream file(bin_file, std::ios::binary);
589 if (file.is_open()) {
591 std::vector<uint8_t> bin_data((std::istreambuf_iterator<char>(file)),
592 std::istreambuf_iterator<char>());
598 std::vector<std::vector<uint8_t>> gfx_sheets;
599 for (
int i = 0; i < 4; i++) {
600 gfx_sheets.emplace_back(converted_bin.begin() + (i * 0x1000),
601 converted_bin.begin() + ((i + 1) * 0x1000));
610 status_ = absl::InternalError(
"Failed to load dungeon map tile16");
627 static bool show_bg1 =
true;
628 static bool show_bg2 =
true;
629 static bool show_bg3 =
true;
631 static bool drawing_bg1 =
true;
632 static bool drawing_bg2 =
false;
633 static bool drawing_bg3 =
false;
635 ImGui::Checkbox(
"Show BG1", &show_bg1);
637 ImGui::Checkbox(
"Show BG2", &show_bg2);
639 ImGui::Checkbox(
"Draw BG1", &drawing_bg1);
641 ImGui::Checkbox(
"Draw BG2", &drawing_bg2);
643 ImGui::Checkbox(
"Draw BG3", &drawing_bg3);
auto mutable_dungeon_palette(int i)
core::ResourceLabelManager * resource_label()
std::string MakeCardTitle(const std::string &base_title) const
void DrawTitleScreenEditor()
void DrawDungeonMapsRoomGfx()
Draw dungeon room graphics editor with enhanced tile16 editing.
std::vector< gfx::Bitmap > tile8_individual_
gfx::SnesPalette palette_
gfx::Tilemap tile16_blockset_
gui::Canvas tilemap_canvas_
std::array< gfx::TileInfo, 4 > current_tile16_info
absl::Status Load() override
absl::Status Update() override
gui::Canvas screen_canvas_
bool show_inventory_menu_
void Initialize() override
gui::Canvas current_tile_canvas_
void DrawDungeonMapsEditor()
Draw dungeon maps editor with enhanced ROM hacking features.
void DrawInventoryToolset()
void DrawOverworldMapEditor()
zelda3::Inventory inventory_
EditingMode current_mode_
zelda3::DungeonMapLabels dungeon_map_labels_
bool paste_button_pressed
void DrawDungeonMapToolset()
gui::Canvas tilesheet_canvas_
void DrawNamingScreenEditor()
void DrawDungeonMapScreen(int i)
void DrawDungeonMapsTabs()
std::vector< zelda3::DungeonMap > dungeon_maps_
void DrawInventoryMenuEditor()
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Represents a bitmap image optimized for SNES ROM hacking.
RAII timer for automatic timing management.
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale)
void DrawOutlineWithColor(int x, int y, int w, int h, ImVec4 color)
ImVector< ImVec2 > * mutable_points()
int GetTileIdFromMousePos()
bool DrawTileSelector(int size, int size_y=0)
bool DrawTilePainter(const Bitmap &bitmap, int size, float scale=1.0f)
void DrawBitmapTable(const BitmapTable &gfx_bin)
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0))
const ImVector< ImVec2 > & points() const
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
void DrawText(const std::string &text, int x, int y)
static EditorCardManager & Get()
Draggable, dockable card for editor sub-windows.
bool Begin(bool *p_open=nullptr)
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
#define ICON_MD_MORE_VERT
#define ICON_MD_EDIT_ATTRIBUTES
#define ICON_MD_INVENTORY
#define PRINT_IF_ERROR(expression)
#define RETURN_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
constexpr uint32_t kRedPen
void RenderTile16(IRenderer *renderer, Tilemap &tilemap, int tile_id)
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)
void UpdateTile16(IRenderer *renderer, Tilemap &tilemap, int tile_id)
std::vector< uint8_t > SnesTo8bppSheet(std::span< uint8_t > sheet, int bpp, int num_sheets)
void VerticalSpacing(float pixels)
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
bool InputTileInfo(const char *label, gfx::TileInfo *tile_info)
IMGUI_API bool 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)
absl::Status LoadDungeonMapTile16(gfx::Tilemap &tile16_blockset, Rom &rom, const std::vector< uint8_t > &gfx_data, bool bin_mode)
Load the dungeon map tile16 from the ROM.
absl::Status SaveDungeonMapTile16(gfx::Tilemap &tile16_blockset, Rom &rom)
Save the dungeon map tile16 to the ROM.
absl::StatusOr< std::vector< DungeonMap > > LoadDungeonMaps(Rom &rom, DungeonMapLabels &dungeon_map_labels)
Load the dungeon maps from the ROM.
Main namespace for the application.
void SelectableLabelWithNameEdit(bool selected, const std::string &type, const std::string &key, const std::string &defaultValue)
Bitmap * GetTile(int tile_id)
Get a cached tile by ID.
TileCache tile_cache
Smart tile cache with LRU eviction.
Bitmap atlas
Master bitmap containing all tiles.
std::vector< std::array< gfx::TileInfo, 4 > > tile_info
Tile metadata (4 tiles per 16x16)