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 <chrono>
5#include <functional>
6#include <memory>
7#include <optional>
8#include <unordered_map>
9#include <vector>
10
11#include "absl/status/status.h"
12#include "absl/status/statusor.h"
13#include "app/gfx/core/bitmap.h"
15#include "app/platform/window.h"
16#include "rom/rom.h"
19#include "zelda3/dungeon/room.h"
21
22namespace yaze {
23namespace zelda3 {
24
39 public:
40 // Editor modes
41 enum class Mode {
42 kSelect, // Select and move objects
43 kInsert, // Insert new objects
44 kDelete, // Delete objects
45 kEdit, // Edit object properties
46 kLayer, // Layer management
47 kPreview // Preview mode
48 };
49
50 // Object selection state
52 std::vector<size_t> selected_objects; // Indices of selected objects
53 bool is_multi_select = false;
54 bool is_dragging = false;
55 int drag_start_x = 0;
56 int drag_start_y = 0;
57 };
58
59 // Object editing state
60 struct EditingState {
63 int current_object_type = 0x10; // Default to wall
65 bool is_editing_size = false;
66 bool is_editing_position = false;
67 int preview_x = 0;
68 int preview_y = 0;
69 int preview_size = 0x12; // Default size
70 };
71
72 // Editor configuration
73 struct EditorConfig {
74 bool snap_to_grid = true;
75 int grid_size = 16; // 16x16 pixel grid
76 bool show_grid = true;
77 bool show_preview = true;
78 bool auto_save = false;
79 int auto_save_interval = 300; // 5 minutes
80 bool validate_objects = true;
82
83 // Phase 4: Visual feedback settings
85 bool show_layer_colors = true;
87 uint32_t selection_color = 0xFFFFFF00; // Yellow
88 uint32_t layer0_color = 0xFFFF0000; // Red tint
89 uint32_t layer1_color = 0xFF00FF00; // Green tint
90 uint32_t layer2_color = 0xFF0000FF; // Blue tint
91 };
92
93 // Undo/Redo system
94 struct UndoPoint {
95 std::vector<RoomObject> objects;
98 std::chrono::steady_clock::time_point timestamp;
99 };
100
101 explicit DungeonObjectEditor(Rom* rom);
103
104 // Core editing operations
105 absl::Status LoadRoom(int room_id);
106 absl::Status SaveRoom();
107 absl::Status ClearRoom();
108
109 // Object manipulation
110 absl::Status InsertObject(int x, int y, int object_type, int size = 0x12,
111 int layer = 0);
112 absl::Status DeleteObject(size_t object_index);
113 absl::Status DeleteSelectedObjects();
114 absl::Status MoveObject(size_t object_index, int new_x, int new_y);
115 absl::Status ResizeObject(size_t object_index, int new_size);
116 absl::Status ChangeObjectType(size_t object_index, int new_type);
117 absl::Status ChangeObjectLayer(size_t object_index, int new_layer);
118
119 // Batch operations
120 absl::Status BatchMoveObjects(const std::vector<size_t>& indices, int dx,
121 int dy);
122 absl::Status BatchChangeObjectLayer(const std::vector<size_t>& indices,
123 int new_layer);
124 absl::Status BatchResizeObjects(const std::vector<size_t>& indices,
125 int new_size);
126
127 // Copy/Paste/Duplicate
128 std::optional<size_t> DuplicateObject(size_t object_index, int offset_x = 1,
129 int offset_y = 1);
130 void CopySelectedObjects(const std::vector<size_t>& indices);
131 std::vector<size_t> PasteObjects();
132
134 absl::Status AlignSelectedObjects(Alignment alignment);
135
136 // Template management
137 absl::Status InsertTemplate(const ObjectTemplate& tmpl, int x, int y);
138 absl::Status CreateTemplateFromSelection(const std::string& name,
139 const std::string& description);
140 const std::vector<ObjectTemplate>& GetTemplates() const;
141
142 // Selection management
143 absl::Status SelectObject(int screen_x, int screen_y);
144 absl::Status SelectObjects(int start_x, int start_y, int end_x, int end_y);
145 absl::Status ClearSelection();
146 absl::Status AddToSelection(size_t object_index);
147 absl::Status RemoveFromSelection(size_t object_index);
148
149 // Mouse and scroll wheel handling
150 absl::Status HandleMouseClick(int x, int y, bool left_button,
151 bool right_button, bool shift_pressed);
152 absl::Status HandleMouseDrag(int start_x, int start_y, int current_x,
153 int current_y);
154 absl::Status HandleMouseRelease(int x,
155 int y); // Phase 4: End drag operations
156 absl::Status HandleScrollWheel(int delta, int x, int y, bool ctrl_pressed);
157 absl::Status HandleKeyPress(int key_code, bool ctrl_pressed,
158 bool shift_pressed);
159
160 // Mode management
161 void SetMode(Mode mode);
163
164 // Layer management
165 void SetCurrentLayer(int layer);
167 absl::StatusOr<std::vector<RoomObject>> GetObjectsByLayer(int layer);
168 absl::Status MoveObjectToLayer(size_t object_index, int layer);
169
170 // Object type management
171 void SetCurrentObjectType(int object_type);
175 absl::StatusOr<std::vector<int>> GetAvailableObjectTypes();
176 absl::Status ValidateObjectType(int object_type);
177
178 // Rendering and preview
179 absl::StatusOr<gfx::Bitmap> RenderPreview(int x, int y);
180 void SetPreviewPosition(int x, int y);
182
183 // Phase 4: Visual feedback and GUI
186 void DrawPropertyUI(); // ImGui panel contents
187 void RenderLayerControls(); // ImGui controls
188 absl::Status HandleDragOperation(int current_x, int current_y);
189
190 // Undo/Redo functionality
191 absl::Status Undo();
192 absl::Status Redo();
193 bool CanUndo() const;
194 bool CanRedo() const;
195 void ClearHistory();
196
197 // Configuration
198 void SetROM(Rom* rom);
199 void SetExternalRoom(Room* room);
200 void SetConfig(const EditorConfig& config);
201 EditorConfig GetConfig() const { return config_; }
202 void SetSnapToGrid(bool enabled);
203 void SetGridSize(int size);
204 void SetShowGrid(bool enabled);
205
206 // Validation and error checking
208 absl::Status ValidateObject(const RoomObject& object);
209 std::vector<std::string> GetValidationErrors();
210
211 // Event callbacks
213 std::function<void(size_t object_index, const RoomObject& object)>;
214 using RoomChangedCallback = std::function<void()>;
215 using SelectionChangedCallback = std::function<void(const SelectionState&)>;
216
220
221 absl::Status InitializeEditor();
222
223 // Getters
224 const Room& GetRoom() const { return *current_room_; }
227 const EditingState& GetEditingState() const { return editing_state_; }
228 size_t GetObjectCount() const {
229 return current_room_ ? current_room_->GetTileObjects().size() : 0;
230 }
231 const std::vector<RoomObject>& GetObjects() const {
233 }
234
235 private:
236 // Internal helper methods
237 absl::Status CreateUndoPoint();
238 absl::Status ApplyUndoPoint(const UndoPoint& undo_point);
239
240 // Coordinate conversion
241 std::pair<int, int> ScreenToRoomCoordinates(int screen_x, int screen_y);
242 std::pair<int, int> RoomToScreenCoordinates(int room_x, int room_y);
243 int SnapToGrid(int coordinate);
244
245 // Object finding and collision detection
246 std::optional<size_t> FindObjectAt(int room_x, int room_y);
247 std::vector<size_t> FindObjectsInArea(int start_x, int start_y, int end_x,
248 int end_y);
249 bool IsObjectAtPosition(const RoomObject& object, int x, int y);
250 bool ObjectsCollide(const RoomObject& obj1, const RoomObject& obj2);
251
252 // Preview and rendering helpers
253 absl::StatusOr<gfx::Bitmap> RenderObjectPreview(int object_type, int x, int y,
254 int size);
255 void UpdatePreviewObject();
256 absl::Status ValidatePreviewPosition(int x, int y);
257
258 // Size editing with scroll wheel
259 absl::Status HandleSizeEdit(int delta, int x, int y);
260 int GetNextSize(int current_size, int delta);
261 int GetPreviousSize(int current_size, int delta);
262 bool IsValidSize(int size);
263
264 // Member variables
266 Room* current_room_ = nullptr;
267 std::unique_ptr<Room> owned_room_;
268
272
273 std::vector<UndoPoint> undo_history_;
274 std::vector<UndoPoint> redo_history_;
275 static constexpr size_t kMaxUndoHistory = 50;
276
277 // Preview system
278 std::optional<RoomObject> preview_object_;
279 bool preview_visible_ = false;
280
281 // Event callbacks
285
286 // Constants
287 static constexpr int kMinObjectSize = 0x00;
288 static constexpr int kMaxObjectSize = 0xFF;
289 static constexpr int kDefaultObjectSize = 0x12;
290 static constexpr int kMinLayer = 0;
291 static constexpr int kMaxLayer = 2;
292
295
296 // Empty objects vector for const getter
297 std::vector<RoomObject> empty_objects_;
298
299 // Clipboard
300 std::vector<RoomObject> clipboard_;
301};
302
306std::unique_ptr<DungeonObjectEditor> CreateDungeonObjectEditor(Rom* rom);
307
311namespace ObjectCategories {
312
314 std::string name;
315 std::vector<int> object_ids;
316 std::string description;
317};
318
322std::vector<ObjectCategory> GetObjectCategories();
323
327absl::StatusOr<std::vector<int>> GetObjectsInCategory(
328 const std::string& category_name);
329
333absl::StatusOr<std::string> GetObjectCategory(int object_id);
334
339 int id;
340 std::string name;
341 std::string description;
342 std::vector<std::pair<int, int>> valid_sizes;
343 std::vector<int> valid_layers;
346};
347
348absl::StatusOr<ObjectInfo> GetObjectInfo(int object_id);
349
350} // namespace ObjectCategories
351
356 bool enabled = true;
357 int sensitivity = 1; // How much size changes per scroll
358 int min_size = 0x00;
359 int max_size = 0xFF;
360 bool wrap_around = false; // Wrap from max to min
361 bool smooth_scrolling = true;
362 int smooth_factor = 2; // Divide delta by this for smoother scrolling
363};
364
369 bool left_click_select = true;
371 bool middle_click_drag = false;
372 bool drag_to_select = true;
373 bool snap_drag_to_grid = true;
374 int double_click_threshold = 500; // milliseconds
375 int drag_threshold = 5; // pixels before drag starts
376};
377
378} // namespace zelda3
379} // namespace yaze
380
381#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.