yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_object_editor.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_DUNGEON_DUNGEON_OBJECT_EDITOR_H
2#define YAZE_APP_ZELDA3_DUNGEON_DUNGEON_OBJECT_EDITOR_H
3
4#include <functional>
5#include <memory>
6#include <optional>
7#include <unordered_map>
8#include <vector>
9
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
12#include "app/gfx/core/bitmap.h"
14#include "app/platform/window.h"
15#include "rom/rom.h"
18#include "zelda3/dungeon/room.h"
20
21namespace yaze {
22namespace zelda3 {
23
38 public:
39 // Editor modes
40 enum class Mode {
41 kSelect, // Select and move objects
42 kInsert, // Insert new objects
43 kDelete, // Delete objects
44 kEdit, // Edit object properties
45 kLayer, // Layer management
46 kPreview // Preview mode
47 };
48
49 // Object selection state
51 std::vector<size_t> selected_objects; // Indices of selected objects
52 bool is_multi_select = false;
53 bool is_dragging = false;
54 int drag_start_x = 0;
55 int drag_start_y = 0;
56 };
57
58 // Object editing state
59 struct EditingState {
62 int current_object_type = 0x10; // Default to wall
64 bool is_editing_size = false;
65 bool is_editing_position = false;
66 int preview_x = 0;
67 int preview_y = 0;
68 int preview_size = 0x12; // Default size
69 };
70
71 // Editor configuration
72 struct EditorConfig {
73 bool snap_to_grid = true;
74 int grid_size = 16; // 16x16 pixel grid
75 bool show_grid = true;
76 bool show_preview = true;
77 bool auto_save = false;
78 int auto_save_interval = 300; // 5 minutes
79 bool validate_objects = true;
81
82 // Phase 4: Visual feedback settings
84 bool show_layer_colors = true;
86 uint32_t selection_color = 0xFFFFFF00; // Yellow
87 uint32_t layer0_color = 0xFFFF0000; // Red tint
88 uint32_t layer1_color = 0xFF00FF00; // Green tint
89 uint32_t layer2_color = 0xFF0000FF; // Blue tint
90 };
91
92 // Undo/Redo system
93 struct UndoPoint {
94 std::vector<RoomObject> objects;
97 std::chrono::steady_clock::time_point timestamp;
98 };
99
100 explicit DungeonObjectEditor(Rom* rom);
102
103 // Core editing operations
104 absl::Status LoadRoom(int room_id);
105 absl::Status SaveRoom();
106 absl::Status ClearRoom();
107
108 // Object manipulation
109 absl::Status InsertObject(int x, int y, int object_type, int size = 0x12,
110 int layer = 0);
111 absl::Status DeleteObject(size_t object_index);
112 absl::Status DeleteSelectedObjects();
113 absl::Status MoveObject(size_t object_index, int new_x, int new_y);
114 absl::Status ResizeObject(size_t object_index, int new_size);
115 absl::Status ChangeObjectType(size_t object_index, int new_type);
116 absl::Status ChangeObjectLayer(size_t object_index, int new_layer);
117
118 // Batch operations
119 absl::Status BatchMoveObjects(const std::vector<size_t>& indices, int dx,
120 int dy);
121 absl::Status BatchChangeObjectLayer(const std::vector<size_t>& indices,
122 int new_layer);
123 absl::Status BatchResizeObjects(const std::vector<size_t>& indices,
124 int new_size);
125
126 // Copy/Paste/Duplicate
127 std::optional<size_t> DuplicateObject(size_t object_index, int offset_x = 1, int offset_y = 1);
128 void CopySelectedObjects(const std::vector<size_t>& indices);
129 std::vector<size_t> PasteObjects();
130
132 absl::Status AlignSelectedObjects(Alignment alignment);
133
134 // Template management
135 absl::Status InsertTemplate(const ObjectTemplate& tmpl, int x, int y);
136 absl::Status CreateTemplateFromSelection(const std::string& name,
137 const std::string& description);
138 const std::vector<ObjectTemplate>& GetTemplates() const;
139
140 // Selection management
141 absl::Status SelectObject(int screen_x, int screen_y);
142 absl::Status SelectObjects(int start_x, int start_y, int end_x, int end_y);
143 absl::Status ClearSelection();
144 absl::Status AddToSelection(size_t object_index);
145 absl::Status RemoveFromSelection(size_t object_index);
146
147 // Mouse and scroll wheel handling
148 absl::Status HandleMouseClick(int x, int y, bool left_button,
149 bool right_button, bool shift_pressed);
150 absl::Status HandleMouseDrag(int start_x, int start_y, int current_x,
151 int current_y);
152 absl::Status HandleMouseRelease(int x,
153 int y); // Phase 4: End drag operations
154 absl::Status HandleScrollWheel(int delta, int x, int y, bool ctrl_pressed);
155 absl::Status HandleKeyPress(int key_code, bool ctrl_pressed,
156 bool shift_pressed);
157
158 // Mode management
159 void SetMode(Mode mode);
161
162 // Layer management
163 void SetCurrentLayer(int layer);
165 absl::StatusOr<std::vector<RoomObject>> GetObjectsByLayer(int layer);
166 absl::Status MoveObjectToLayer(size_t object_index, int layer);
167
168 // Object type management
169 void SetCurrentObjectType(int object_type);
173 absl::StatusOr<std::vector<int>> GetAvailableObjectTypes();
174 absl::Status ValidateObjectType(int object_type);
175
176 // Rendering and preview
177 absl::StatusOr<gfx::Bitmap> RenderPreview(int x, int y);
178 void SetPreviewPosition(int x, int y);
180
181 // Phase 4: Visual feedback and GUI
184 void DrawPropertyUI(); // ImGui panel contents
185 void RenderLayerControls(); // ImGui controls
186 absl::Status HandleDragOperation(int current_x, int current_y);
187
188 // Undo/Redo functionality
189 absl::Status Undo();
190 absl::Status Redo();
191 bool CanUndo() const;
192 bool CanRedo() const;
193 void ClearHistory();
194
195 // Configuration
196 void SetROM(Rom* rom);
197 void SetExternalRoom(Room* room);
198 void SetConfig(const EditorConfig& config);
199 EditorConfig GetConfig() const { return config_; }
200 void SetSnapToGrid(bool enabled);
201 void SetGridSize(int size);
202 void SetShowGrid(bool enabled);
203
204 // Validation and error checking
206 absl::Status ValidateObject(const RoomObject& object);
207 std::vector<std::string> GetValidationErrors();
208
209 // Event callbacks
211 std::function<void(size_t object_index, const RoomObject& object)>;
212 using RoomChangedCallback = std::function<void()>;
213 using SelectionChangedCallback = std::function<void(const SelectionState&)>;
214
218
219 absl::Status InitializeEditor();
220
221 // Getters
222 const Room& GetRoom() const { return *current_room_; }
225 const EditingState& GetEditingState() const { return editing_state_; }
226 size_t GetObjectCount() const {
227 return current_room_ ? current_room_->GetTileObjects().size() : 0;
228 }
229 const std::vector<RoomObject>& GetObjects() const {
231 }
232
233 private:
234 // Internal helper methods
235 absl::Status CreateUndoPoint();
236 absl::Status ApplyUndoPoint(const UndoPoint& undo_point);
237
238 // Coordinate conversion
239 std::pair<int, int> ScreenToRoomCoordinates(int screen_x, int screen_y);
240 std::pair<int, int> RoomToScreenCoordinates(int room_x, int room_y);
241 int SnapToGrid(int coordinate);
242
243 // Object finding and collision detection
244 std::optional<size_t> FindObjectAt(int room_x, int room_y);
245 std::vector<size_t> FindObjectsInArea(int start_x, int start_y, int end_x,
246 int end_y);
247 bool IsObjectAtPosition(const RoomObject& object, int x, int y);
248 bool ObjectsCollide(const RoomObject& obj1, const RoomObject& obj2);
249
250 // Preview and rendering helpers
251 absl::StatusOr<gfx::Bitmap> RenderObjectPreview(int object_type, int x, int y,
252 int size);
253 void UpdatePreviewObject();
254 absl::Status ValidatePreviewPosition(int x, int y);
255
256 // Size editing with scroll wheel
257 absl::Status HandleSizeEdit(int delta, int x, int y);
258 int GetNextSize(int current_size, int delta);
259 int GetPreviousSize(int current_size, int delta);
260 bool IsValidSize(int size);
261
262 // Member variables
264 Room* current_room_ = nullptr;
265 std::unique_ptr<Room> owned_room_;
266
270
271 std::vector<UndoPoint> undo_history_;
272 std::vector<UndoPoint> redo_history_;
273 static constexpr size_t kMaxUndoHistory = 50;
274
275 // Preview system
276 std::optional<RoomObject> preview_object_;
277 bool preview_visible_ = false;
278
279 // Event callbacks
283
284 // Constants
285 static constexpr int kMinObjectSize = 0x00;
286 static constexpr int kMaxObjectSize = 0xFF;
287 static constexpr int kDefaultObjectSize = 0x12;
288 static constexpr int kMinLayer = 0;
289 static constexpr int kMaxLayer = 2;
290
293
294 // Empty objects vector for const getter
295 std::vector<RoomObject> empty_objects_;
296
297 // Clipboard
298 std::vector<RoomObject> clipboard_;
299};
300
304std::unique_ptr<DungeonObjectEditor> CreateDungeonObjectEditor(Rom* rom);
305
309namespace ObjectCategories {
310
312 std::string name;
313 std::vector<int> object_ids;
314 std::string description;
315};
316
320std::vector<ObjectCategory> GetObjectCategories();
321
325absl::StatusOr<std::vector<int>> GetObjectsInCategory(
326 const std::string& category_name);
327
331absl::StatusOr<std::string> GetObjectCategory(int object_id);
332
337 int id;
338 std::string name;
339 std::string description;
340 std::vector<std::pair<int, int>> valid_sizes;
341 std::vector<int> valid_layers;
344};
345
346absl::StatusOr<ObjectInfo> GetObjectInfo(int object_id);
347
348} // namespace ObjectCategories
349
354 bool enabled = true;
355 int sensitivity = 1; // How much size changes per scroll
356 int min_size = 0x00;
357 int max_size = 0xFF;
358 bool wrap_around = false; // Wrap from max to min
359 bool smooth_scrolling = true;
360 int smooth_factor = 2; // Divide delta by this for smoother scrolling
361};
362
367 bool left_click_select = true;
369 bool middle_click_drag = false;
370 bool drag_to_select = true;
371 bool snap_drag_to_grid = true;
372 int double_click_threshold = 500; // milliseconds
373 int drag_threshold = 5; // pixels before drag starts
374};
375
376} // namespace zelda3
377} // namespace yaze
378
379#endif // YAZE_APP_ZELDA3_DUNGEON_DUNGEON_OBJECT_EDITOR_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:24
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
Interactive dungeon object editor with scroll wheel support.
std::function< void(const SelectionState &)> SelectionChangedCallback
absl::Status HandleMouseDrag(int start_x, int start_y, int current_x, int current_y)
absl::Status HandleScrollWheel(int delta, int x, int y, bool ctrl_pressed)
std::pair< int, int > ScreenToRoomCoordinates(int screen_x, int screen_y)
void SetSnapToGrid(bool enabled)
absl::Status ValidateObjectType(int object_type)
int GetNextSize(int current_size, int delta)
void SetRoomChangedCallback(RoomChangedCallback callback)
absl::Status ValidatePreviewPosition(int x, int y)
std::pair< int, int > RoomToScreenCoordinates(int room_x, int room_y)
absl::Status HandleKeyPress(int key_code, bool ctrl_pressed, bool shift_pressed)
absl::Status InsertObject(int x, int y, int object_type, int size=0x12, int layer=0)
const std::vector< ObjectTemplate > & GetTemplates() const
absl::Status BatchMoveObjects(const std::vector< size_t > &indices, int dx, int dy)
absl::Status ChangeObjectLayer(size_t object_index, int new_layer)
absl::Status BatchChangeObjectLayer(const std::vector< size_t > &indices, int new_layer)
absl::Status DeleteObject(size_t object_index)
void CopySelectedObjects(const std::vector< size_t > &indices)
void SetSelectionChangedCallback(SelectionChangedCallback callback)
absl::Status SelectObject(int screen_x, int screen_y)
std::optional< size_t > DuplicateObject(size_t object_index, int offset_x=1, int offset_y=1)
absl::StatusOr< gfx::Bitmap > RenderPreview(int x, int y)
absl::Status MoveObjectToLayer(size_t object_index, int layer)
absl::Status AlignSelectedObjects(Alignment alignment)
void SetPreviewPosition(int x, int y)
std::optional< size_t > FindObjectAt(int room_x, int room_y)
const EditingState & GetEditingState() const
absl::Status AddToSelection(size_t object_index)
const std::vector< RoomObject > & GetObjects() const
void RenderLayerVisualization(gfx::Bitmap &canvas)
std::vector< std::string > GetValidationErrors()
const SelectionState & GetSelection() const
void SetConfig(const EditorConfig &config)
absl::StatusOr< gfx::Bitmap > RenderObjectPreview(int object_type, int x, int y, int size)
absl::StatusOr< std::vector< int > > GetAvailableObjectTypes()
std::function< void(size_t object_index, const RoomObject &object)> ObjectChangedCallback
absl::Status ValidateObject(const RoomObject &object)
absl::Status HandleDragOperation(int current_x, int current_y)
absl::Status HandleSizeEdit(int delta, int x, int y)
bool ObjectsCollide(const RoomObject &obj1, const RoomObject &obj2)
absl::Status SelectObjects(int start_x, int start_y, int end_x, int end_y)
bool IsObjectAtPosition(const RoomObject &object, int x, int y)
void SetObjectChangedCallback(ObjectChangedCallback callback)
absl::Status HandleMouseRelease(int x, int y)
absl::Status RemoveFromSelection(size_t object_index)
absl::Status InsertTemplate(const ObjectTemplate &tmpl, int x, int y)
absl::Status MoveObject(size_t object_index, int new_x, int new_y)
absl::Status ResizeObject(size_t object_index, int new_size)
std::optional< RoomObject > preview_object_
absl::Status BatchResizeObjects(const std::vector< size_t > &indices, int new_size)
absl::Status ChangeObjectType(size_t object_index, int new_type)
std::vector< RoomObject > empty_objects_
std::vector< size_t > FindObjectsInArea(int start_x, int start_y, int end_x, int end_y)
SelectionChangedCallback selection_changed_callback_
absl::Status ApplyUndoPoint(const UndoPoint &undo_point)
absl::Status HandleMouseClick(int x, int y, bool left_button, bool right_button, bool shift_pressed)
int GetPreviousSize(int current_size, int delta)
void RenderSelectionHighlight(gfx::Bitmap &canvas)
absl::StatusOr< std::vector< RoomObject > > GetObjectsByLayer(int layer)
absl::Status CreateTemplateFromSelection(const std::string &name, const std::string &description)
const std::vector< RoomObject > & GetTileObjects() const
Definition room.h:346
std::vector< ObjectCategory > GetObjectCategories()
Get all available object categories.
absl::StatusOr< ObjectInfo > GetObjectInfo(int object_id)
absl::StatusOr< std::string > GetObjectCategory(int object_id)
Get category for a specific object.
absl::StatusOr< std::vector< int > > GetObjectsInCategory(const std::string &category_name)
Get objects in a specific category.
std::unique_ptr< DungeonObjectEditor > CreateDungeonObjectEditor(Rom *rom)
Factory function to create dungeon object editor.
std::chrono::steady_clock::time_point timestamp
Mouse interaction configuration.
std::vector< std::pair< int, int > > valid_sizes
Scroll wheel behavior configuration.