5#include <unordered_map>
8#include "absl/status/status.h"
9#include "absl/strings/str_format.h"
27#include "imgui/imgui.h"
28#include "imgui_memory_editor.h"
45 [
this]() { DrawOverworldCanvas(); });
47 std::to_address(
layout_node_.GetNode(
"OverworldTileSelector")),
48 [
this]() { status_ = DrawTileSelector(); });
51 if (rom_->is_loaded()) {
52 status_ = UpdateUsageStats();
56 [
this]() { DrawToolset(); });
57 gui::zeml::Bind(std::to_address(layout_node_.GetNode(
"OwTile16Editor")),
59 if (rom_->is_loaded()) {
60 status_ = tile16_editor_.Update();
63 gui::zeml::Bind(std::to_address(layout_node_.GetNode(
"OwGfxGroupEditor")),
65 if (rom_->is_loaded()) {
66 status_ = gfx_group_editor_.Update();
85 overworld_canvas_fullscreen_ = !overworld_canvas_fullscreen_;
91 current_mode = EditingMode::PAN;
92 ow_map_canvas_.set_draggable(
true);
98 current_mode = EditingMode::DRAW_TILE;
104 current_mode = EditingMode::ENTRANCES;
109 current_mode = EditingMode::EXITS;
114 current_mode = EditingMode::ITEMS;
119 current_mode == EditingMode::SPRITES))
120 current_mode = EditingMode::SPRITES;
125 current_mode == EditingMode::TRANSPORTS))
126 current_mode = EditingMode::TRANSPORTS;
131 current_mode = EditingMode::MUSIC;
140 show_gfx_group_editor_ = !show_gfx_group_editor_;
146 std::vector<uint8_t> png_data;
147 png_data = maps_bmp_[current_map_].GetPngData();
148 if (png_data.size() > 0) {
151 status_ = absl::InternalError(
152 "Failed to convert overworld map surface to PNG");
162 Checkbox(
"Properties", &show_properties_editor_);
173 return absl::OkStatus();
184 static bool use_work_area =
true;
185 static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration |
186 ImGuiWindowFlags_NoMove |
187 ImGuiWindowFlags_NoSavedSettings;
188 const ImGuiViewport *viewport = ImGui::GetMainViewport();
189 ImGui::SetNextWindowPos(use_work_area ? viewport->WorkPos : viewport->Pos);
190 ImGui::SetNextWindowSize(use_work_area ? viewport->WorkSize : viewport->Size);
205 ImGuiWindowFlags_MenuBar);
224 if (!ImGui::IsAnyItemActive()) {
226 if (ImGui::IsKeyDown(ImGuiKey_1)) {
228 }
else if (ImGui::IsKeyDown(ImGuiKey_2)) {
230 }
else if (ImGui::IsKeyDown(ImGuiKey_3)) {
232 }
else if (ImGui::IsKeyDown(ImGuiKey_4)) {
234 }
else if (ImGui::IsKeyDown(ImGuiKey_5)) {
236 }
else if (ImGui::IsKeyDown(ImGuiKey_6)) {
238 }
else if (ImGui::IsKeyDown(ImGuiKey_7)) {
240 }
else if (ImGui::IsKeyDown(ImGuiKey_8)) {
247 "##WorldId",
"##GfxId",
"##PalId",
"##SprGfxId",
248 "##5thCol",
"##6thCol",
"##7thCol",
"##8thCol"};
253 ImGui::TableSetupColumn(name);
256 ImGui::SetNextItemWidth(120.f);
263 ->mutable_area_graphics(),
274 ->mutable_area_palette(),
307 ImGui::SetNextItemWidth(100.f);
314 HOVER_HINT(
"Enable Mosaic effect for the current map");
323 ImGui::TableSetupColumn(name);
326 ImGui::SetNextItemWidth(120.f);
331 if (ImGui::Button(
"Tile Graphics", ImVec2(120, 0))) {
332 ImGui::OpenPopup(
"TileGraphicsPopup");
334 if (ImGui::BeginPopup(
"TileGraphicsPopup")) {
335 static const std::array<std::string, 8> kCustomMapSettingsColumnNames = {
336 "TileGfx0",
"TileGfx1",
"TileGfx2",
"TileGfx3",
337 "TileGfx4",
"TileGfx5",
"TileGfx6",
"TileGfx7"};
338 for (
int i = 0; i < 8; ++i) {
342 ->mutable_custom_tileset(i),
356 ->mutable_area_palette(),
389 ImGui::SetNextItemWidth(100.f);
396 HOVER_HINT(
"Enable Mosaic effect for the current map");
405 for (
int i = 0; i < 0x40; i++) {
439 int mouse_x = mouse_position.x;
440 int mouse_y = mouse_position.y;
446 auto &selected_world =
449 :
overworld_.mutable_map_tiles()->special_world;
451 int index_x = superX * 32 + tile16_x;
452 int index_y = superY * 32 + tile16_y;
458 const ImVec2 &click_position,
const std::vector<uint8_t> &tile_data) {
466 ImVec2 start_position;
467 start_position.x =
static_cast<float>(tile_index_x *
kTile16Size);
468 start_position.y =
static_cast<float>(tile_index_y *
kTile16Size);
495 if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) ||
496 ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
497 auto &selected_world =
501 :
overworld_.mutable_map_tiles()->special_world;
512 if (start_x > end_x) std::swap(start_x, end_x);
513 if (start_y > end_y) std::swap(start_y, end_y);
515 constexpr int local_map_size = 512;
517 constexpr int tiles_per_local_map = local_map_size /
kTile16Size;
519 for (
int y = start_y, i = 0; y <= end_y; y +=
kTile16Size) {
520 for (
int x = start_x; x <= end_x; x +=
kTile16Size, ++i) {
522 int local_map_x = x / local_map_size;
523 int local_map_y = y / local_map_size;
530 int index_x = local_map_x * tiles_per_local_map + tile16_x;
531 int index_y = local_map_y * tiles_per_local_map + tile16_y;
532 int tile16_id =
overworld_.GetTileFromPosition(
534 selected_world[index_x][index_y] = tile16_id;
553 static std::vector<int> tile16_ids;
556 if (tile16_ids.size() != 0) {
562 tile16_ids.push_back(
overworld_.GetTileFromPosition(each));
572 const auto mouse_position = ImGui::GetIO().MousePos;
573 const int large_map_size = 1024;
595 const int highlight_parent =
596 overworld_.overworld_map(current_highlighted_map)->parent();
597 const int parent_map_x = highlight_parent % 8;
598 const int parent_map_y = highlight_parent / 8;
603 const int current_map_x = current_highlighted_map % 8;
604 const int current_map_y = current_highlighted_map / 8;
611 ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
619 if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right)) {
623 return absl::OkStatus();
627 if (ImGui::IsMouseDragging(ImGuiMouseButton_Middle)) {
633 if (ImGui::IsMouseReleased(ImGuiMouseButton_Middle) &&
681 if (ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows) &&
682 ImGui::IsMouseDragging(ImGuiMouseButton_Middle)) {
683 ImGui::SetScrollX(ImGui::GetScrollX() + ImGui::GetIO().MouseWheelH * 16.0f);
684 ImGui::SetScrollY(ImGui::GetScrollY() + ImGui::GetIO().MouseWheel * 16.0f);
702 int grid_x =
static_cast<int>(tile_pos.x / 32);
703 int grid_y =
static_cast<int>(tile_pos.y / 32);
704 int id = grid_x + grid_y * 8;
720 return absl::OkStatus();
729 int offset = 0x40 * (key + 1);
734 auto texture = value.texture();
736 (ImTextureID)(intptr_t)texture,
773 return absl::OkStatus();
778 ImGuiTabBarFlags_FittingPolicyScroll)) {
779 if (BeginTabItem(
"Tile16")) {
783 if (BeginTabItem(
"Tile8")) {
791 if (BeginTabItem(
"Area Graphics")) {
797 return absl::OkStatus();
806 auto color = ImVec4(255, 255, 0, 100);
808 color = ImVec4(255, 255, 255, 200);
818 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
823 ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
836 auto deleted_entrance_id =
overworld_.deleted_entrances().back();
838 auto &entrance =
overworld_.entrances()[deleted_entrance_id];
840 entrance.entrance_id_ = deleted_entrance_id;
843 entrance.deleted =
false;
847 const auto is_hovering =
850 if (!is_hovering && ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
851 ImGui::OpenPopup(
"Entrance Inserter");
859 overworld_.mutable_deleted_entrances()->emplace_back(
868 for (
auto &each : *
overworld_.mutable_exits()) {
872 ImVec4(255, 255, 255, 150));
880 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
885 ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
890 ImGui::OpenPopup(
"Exit editor");
906 if (!hovering && ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
907 ImGui::OpenPopup(
"Exit Inserter");
919 for (
auto &item : *
overworld_.mutable_all_items()) {
923 ow_map_canvas_.DrawRect(item.x_, item.y_, 16, 16, ImVec4(255, 0, 0, 150));
933 if (hovering && ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
939 std::string item_name =
"";
943 item_name = absl::StrFormat(
"0x%02X", item.id_);
956 if (!hovering && ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
957 ImGui::OpenPopup(
"Item Inserter");
970 if (!sprite.deleted()) {
971 int map_x = sprite.map_x();
972 int map_y = sprite.map_y();
974 ImVec4(255, 0, 255, 150));
981 ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
993 ow_map_canvas_.DrawText(absl::StrFormat(
"%s", sprite.name()), map_x,
1005 if (!hovering && ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
1006 ImGui::OpenPopup(
"Sprite Inserter");
1036 return absl::OkStatus();
1040 util::logf(
"Loading overworld.");
1045 util::logf(
"Loading overworld graphics.");
1051 util::logf(
"Loading overworld tileset.");
1059 auto tile16_blockset_data =
overworld_.tile16_blockset_data();
1060 util::logf(
"Loading overworld tile16 graphics.");
1066 util::logf(
"Loading overworld maps.");
1070 auto palette =
overworld_.current_area_palette();
1075 }
catch (
const std::bad_alloc &e) {
1076 std::cout <<
"Error: " << e.what() << std::endl;
1085 return absl::OkStatus();
1090 const int depth = 0x10;
1091 for (
int i = 0; i < 3; i++)
1092 for (
auto const &sprite : *
overworld_.mutable_sprites(i)) {
1093 int width = sprite.width();
1094 int height = sprite.height();
1095 if (width == 0 || height == 0) {
1102 *sprite.preview_graphics());
1106 return absl::OkStatus();
1110 overworld_.mutable_overworld_map(map_index)->LoadAreaGraphics();
1119 overworld_.mutable_overworld_map(map_index)->bitmap_data());
1120 maps_bmp_[map_index].set_modified(
true);
1125 std::vector<std::future<void>> futures;
1126 std::array<int, 4> indices = {0, 0, 0, 0};
1128 auto refresh_map_async = [
this](
int map_index) {
1137 for (
int i = 1; i < 4; i++) {
1138 int sibling_index =
overworld_.overworld_map(source_map_id)->parent() + i;
1139 if (i >= 2) sibling_index += 6;
1141 std::async(std::launch::async, refresh_map_async, sibling_index));
1142 indices[i] = sibling_index;
1145 indices[0] = source_map_id;
1147 std::async(std::launch::async, refresh_map_async, source_map_id));
1149 for (
auto &each : futures) {
1153 int n = is_large ? 4 : 1;
1155 for (
int i = 0; i < n; ++i) {
1163 const auto current_map_palette =
overworld_.current_area_palette();
1167 for (
int i = 1; i < 4; i++) {
1169 if (i >= 2) sibling_index += 6;
1171 overworld_.mutable_overworld_map(sibling_index)->LoadPalette());
1172 maps_bmp_[sibling_index].SetPalette(current_map_palette);
1177 return absl::OkStatus();
1182 if (current_ow_map.is_large_map()) {
1184 for (
int i = 1; i < 4; i++) {
1185 int sibling_index = current_ow_map.parent() + i;
1189 auto &map = *
overworld_.mutable_overworld_map(sibling_index);
1190 map.set_area_graphics(current_ow_map.area_graphics());
1191 map.set_area_palette(current_ow_map.area_palette());
1196 map.set_message_id(current_ow_map.message_id());
1204 return absl::OkStatus();
1211 const auto tile16_data =
overworld_.tile16_blockset_data();
1215 return absl::OkStatus();
1219 static bool init_properties =
false;
1221 if (!init_properties) {
1222 for (
int i = 0; i < 0x40; i++) {
1223 std::string area_graphics_str = absl::StrFormat(
1224 "%02hX",
overworld_.overworld_map(i)->area_graphics());
1226 ->push_back(area_graphics_str);
1228 area_graphics_str = absl::StrFormat(
1229 "%02hX",
overworld_.overworld_map(i + 0x40)->area_graphics());
1231 ->push_back(area_graphics_str);
1233 std::string area_palette_str =
1234 absl::StrFormat(
"%02hX",
overworld_.overworld_map(i)->area_palette());
1236 ->push_back(area_palette_str);
1238 area_palette_str = absl::StrFormat(
1239 "%02hX",
overworld_.overworld_map(i + 0x40)->area_palette());
1241 ->push_back(area_palette_str);
1242 std::string sprite_gfx_str = absl::StrFormat(
1243 "%02hX",
overworld_.overworld_map(i)->sprite_graphics(1));
1245 ->push_back(sprite_gfx_str);
1247 sprite_gfx_str = absl::StrFormat(
1248 "%02hX",
overworld_.overworld_map(i)->sprite_graphics(2));
1250 ->push_back(sprite_gfx_str);
1252 sprite_gfx_str = absl::StrFormat(
1253 "%02hX",
overworld_.overworld_map(i + 0x40)->sprite_graphics(1));
1255 ->push_back(sprite_gfx_str);
1257 sprite_gfx_str = absl::StrFormat(
1258 "%02hX",
overworld_.overworld_map(i + 0x40)->sprite_graphics(2));
1260 ->push_back(sprite_gfx_str);
1262 std::string sprite_palette_str = absl::StrFormat(
1263 "%02hX",
overworld_.overworld_map(i)->sprite_palette(1));
1265 ->push_back(sprite_palette_str);
1267 sprite_palette_str = absl::StrFormat(
1268 "%02hX",
overworld_.overworld_map(i)->sprite_palette(2));
1270 ->push_back(sprite_palette_str);
1272 sprite_palette_str = absl::StrFormat(
1273 "%02hX",
overworld_.overworld_map(i + 0x40)->sprite_palette(1));
1275 ->push_back(sprite_palette_str);
1277 sprite_palette_str = absl::StrFormat(
1278 "%02hX",
overworld_.overworld_map(i + 0x40)->sprite_palette(2));
1280 ->push_back(sprite_palette_str);
1282 init_properties =
true;
1285 Text(
"Area Gfx LW/DW");
1293 Text(
"Sprite Gfx LW/DW");
1307 Text(
"Area Pal LW/DW");
1314 static bool show_gfx_group =
false;
1315 Checkbox(
"Show Gfx Group Editor", &show_gfx_group);
1316 if (show_gfx_group) {
1324 if (BeginTable(
"UsageStatsTable", 3,
kOWEditFlags, ImVec2(0, 0))) {
1325 TableSetupColumn(
"Entrances");
1326 TableSetupColumn(
"Grid", ImGuiTableColumnFlags_WidthStretch,
1327 ImGui::GetContentRegionAvail().x);
1328 TableSetupColumn(
"Usage", ImGuiTableColumnFlags_WidthFixed, 256);
1333 if (BeginChild(
"UnusedSpritesetScroll", ImVec2(0, 0),
true,
1334 ImGuiWindowFlags_HorizontalScrollbar)) {
1335 for (
int i = 0; i < 0x81; i++) {
1336 auto entrance_name =
rom_->resource_label()->CreateOrGetLabel(
1339 std::string str = absl::StrFormat(
"%#x - %s", i, entrance_name);
1342 ? ImGuiSelectableFlags_Disabled
1348 if (IsItemHovered()) {
1350 Text(
"Entrance ID: %d", i);
1351 Text(
"Map ID: %d",
overworld_.entrances().at(i).map_id_);
1352 Text(
"Entrance ID: %d",
overworld_.entrances().at(i).entrance_id_);
1353 Text(
"X: %d",
overworld_.entrances().at(i).x_);
1354 Text(
"Y: %d",
overworld_.entrances().at(i).y_);
1356 overworld_.entrances().at(i).deleted ?
"Yes" :
"No");
1371 return absl::OkStatus();
1376 int total_squares = 128;
1377 int squares_wide = 8;
1378 int squares_tall = (total_squares + squares_wide - 1) /
1382 for (
int row = 0; row < squares_tall; ++row) {
1385 for (
int col = 0; col < squares_wide; ++col) {
1386 if (row * squares_wide + col >= total_squares) {
1394 PushStyleColor(ImGuiCol_Button,
1395 ImVec4(1.0f, 0.5f, 0.0f,
1400 if (Button(
"##square", ImVec2(20, 20))) {
1412 if (IsItemHovered()) {
1425 int relative_x = (int)
ow_map_canvas_.drawn_tile_position().x % 512;
1426 int relative_y = (int)
ow_map_canvas_.drawn_tile_position().y % 512;
1427 Text(
"Current Tile16 Drawn Position (Relative): %d, %d", relative_x,
1431 Text(
"Light World Map Tiles: %d",
1432 (
int)
overworld_.mutable_map_tiles()->light_world.size());
1433 Text(
"Dark World Map Tiles: %d",
1434 (
int)
overworld_.mutable_map_tiles()->dark_world.size());
1435 Text(
"Special World Map Tiles: %d",
1436 (
int)
overworld_.mutable_map_tiles()->special_world.size());
1438 static bool view_lw_map_tiles =
false;
1439 static MemoryEditor mem_edit;
1441 if (Button(
"View Light World Map Tiles")) {
1442 view_lw_map_tiles = !view_lw_map_tiles;
1445 if (view_lw_map_tiles) {
1446 mem_edit.DrawContents(
1457 return absl::OkStatus();
void CreateAndRenderBitmap(int width, int height, int depth, const std::vector< uint8_t > &data, gfx::Bitmap &bitmap, gfx::SnesPalette &palette)
void UpdateBitmap(gfx::Bitmap *bitmap)
void RenderBitmap(gfx::Bitmap *bitmap)
absl::Status Clear() override
gui::zeml::Node layout_node_
zelda3::OverworldItem current_item_
bool overworld_canvas_fullscreen_
bool map_blockset_loaded_
absl::Status UpdateUsageStats()
zelda3::OverworldEntranceTileTypes entrance_tiletypes_
zelda3::OverworldEntrance current_entrance_
zelda3::Sprite current_sprite_
absl::Status CheckForCurrentMap()
Check for changes to the overworld map. Calls RefreshOverworldMap and RefreshTile16Blockset on the cu...
void DrawOverworldEdits()
gfx::Bitmap current_gfx_bmp_
gfx::Tilemap tile16_blockset_
bool middle_mouse_dragging_
Tile16Editor tile16_editor_
gui::Canvas ow_map_canvas_
void DrawOverworldExits(ImVec2 zero, ImVec2 scrolling)
void DrawOverworldItems()
zelda3::GameEntity * dragged_entity_
std::array< gfx::Bitmap, zelda3::kNumOverworldMaps > maps_bmp_
void RefreshOverworldMap()
void CheckForOverworldEdits()
Check for changes to the overworld map.
zelda3::OverworldExit current_exit_
void RefreshMapProperties()
void RenderUpdatedMapBitmap(const ImVec2 &click_position, const std::vector< uint8_t > &tile_data)
gui::Canvas current_gfx_canvas_
void DrawCustomOverworldMapSettings()
absl::Status DrawTileSelector()
void Initialize() override
void DrawFullscreenCanvas()
void DrawOverworldProperties()
absl::Status RefreshMapPalette()
void DrawOverworldMapSettings()
void DrawOverworldCanvas()
gui::Canvas blockset_canvas_
absl::Status RefreshTile16Blockset()
void CheckForSelectRectangle()
Draw and create the tile16 IDs that are currently selected.
void RefreshChildMap(int i)
absl::Status Load() override
std::vector< gfx::Bitmap > sprite_previews_
absl::Status DrawAreaGraphics()
bool show_gfx_group_editor_
GfxGroupEditor gfx_group_editor_
absl::Status Update() final
void DrawOverworldSprites()
bool show_properties_editor_
EditingMode previous_mode
gui::Table toolset_table_
gui::Canvas graphics_bin_canvas_
gfx::BitmapTable current_graphics_set_
zelda3::Overworld overworld_
absl::Status LoadGraphics()
Load the Bitmap objects for each OverworldMap.
absl::Status LoadSpriteGraphics()
absl::Status Save() override
void DrawOverworldEntrances(ImVec2 canvas_p, ImVec2 scrolling, bool holes=false)
zelda3::GameEntity * current_entity_
gui::Canvas properties_canvas_
gfx::SnesPalette palette_
gfx::Bitmap tile16_blockset_bmp_
absl::Status DrawTile16Selector()
Represents a bitmap image.
void WriteToPixel(int position, uint8_t value)
Write a value to a pixel at the given position.
void set_modified(bool modified)
#define ICON_MD_GRID_VIEW
#define ICON_MD_MORE_VERT
#define ICON_MD_OPEN_IN_FULL
#define ICON_MD_TABLE_CHART
#define ICON_MD_DOOR_BACK
#define ICON_MD_MUSIC_NOTE
#define ICON_MD_DOOR_FRONT
#define ICON_MD_ADD_LOCATION
#define ICON_MD_PEST_CONTROL_RODENT
#define ICON_MD_CONTENT_COPY
#define ICON_MD_PAN_TOOL_ALT
#define PRINT_IF_ERROR(expression)
#define RETURN_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
#define HOVER_HINT(string)
void CopyImageToClipboard(const std::vector< uint8_t > &data)
Editors are the view controllers for the application.
void DrawExitInserterPopup()
constexpr absl::string_view kOWMapTable
constexpr ImGuiTableFlags kOWMapFlags
constexpr unsigned int kOverworldMapSize
bool DrawSpriteEditorPopup(zelda3::Sprite &sprite)
void DrawItemInsertPopup()
bool DrawEntranceInserterPopup()
void DrawSpriteInserterPopup()
constexpr absl::string_view kWorldList
constexpr absl::string_view kGamePartComboString
void HandleEntityDragging(zelda3::GameEntity *entity, ImVec2 canvas_p0, ImVec2 scrolling, bool &is_dragging_entity, zelda3::GameEntity *&dragged_entity, zelda3::GameEntity *¤t_entity, bool free_movement)
bool DrawOverworldEntrancePopup(zelda3::OverworldEntrance &entrance)
bool IsMouseHoveringOverEntity(const zelda3::GameEntity &entity, ImVec2 canvas_p0, ImVec2 scrolling)
absl::Status DisplayPalette(gfx::SnesPalette &palette, bool loaded)
bool DrawItemEditorPopup(zelda3::OverworldItem &item)
constexpr int kTile16Size
constexpr ImGuiTableFlags kOWEditFlags
constexpr float kInputFieldSize
constexpr absl::string_view kTileSelectorTab
constexpr std::array< const char *, 8 > kMapSettingsColumnNames
bool DrawExitEditorPopup(zelda3::OverworldExit &exit)
Tilemap CreateTilemap(std::vector< uint8_t > &data, int width, int height, int tile_size, int num_tiles, SnesPalette &palette)
void UpdateTilemap(Tilemap &tilemap, const std::vector< uint8_t > &data)
std::vector< uint8_t > GetTilemapData(Tilemap &tilemap, int tile_id)
void Render(Node &node)
Render a zeml tree.
std::string LoadFile(const std::string &filename)
void Bind(Node *node, std::function< void()> callback)
Bind a callback to a node.
Node Parse(const std::string &yazon_input, const std::map< std::string, void * > &data_bindings)
Parse a zeml string.
void BeginChildBothScrollbars(int id)
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
void AddTableColumn(Table &table, const std::string &label, GuiElement element)
void DrawTable(Table ¶ms)
void EndWindowWithDisplaySettings()
void BeginWindowWithDisplaySettings(const char *id, bool *active, const ImVec2 &size, ImGuiWindowFlags flags)
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
void BeginChildWithScrollbar(const char *str_id)
std::string HexByte(uint8_t byte, HexStringParams params)
constexpr std::string_view kEntranceNames[]
constexpr int kNumTile16Individual
constexpr int kNumOverworldMaps
const std::vector< std::string > kSecretItemNames
absl::StatusOr< OverworldEntranceTileTypes > LoadEntranceTileTypes(Rom *rom)