feat(dungeon): add z3ed dungeon emulator commands and unified layout

- Introduced new commands for dungeon editing, including exporting room data, listing objects, and setting room properties.
- Implemented a hex viewer component for inspecting ROM data in a hexadecimal format.
- Updated the tool dispatcher to handle new dungeon commands and integrated them into the CLI.
- Enhanced the main menu and unified layout to include the hex viewer and improved navigation.
- Refactored existing components for better state management and event handling.

Benefits:
- Expanded functionality for dungeon editing and ROM inspection.
- Improved user experience with new tools and streamlined navigation.
This commit is contained in:
scawful
2025-10-10 20:34:12 -04:00
parent 1435c15400
commit c77ca503ca
18 changed files with 1327 additions and 718 deletions

View File

@@ -763,71 +763,6 @@ void HelpComponent(ftxui::ScreenInteractive &screen) {
screen.Loop(renderer);
}
void HexViewerComponent(ftxui::ScreenInteractive &screen) {
ReturnIfRomNotLoaded(screen);
auto back_button =
Button("Back", [&] { SwitchComponents(screen, LayoutID::kDashboard); });
static int offset = 0;
const int lines_to_show = 20;
auto renderer = Renderer(back_button, [&] {
std::vector<Element> rows;
for (int i = 0; i < lines_to_show; ++i) {
int current_offset = offset + (i * 16);
if (current_offset >= static_cast<int>(app_context.rom.size())) {
break;
}
Elements row;
row.push_back(text(absl::StrFormat("0x%08X: ", current_offset)) | color(Color::Yellow));
for (int j = 0; j < 16; ++j) {
if (current_offset + j < static_cast<int>(app_context.rom.size())) {
row.push_back(text(absl::StrFormat("%02X ", app_context.rom.vector()[current_offset + j])));
} else {
row.push_back(text(" "));
}
}
row.push_back(separator());
for (int j = 0; j < 16; ++j) {
if (current_offset + j < static_cast<int>(app_context.rom.size())) {
char c = app_context.rom.vector()[current_offset + j];
row.push_back(text(std::isprint(c) ? std::string(1, c) : "."));
} else {
row.push_back(text(" "));
}
}
rows.push_back(hbox(row));
}
return vbox({
text("Hex Viewer") | center | bold,
separator(),
vbox(rows) | frame | flex,
separator(),
text(absl::StrFormat("Offset: 0x%08X", offset)),
separator(),
back_button->Render() | center,
}) | border;
});
auto event_handler = CatchEvent(renderer, [&](Event event) {
if (event == Event::ArrowUp) offset = std::max(0, offset - 16);
if (event == Event::ArrowDown) offset = std::min(static_cast<int>(app_context.rom.size()) - (lines_to_show * 16), offset + 16);
if (event == Event::PageUp) offset = std::max(0, offset - (lines_to_show * 16));
if (event == Event::PageDown) offset = std::min(static_cast<int>(app_context.rom.size()) - (lines_to_show * 16), offset + (lines_to_show * 16));
if (event == Event::Character('q')) SwitchComponents(screen, LayoutID::kExit);
if (event == Event::Return) SwitchComponents(screen, LayoutID::kDashboard);
return false;
});
screen.Loop(event_handler);
}
void DashboardComponent(ftxui::ScreenInteractive &screen) {
static int selected = 0;