Add Comprehensive Dungeon Editor Design Plan
- Introduced a detailed design plan document for the Yaze Dungeon Editor, outlining the current architecture, main components, and core systems. - Documented identified issues and applied fixes, including crash prevention and UI simplification, along with a roadmap for future development phases. - Enhanced clarity on the implementation guidelines, testing strategies, and performance considerations to support ongoing development efforts. - Established a structured approach for new developers to understand the codebase and contribute effectively to the project.
This commit is contained in:
@@ -65,6 +65,10 @@ void DungeonCanvasViewer::DrawDungeonTabView() {
|
||||
Separator();
|
||||
}
|
||||
|
||||
void DungeonCanvasViewer::Draw(int room_id) {
|
||||
DrawDungeonCanvas(room_id);
|
||||
}
|
||||
|
||||
void DungeonCanvasViewer::DrawDungeonCanvas(int room_id) {
|
||||
// Validate room_id and ROM
|
||||
if (room_id < 0 || room_id >= 128) {
|
||||
|
||||
@@ -20,22 +20,23 @@ class DungeonCanvasViewer {
|
||||
|
||||
void DrawDungeonTabView();
|
||||
void DrawDungeonCanvas(int room_id);
|
||||
void Draw(int room_id);
|
||||
|
||||
void set_rom(Rom* rom) {
|
||||
void SetRom(Rom* rom) {
|
||||
rom_ = rom;
|
||||
object_renderer_.SetROM(rom);
|
||||
}
|
||||
Rom* rom() const { return rom_; }
|
||||
|
||||
// Room data access
|
||||
void set_rooms(std::array<zelda3::Room, 0x128>* rooms) { rooms_ = rooms; }
|
||||
void SetRooms(std::array<zelda3::Room, 0x128>* rooms) { rooms_ = rooms; }
|
||||
void set_active_rooms(const ImVector<int>& rooms) { active_rooms_ = rooms; }
|
||||
void set_current_active_room_tab(int tab) { current_active_room_tab_ = tab; }
|
||||
|
||||
// Palette access
|
||||
void set_current_palette_group_id(uint64_t id) { current_palette_group_id_ = id; }
|
||||
void set_current_palette_id(uint64_t id) { current_palette_id_ = id; }
|
||||
void set_current_palette_group(const gfx::PaletteGroup& group) { current_palette_group_ = group; }
|
||||
void SetCurrentPaletteId(uint64_t id) { current_palette_id_ = id; }
|
||||
void SetCurrentPaletteGroup(const gfx::PaletteGroup& group) { current_palette_group_ = group; }
|
||||
|
||||
// Canvas access
|
||||
gui::Canvas& canvas() { return canvas_; }
|
||||
|
||||
@@ -100,6 +100,21 @@ absl::Status DungeonEditor::Load() {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the new UI components with loaded data
|
||||
room_selector_.set_rom(rom_);
|
||||
room_selector_.set_rooms(&rooms_);
|
||||
room_selector_.set_entrances(&entrances_);
|
||||
room_selector_.set_active_rooms(active_rooms_);
|
||||
|
||||
canvas_viewer_.SetRom(rom_);
|
||||
canvas_viewer_.SetRooms(&rooms_);
|
||||
canvas_viewer_.SetCurrentPaletteGroup(current_palette_group_);
|
||||
canvas_viewer_.SetCurrentPaletteId(current_palette_id_);
|
||||
|
||||
object_selector_.SetRom(rom_);
|
||||
object_selector_.SetCurrentPaletteGroup(current_palette_group_);
|
||||
object_selector_.SetCurrentPaletteId(current_palette_id_);
|
||||
|
||||
is_loaded_ = true;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
@@ -230,33 +245,21 @@ absl::Status DungeonEditor::UpdateDungeonRoomView() {
|
||||
TableHeadersRow();
|
||||
TableNextRow();
|
||||
|
||||
// Column 1: Room and Entrance Selector
|
||||
// Column 1: Room and Entrance Selector (using new component)
|
||||
TableNextColumn();
|
||||
if (ImGui::BeginTabBar("##DungeonRoomTabBar")) {
|
||||
TAB_ITEM("Rooms");
|
||||
DrawRoomSelector();
|
||||
END_TAB_ITEM();
|
||||
TAB_ITEM("Entrances");
|
||||
DrawEntranceSelector();
|
||||
END_TAB_ITEM();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
room_selector_.Draw();
|
||||
|
||||
// Column 2: Main Canvas
|
||||
// Column 2: Main Canvas (using new component)
|
||||
TableNextColumn();
|
||||
DrawDungeonTabView();
|
||||
|
||||
// Column 3: Object Selector and Editor
|
||||
TableNextColumn();
|
||||
if (ImGui::BeginTabBar("##ObjectEditorTabBar")) {
|
||||
TAB_ITEM("Graphics");
|
||||
DrawTileSelector();
|
||||
END_TAB_ITEM();
|
||||
TAB_ITEM("Editor");
|
||||
DrawIntegratedEditingPanels();
|
||||
END_TAB_ITEM();
|
||||
ImGui::EndTabBar();
|
||||
int current_room = current_room_id_;
|
||||
if (!active_rooms_.empty() && current_active_room_tab_ < active_rooms_.Size) {
|
||||
current_room = active_rooms_[current_active_room_tab_];
|
||||
}
|
||||
canvas_viewer_.Draw(current_room);
|
||||
|
||||
// Column 3: Object Selector and Editor (using new component)
|
||||
TableNextColumn();
|
||||
object_selector_.Draw();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ constexpr ImGuiTableFlags kDungeonTableFlags =
|
||||
class DungeonEditor : public Editor {
|
||||
public:
|
||||
explicit DungeonEditor(Rom* rom = nullptr)
|
||||
: rom_(rom), object_renderer_(rom), preview_object_(0, 0, 0, 0, 0) {
|
||||
: rom_(rom), object_renderer_(rom), preview_object_(0, 0, 0, 0, 0),
|
||||
room_selector_(rom), canvas_viewer_(rom), object_selector_(rom) {
|
||||
type_ = EditorType::kDungeon;
|
||||
// Initialize the new dungeon editor system
|
||||
if (rom) {
|
||||
@@ -67,7 +68,13 @@ class DungeonEditor : public Editor {
|
||||
|
||||
void add_room(int i) { active_rooms_.push_back(i); }
|
||||
|
||||
void set_rom(Rom* rom) { rom_ = rom; }
|
||||
void set_rom(Rom* rom) {
|
||||
rom_ = rom;
|
||||
// Update the new UI components with the new ROM
|
||||
room_selector_.set_rom(rom_);
|
||||
canvas_viewer_.SetRom(rom_);
|
||||
object_selector_.SetRom(rom_);
|
||||
}
|
||||
Rom* rom() const { return rom_; }
|
||||
|
||||
private:
|
||||
@@ -212,6 +219,11 @@ class DungeonEditor : public Editor {
|
||||
std::array<zelda3::RoomEntrance, 0x8C> entrances_ = {};
|
||||
zelda3::ObjectRenderer object_renderer_;
|
||||
|
||||
// New UI components
|
||||
DungeonRoomSelector room_selector_;
|
||||
DungeonCanvasViewer canvas_viewer_;
|
||||
DungeonObjectSelector object_selector_;
|
||||
|
||||
absl::flat_hash_map<uint16_t, int> spriteset_usage_;
|
||||
absl::flat_hash_map<uint16_t, int> blockset_usage_;
|
||||
absl::flat_hash_map<uint16_t, int> palette_usage_;
|
||||
|
||||
@@ -127,6 +127,20 @@ void DungeonObjectSelector::DrawObjectRenderer() {
|
||||
}
|
||||
}
|
||||
|
||||
void DungeonObjectSelector::Draw() {
|
||||
if (ImGui::BeginTabBar("##ObjectEditorTabBar")) {
|
||||
if (ImGui::BeginTabItem("Graphics")) {
|
||||
DrawRoomGraphics();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Editor")) {
|
||||
DrawIntegratedEditingPanels();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
}
|
||||
|
||||
void DungeonObjectSelector::DrawRoomGraphics() {
|
||||
const auto height = 0x40;
|
||||
room_gfx_canvas_.DrawBackground();
|
||||
|
||||
@@ -22,11 +22,16 @@ class DungeonObjectSelector {
|
||||
void DrawTileSelector();
|
||||
void DrawObjectRenderer();
|
||||
void DrawIntegratedEditingPanels();
|
||||
void Draw();
|
||||
|
||||
void set_rom(Rom* rom) {
|
||||
rom_ = rom;
|
||||
object_renderer_.SetROM(rom);
|
||||
}
|
||||
void SetRom(Rom* rom) {
|
||||
rom_ = rom;
|
||||
object_renderer_.SetROM(rom);
|
||||
}
|
||||
Rom* rom() const { return rom_; }
|
||||
|
||||
// Editor system access
|
||||
@@ -43,6 +48,8 @@ class DungeonObjectSelector {
|
||||
|
||||
// Palette access
|
||||
void set_current_palette_group_id(uint64_t id) { current_palette_group_id_ = id; }
|
||||
void SetCurrentPaletteGroup(const gfx::PaletteGroup& palette_group) { current_palette_group_ = palette_group; }
|
||||
void SetCurrentPaletteId(uint64_t palette_id) { current_palette_id_ = palette_id; }
|
||||
|
||||
private:
|
||||
void DrawRoomGraphics();
|
||||
@@ -69,6 +76,8 @@ class DungeonObjectSelector {
|
||||
|
||||
// Palette data
|
||||
uint64_t current_palette_group_id_ = 0;
|
||||
uint64_t current_palette_id_ = 0;
|
||||
gfx::PaletteGroup current_palette_group_;
|
||||
|
||||
// Object preview system
|
||||
zelda3::RoomObject preview_object_{0, 0, 0, 0, 0};
|
||||
|
||||
@@ -10,9 +10,28 @@
|
||||
namespace yaze::editor {
|
||||
|
||||
using ImGui::BeginChild;
|
||||
using ImGui::BeginTabBar;
|
||||
using ImGui::BeginTabItem;
|
||||
using ImGui::EndChild;
|
||||
using ImGui::EndTabBar;
|
||||
using ImGui::EndTabItem;
|
||||
using ImGui::Separator;
|
||||
using ImGui::SameLine;
|
||||
using ImGui::Text;
|
||||
|
||||
void DungeonRoomSelector::Draw() {
|
||||
if (ImGui::BeginTabBar("##DungeonRoomTabBar")) {
|
||||
if (ImGui::BeginTabItem("Rooms")) {
|
||||
DrawRoomSelector();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Entrances")) {
|
||||
DrawEntranceSelector();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
}
|
||||
|
||||
void DungeonRoomSelector::DrawRoomSelector() {
|
||||
if (!rom_ || !rom_->is_loaded()) {
|
||||
|
||||
@@ -17,6 +17,7 @@ class DungeonRoomSelector {
|
||||
public:
|
||||
explicit DungeonRoomSelector(Rom* rom = nullptr) : rom_(rom) {}
|
||||
|
||||
void Draw();
|
||||
void DrawRoomSelector();
|
||||
void DrawEntranceSelector();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user