5#include "absl/status/status.h"
8#include "imgui/imgui.h"
25 constexpr float kWorldSize = 512.0f * 8.0f;
26 return ImVec2(kWorldSize * scale, kWorldSize * scale);
31 ImVec2 visible_size) {
32 float max_scroll_x = std::max(0.0f, content_size.x - visible_size.x);
33 float max_scroll_y = std::max(0.0f, content_size.y - visible_size.y);
35 float clamped_x = std::clamp(scroll.x, -max_scroll_x, 0.0f);
36 float clamped_y = std::clamp(scroll.y, -max_scroll_y, 0.0f);
38 return ImVec2(clamped_x, clamped_y);
66 const int large_map_size = 1024;
74 if (map_x < 0 || map_x >= 8 || map_y < 0 || map_y >= 8) {
75 return absl::OkStatus();
78 const bool allow_special_tail =
82 return absl::OkStatus();
86 int hovered_map = map_x + map_y * 8;
101 bool should_build =
false;
113 ImGui::IsMouseClicked(ImGuiMouseButton_Left) ||
114 ImGui::IsMouseClicked(ImGuiMouseButton_Right);
135 bool use_v3_area_sizes =
139 if (use_v3_area_sizes) {
143 const int highlight_parent =
150 parent_map_x = highlight_parent % 8;
151 parent_map_y = highlight_parent / 8;
153 parent_map_x = (highlight_parent - 0x40) % 8;
154 parent_map_y = (highlight_parent - 0x40) / 8;
156 parent_map_x = (highlight_parent - 0x80) % 8;
157 parent_map_y = (highlight_parent - 0x80) / 8;
162 case AreaSizeEnum::LargeArea:
165 large_map_size, large_map_size);
167 case AreaSizeEnum::WideArea:
172 case AreaSizeEnum::TallArea:
177 case AreaSizeEnum::SmallArea:
189 const int highlight_parent =
195 parent_map_x = highlight_parent % 8;
196 parent_map_y = highlight_parent / 8;
198 parent_map_x = (highlight_parent - 0x40) % 8;
199 parent_map_y = (highlight_parent - 0x40) / 8;
201 parent_map_x = (highlight_parent - 0x80) % 8;
202 parent_map_y = (highlight_parent - 0x80) / 8;
207 large_map_size, large_map_size);
212 current_map_x = current_highlighted_map % 8;
213 current_map_y = current_highlighted_map / 8;
215 current_map_x = (current_highlighted_map - 0x40) % 8;
216 current_map_y = (current_highlighted_map - 0x40) / 8;
218 current_map_x = (current_highlighted_map - 0x80) % 8;
219 current_map_y = (current_highlighted_map - 0x80) / 8;
249 ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
255 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right)) {
259 return absl::OkStatus();
270 ImGui::IsMouseClicked(ImGuiMouseButton_Right) &&
271 ImGui::IsItemHovered()) {
277 if (ImGui::IsMouseClicked(ImGuiMouseButton_Middle) &&
278 ImGui::IsItemHovered()) {
286 int hovered_map = map_x + map_y * 8;
294 if (hovered_map >= 0 && hovered_map < 0xA0) {
307 if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) &&
308 ImGui::IsItemHovered()) {
321 bool should_pan =
false;
323 if (ImGui::IsMouseDragging(ImGuiMouseButton_Middle)) {
325 }
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left) &&
341 ImVec2 delta = ImGui::GetIO().MouseDelta;
342 float new_scroll_x = ImGui::GetScrollX() - delta.x;
343 float new_scroll_y = ImGui::GetScrollY() - delta.y;
346 float max_scroll_x = ImGui::GetScrollMaxX();
347 float max_scroll_y = ImGui::GetScrollMaxY();
350 new_scroll_x = std::clamp(new_scroll_x, 0.0f, max_scroll_x);
351 new_scroll_y = std::clamp(new_scroll_y, 0.0f, max_scroll_y);
353 ImGui::SetScrollX(new_scroll_x);
354 ImGui::SetScrollY(new_scroll_y);
385 ImGui::SetScrollX(0);
386 ImGui::SetScrollY(0);
393 if (scale <= 0.0f) scale = 1.0f;
401 ImVec2 viewport_px = ImGui::GetContentRegionAvail();
408 float scroll_x = center_x - viewport_px.x / 2.0f;
409 float scroll_y = center_y - viewport_px.y / 2.0f;
412 scroll_x = std::clamp(scroll_x, 0.0f, ImGui::GetScrollMaxX());
413 scroll_y = std::clamp(scroll_y, 0.0f, ImGui::GetScrollMaxY());
415 ImGui::SetScrollX(scroll_x);
416 ImGui::SetScrollY(scroll_y);
472 int world_offset = (center_map / 64) * 64;
473 int local_index = center_map % 64;
474 int map_x = local_index % 8;
475 int map_y = local_index / 8;
479 static const int dx[] = {-1, 1, 0, 0};
480 static const int dy[] = {0, 0, -1, 1};
482 for (
int i = 0; i < 4; ++i) {
483 int nx = map_x + dx[i];
484 int ny = map_y + dy[i];
487 if (nx >= 0 && nx < 8 && ny >= 0 && ny < max_rows) {
488 int neighbor_index = world_offset + ny * 8 + nx;
519 "Background preload of map %d failed: %s", map_to_preload,
520 status.message().data());
void ScrollBlocksetCanvasToCurrentTile()
Scroll the blockset (tile16 selector) to show the currently selected tile16.
static constexpr float kHoverBuildDelay
absl::Status CheckForCurrentMap()
Detect which map the mouse is over, trigger lazy loading, draw the selection outline,...
void UpdateBlocksetSelectorState()
Push current tile count and selection into the blockset widget.
void ProcessPreloadQueue()
Process one map from the preload queue (call once per frame).
CanvasNavigationCallbacks callbacks_
CanvasNavigationContext ctx_
void HandleOverworldPan()
Pan the overworld canvas via middle-click or left-click drag (in MOUSE mode when not hovering an enti...
void QueueAdjacentMapsForPreload(int center_map)
Queue the 4-connected neighbors of center_map for lazy build.
static constexpr float kPreloadStartDelay
std::vector< int > preload_queue_
void Initialize(const CanvasNavigationContext &context, const CanvasNavigationCallbacks &callbacks)
Initialize with shared state and callbacks.
void HandleMapInteraction()
Handle tile-mode right-click (eyedropper) and middle-click (lock/properties toggle),...
void ZoomOut()
Decrease canvas zoom by one step.
void CenterOverworldView()
Center the viewport on the current map.
void CheckForMousePan()
Legacy wrapper – delegates to HandleOverworldPan().
void ZoomIn()
Increase canvas zoom by one step.
void ResetOverworldView()
Reset scroll to top-left and scale to 1.0.
void HandleOverworldZoom()
No-op stub preserved for API compatibility.
void ClampOverworldScroll()
No-op stub – ImGui handles scroll clamping automatically.
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
auto global_scale() const
auto hover_mouse_pos() const
auto drawn_tile_position() const
void set_global_scale(float scale)
void DrawOutline(int x, int y, int w, int h)
static OverworldVersion GetVersion(const Rom &rom)
Detect ROM version from ASM marker byte.
static bool SupportsAreaEnum(OverworldVersion version)
Check if ROM supports area enum system (v3+ only)
auto overworld_map(int i) const
absl::Status EnsureMapBuilt(int map_index)
Build a map on-demand if it hasn't been built yet.
#define LOG_DEBUG(category, format,...)
ImVec2 CalculateOverworldContentSize(float scale)
ImVec2 ClampScrollPosition(ImVec2 scroll, ImVec2 content_size, ImVec2 visible_size)
Editors are the view controllers for the application.
constexpr unsigned int kOverworldMapSize
constexpr float kOverworldMaxZoom
constexpr float kOverworldMinZoom
constexpr float kOverworldZoomStep
constexpr int kNumTile16Individual
constexpr int kSpecialWorldMapIdStart
constexpr int kNumOverworldMaps
AreaSizeEnum
Area size enumeration for v3+ ROMs.
#define RETURN_IF_ERROR(expr)
bool kEnableSpecialWorldExpansion
struct yaze::core::FeatureFlags::Flags::Overworld overworld
Callbacks for operations that remain in the OverworldEditor.
std::function< void()> refresh_overworld_map
std::function< absl::Status()> refresh_tile16_blockset
std::function< bool()> is_entity_hovered
Returns true if an entity is currently hovered (for pan suppression).
std::function< bool()> pick_tile16_from_hovered_canvas
std::function< void(int)> ensure_map_texture
Shared state pointers that the navigation manager reads/writes.
bool * show_map_properties_panel
std::unique_ptr< gui::TileSelectorWidget > * blockset_selector
std::array< gfx::Bitmap, zelda3::kNumOverworldMaps > * maps_bmp
gui::Canvas * ow_map_canvas
zelda3::Overworld * overworld
bool * is_dragging_entity
gfx::Tilemap * tile16_blockset
EditingMode * current_mode
Bitmap atlas
Master bitmap containing all tiles.