yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sprite_editor_catalog.cc
Go to the documentation of this file.
2
5#include "core/project.h"
7#include "util/file_util.h"
8#include "util/i18n/tr.h"
9
10namespace yaze::editor {
11
13 const zelda3::SpriteSourceBinding& binding,
14 const std::string& catalog_key) {
15 if (binding.role != "draw")
16 return absl::InvalidArgumentError("Only draw bindings can be imported");
19 catalog_source_->lines, catalog_source_->label_line, binding.adapter);
20 if (!frames.ok())
21 return frames.status();
23 auto& asset = custom_sprite_bindings_.back();
24 asset.catalog_key = catalog_key;
25 asset.draw_adapter = binding.adapter;
26 asset.source_path = binding.path;
27 asset.source_label = binding.label;
28 asset.source_sha256 =
30 source_check_status_ = absl::OkStatus();
31 source_checked_ = true;
32 auto& sprite = custom_sprites_.back();
33 sprite.sprName = binding.label + " (draw copy)";
34 sprite.userRoutines.emplace_back(
35 "Import provenance", "; Draw-data copy from " + binding.path + " : " +
36 binding.label +
37 "\n; Source ASM remains authoritative. Graphics "
38 "and timing require authoring.\n");
39 sprite.editor.Frames = std::move(*frames);
40 sprite.animations.clear();
41 sprite.animations.emplace_back(0, sprite.editor.Frames.size() - 1, 6,
42 "Preview (author timing)");
46 visible.push_back("sprite.custom_editor");
48 visible);
49 }
50 return absl::OkStatus();
51}
52
57
59 const auto* owner = project();
60 const std::string path =
61 owner && !owner->sprite_catalog_file.empty()
62 ? owner->GetAbsolutePath(owner->sprite_catalog_file)
63 : "";
64 const std::string root =
65 owner && !owner->sprite_source_root.empty()
66 ? owner->GetAbsolutePath(owner->sprite_source_root)
67 : "";
68 if (owner != catalog_project_ || path != catalog_path_ ||
69 root != catalog_source_root_ ||
71 (void)ReloadSpriteCatalog();
72 }
73}
74
76 // Clear first: a failed reload must never display a previous project's data.
77 sprite_catalog_.reset();
78 catalog_source_.reset();
79 catalog_source_status_ = absl::OkStatus();
80 catalog_filter_.Clear();
87 project() && !project()->sprite_catalog_file.empty()
88 ? project()->GetAbsolutePath(project()->sprite_catalog_file)
89 : "";
91 project() && !project()->sprite_source_root.empty()
92 ? project()->GetAbsolutePath(project()->sprite_source_root)
93 : "";
94 if (catalog_path_.empty()) {
95 catalog_status_ = absl::FailedPreconditionError(
96 "Choose a sprite catalog for this project.");
97 } else {
99 catalog_status_ = result.status();
100 if (result.ok())
101 sprite_catalog_ = std::move(*result);
102 }
103 return catalog_status_;
104}
105
107 const zelda3::SpriteSourceBinding& binding) {
108 catalog_source_.reset();
109 auto result = zelda3::ReadSpriteSource(catalog_source_root_, binding);
110 catalog_source_status_ = result.status();
111 if (result.ok()) {
112 catalog_source_ = std::move(*result);
114 }
116}
117
120 ImGui::TextUnformatted(tr("Sprite Catalog — read-only"));
121 if (!project()) {
122 ImGui::TextWrapped(
123 tr("Open a Yaze project to browse its custom sprite catalog."));
124 return;
125 }
126 if (ImGui::Button(tr("Choose catalog..."))) {
128 {{{"Sprite catalog", "json"}}});
129 if (!path.empty()) {
131 (void)ReloadSpriteCatalog();
132 }
133 }
134 ImGui::SameLine();
135 if (ImGui::Button(tr("Choose source root..."))) {
137 if (!path.empty()) {
138 project()->sprite_source_root = path;
139 (void)ReloadSpriteCatalog();
140 }
141 }
142 ImGui::SameLine();
143 if (ImGui::Button(tr("Reload catalog")))
144 (void)ReloadSpriteCatalog();
145 ImGui::TextWrapped(
146 tr("Save the project to retain these paths. Source files and ROM data "
147 "are not changed."));
148 ImGui::TextWrapped("%s: %s", tr("Catalog"), catalog_path_.c_str());
149 ImGui::TextWrapped("%s: %s", tr("Source root"), catalog_source_root_.c_str());
150 if (!catalog_status_.ok()) {
151 ImGui::TextWrapped("%s", catalog_status_.ToString().c_str());
152 return;
153 }
154 if (!sprite_catalog_)
155 return;
156 ImGui::Separator();
157 catalog_filter_.Draw(tr("Filter families / variants"));
158 const auto& families = sprite_catalog_->families();
159 for (size_t i = 0; i < families.size(); ++i) {
160 const auto& family = families[i];
161 bool visible = catalog_filter_.PassFilter(family.name.c_str()) ||
162 catalog_filter_.PassFilter(family.key.c_str());
163 for (const auto& variant : family.variants) {
164 visible |= catalog_filter_.PassFilter(variant.name.c_str()) ||
165 catalog_filter_.PassFilter(variant.key.c_str());
166 }
167 if (!visible)
168 continue;
169 ImGui::PushID(family.key.c_str());
170 if (ImGui::Selectable(family.name.c_str(),
171 catalog_family_index_ == static_cast<int>(i))) {
172 catalog_family_index_ = static_cast<int>(i);
173 catalog_raw_subtype_ = family.variants.front().authored_subtype;
174 catalog_source_.reset();
175 catalog_source_status_ = absl::OkStatus();
176 }
177 ImGui::SameLine();
178 ImGui::TextDisabled("$%02X", family.main_id);
179 ImGui::PopID();
180 }
181 const auto& family = families[catalog_family_index_];
182 ImGui::Separator();
183 ImGui::Text("%s ($%02X)", family.name.c_str(), family.main_id);
184 for (const auto& variant : family.variants) {
185 ImGui::PushID(variant.key.c_str());
186 if (ImGui::Selectable(variant.name.c_str(),
187 catalog_raw_subtype_ == variant.authored_subtype)) {
188 catalog_raw_subtype_ = variant.authored_subtype;
189 catalog_source_.reset();
190 catalog_source_status_ = absl::OkStatus();
191 }
192 ImGui::SameLine();
193 ImGui::TextDisabled("$%02X", variant.authored_subtype);
194 ImGui::PopID();
195 }
196 if (ImGui::InputInt(tr("Inspect raw subtype (decimal)"),
198 catalog_source_.reset();
199 catalog_source_status_ = absl::OkStatus();
200 }
201 const auto result =
202 sprite_catalog_->Resolve(family.main_id, catalog_raw_subtype_);
203 if (result.variant)
204 ImGui::Text("%s: %s", tr("Resolved variant"), result.variant->name.c_str());
205 ImGui::TextWrapped("%s", result.explanation.c_str());
206 ImGui::TextWrapped(
207 tr("Preview unavailable in catalog. Import literal draw tables to edit a "
208 "copy in Custom Sprites. Select "
209 "the correct graphics sheets there; catalog graphics are not bound."));
210 ImGui::TextWrapped(
211 tr("Source remains read-only. Placement and runtime generation are "
212 "unavailable."));
213
214 auto draw_bindings =
215 [this, &result](const std::vector<zelda3::SpriteSourceBinding>& sources) {
216 for (const auto& binding : sources) {
217 ImGui::PushID(binding.role.c_str());
218 if (ImGui::SmallButton(tr("View source")))
219 (void)OpenCatalogSource(binding);
220 if (binding.role == "draw") {
221 ImGui::SameLine();
222 if (ImGui::SmallButton(tr("Import draw copy"))) {
224 binding, result.variant ? result.variant->key : "");
225 }
226 }
227 ImGui::SameLine();
228 ImGui::TextWrapped("%s: %s — %s", binding.role.c_str(),
229 binding.label.c_str(), binding.path.c_str());
230 ImGui::PopID();
231 }
232 };
233 ImGui::PushID("family_sources");
234 draw_bindings(family.sources);
235 ImGui::PopID();
236 if (result.variant) {
237 ImGui::PushID("variant_sources");
238 draw_bindings(result.variant->sources);
239 ImGui::PopID();
240 }
241 if (!catalog_source_status_.ok())
242 ImGui::TextWrapped("%s", catalog_source_status_.ToString().c_str());
243 if (catalog_source_) {
244 ImGui::Separator();
245 ImGui::TextWrapped("%s:%d (%s)", catalog_source_->path.c_str(),
246 catalog_source_->label_line, tr("read-only"));
247 if (ImGui::BeginChild("CatalogSource", ImVec2(0, 0), true,
248 ImGuiWindowFlags_HorizontalScrollbar)) {
250 ImGui::SetScrollY((catalog_source_->label_line - 1) *
251 ImGui::GetTextLineHeightWithSpacing());
253 }
254 ImGuiListClipper clipper;
255 clipper.Begin(static_cast<int>(catalog_source_->lines.size()));
256 while (clipper.Step()) {
257 for (int line = clipper.DisplayStart; line < clipper.DisplayEnd;
258 ++line) {
259 ImGui::Text("%s %5d %s",
260 line + 1 == catalog_source_->label_line ? ">" : " ",
261 line + 1, catalog_source_->lines[line].c_str());
262 }
263 }
264 }
265 ImGui::EndChild();
266 }
267}
268} // namespace yaze::editor
project::YazeProject * project() const
Definition editor.h:358
virtual void SetDependencies(const EditorDependencies &deps)
Definition editor.h:254
EditorDependencies dependencies_
Definition editor.h:370
std::vector< project::SpriteAssetBinding > custom_sprite_bindings_
std::optional< zelda3::SpriteSourceDocument > catalog_source_
std::optional< zelda3::SpriteCatalog > sprite_catalog_
absl::Status ImportCatalogDraw(const zelda3::SpriteSourceBinding &binding, const std::string &catalog_key="")
std::vector< zsprite::ZSprite > custom_sprites_
void SetDependencies(const EditorDependencies &deps) override
absl::Status catalog_source_status_
const project::YazeProject * catalog_project_
absl::Status OpenCatalogSource(const zelda3::SpriteSourceBinding &binding)
ImGuiTextFilter catalog_filter_
void SetVisibleWindows(size_t session_id, const std::vector< std::string > &window_ids)
Set which panels should be visible for a session.
std::vector< std::string > GetVisibleWindowIds(size_t session_id) const
Get list of currently visible panel IDs for a session.
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
static std::string ShowOpenFolderDialog()
ShowOpenFolderDialog opens a file dialog and returns the selected folder path. Uses global feature fl...
static absl::StatusOr< SpriteCatalog > Load(const std::string &path)
std::string ComputeSourceArtifactSha256(std::string_view content)
absl::StatusOr< std::vector< zsprite::Frame > > ImportDrawAsset(const std::vector< std::string > &lines, size_t first_line, const std::string &adapter)
Editors are the view controllers for the application.
absl::StatusOr< SpriteSourceDocument > ReadSpriteSource(const std::string &source_root, const SpriteSourceBinding &binding)
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
Unified dependency container for all editor types.
Definition editor.h:170
WorkspaceWindowManager * window_manager
Definition editor.h:182
std::string sprite_catalog_file
Definition project.h:331
std::string GetAbsolutePath(const std::string &relative_path) const
Definition project.cc:2028
std::string sprite_source_root
Definition project.h:332