11#include "imgui/imgui.h"
23 const bool has_source =
24 std::any_of(tags.begin(), tags.end(), [](
const auto& tag) {
25 return tag.enabled && tag.address == 0x01CC08 &&
26 std::string_view(tag.source)
27 .starts_with(
"Dungeons/crumblefloor_tag.asm:");
34 for (
const auto tag : {room.
tag1(), room.
tag2()}) {
35 const int id =
static_cast<int>(tag);
36 if (id < 0 || id > 0x3F) {
39 const auto vector = rom.
ReadWord(0xC27D +
id * 2);
40 if (vector.ok() && *vector == 0xCC08) {
51 const auto& coverage = objects.coverage_data();
52 for (
int y = 0; y < 32; ++y) {
53 for (
int x = 0; x < 32; ++x) {
54 const size_t pixel = y * 16 * 512 + x * 16;
55 const bool object_written =
56 pixel < coverage.size() && coverage[pixel] != 0;
58 (object_written ? objects : layout).GetTileAt(x * 2, y * 2);
73 message_ = had_route ?
"Preview reset: room or floor data changed." :
"";
87 "Crumble preview needs an active Oracle crumble tag and its source "
91 const bool has_floor =
92 std::any_of(
words_.begin(),
words_.end(), [](
auto word) {
93 const auto cell = ClassifyCrumbleFloorWord(word);
94 return cell == CrumbleFloorCell::kIntact ||
95 cell == CrumbleFloorCell::kCracked;
100 "Crumble tag is active, but BG1 has no matching floor cells. "
101 "Inspect or place a floor pattern before rehearsing.");
104 ImGui::BeginDisabled(!interactive);
105 ImGui::Checkbox(
"Rehearse floor##crumble", &
rehearsing_);
107 "Read-only floor rehearsal");
109 if (ImGui::SmallButton(
"Back##crumble")) {
115 if (ImGui::SmallButton(
"Reset##crumble")) {
120 ImGui::EndDisabled();
122 "Green: intact. Amber: cracked. Red: pit. Leaving a cell wears it; "
123 "standing still does not.");
126 "Click a highlighted cell, then adjacent cells. Escape exits. "
127 "Floor-only model: collision, enemies, jumps, Minish and room entry "
128 "are excluded. No ROM edits.");
131 ImGui::TextWrapped(
"%s",
message_.c_str());
136 bool interactive,
bool shortcut_focus) {
140 const bool owns_input =
rehearsing_ && interactive;
141 if (owns_input && shortcut_focus && !ImGui::GetIO().WantTextInput &&
142 ImGui::IsKeyPressed(ImGuiKey_Escape)) {
148 ImGui::IsMouseClicked(ImGuiMouseButton_Left) &&
149 !ImGui::IsMouseDown(ImGuiMouseButton_Middle) &&
150 !ImGui::IsMouseDown(ImGuiMouseButton_Right)) {
152 message_ = status.ok() ?
"" : std::string(status.message());
165 const auto color = ImGui::GetColorU32(
168 : theme.status_error);
172 ImVec2((i % 32 + 1) * 16, (i / 32 + 1) * 16));
173 rt.
draw_list->AddRectFilled(p, q, (color & 0x00FFFFFF) | 0x33000000);
176 const auto center = [&](
int cell) {
178 ImVec2((cell % 32) * 16 + 8, (cell / 32) * 16 + 8));
180 for (
size_t i = 1; i <
model_.
route().size(); ++i) {
183 ImGui::GetColorU32(ImGuiCol_Text), 2.0f);
187 4.0f * transform.
scale(),
188 ImGui::GetColorU32(ImGuiCol_Text));
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::StatusOr< uint16_t > ReadWord(int offset) const
const std::vector< RoomTagEntry > & room_tags() const
Get all room tags.
bool loaded() const
Check if the manifest has been loaded.
void Reset(const Words &words)
CrumbleFloorCell cell(int index) const
absl::Status Step(int x, int y)
std::optional< int > current() const
std::array< uint16_t, kCellCount > Words
const std::vector< int > & route() const
static constexpr int kCellCount
void Sync(const Rom *rom, const project::YazeProject *project, const zelda3::Room &room)
const project::YazeProject * project_
CrumbleFloorModel::Words words_
bool DrawCanvas(const gui::CanvasRuntime &rt, bool interactive, bool shortcut_focus)
void DrawControls(bool interactive)
auto & object_bg1_buffer()
const AgentUITheme & GetTheme()
Editors are the view controllers for the application.
CrumbleFloorModel::Words ReadCrumbleFloorWords(const zelda3::Room &room)
bool HasOracleCrumbleTag(const Rom &rom, const project::YazeProject *project, const zelda3::Room &room)
void AutoRegisterLastItem(const std::string &widget_type, const std::string &explicit_label, const std::string &description)
Automatically register the last ImGui item.
Modern project structure with comprehensive settings consolidation.
core::HackManifest hack_manifest