8#include "absl/strings/str_format.h"
20#include "imgui/imgui.h"
34 {.card_id =
"screen.dungeon_maps",
35 .display_name =
"Dungeon Maps",
36 .window_title =
" Dungeon Map Editor",
39 .shortcut_hint =
"Alt+1",
41 .enabled_condition = [
this]() {
return rom()->
is_loaded(); },
42 .disabled_tooltip =
"Load a ROM first"});
43 window_manager->RegisterPanel(
44 {.card_id =
"screen.inventory_menu",
45 .display_name =
"Inventory Menu",
46 .window_title =
" Inventory Menu",
49 .shortcut_hint =
"Alt+2",
51 .enabled_condition = [
this]() {
return rom()->
is_loaded(); },
52 .disabled_tooltip =
"Load a ROM first"});
53 window_manager->RegisterPanel(
54 {.card_id =
"screen.overworld_map",
55 .display_name =
"Overworld Map",
56 .window_title =
" Overworld Map",
59 .shortcut_hint =
"Alt+3",
61 .enabled_condition = [
this]() {
return rom()->
is_loaded(); },
62 .disabled_tooltip =
"Load a ROM first"});
63 window_manager->RegisterPanel(
64 {.card_id =
"screen.title_screen",
65 .display_name =
"Title Screen",
66 .window_title =
" Title Screen",
69 .shortcut_hint =
"Alt+4",
71 .enabled_condition = [
this]() {
return rom()->
is_loaded(); },
72 .disabled_tooltip =
"Load a ROM first"});
73 window_manager->RegisterPanel(
74 {.card_id =
"screen.naming_screen",
75 .display_name =
"Naming Screen",
76 .window_title =
" Naming Screen",
79 .shortcut_hint =
"Alt+5",
81 .enabled_condition = [
this]() {
return rom()->
is_loaded(); },
82 .disabled_tooltip =
"Load a ROM first"});
85 window_manager->RegisterWindowContent(std::make_unique<DungeonMapsPanel>(
87 window_manager->RegisterWindowContent(std::make_unique<InventoryMenuPanel>(
89 window_manager->RegisterWindowContent(std::make_unique<OverworldMapScreenPanel>(
91 window_manager->RegisterWindowContent(std::make_unique<TitleScreenPanel>(
93 window_manager->RegisterWindowContent(std::make_unique<NamingScreenPanel>(
97 window_manager->OpenWindow(
"screen.title_screen");
121 for (
int i = 0; i < 4; i++) {
123 *
game_data()->palette_groups.dungeon_main.mutable_palette(3));
131 const int tile8_width = 128;
132 const int tile8_height = 128;
133 std::vector<uint8_t> tile8_data(tile8_width * tile8_height);
136 for (
int sheet_idx = 0; sheet_idx < 4; sheet_idx++) {
137 const auto& sheet = *
sheets_[sheet_idx];
138 int dest_y_offset = sheet_idx * 32;
140 for (
int y = 0; y < 32; y++) {
141 for (
int x = 0; x < 128; x++) {
142 int src_index = y * 128 + x;
143 int dest_index = (dest_y_offset + y) * 128 + x;
145 if (src_index < sheet.size() && dest_index < tile8_data.size()) {
146 tile8_data[dest_index] = sheet.data()[src_index];
162 return absl::OkStatus();
172 return absl::OkStatus();
195 ImGui::TextColored(theme.text_error_red,
"Error loading inventory: %s",
203 if (ImGui::BeginTable(
"InventoryScreen", 4, ImGuiTableFlags_Resizable)) {
204 ImGui::TableSetupColumn(
"Canvas");
205 ImGui::TableSetupColumn(
"Tilesheet");
206 ImGui::TableSetupColumn(
"Item Icons");
207 ImGui::TableSetupColumn(
"Palette");
208 ImGui::TableHeadersRow();
210 ImGui::TableNextColumn();
222 ImGui::TableNextColumn();
225 frame_opts.
canvas_size = ImVec2(128 * 2 + 2, (192 * 2) + 4);
235 ImGui::TableNextColumn();
238 ImGui::TableNextColumn();
254 if (ImGui::BeginTable(
"InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit,
256 ImGui::TableSetupColumn(
"#drawTool");
257 ImGui::TableSetupColumn(
"#sep1");
258 ImGui::TableSetupColumn(
"#zoomOut");
259 ImGui::TableSetupColumn(
"#zoomIN");
260 ImGui::TableSetupColumn(
"#sep2");
261 ImGui::TableSetupColumn(
"#bg2Tool");
262 ImGui::TableSetupColumn(
"#bg3Tool");
263 ImGui::TableSetupColumn(
"#itemTool");
265 ImGui::TableNextColumn();
270 ImGui::EndDisabled();
271 ImGui::TableNextColumn();
276 ImGui::EndDisabled();
277 ImGui::TableNextColumn();
279 ImGui::TableNextColumn();
283 ImGui::TableNextColumn();
287 ImGui::TableNextColumn();
289 ImGui::TableNextColumn();
293 ImGui::TableNextColumn();
303 if (ImGui::BeginChild(
"##ItemIconsList", ImVec2(0, 0),
true,
304 ImGuiWindowFlags_HorizontalScrollbar)) {
305 ImGui::Text(
"Item Icons (2x2 tiles each)");
311 "No item icons loaded. Icons will be loaded when the "
312 "inventory is initialized.");
318 if (ImGui::BeginTable(
"##IconsTable", 2,
319 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
320 ImGui::TableSetupColumn(
"Icon Name");
321 ImGui::TableSetupColumn(
"Tile Data");
322 ImGui::TableHeadersRow();
324 for (
size_t i = 0; i < icons.size(); i++) {
325 const auto& icon = icons[i];
327 ImGui::TableNextRow();
328 ImGui::TableNextColumn();
331 if (ImGui::Selectable(icon.name.c_str(),
false,
332 ImGuiSelectableFlags_SpanAllColumns)) {
336 ImGui::TableNextColumn();
338 ImGui::Text(
"TL:%04X TR:%04X", icon.tile_tl, icon.tile_tr);
340 ImGui::Text(
"BL:%04X BR:%04X", icon.tile_bl, icon.tile_br);
348 "NOTE: Individual icon editing will be implemented in the future "
349 "Oracle of Secrets menu editor. Each icon is composed of 4 tile words "
350 "representing a 2x2 arrangement of 8x8 tiles in SNES tile format "
351 "(vhopppcc cccccccc).");
366 auto boss_room = current_dungeon.boss_room;
369 std::vector<int> tile_ids_to_render;
370 std::vector<ImVec2> tile_positions;
375 if (current_dungeon.floor_rooms[
floor_number][j] != 0x0F) {
376 int tile16_id = current_dungeon.floor_gfx[
floor_number][j];
377 int posX = ((j % 5) * 32);
378 int posY = ((j / 5) * 32);
381 tile_ids_to_render.push_back(tile16_id);
382 tile_positions.emplace_back(posX * 2, posY * 2);
387 for (
size_t idx = 0; idx < tile_ids_to_render.size(); ++idx) {
388 int tile16_id = tile_ids_to_render[idx];
389 ImVec2 pos = tile_positions[idx];
393 const int tile_x = (tile16_id % tiles_per_row) * 16;
394 const int tile_y = (tile16_id / tiles_per_row) * 16;
396 std::vector<uint8_t> tile_data(16 * 16);
397 int tile_data_offset = 0;
414 if (cached_tile && cached_tile->is_active()) {
416 if (!cached_tile->texture()) {
427 if (current_dungeon.floor_rooms[
floor_number][j] != 0x0F) {
428 int posX = ((j % 5) * 32);
429 int posY = ((j / 5) * 32);
431 if (current_dungeon.floor_rooms[
floor_number][j] == boss_room) {
459 current_dungeon.nbr_of_floor + current_dungeon.nbr_of_basement;
460 for (
int i = 0; i < nbr_floors; i++) {
461 int basement_num = current_dungeon.nbr_of_basement - i;
462 std::string tab_name = absl::StrFormat(
"Basement %d", basement_num);
463 if (i >= current_dungeon.nbr_of_basement) {
464 tab_name = absl::StrFormat(
"Floor %d",
465 i - current_dungeon.nbr_of_basement + 1);
467 if (ImGui::BeginTabItem(tab_name.data())) {
484 "Edit room assignment"));
499 const auto button_size = ImVec2(130, 0);
501 if (ImGui::Button(
"Add Floor", button_size) &&
502 current_dungeon.nbr_of_floor < 8) {
504 current_dungeon.nbr_of_floor++;
509 if (ImGui::Button(
"Remove Floor", button_size) &&
510 current_dungeon.nbr_of_floor > 0) {
512 current_dungeon.nbr_of_floor--;
517 if (ImGui::Button(
"Add Basement", button_size) &&
518 current_dungeon.nbr_of_basement < 8) {
520 current_dungeon.nbr_of_basement++;
525 if (ImGui::Button(
"Remove Basement", button_size) &&
526 current_dungeon.nbr_of_basement > 0) {
528 current_dungeon.nbr_of_basement--;
533 if (ImGui::Button(
"Copy Floor", button_size)) {
537 if (ImGui::Button(
"Paste Floor", button_size)) {
561 if (ImGui::BeginChild(
"##DungeonMapTiles", ImVec2(0, 0),
true)) {
565 tilesheet_opts.
canvas_size = ImVec2((256 * 2) + 2, (192 * 2) + 4);
580 ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
617 auto current_tile_rt =
626 const int tiles_per_row =
632 std::vector<uint8_t> tile_data(64);
633 for (
int py = 0; py < 8; py++) {
634 for (
int px = 0; px < 8; px++) {
635 int src_x = tile_x + px;
636 int src_y = tile_y + py;
638 int dst_index = py * 8 + px;
649 std::move(new_tile8));
653 if (cached_tile8 && cached_tile8->is_active()) {
655 if (!cached_tile8->texture()) {
677 auto* selected_tile =
679 if (selected_tile && selected_tile->is_active()) {
681 if (!selected_tile->texture()) {
698 if (ImGui::Button(
"Modify Tile16")) {
742 static std::vector<std::string> dungeon_names = {
743 "Sewers/Sanctuary",
"Hyrule Castle",
"Eastern Palace",
744 "Desert Palace",
"Tower of Hera",
"Agahnim's Tower",
745 "Palace of Darkness",
"Swamp Palace",
"Skull Woods",
746 "Thieves' Town",
"Ice Palace",
"Misery Mire",
747 "Turtle Rock",
"Ganon's Tower"};
749 if (ImGui::BeginTable(
"DungeonMapsTable", 4,
750 ImGuiTableFlags_Resizable |
751 ImGuiTableFlags_Reorderable |
752 ImGuiTableFlags_Hideable)) {
753 ImGui::TableSetupColumn(
"Dungeon");
754 ImGui::TableSetupColumn(
"Map");
755 ImGui::TableSetupColumn(
"Rooms Gfx");
756 ImGui::TableSetupColumn(
"Tiles Gfx");
757 ImGui::TableHeadersRow();
759 ImGui::TableNextColumn();
760 for (
int i = 0; i < dungeon_names.size(); i++) {
764 if (ImGui::IsItemClicked()) {
769 ImGui::TableNextColumn();
772 ImGui::TableNextColumn();
775 ImGui::TableNextColumn();
788 ImGui::Text(
"For use with custom inserted graphics assembly patches.");
789 if (ImGui::Button(
"Load GFX from BIN file"))
798 if (!bin_file.empty()) {
799 std::ifstream file(bin_file, std::ios::binary);
800 if (file.is_open()) {
802 std::vector<uint8_t> bin_data((std::istreambuf_iterator<char>(file)),
803 std::istreambuf_iterator<char>());
809 std::vector<std::vector<uint8_t>> gfx_sheets;
810 for (
int i = 0; i < 4; i++) {
811 gfx_sheets.emplace_back(converted_bin.begin() + (i * 0x1000),
812 converted_bin.begin() + ((i + 1) * 0x1000));
813 sheets_[i] = std::make_unique<gfx::Bitmap>(128, 32, 8, gfx_sheets[i]);
815 *
game_data()->palette_groups.dungeon_main.mutable_palette(3));
822 status_ = absl::InternalError(
"Failed to load dungeon map tile16");
835 ImGui::TextColored(theme.text_error_red,
"Error loading title screen: %s",
843 ImGui::Text(
"Title screen not loaded. Ensure ROM is loaded.");
855 ImGui::OpenPopup(
"SaveSuccess");
862 if (ImGui::BeginPopup(
"SaveSuccess")) {
863 ImGui::Text(
"Title screen saved successfully!");
886 if (ImGui::BeginTable(
"TitleScreenTable", 2,
887 ImGuiTableFlags_Resizable | ImGuiTableFlags_Borders)) {
888 ImGui::TableSetupColumn(
"Title Screen (Composite)");
889 ImGui::TableSetupColumn(
"Tile Selector");
890 ImGui::TableHeadersRow();
893 ImGui::TableNextColumn();
897 ImGui::TableNextColumn();
910 if (composite_bitmap.is_active()) {
919 int tile_x =
static_cast<int>(click_pos.x) / 8;
920 int tile_y =
static_cast<int>(click_pos.y) / 8;
922 if (tile_x >= 0 && tile_x < 32 && tile_y >= 0 && tile_y < 32) {
923 int tilemap_index = tile_y * 32 + tile_x;
965 if (bg1_bitmap.is_active()) {
974 int tile_x =
static_cast<int>(click_pos.x) / 8;
975 int tile_y =
static_cast<int>(click_pos.y) / 8;
977 if (tile_x >= 0 && tile_x < 32 && tile_y >= 0 && tile_y < 32) {
978 int tilemap_index = tile_y * 32 + tile_x;
1010 if (bg2_bitmap.is_active()) {
1019 int tile_x =
static_cast<int>(click_pos.x) / 8;
1020 int tile_y =
static_cast<int>(click_pos.y) / 8;
1022 if (tile_x >= 0 && tile_x < 32 && tile_y >= 0 && tile_y < 32) {
1023 int tilemap_index = tile_y * 32 + tile_x;
1029 tile_word |= 0x4000;
1031 tile_word |= 0x8000;
1055 if (tiles8_bitmap.is_active()) {
1064 int tile_x =
static_cast<int>(click_pos.x) / 8;
1065 int tile_y =
static_cast<int>(click_pos.y) / 8;
1066 int tiles_per_row = 128 / 8;
1084 ImGui::SetNextItemWidth(100);
1097 ImGui::TextColored(theme.text_error_red,
1098 "Error loading overworld map: %s",
1106 ImGui::Text(
"Overworld map not loaded. Ensure ROM is loaded.");
1118 ImGui::OpenPopup(
"OWSaveSuccess");
1136 if (ImGui::Button(
"Load Custom Map...")) {
1138 if (!path.empty()) {
1141 ImGui::OpenPopup(
"CustomMapLoadError");
1146 if (ImGui::Button(
"Save Custom Map...")) {
1148 if (!path.empty()) {
1151 ImGui::OpenPopup(
"CustomMapSaveSuccess");
1160 if (ImGui::BeginPopup(
"CustomMapLoadError")) {
1161 ImGui::Text(
"Error loading custom map: %s",
status_.message().data());
1164 if (ImGui::BeginPopup(
"CustomMapSaveSuccess")) {
1165 ImGui::Text(
"Custom map saved successfully!");
1170 if (ImGui::BeginPopup(
"OWSaveSuccess")) {
1171 ImGui::Text(
"Overworld map saved successfully!");
1176 if (ImGui::BeginTable(
"OWMapTable", 3,
1177 ImGuiTableFlags_Resizable | ImGuiTableFlags_Borders)) {
1178 ImGui::TableSetupColumn(
"Map Canvas");
1179 ImGui::TableSetupColumn(
"Tileset");
1180 ImGui::TableSetupColumn(
"Palette");
1181 ImGui::TableHeadersRow();
1184 ImGui::TableNextColumn();
1189 if (map_bitmap.is_active()) {
1198 int tile_x =
static_cast<int>(click_pos.x) / 8;
1199 int tile_y =
static_cast<int>(click_pos.y) / 8;
1201 if (tile_x >= 0 && tile_x < 64 && tile_y >= 0 && tile_y < 64) {
1202 int tile_index = tile_x + (tile_y * 64);
1226 ImGui::TableNextColumn();
1231 if (tiles8_bitmap.is_active()) {
1239 int tile_x =
static_cast<int>(click_pos.x) / 8;
1240 int tile_y =
static_cast<int>(click_pos.y) / 8;
1249 ImGui::TableNextColumn();
1260 static bool show_bg1 =
true;
1261 static bool show_bg2 =
true;
1262 static bool show_bg3 =
true;
1264 static bool drawing_bg1 =
true;
1265 static bool drawing_bg2 =
false;
1266 static bool drawing_bg3 =
false;
1268 ImGui::Checkbox(
"Show BG1", &show_bg1);
1270 ImGui::Checkbox(
"Show BG2", &show_bg2);
1272 ImGui::Checkbox(
"Draw BG1", &drawing_bg1);
1274 ImGui::Checkbox(
"Draw BG2", &drawing_bg2);
1276 ImGui::Checkbox(
"Draw BG3", &drawing_bg3);
1343 if (idx >= 0 && idx <
static_cast<int>(
dungeon_maps_.size())) {
project::ResourceLabelManager * resource_label()
UndoManager undo_manager_
zelda3::GameData * game_data() const
EditorDependencies dependencies_
void DrawTitleScreenEditor()
void DrawDungeonMapsRoomGfx()
Draw dungeon room graphics editor with enhanced tile16 editing.
gfx::SnesPalette palette_
absl::Status Undo() override
void DrawTitleScreenBlocksetSelector()
bool title_screen_loaded_
ScreenSnapshot CaptureTile16CompSnapshot() const
gui::Canvas ow_map_canvas_
gfx::Tilemap tile16_blockset_
ScreenSnapshot pending_dungeon_before_
void DrawTitleScreenBG2Canvas()
gui::Canvas tilemap_canvas_
void DrawInventoryItemIcons()
std::array< gfx::TileInfo, 4 > current_tile16_info
absl::Status Save() override
absl::Status Load() override
void SaveDungeonMapUndoState(const std::string &description)
absl::Status Update() override
gui::Canvas screen_canvas_
std::string pending_tile16_desc_
void DrawTitleScreenBG1Canvas()
gui::Canvas title_bg1_canvas_
void RestoreFromSnapshot(const ScreenSnapshot &snapshot)
zelda3::OverworldMapScreen ow_map_screen_
ScreenSnapshot pending_tile16_before_
void Initialize() override
int selected_title_tile16_
ScreenSnapshot CaptureDungeonMapSnapshot() const
gui::Canvas current_tile_canvas_
void DrawDungeonMapsEditor()
Draw dungeon maps editor with enhanced ROM hacking features.
gui::Canvas title_bg2_canvas_
absl::Status Redo() override
void SaveTile16CompUndoState(const std::string &description)
void DrawInventoryToolset()
void CommitTile16CompUndo()
gfx::Tilemap tile8_tilemap_
bool has_pending_dungeon_undo_
void DrawTitleScreenCompositeCanvas()
zelda3::TitleScreen title_screen_
void DrawOverworldMapEditor()
zelda3::Inventory inventory_
EditingMode current_mode_
zelda3::DungeonMapLabels dungeon_map_labels_
bool paste_button_pressed
gui::Canvas ow_tileset_canvas_
gui::Canvas title_blockset_canvas_
void DrawDungeonMapToolset()
gui::Canvas tilesheet_canvas_
void DrawNamingScreenEditor()
void DrawDungeonMapScreen(int i)
bool has_pending_tile16_undo_
void DrawDungeonMapsTabs()
std::vector< zelda3::DungeonMap > dungeon_maps_
std::string pending_dungeon_desc_
void CommitDungeonMapUndo()
void DrawInventoryMenuEditor()
void Push(std::unique_ptr< UndoAction > action)
void RegisterPanel(size_t session_id, const WindowDescriptor &base_info)
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Represents a bitmap image optimized for SNES ROM hacking.
const uint8_t * data() const
const SnesPalette & palette() const
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
void set_data(const std::vector< uint8_t > &data)
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap using SNES palette format.
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 (SNES metatile size)
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)
bool IsMouseHovering() const
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 std::string ShowSaveFileDialog(const std::string &default_name="", const std::string &default_extension="")
ShowSaveFileDialog opens a save file dialog and returns the selected filepath. Uses global feature fl...
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
absl::Status Create(Rom *rom, GameData *game_data=nullptr)
Initialize and load inventory screen data from ROM.
auto & mutable_lw_tiles()
absl::Status SaveCustomMap(const std::string &file_path, bool use_dark_world)
Save map data to external binary file.
auto & mutable_dw_tiles()
absl::Status LoadCustomMap(const std::string &file_path)
Load custom map from external binary file.
absl::Status Save(Rom *rom)
Save changes back to ROM.
absl::Status RenderMapLayer(bool use_dark_world)
Render map tiles into bitmap.
absl::Status Create(Rom *rom)
Initialize and load overworld map data from ROM.
auto & composite_bitmap()
auto & mutable_bg1_buffer()
absl::Status Create(Rom *rom, GameData *game_data=nullptr)
Initialize and load title screen data from ROM.
auto & mutable_bg2_buffer()
absl::Status RenderCompositeLayer(bool show_bg1, bool show_bg2)
Render composite layer with BG1 on top of BG2 with transparency.
absl::Status Save(Rom *rom)
absl::Status RenderBG2Layer()
Render BG2 tilemap into bitmap pixels Converts tile IDs from tiles_bg2_buffer_ into pixel data.
absl::Status RenderBG1Layer()
Render BG1 tilemap into bitmap pixels Converts tile IDs from tiles_bg1_buffer_ into pixel data.
#define ICON_MD_MORE_VERT
#define ICON_MD_INVENTORY
#define PRINT_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
const AgentUITheme & GetTheme()
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< const uint8_t > sheet, int bpp, int num_sheets)
void EndCanvas(Canvas &canvas)
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
bool DrawTileSelector(const CanvasRuntime &rt, int size, int size_y, ImVec2 *out_selected_pos)
void BeginCanvas(Canvas &canvas, ImVec2 child_size)
bool BeginThemedTabBar(const char *id, ImGuiTabBarFlags flags)
A stylized tab bar with "Mission Control" branding.
IMGUI_API absl::Status InlinePaletteEditor(gfx::SnesPalette &palette, const std::string &title, ImGuiColorEditFlags flags)
Full inline palette editor with color picker and copy options.
bool InputTileInfo(const char *label, gfx::TileInfo *tile_info)
IMGUI_API bool DisplayPalette(gfx::SnesPalette &palette, bool loaded)
bool ToolbarIconButton(const char *icon, const char *tooltip, bool is_active)
Convenience wrapper for toolbar-sized icon buttons.
void DrawBitmap(const CanvasRuntime &rt, gfx::Bitmap &bitmap, int border_offset, float scale)
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, GameData *game_data, 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.
absl::Status SaveDungeonMaps(Rom &rom, std::vector< DungeonMap > &dungeon_maps)
Save the dungeon maps to the ROM.
#define RETURN_IF_ERROR(expr)
zelda3::DungeonMap map_data
std::vector< std::array< std::string, zelda3::kNumRooms > > labels
WorkspaceWindowManager * window_manager
Unified screen editor snapshot.
DungeonMapSnapshot dungeon_map
Tile16CompSnapshot tile16_comp
std::array< gfx::TileInfo, 4 > tile_info
PaletteGroup dungeon_main
auto mutable_palette(int i)
void CacheTile(int tile_id, const Bitmap &bitmap)
Cache a tile bitmap by copying it.
Bitmap * GetTile(int tile_id)
Get a cached tile by ID.
Pair tile_size
Size of individual tiles (8x8 or 16x16)
TileCache tile_cache
Smart tile cache with LRU eviction.
Pair map_size
Size of tilemap in tiles.
Bitmap atlas
Master bitmap containing all tiles.
std::vector< std::array< gfx::TileInfo, 4 > > tile_info
Tile metadata (4 tiles per 16x16)
std::optional< float > grid_step
void SelectableLabelWithNameEdit(bool selected, const std::string &type, const std::string &key, const std::string &defaultValue)
gfx::PaletteGroupMap palette_groups