yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
lyra_terrain_canvas.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_OVERWORLD_LYRA_TERRAIN_CANVAS_H_
2#define YAZE_APP_EDITOR_OVERWORLD_LYRA_TERRAIN_CANVAS_H_
3
4#include <array>
5#include <memory>
6#include <optional>
7#include <string>
8#include <unordered_map>
9#include <vector>
10
13#include "app/gfx/core/bitmap.h"
16#include "core/project.h"
17#include "imgui/imgui.h"
19
20namespace yaze::editor {
21
22// Publishes a validated sidecar while retaining the exact loaded bytes as the
23// compare-and-swap baseline. The caller keeps project draft state until the
24// project reference itself is saved successfully. Returns the published bytes.
25absl::StatusOr<std::string> PublishLyraTerrainSource(
26 const project::YazeProject& project, const std::string& source_path,
27 const std::optional<std::string>& source_bytes,
28 const core::LyraTerrainDocument& document);
29
30// Project-owned terrain. This view never routes edits through the ROM map model.
32 public:
33 LyraTerrainCanvas() = default;
37 absl::Status Load(project::YazeProject* project,
38 zelda3::Overworld& overworld);
39 // Validates a selected source through a project copy. A failed replacement
40 // retains the current document, pending properties, and owner reference.
41 absl::Status Open(project::YazeProject* project, const std::string& path,
42 zelda3::Overworld& overworld);
43 absl::Status Create(project::YazeProject* project,
44 zelda3::Overworld& overworld);
45 absl::Status Save(project::YazeProject* project,
46 zelda3::Overworld& overworld);
47 absl::Status SaveAs(project::YazeProject* project,
48 const std::string& project_path,
49 zelda3::Overworld& overworld);
50 // Also used after native save to qualify a build receipt against the live
51 // document, including clean saves that do not republish the sidecar.
52 absl::Status ValidateSave(project::YazeProject* project,
53 zelda3::Overworld& overworld);
54 bool dirty() const;
56 bool loaded() const { return document_ != nullptr; }
57 // Rendering only. TilePaintingManager owns the shared Overworld gestures.
58 void DrawSpecialWorld(const gui::CanvasRuntime& canvas);
59 // Coordinates are document-relative Tile16 cells; footprints clip at its
60 // edge. The entire brush is validated before any cells are changed.
61 absl::Status PaintPattern(const TileBrush& brush, int x, int y, int width,
62 int height, bool finalize, UndoManager& history);
63 void FinishStroke(UndoManager& history);
64 void Reset();
65 const core::LyraTerrainDocument* document() const { return document_.get(); }
66 const gfx::Bitmap& atlas() const { return atlas_; }
67 gfx::Bitmap& atlas() { return atlas_; }
68 bool stroke_active() const { return stroke_active_; }
69 // All edits share the project's history and atomic sidecar save path.
70 absl::Status EditAuthoring(core::LyraAuthoringState after,
71 zelda3::Overworld& overworld,
72 UndoManager& history);
73 // A size explicitly assigns this page as the parent. Null unassigns the
74 // containing area, including all its pages, through the same Undo history.
75 absl::Status SetGameplayArea(int map_id,
76 std::optional<core::LyraGameplayAreaSize> size,
77 zelda3::Overworld& overworld,
78 UndoManager& history);
79 absl::Status PrepareMapAssets(zelda3::Overworld& overworld, int state);
80 gfx::Bitmap& MapAtlas(int map_id);
81 gfx::Bitmap* MapGraphics(int map_id);
82 void DrawProperties(int map_id, int& state, zelda3::Overworld& overworld,
83 UndoManager& history);
85 return document_ && placement_kind_ != 0;
86 }
87 void DrawSpritePreview(const gui::CanvasRuntime& canvas, int map_id,
88 const core::LyraSpritePlacement& sprite);
89 void DrawEntities(const gui::CanvasRuntime& canvas, int world, int state);
90 void HandleEntityInput(const gui::CanvasRuntime& canvas, int world,
91 zelda3::Overworld& overworld, UndoManager& history);
92
93 private:
95
96 // A map's unapplied property edits. `baseline` is the live value the edits
97 // started from; pending drafts differ from both baseline and current live.
102 // Creates or reconciles the entry: clean drafts follow live properties and a
103 // pending draft that now equals live becomes clean.
105 bool PropertyPending(int map_index) const;
106 // Live properties changed after a pending draft started.
107 bool PropertyConflict(int map_index) const;
108 std::vector<int> PendingPropertyMaps() const;
109 static std::string FormatMapIds(const std::vector<int>& map_ids);
110 // Refuses a conflicting draft; success and validation failure both leave
111 // other maps untouched.
112 absl::Status ApplyPropertyDraft(int map_index, zelda3::Overworld& overworld,
113 UndoManager& history);
114 void RevertPropertyDraft(int map_index);
115 // Every control edits live authoring directly; no draft outlives a frame.
116 void DrawEdgeConnections(int map_id, zelda3::Overworld& overworld,
117 UndoManager& history);
118 void DrawGameplayArea(int map_id, zelda3::Overworld& overworld,
119 UndoManager& history);
120 absl::Status ApplyAuthoring(core::LyraAuthoringState after,
121 zelda3::Overworld& overworld,
122 UndoManager& history);
123 struct MapAssets {
126 std::string binding;
127 std::unordered_map<int, std::unique_ptr<gfx::Bitmap>> sprites;
128 std::unordered_map<int, SDL_Rect> sprite_bounds;
129 ~MapAssets();
130 };
131 absl::StatusOr<std::unique_ptr<MapAssets>> ResolveMapAssets(
132 zelda3::Overworld& overworld, const core::LyraMapProperties& properties,
133 int state, bool textures);
134 // Returns `candidate` with the native area parent's graphics selectors only
135 // after every field and Lyra state validates. Never mutates the source map.
136 absl::StatusOr<core::LyraMapProperties> CopyNativeGraphicsSettings(
137 zelda3::Overworld& overworld, int source_map,
138 core::LyraMapProperties candidate);
139 absl::Status CheckAssetSources(zelda3::Overworld& overworld);
140 absl::Status ValidateMapAssets(zelda3::Overworld& overworld,
141 const core::LyraAuthoringState& authoring);
142 absl::Status BindSource(zelda3::Overworld& overworld,
144 gfx::Bitmap* atlas = nullptr);
145 // Called only after document, native profile, and CPU atlas all validate.
146 // Texture commands use the committed bitmap's stable member address.
147 void InstallDocument(std::shared_ptr<core::LyraTerrainDocument> document,
148 gfx::Bitmap atlas, std::string source_path,
149 std::optional<std::string> source_bytes,
150 bool unpublished);
151 void DrawTile(ImDrawList* draw, const gfx::Bitmap& atlas, int tile,
152 ImVec2 min, float size) const;
153 void PaintStamp(int x, int y);
154 void PaintLine(int x, int y);
155
156 std::shared_ptr<core::LyraTerrainDocument> document_;
158 std::string source_path_;
159 std::optional<std::string> source_bytes_;
160 bool unpublished_ = false;
162 bool stroke_active_ = false;
163 std::optional<ImVec2> last_cell_;
167 absl::Status status_;
168 std::unordered_map<std::string, std::unique_ptr<MapAssets>> map_assets_;
169 std::array<MapAssets*, 32> displayed_assets_{};
172 std::vector<uint8_t> source_rom_, source_graphics_;
173 std::string source_metadata_;
174 absl::Status source_status_;
176 std::optional<core::LyraAuthoringState> validated_authoring_;
177 bool assets_valid_ = false;
178 // Tracks navigation for transient copy feedback only.
180 std::array<std::optional<PropertyDraft>, core::LyraTerrainDocument::kMapCount>
183 // Cleared whenever the destination map changes.
184 std::string copy_message_;
185 bool copy_failed_ = false;
189 // Independent of placement_type_, which other placement modes overwrite.
191 std::array<char, 64> sprite_filter_{};
192 uint32_t selected_entity_ = 0;
194 std::optional<core::LyraAuthoringState> drag_before_;
195 int drag_map_ = -1;
196};
197
198} // namespace yaze::editor
199#endif
void DrawEntities(const gui::CanvasRuntime &canvas, int world, int state)
void DrawProperties(int map_id, int &state, zelda3::Overworld &overworld, UndoManager &history)
bool PropertyConflict(int map_index) const
absl::Status PaintPattern(const TileBrush &brush, int x, int y, int width, int height, bool finalize, UndoManager &history)
LyraTerrainCanvas & operator=(const LyraTerrainCanvas &)=delete
bool PropertyPending(int map_index) const
absl::Status PrepareMapAssets(zelda3::Overworld &overworld, int state)
absl::Status SaveAs(project::YazeProject *project, const std::string &project_path, zelda3::Overworld &overworld)
std::optional< std::string > source_bytes_
absl::Status SetGameplayArea(int map_id, std::optional< core::LyraGameplayAreaSize > size, zelda3::Overworld &overworld, UndoManager &history)
void DrawSpecialWorld(const gui::CanvasRuntime &canvas)
void HandleEntityInput(const gui::CanvasRuntime &canvas, int world, zelda3::Overworld &overworld, UndoManager &history)
std::shared_ptr< core::LyraTerrainDocument > document_
std::optional< core::LyraAuthoringState > validated_authoring_
std::vector< int > PendingPropertyMaps() const
absl::Status ValidateMapAssets(zelda3::Overworld &overworld, const core::LyraAuthoringState &authoring)
gfx::Bitmap & MapAtlas(int map_id)
absl::Status Create(project::YazeProject *project, zelda3::Overworld &overworld)
std::array< std::optional< PropertyDraft >, core::LyraTerrainDocument::kMapCount > property_drafts_
absl::StatusOr< std::unique_ptr< MapAssets > > ResolveMapAssets(zelda3::Overworld &overworld, const core::LyraMapProperties &properties, int state, bool textures)
void DrawEdgeConnections(int map_id, zelda3::Overworld &overworld, UndoManager &history)
void InstallDocument(std::shared_ptr< core::LyraTerrainDocument > document, gfx::Bitmap atlas, std::string source_path, std::optional< std::string > source_bytes, bool unpublished)
absl::Status EditAuthoring(core::LyraAuthoringState after, zelda3::Overworld &overworld, UndoManager &history)
const core::LyraTerrainDocument * document() const
const gfx::Bitmap & atlas() const
static std::string FormatMapIds(const std::vector< int > &map_ids)
std::array< MapAssets *, 32 > displayed_assets_
std::array< char, 64 > sprite_filter_
void DrawGameplayArea(int map_id, zelda3::Overworld &overworld, UndoManager &history)
std::vector< uint8_t > source_graphics_
gfx::Bitmap * MapGraphics(int map_id)
std::unordered_map< std::string, std::unique_ptr< MapAssets > > map_assets_
void DrawSpritePreview(const gui::CanvasRuntime &canvas, int map_id, const core::LyraSpritePlacement &sprite)
void DrawTile(ImDrawList *draw, const gfx::Bitmap &atlas, int tile, ImVec2 min, float size) const
std::optional< core::LyraAuthoringState > drag_before_
absl::Status BindSource(zelda3::Overworld &overworld, core::LyraTerrainProfile *profile, gfx::Bitmap *atlas=nullptr)
absl::StatusOr< core::LyraMapProperties > CopyNativeGraphicsSettings(zelda3::Overworld &overworld, int source_map, core::LyraMapProperties candidate)
absl::Status CheckAssetSources(zelda3::Overworld &overworld)
absl::Status ApplyPropertyDraft(int map_index, zelda3::Overworld &overworld, UndoManager &history)
absl::Status Load(project::YazeProject *project, zelda3::Overworld &overworld)
absl::Status Save(project::YazeProject *project, zelda3::Overworld &overworld)
void FinishStroke(UndoManager &history)
absl::Status ApplyAuthoring(core::LyraAuthoringState after, zelda3::Overworld &overworld, UndoManager &history)
core::LyraMapProperties & PropertyDraftFor(int map_index)
absl::Status ValidateSave(project::YazeProject *project, zelda3::Overworld &overworld)
LyraTerrainCanvas(const LyraTerrainCanvas &)=delete
absl::Status Open(project::YazeProject *project, const std::string &path, zelda3::Overworld &overworld)
Manages undo/redo stacks for a single editor.
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
Editors are the view controllers for the application.
absl::StatusOr< std::string > PublishLyraTerrainSource(const project::YazeProject &project, const std::string &source_path, const std::optional< std::string > &source_bytes, const core::LyraTerrainDocument &document)
std::unordered_map< int, std::unique_ptr< gfx::Bitmap > > sprites
std::unordered_map< int, SDL_Rect > sprite_bounds
Modern project structure with comprehensive settings consolidation.
Definition project.h:290