yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
map_texture_coordinator.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <new>
5
9#include "util/log.h"
11
12namespace yaze::editor {
13
14namespace {
15
17 return ctx.overworld && ctx.maps_bmp;
18}
19
20} // namespace
21
23 if (!ctx_.maps_bmp) {
24 return;
25 }
26 for (auto& bitmap : *ctx_.maps_bmp) {
27 bitmap = gfx::Bitmap();
28 }
29}
30
32 if (ctx_.renderer) {
34 }
35 if (!HasTextureContext(ctx_) || !ctx_.current_map || !ctx_.current_world ||
37 return;
38 }
39
40 int refresh_count = 0;
41 constexpr int kMaxRefreshesPerFrame = 2;
42
43 const auto try_refresh_map = [&](int map_index) {
44 if (map_index < 0 || map_index >= zelda3::kNumOverworldMaps ||
45 refresh_count >= kMaxRefreshesPerFrame) {
46 return;
47 }
48 auto& bitmap = (*ctx_.maps_bmp)[map_index];
49 if (bitmap.modified() && bitmap.is_active()) {
50 ctx_.refresh_map_on_demand(map_index);
51 ++refresh_count;
52 }
53 };
54
55 try_refresh_map(*ctx_.current_map);
56
57 const int current_world = std::clamp(*ctx_.current_world, 0, 2);
58 const int world_start = current_world * 0x40;
59 const int world_end = std::min(world_start + 0x40, zelda3::kNumOverworldMaps);
60 for (int map_index = world_start;
61 map_index < world_end && refresh_count < kMaxRefreshesPerFrame;
62 ++map_index) {
63 if (map_index == *ctx_.current_map) {
64 continue;
65 }
66 try_refresh_map(map_index);
67 }
68}
69
71 if (!HasTextureContext(ctx_) || map_index < 0 ||
72 map_index >= zelda3::kNumOverworldMaps) {
73 return;
74 }
75
76 const auto* existing_map = ctx_.overworld->overworld_map(map_index);
77 const bool was_built = existing_map && existing_map->is_built();
78
79 auto status = ctx_.overworld->EnsureMapBuilt(map_index);
80 if (!status.ok()) {
81 LOG_ERROR("OverworldMapTextureCoordinator", "Failed to build map %d: %s",
82 map_index, status.message());
83 return;
84 }
85
86 auto& bitmap = (*ctx_.maps_bmp)[map_index];
87 const auto* map = ctx_.overworld->overworld_map(map_index);
88 if (!map) {
89 return;
90 }
91 const bool needs_bitmap_sync = !was_built || bitmap.modified();
92
93 if (!bitmap.is_active()) {
94 const auto& palette = map->current_palette();
95 try {
96 bitmap.Create(kOverworldMapSize, kOverworldMapSize, 0x80,
97 map->bitmap_data());
98 bitmap.SetPalette(palette);
99 } catch (const std::bad_alloc& e) {
100 LOG_ERROR("OverworldMapTextureCoordinator",
101 "Error allocating bitmap for map %d: %s", map_index, e.what());
102 return;
103 }
104 } else if (needs_bitmap_sync) {
105 bitmap.set_data(map->bitmap_data());
106 bitmap.SetPalette(map->current_palette());
107 bitmap.set_modified(false);
108 }
109
110 if (!bitmap.texture() && bitmap.is_active()) {
113 } else if (needs_bitmap_sync && bitmap.texture() && bitmap.is_active()) {
116 }
117}
118
120 int world, bool process_texture_queue) {
121 if (!HasTextureContext(ctx_)) {
122 return;
123 }
124
125 const int clamped_world = std::clamp(world, 0, 2);
126 const int world_start = clamped_world * 0x40;
127 const int world_end = std::min(world_start + 0x40, zelda3::kNumOverworldMaps);
128 if (world_start >= zelda3::kNumOverworldMaps) {
129 return;
130 }
131
132 const int current_world = ctx_.current_world ? *ctx_.current_world : 0;
133 const int current_map = ctx_.current_map ? *ctx_.current_map : world_start;
134 const int current_local_map =
135 (current_world == clamped_world) ? (current_map & 0x3F) : 0;
136 const int first_map = world_start + std::clamp(current_local_map, 0,
137 world_end - world_start - 1);
138 constexpr int kMaxMapsToPrime = 8;
139 const int prime_end = std::min(first_map + kMaxMapsToPrime, world_end);
140 for (int map_index = first_map; map_index < prime_end; ++map_index) {
141 EnsureMapTexture(map_index);
142 }
143
144 if (process_texture_queue) {
146 }
147}
148
149} // namespace yaze::editor
void PrimeWorldMaps(int world, bool process_texture_queue=false)
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Definition arena.cc:36
void ProcessTextureQueue(IRenderer *renderer)
Definition arena.cc:116
static Arena & Get()
Definition arena.cc:21
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
auto overworld_map(int i) const
Definition overworld.h:662
absl::Status EnsureMapBuilt(int map_index)
Build a map on-demand if it hasn't been built yet.
#define LOG_ERROR(category, format,...)
Definition log.h:109
Editors are the view controllers for the application.
constexpr unsigned int kOverworldMapSize
constexpr int kNumOverworldMaps
Definition common.h:85
std::function< void(int map_index)> refresh_map_on_demand
std::array< gfx::Bitmap, zelda3::kNumOverworldMaps > * maps_bmp