yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sprite_editor.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_SPRITE_EDITOR_H
2#define YAZE_APP_EDITOR_SPRITE_EDITOR_H
3
4#include <cstdint>
5#include <map>
6#include <optional>
7#include <set>
8#include <string>
9#include <vector>
10
11#include "absl/status/status.h"
12#include "app/editor/editor.h"
17#include "app/gfx/core/bitmap.h"
20#include "rom/rom.h"
25
26namespace yaze {
27namespace editor {
28
29constexpr ImGuiTabItemFlags kSpriteTabFlags =
30 ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip;
31
32constexpr ImGuiTabBarFlags kSpriteTabBarFlags =
33 ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable |
34 ImGuiTabBarFlags_FittingPolicyResizeDown |
35 ImGuiTabBarFlags_TabListPopupButton;
36
37constexpr ImGuiTableFlags kSpriteTableFlags =
38 ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable |
39 ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter |
40 ImGuiTableFlags_BordersV;
41
50class SpriteEditor : public Editor {
53
54 public:
55 explicit SpriteEditor(Rom* rom = nullptr) : rom_(rom) {
57 }
58
59 void Initialize() override;
60 absl::Status Load() override;
61 absl::Status Update() override;
62 absl::Status Undo() override { return undo_manager_.Undo(); }
63 absl::Status Redo() override { return undo_manager_.Redo(); }
64 absl::Status Cut() override;
65 absl::Status Copy() override;
66 absl::Status Paste() override;
67 absl::Status Find() override { return absl::UnimplementedError("Find"); }
68 absl::Status Save() override;
69 // Background saves retain untitled documents instead of opening Save As.
70 absl::Status SaveForAutosave();
74 absl::Status PrepareProjectSave() { return Save(); }
76
77 void SetDependencies(const EditorDependencies& deps) override;
85 // Catalog failures are panel-local and never block unrelated editor loading.
86 absl::Status ReloadSpriteCatalog();
87 absl::Status OpenCatalogSource(const zelda3::SpriteSourceBinding& binding);
88 const std::optional<zelda3::SpriteCatalog>& sprite_catalog() const {
89 return sprite_catalog_;
90 }
91 const std::optional<zelda3::SpriteSourceDocument>& catalog_source() const {
92 return catalog_source_;
93 }
94
95 absl::Status ImportCatalogDraw(const zelda3::SpriteSourceBinding& binding,
96 const std::string& catalog_key = "");
97 absl::Status OpenSpriteAsset(const std::string& path);
98 absl::Status SaveSpriteAsset(const std::string& path);
99 absl::Status ReloadProjectSpriteAssets();
100 absl::Status CheckCurrentSpriteSource();
101 absl::StatusOr<std::string> ExportCurrentSpriteDraw();
102 absl::Status SetSpriteBehavior(const project::SpriteBehavior& behavior);
103 absl::Status BindOracleBehaviorProfile();
104 absl::StatusOr<std::string> ExportCurrentSpriteBehavior(
105 const std::string& prefix);
106 absl::Status SetSpriteGraphics(
107 const std::array<uint8_t, 8>& sheets,
108 const std::array<project::SpritePaletteBinding, 8>& rows);
109 absl::Status SetSpriteGraphicsSource(
110 int slot, const project::SpriteGraphicsSource& source);
111 // Known static poses become detached copies. IDs without a static layout
112 // become explicitly empty templates; this never patches vanilla draw code.
113 absl::Status CreateSpriteAssetFromVanilla(int sprite_id);
115
117 return current_custom_sprite_index_ >= 0 &&
119 static_cast<int>(custom_sprites_.size())
121 : nullptr;
122 }
123
124 void set_rom(Rom* rom) { rom_ = rom; }
125 Rom* rom() const { return rom_; }
126
127 private:
128 std::optional<zsprite::Frame> frame_clipboard_;
133 char behavior_prefix_[65] = "Sprite_CustomBehavior";
135 absl::Status behavior_status_;
137 std::vector<project::SpriteAssetBinding> custom_sprite_bindings_;
138 absl::Status asset_load_status_;
143 bool source_checked_ = false;
148 char graphics_source_path_[4097] = {};
152 absl::Status OpenBoundBinInScratch(int slot);
153 void DrawSpriteCatalog();
155 std::optional<zelda3::SpriteCatalog> sprite_catalog_;
156 std::optional<zelda3::SpriteSourceDocument> catalog_source_;
157 absl::Status catalog_status_;
161 std::string catalog_path_;
165 ImGuiTextFilter catalog_filter_;
167
168 // ============================================================
169 // Editor-Level Methods
170 // ============================================================
172
173 // ============================================================
174 // Vanilla Sprite Editor Methods
175 // ============================================================
176 void SelectVanillaSprite(int sprite_id);
179 void DrawSpritesList();
180 void DrawSpriteCanvas();
181 void DrawCurrentSheets(bool use_asset_binding);
182 void DrawToolset();
183
184 // ============================================================
185 // Custom ZSM Sprite Editor Methods
186 // ============================================================
187 void DrawCustomSprites();
189
190 // File operations
191 void CreateNewZSprite();
192 void LoadZsmFile(const std::string& path);
193 void SaveZsmFile(const std::string& path);
194 void SaveZsmFileAs();
196 const std::string& GetCurrentZsmPath() const;
197 void SetCurrentZsmPath(const std::string& path);
198
199 // Properties panel
202 void DrawStatProperties();
203
204 // Animation panel
205 void DrawAnimationPanel();
207 void DrawFrameEditor();
208 void UpdateAnimationPlayback(float delta_time);
209
210 // User routines panel
212
213 // Canvas rendering
214 void RenderZSpriteFrame(int frame_index);
215 void DrawZSpriteOnCanvas();
216
217 // Graphics pipeline
218 void RefreshSpritePreviewGraphics(bool use_asset_binding);
219 void LoadSpriteGraphicsBuffer(bool use_asset_binding = true);
220 void LoadSpritePalettes(bool use_asset_binding = true);
222
223 // ============================================================
224 // Undo/Redo Helpers
225 // ============================================================
227 void RestoreFromSnapshot(const SpriteSnapshot& snapshot);
230 void MarkSpriteMutated();
231
232 // ============================================================
233 // Vanilla Sprite State
234 // ============================================================
235 ImVector<int> active_sprites_;
238 uint8_t current_sheets_[8] = {0x73, 0x74, 0x79, 0x7A, 0x73, 0x73, 0x73, 0x73};
239 uint8_t vanilla_sheets_[8] = {0x73, 0x74, 0x79, 0x7A, 0x73, 0x73, 0x73, 0x73};
240 bool sheets_loaded_ = false;
241
242 // OAM Configuration for vanilla sprites
243 struct OAMConfig {
244 uint16_t x = 0;
245 uint16_t y = 0;
246 uint8_t tile = 0;
247 uint8_t palette = 0;
248 uint8_t priority = 0;
249 bool flip_x = false;
250 bool flip_y = false;
251 };
256
257 // ============================================================
258 // Custom ZSM Sprite State
259 // ============================================================
260 std::vector<zsprite::ZSprite> custom_sprites_;
261 std::vector<std::string> custom_sprite_paths_;
263 bool zsm_dirty_ = false;
266
267 // Animation playback state
268 bool animation_playing_ = false;
271 float frame_timer_ = 0.0f;
272 float last_frame_time_ = 0.0f;
273
274 // UI state
277 bool show_tile_grid_ = true;
278
279 // Sprite preview bitmap (rendered from OAM tiles)
282
283 // ============================================================
284 // Graphics Pipeline State
285 // ============================================================
287 std::vector<uint8_t> sprite_gfx_buffer_; // 8BPP combined sheets buffer
288 gfx::PaletteGroup sprite_palettes_; // Loaded sprite palettes
289 bool gfx_buffer_loaded_ = false;
291 std::array<gfx::Bitmap, 8> external_sheet_previews_;
293 std::array<uint8_t, 8> loaded_preview_sheets_{};
294 std::array<uint64_t, 8> loaded_preview_revisions_{};
296
297 // ============================================================
298 // Spriteset-aware preview
299 // ============================================================
300 // Slots 0-3 take the static sprite sheets and slots 4-7 a spriteset's
301 // values + 0x73, as the game loads them (zelda3/sprite/sprite_sheet_slots).
302 void DrawSpritesetPicker(bool use_asset_binding);
303 void ApplySpritesetToSheets(int spriteset, bool use_asset_binding);
305 absl::Status OpenSelectedOamGraphics();
308 uint16_t preview_room_ = 0;
310 std::optional<gfx::PaletteGroup> room_palette_cache_;
312 std::optional<std::map<int, zelda3::OverworldAreaGfxInfo>> usage_areas_;
313 std::optional<std::map<int, zelda3::RoomGfxInfo>> usage_rooms_;
314 const Rom* usage_rom_ = nullptr;
315 std::string tile_check_key_;
316 std::vector<zelda3::SpriteTileIssue> tile_issues_;
318
319 // ============================================================
320 // Canvas
321 // ============================================================
322 gui::Canvas sprite_canvas_{"SpriteCanvas", ImVec2(0x200, 0x200),
324
325 gui::Canvas graphics_sheet_canvas_{"GraphicsSheetCanvas",
326 ImVec2(0x80 * 2 + 2, 0x40 * 8 + 2),
328
329 // ============================================================
330 // Undo State
331 // ============================================================
335
336 // ============================================================
337 // Common State
338 // ============================================================
339 absl::Status status_;
341};
342
343} // namespace editor
344} // namespace yaze
345
346#endif // YAZE_APP_EDITOR_SPRITE_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:52
Interface for editor classes.
Definition editor.h:252
UndoManager undo_manager_
Definition editor.h:383
project::YazeProject * project() const
Definition editor.h:370
EditorDependencies dependencies_
Definition editor.h:382
EditorType type_
Definition editor.h:381
Draws sprite OAM tiles to bitmaps for preview rendering.
Allows the user to edit sprites.
absl::Status SetSpriteBehavior(const project::SpriteBehavior &behavior)
std::array< gfx::Bitmap, 8 > external_sheet_previews_
friend struct SpriteEditorPreviewTestPeer
ImVector< int > active_sprites_
absl::Status Find() override
absl::Status OpenSpriteAsset(const std::string &path)
void UpdateAnimationPlayback(float delta_time)
const std::optional< zelda3::SpriteCatalog > & sprite_catalog() const
std::vector< project::SpriteAssetBinding > custom_sprite_bindings_
std::vector< zelda3::SpriteTileIssue > tile_issues_
void LoadSpriteGraphicsBuffer(bool use_asset_binding=true)
absl::Status OpenSelectedOamGraphics()
std::optional< zelda3::SpriteSourceDocument > catalog_source_
std::optional< zelda3::SpriteCatalog > sprite_catalog_
const zsprite::ZSprite * current_custom_sprite() const
std::set< int > dirty_sprite_indices_
void RefreshSpritePreviewGraphics(bool use_asset_binding)
std::array< uint64_t, 8 > loaded_preview_revisions_
void RenderZSpriteFrame(int frame_index)
absl::Status Paste() override
std::array< uint8_t, 8 > loaded_preview_sheets_
absl::StatusOr< std::string > ExportCurrentSpriteDraw()
void LoadSpritePalettes(bool use_asset_binding=true)
std::optional< zsprite::Frame > frame_clipboard_
bool HasPendingSpriteChanges() const
absl::Status OpenBoundBinInScratch(int slot)
absl::Status Update() override
absl::Status graphics_source_edit_status_
gfx::PaletteGroup sprite_palettes_
void LoadZsmFile(const std::string &path)
absl::Status Redo() override
absl::Status Cut() override
absl::Status ImportCatalogDraw(const zelda3::SpriteSourceBinding &binding, const std::string &catalog_key="")
absl::StatusOr< std::string > ExportCurrentSpriteBehavior(const std::string &prefix)
absl::Status Undo() override
void RenderVanillaSprite(const zelda3::SpriteOamLayout &layout)
absl::Status CreateSpriteAssetFromVanilla(int sprite_id)
absl::Status palette_binding_status_
void DrawCurrentSheets(bool use_asset_binding)
std::optional< std::map< int, zelda3::RoomGfxInfo > > usage_rooms_
const std::string & GetCurrentZsmPath() const
absl::Status SaveSpriteAsset(const std::string &path)
void RestoreFromSnapshot(const SpriteSnapshot &snapshot)
std::vector< zsprite::ZSprite > custom_sprites_
std::vector< uint8_t > sprite_gfx_buffer_
project::YazeProject * project() const
const std::optional< zelda3::SpriteSourceDocument > & catalog_source() const
void DrawSpritesetPicker(bool use_asset_binding)
absl::Status SetSpriteGraphicsSource(int slot, const project::SpriteGraphicsSource &source)
const project::SpriteAssetBinding * current_sprite_binding() const
absl::Status PrepareProjectSave()
void SetCurrentZsmPath(const std::string &path)
absl::Status Copy() override
void SetDependencies(const EditorDependencies &deps) override
const zelda3::GameData * preview_graphics_owner_
absl::Status Save() override
std::optional< std::map< int, zelda3::OverworldAreaGfxInfo > > usage_areas_
friend class AuthoringSaveWorkflowTestPeer
SpriteSnapshot undo_before_snapshot_
void SaveZsmFile(const std::string &path)
absl::Status catalog_source_status_
void ApplySpritesetToSheets(int spriteset, bool use_asset_binding)
SpriteSnapshot CaptureCurrentSpriteSnapshot() const
absl::Status graphics_binding_status_
absl::Status graphics_context_status_
const project::YazeProject * catalog_project_
std::optional< gfx::PaletteGroup > room_palette_cache_
absl::Status OpenCatalogSource(const zelda3::SpriteSourceBinding &binding)
absl::Status Load() override
ImGuiTextFilter catalog_filter_
std::vector< std::string > custom_sprite_paths_
void SelectVanillaSprite(int sprite_id)
SpriteEditor(Rom *rom=nullptr)
const zelda3::SpriteOamLayout * CurrentPreviewLayout() const
absl::Status SetSpriteGraphics(const std::array< uint8_t, 8 > &sheets, const std::array< project::SpritePaletteBinding, 8 > &rows)
absl::Status Redo()
Redo the top action. Returns error if stack is empty.
absl::Status Undo()
Undo the top action. Returns error if stack is empty.
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:64
Which graphics sheets exist, which tables use them, and which 16x16 blocks are free.
constexpr ImGuiTableFlags kSpriteTableFlags
constexpr ImGuiTabItemFlags kSpriteTabFlags
constexpr ImGuiTabBarFlags kSpriteTabBarFlags
Which graphics sheets back sprite OAM tiles 0x000-0x1FF.
Unified dependency container for all editor types.
Definition editor.h:170
std::function< project::YazeProject *()> project_context_provider
Definition editor.h:197
Snapshot of a custom ZSprite's editable state for undo/redo.
Represents a group of palettes.
Modern project structure with comprehensive settings consolidation.
Definition project.h:290
Complete OAM layout for a vanilla sprite.