yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sprite_editor.cc
Go to the documentation of this file.
1#include "sprite_editor.h"
3
6#include "util/file_util.h"
10#include "app/gui/core/input.h"
12#include "util/hex.h"
13
14namespace yaze {
15namespace editor {
16
17using ImGui::BeginTable;
18using ImGui::Button;
19using ImGui::EndTable;
20using ImGui::Selectable;
21using ImGui::Separator;
22using ImGui::TableHeadersRow;
23using ImGui::TableNextColumn;
24using ImGui::TableNextRow;
25using ImGui::TableSetupColumn;
26using ImGui::Text;
27
29 if (!dependencies_.card_registry) return;
30 auto* card_registry = dependencies_.card_registry;
31
32 card_registry->RegisterCard({.card_id = "sprite.vanilla_editor", .display_name = "Vanilla Sprites",
33 .icon = ICON_MD_SMART_TOY, .category = "Sprite",
34 .shortcut_hint = "Alt+Shift+1", .priority = 10});
35 card_registry->RegisterCard({.card_id = "sprite.custom_editor", .display_name = "Custom Sprites",
36 .icon = ICON_MD_ADD_CIRCLE, .category = "Sprite",
37 .shortcut_hint = "Alt+Shift+2", .priority = 20});
38
39 // Show vanilla editor by default
40 card_registry->ShowCard("sprite.vanilla_editor");
41}
42
43absl::Status SpriteEditor::Load() {
44 gfx::ScopedTimer timer("SpriteEditor::Load");
45 return absl::OkStatus();
46}
47
48absl::Status SpriteEditor::Update() {
49 if (rom()->is_loaded() && !sheets_loaded_) {
50 sheets_loaded_ = true;
51 }
52
53 if (!dependencies_.card_registry) return absl::OkStatus();
54 auto* card_registry = dependencies_.card_registry;
55
56 static gui::EditorCard vanilla_card("Vanilla Sprites", ICON_MD_SMART_TOY);
57 static gui::EditorCard custom_card("Custom Sprites", ICON_MD_ADD_CIRCLE);
58
59 vanilla_card.SetDefaultSize(900, 700);
60 custom_card.SetDefaultSize(800, 600);
61
62 // Vanilla Sprites Card - Check visibility flag exists and is true before rendering
63 bool* vanilla_visible = card_registry->GetVisibilityFlag("sprite.vanilla_editor");
64 if (vanilla_visible && *vanilla_visible) {
65 if (vanilla_card.Begin(vanilla_visible)) {
67 }
68 vanilla_card.End();
69 }
70
71 // Custom Sprites Card - Check visibility flag exists and is true before rendering
72 bool* custom_visible = card_registry->GetVisibilityFlag("sprite.custom_editor");
73 if (custom_visible && *custom_visible) {
74 if (custom_card.Begin(custom_visible)) {
76 }
77 custom_card.End();
78 }
79
80 return status_.ok() ? absl::OkStatus() : status_;
81}
82
84 // Sidebar is now drawn by EditorManager for card-based editors
85 // This method kept for compatibility but sidebar handles card toggles
86}
87
88
90 if (ImGui::BeginTable("##SpriteCanvasTable", 3, ImGuiTableFlags_Resizable,
91 ImVec2(0, 0))) {
92 TableSetupColumn("Sprites List", ImGuiTableColumnFlags_WidthFixed, 256);
93 TableSetupColumn("Canvas", ImGuiTableColumnFlags_WidthStretch,
94 ImGui::GetContentRegionAvail().x);
95 TableSetupColumn("Tile Selector", ImGuiTableColumnFlags_WidthFixed, 256);
96 TableHeadersRow();
97 TableNextRow();
98
99 TableNextColumn();
101
102 TableNextColumn();
103 static int next_tab_id = 0;
104
105 if (ImGui::BeginTabBar("SpriteTabBar", kSpriteTabBarFlags)) {
106 if (ImGui::TabItemButton(ICON_MD_ADD, kSpriteTabBarFlags)) {
107 if (std::find(active_sprites_.begin(), active_sprites_.end(),
109 // Room is already open
110 next_tab_id++;
111 }
112 active_sprites_.push_back(next_tab_id++); // Add new tab
113 }
114
115 // Submit our regular tabs
116 for (int n = 0; n < active_sprites_.Size;) {
117 bool open = true;
118
119 if (active_sprites_[n] > sizeof(zelda3::kSpriteDefaultNames) / 4) {
120 active_sprites_.erase(active_sprites_.Data + n);
121 continue;
122 }
123
124 if (ImGui::BeginTabItem(
125 zelda3::kSpriteDefaultNames[active_sprites_[n]].data(), &open,
126 ImGuiTabItemFlags_None)) {
128 ImGui::EndTabItem();
129 }
130
131 if (!open)
132 active_sprites_.erase(active_sprites_.Data + n);
133 else
134 n++;
135 }
136
137 ImGui::EndTabBar();
138 }
139
140 TableNextColumn();
141 if (sheets_loaded_) {
143 }
144 ImGui::EndTable();
145 }
146}
147
149 static bool flip_x = false;
150 static bool flip_y = false;
151 if (ImGui::BeginChild(gui::GetID("##SpriteCanvas"),
152 ImGui::GetContentRegionAvail(), true)) {
157
158 // Draw a table with OAM configuration
159 // X, Y, Tile, Palette, Priority, Flip X, Flip Y
160 if (ImGui::BeginTable("##OAMTable", 7, ImGuiTableFlags_Resizable,
161 ImVec2(0, 0))) {
162 TableSetupColumn("X", ImGuiTableColumnFlags_WidthStretch);
163 TableSetupColumn("Y", ImGuiTableColumnFlags_WidthStretch);
164 TableSetupColumn("Tile", ImGuiTableColumnFlags_WidthStretch);
165 TableSetupColumn("Palette", ImGuiTableColumnFlags_WidthStretch);
166 TableSetupColumn("Priority", ImGuiTableColumnFlags_WidthStretch);
167 TableSetupColumn("Flip X", ImGuiTableColumnFlags_WidthStretch);
168 TableSetupColumn("Flip Y", ImGuiTableColumnFlags_WidthStretch);
169 TableHeadersRow();
170 TableNextRow();
171
172 TableNextColumn();
174
175 TableNextColumn();
177
178 TableNextColumn();
180
181 TableNextColumn();
183
184 TableNextColumn();
186
187 TableNextColumn();
188 if (ImGui::Checkbox("##XFlip", &flip_x)) {
189 oam_config_.flip_x = flip_x;
190 }
191
192 TableNextColumn();
193 if (ImGui::Checkbox("##YFlip", &flip_y)) {
194 oam_config_.flip_y = flip_y;
195 }
196
197 ImGui::EndTable();
198 }
199
201
203
204 ImGui::EndChild();
205 }
206}
207
209 if (ImGui::BeginChild(gui::GetID("sheet_label"),
210 ImVec2(ImGui::GetContentRegionAvail().x, 0), true,
211 ImGuiWindowFlags_NoDecoration)) {
212 for (int i = 0; i < 8; i++) {
213 std::string sheet_label = absl::StrFormat("Sheet %d", i);
214 gui::InputHexByte(sheet_label.c_str(), &current_sheets_[i]);
215 if (i % 2 == 0) ImGui::SameLine();
216 }
217
221 for (int i = 0; i < 8; i++) {
223 gfx::Arena::Get().gfx_sheets().at(current_sheets_[i]), 1,
224 (i * 0x40) + 1, 2);
225 }
228 }
229 ImGui::EndChild();
230}
231
233 if (ImGui::BeginChild(gui::GetID("##SpritesList"),
234 ImVec2(ImGui::GetContentRegionAvail().x, 0), true,
235 ImGuiWindowFlags_NoDecoration)) {
236 int i = 0;
237 for (const auto each_sprite_name : zelda3::kSpriteDefaultNames) {
239 current_sprite_id_ == i, "Sprite Names", util::HexByte(i),
240 zelda3::kSpriteDefaultNames[i].data());
241 if (ImGui::IsItemClicked()) {
243 if (!active_sprites_.contains(i)) {
244 active_sprites_.push_back(i);
245 }
246 }
247 i++;
248 }
249 ImGui::EndChild();
250 }
251}
252
254 if (ImGui::Button("Add Frame")) {
255 // Add a new frame
256 }
257 if (ImGui::Button("Remove Frame")) {
258 // Remove the current frame
259 }
260}
261
263 if (BeginTable("##CustomSpritesTable", 3,
264 ImGuiTableFlags_Resizable | ImGuiTableFlags_Borders |
265 ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable,
266 ImVec2(0, 0))) {
267 TableSetupColumn("Metadata", ImGuiTableColumnFlags_WidthFixed, 256);
268 TableSetupColumn("Canvas", ImGuiTableColumnFlags_WidthFixed, 256);
269 TableSetupColumn("TIlesheets", ImGuiTableColumnFlags_WidthFixed, 256);
270
271 TableHeadersRow();
272 TableNextRow();
273 TableNextColumn();
274
275 Separator();
277
278 TableNextColumn();
280
281 TableNextColumn();
283
284 EndTable();
285 }
286}
287
289 // ZSprite Maker format open file dialog
290 if (ImGui::Button("Open ZSprite")) {
291 // Open ZSprite file
292 std::string file_path = util::FileDialogWrapper::ShowOpenFileDialog();
293 if (!file_path.empty()) {
294 zsprite::ZSprite zsprite;
295 status_ = zsprite.Load(file_path);
296 if (status_.ok()) {
297 custom_sprites_.push_back(zsprite);
298 }
299 }
300 }
301
302 for (const auto custom_sprite : custom_sprites_) {
303 Selectable("%s", custom_sprite.sprName.c_str());
304 if (ImGui::IsItemClicked()) {
305 current_sprite_id_ = 256 + stoi(custom_sprite.property_sprid.Text);
306 if (!active_sprites_.contains(current_sprite_id_)) {
308 }
309 }
310 Separator();
311 }
312
313 for (const auto custom_sprite : custom_sprites_) {
314 // Draw the custom sprite metadata
315 Text("Sprite ID: %s", custom_sprite.property_sprid.Text.c_str());
316 Text("Sprite Name: %s", custom_sprite.property_sprname.Text.c_str());
317 Text("Sprite Palette: %s", custom_sprite.property_palette.Text.c_str());
318 Separator();
319 }
320}
321
322} // namespace editor
323} // namespace yaze
project::ResourceLabelManager * resource_label()
Definition rom.h:223
void RegisterCard(size_t session_id, const CardInfo &base_info)
Register a card for a specific session.
EditorDependencies dependencies_
Definition editor.h:165
ImVector< int > active_sprites_
void DrawAnimationFrames()
Draws the animation frames manager.
void DrawCurrentSheets()
Draws the current sheets.
void DrawSpriteCanvas()
Draws the sprite canvas.
absl::Status Update() override
void DrawSpritesList()
Draws the sprites list.
std::vector< zsprite::ZSprite > custom_sprites_
absl::Status Load() override
static Arena & Get()
Definition arena.cc:15
RAII timer for automatic timing management.
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale)
Definition canvas.cc:1004
void DrawContextMenu()
Definition canvas.cc:428
bool DrawTileSelector(int size, int size_y=0)
Definition canvas.cc:862
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0))
Definition canvas.cc:372
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
Definition canvas.cc:1304
Draggable, dockable card for editor sub-windows.
bool Begin(bool *p_open=nullptr)
void SetDefaultSize(float width, float height)
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
#define ICON_MD_ADD
Definition icons.h:84
#define ICON_MD_ADD_CIRCLE
Definition icons.h:93
#define ICON_MD_SMART_TOY
Definition icons.h:1779
constexpr ImGuiTabBarFlags kSpriteTabBarFlags
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
Definition input.cc:175
ImGuiID GetID(const std::string &id)
Definition input.cc:339
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
Definition input.cc:189
std::string HexByte(uint8_t byte, HexStringParams params)
Definition hex.cc:30
Main namespace for the application.
Definition controller.cc:20
EditorCardRegistry * card_registry
Definition editor.h:80
absl::Status Load(const std::string &filename)
Definition zsprite.h:74
void SelectableLabelWithNameEdit(bool selected, const std::string &type, const std::string &key, const std::string &defaultValue)
Definition project.cc:855