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/core/window.h"
13#include "app/gfx/bitmap.h"
15#include "app/rom.h"
18
19namespace yaze {
20namespace zelda3 {
21
36 public:
37 // Editor modes
38 enum class Mode {
39 kSelect, // Select and move objects
40 kInsert, // Insert new objects
41 kDelete, // Delete objects
42 kEdit, // Edit object properties
43 kLayer, // Layer management
44 kPreview // Preview mode
45 };
46
47 // Object selection state
49 std::vector<size_t> selected_objects; // Indices of selected objects
50 bool is_multi_select = false;
51 bool is_dragging = false;
52 int drag_start_x = 0;
53 int drag_start_y = 0;
54 };
55
56 // Object editing state
57 struct EditingState {
60 int current_object_type = 0x10; // Default to wall
62 bool is_editing_size = false;
63 bool is_editing_position = false;
64 int preview_x = 0;
65 int preview_y = 0;
66 int preview_size = 0x12; // Default size
67 };
68
69 // Editor configuration
70 struct EditorConfig {
71 bool snap_to_grid = true;
72 int grid_size = 16; // 16x16 pixel grid
73 bool show_grid = true;
74 bool show_preview = true;
75 bool auto_save = false;
76 int auto_save_interval = 300; // 5 minutes
77 bool validate_objects = true;
79
80 // Phase 4: Visual feedback settings
82 bool show_layer_colors = true;
84 uint32_t selection_color = 0xFFFFFF00; // Yellow
85 uint32_t layer0_color = 0xFFFF0000; // Red tint
86 uint32_t layer1_color = 0xFF00FF00; // Green tint
87 uint32_t layer2_color = 0xFF0000FF; // Blue tint
88 };
89
90 // Undo/Redo system
91 struct UndoPoint {
92 std::vector<RoomObject> objects;
95 std::chrono::steady_clock::time_point timestamp;
96 };
97
98 explicit DungeonObjectEditor(Rom* rom);
100
101 // Core editing operations
102 absl::Status LoadRoom(int room_id);
103 absl::Status SaveRoom();
104 absl::Status ClearRoom();
105
106 // Object manipulation
107 absl::Status InsertObject(int x, int y, int object_type, int size = 0x12,
108 int layer = 0);
109 absl::Status DeleteObject(size_t object_index);
110 absl::Status DeleteSelectedObjects();
111 absl::Status MoveObject(size_t object_index, int new_x, int new_y);
112 absl::Status ResizeObject(size_t object_index, int new_size);
113 absl::Status ChangeObjectType(size_t object_index, int new_type);
114 absl::Status ChangeObjectLayer(size_t object_index, int new_layer);
115
116 // Selection management
117 absl::Status SelectObject(int screen_x, int screen_y);
118 absl::Status SelectObjects(int start_x, int start_y, int end_x, int end_y);
119 absl::Status ClearSelection();
120 absl::Status AddToSelection(size_t object_index);
121 absl::Status RemoveFromSelection(size_t object_index);
122
123 // Mouse and scroll wheel handling
124 absl::Status HandleMouseClick(int x, int y, bool left_button,
125 bool right_button, bool shift_pressed);
126 absl::Status HandleMouseDrag(int start_x, int start_y, int current_x,
127 int current_y);
128 absl::Status HandleMouseRelease(int x, int y); // Phase 4: End drag operations
129 absl::Status HandleScrollWheel(int delta, int x, int y, bool ctrl_pressed);
130 absl::Status HandleKeyPress(int key_code, bool ctrl_pressed,
131 bool shift_pressed);
132
133 // Mode management
134 void SetMode(Mode mode);
136
137 // Layer management
138 void SetCurrentLayer(int layer);
140 absl::StatusOr<std::vector<RoomObject>> GetObjectsByLayer(int layer);
141 absl::Status MoveObjectToLayer(size_t object_index, int layer);
142
143 // Object type management
144 void SetCurrentObjectType(int object_type);
148 absl::StatusOr<std::vector<int>> GetAvailableObjectTypes();
149 absl::Status ValidateObjectType(int object_type);
150
151 // Rendering and preview
152 absl::StatusOr<gfx::Bitmap> RenderPreview(int x, int y);
153 void SetPreviewPosition(int x, int y);
155
156 // Phase 4: Visual feedback and GUI
159 void RenderObjectPropertyPanel(); // ImGui panel
160 void RenderLayerControls(); // ImGui controls
161 absl::Status HandleDragOperation(int current_x, int current_y);
162
163 // Undo/Redo functionality
164 absl::Status Undo();
165 absl::Status Redo();
166 bool CanUndo() const;
167 bool CanRedo() const;
168 void ClearHistory();
169
170 // Configuration
171 void SetROM(Rom* rom);
172 void SetConfig(const EditorConfig& config);
173 EditorConfig GetConfig() const { return config_; }
174 void SetSnapToGrid(bool enabled);
175 void SetGridSize(int size);
176 void SetShowGrid(bool enabled);
177
178 // Validation and error checking
179 absl::Status ValidateRoom();
180 absl::Status ValidateObject(const RoomObject& object);
181 std::vector<std::string> GetValidationErrors();
182
183 // Event callbacks
185 std::function<void(size_t object_index, const RoomObject& object)>;
186 using RoomChangedCallback = std::function<void()>;
187 using SelectionChangedCallback = std::function<void(const SelectionState&)>;
188
192
193 // Getters
194 const Room& GetRoom() const { return *current_room_; }
195 Room* GetMutableRoom() { return current_room_.get(); }
197 const EditingState& GetEditingState() const { return editing_state_; }
198 size_t GetObjectCount() const {
199 return current_room_ ? current_room_->GetTileObjects().size() : 0;
200 }
201 const std::vector<RoomObject>& GetObjects() const {
202 return current_room_ ? current_room_->GetTileObjects() : empty_objects_;
203 }
204
205 private:
206 // Internal helper methods
207 absl::Status InitializeEditor();
208 absl::Status CreateUndoPoint();
209 absl::Status ApplyUndoPoint(const UndoPoint& undo_point);
210
211 // Coordinate conversion
212 std::pair<int, int> ScreenToRoomCoordinates(int screen_x, int screen_y);
213 std::pair<int, int> RoomToScreenCoordinates(int room_x, int room_y);
214 int SnapToGrid(int coordinate);
215
216 // Object finding and collision detection
217 std::optional<size_t> FindObjectAt(int room_x, int room_y);
218 std::vector<size_t> FindObjectsInArea(int start_x, int start_y, int end_x,
219 int end_y);
220 bool IsObjectAtPosition(const RoomObject& object, int x, int y);
221 bool ObjectsCollide(const RoomObject& obj1, const RoomObject& obj2);
222
223 // Preview and rendering helpers
224 absl::StatusOr<gfx::Bitmap> RenderObjectPreview(int object_type, int x, int y,
225 int size);
226 void UpdatePreviewObject();
227 absl::Status ValidatePreviewPosition(int x, int y);
228
229 // Size editing with scroll wheel
230 absl::Status HandleSizeEdit(int delta, int x, int y);
231 int GetNextSize(int current_size, int delta);
232 int GetPreviousSize(int current_size, int delta);
233 bool IsValidSize(int size);
234
235 // Member variables
237 std::unique_ptr<Room> current_room_;
238
242
243 std::vector<UndoPoint> undo_history_;
244 std::vector<UndoPoint> redo_history_;
245 static constexpr size_t kMaxUndoHistory = 50;
246
247 // Preview system
248 std::optional<RoomObject> preview_object_;
249 bool preview_visible_ = false;
250
251 // Event callbacks
255
256 // Constants
257 static constexpr int kMinObjectSize = 0x00;
258 static constexpr int kMaxObjectSize = 0xFF;
259 static constexpr int kDefaultObjectSize = 0x12;
260 static constexpr int kMinLayer = 0;
261 static constexpr int kMaxLayer = 2;
262
263 // Empty objects vector for const getter
264 std::vector<RoomObject> empty_objects_;
265};
266
270std::unique_ptr<DungeonObjectEditor> CreateDungeonObjectEditor(Rom* rom);
271
275namespace ObjectCategories {
276
278 std::string name;
279 std::vector<int> object_ids;
280 std::string description;
281};
282
286std::vector<ObjectCategory> GetObjectCategories();
287
291absl::StatusOr<std::vector<int>> GetObjectsInCategory(
292 const std::string& category_name);
293
297absl::StatusOr<std::string> GetObjectCategory(int object_id);
298
303 int id;
304 std::string name;
305 std::string description;
306 std::vector<std::pair<int, int>> valid_sizes;
307 std::vector<int> valid_layers;
310};
311
312absl::StatusOr<ObjectInfo> GetObjectInfo(int object_id);
313
314} // namespace ObjectCategories
315
320 bool enabled = true;
321 int sensitivity = 1; // How much size changes per scroll
322 int min_size = 0x00;
323 int max_size = 0xFF;
324 bool wrap_around = false; // Wrap from max to min
325 bool smooth_scrolling = true;
326 int smooth_factor = 2; // Divide delta by this for smoother scrolling
327};
328
333 bool left_click_select = true;
335 bool middle_click_drag = false;
336 bool drag_to_select = true;
337 bool snap_drag_to_grid = true;
338 int double_click_threshold = 500; // milliseconds
339 int drag_threshold = 5; // pixels before drag starts
340};
341
342} // namespace zelda3
343} // namespace yaze
344
345#endif // YAZE_APP_ZELDA3_DUNGEON_DUNGEON_OBJECT_EDITOR_H
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:71
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:66
Interactive dungeon object editor with scroll wheel support.
std::function< void(size_t object_index, const RoomObject &object)> ObjectChangedCallback
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)
absl::Status ChangeObjectLayer(size_t object_index, int new_layer)
absl::Status DeleteObject(size_t object_index)
void SetSelectionChangedCallback(SelectionChangedCallback callback)
absl::Status SelectObject(int screen_x, int screen_y)
absl::StatusOr< gfx::Bitmap > RenderPreview(int x, int y)
absl::Status MoveObjectToLayer(size_t object_index, int layer)
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()
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 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 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)
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.
Main namespace for the application.
std::chrono::steady_clock::time_point timestamp
Mouse interaction configuration.
std::vector< std::pair< int, int > > valid_sizes
Scroll wheel behavior configuration.