6#include "absl/status/status.h"
7#include "absl/strings/str_format.h"
25 std::vector<gfx::TileInfo> tiles;
29 tiles.push_back(
gfx::TileInfo(
static_cast<uint16_t
>(i + 1), 0,
30 false,
false,
false));
42 const int size_nibble =
object.size_ & 0x0F;
46 (routine.
id == 5 || routine.
id == 17)) {
47 const int count = (routine.
id == 5) ? (size_nibble + 7) : (size_nibble + 6);
48 const int max_anchor =
50 anchor.
y = std::clamp(count - 1, 0, std::max(0, max_anchor));
59 routine.
id >= 75 && routine.
id <= 78) {
60 const int side = size_nibble + 4;
61 const bool mirror_x = (routine.
id == 77 || routine.
id == 78);
62 const bool mirror_y = (routine.
id == 76 || routine.
id == 78);
110 int routine_id,
const RoomObject&
object)
const {
112 if (info ==
nullptr) {
113 return absl::InvalidArgumentError(
114 absl::StrFormat(
"Unknown routine id %d", routine_id));
127 const AnchorPos anchor = ChooseAnchor(routine,
object);
128 adjusted.
x_ = anchor.x;
129 adjusted.
y_ = anchor.y;
132 static const std::vector<gfx::TileInfo> kTiles = MakeDummyTiles();
140 .
tiles = std::span<const gfx::TileInfo>(kTiles.data(), kTiles.size()),
144 .room_gfx_buffer =
nullptr,
145 .secondary_bg =
nullptr,
155 int min_x = std::numeric_limits<int>::max();
156 int min_y = std::numeric_limits<int>::max();
157 int max_x = std::numeric_limits<int>::min();
158 int max_y = std::numeric_limits<int>::min();
160 for (
int y = 0; y < tiles_h; ++y) {
161 for (
int x = 0; x < tiles_w; ++x) {
164 min_x = std::min(min_x, x);
165 min_y = std::min(min_y, y);
166 max_x = std::max(max_x, x);
167 max_y = std::max(max_y, y);
172 if (max_x == std::numeric_limits<int>::min()) {
188 if (routine_id < 0) {
189 return absl::NotFoundError(
190 absl::StrFormat(
"No routine mapping for object 0x%03X",
object.id_));
194 CacheKey key{routine_id,
object.id_,
object.size_};
195 auto cache_it =
cache_.find(key);
196 if (cache_it !=
cache_.end()) {
197 return cache_it->second;
213 int routine_id,
const RoomObject&
object)
const {
251 return routine_id >= 75 && routine_id <= 78;
258 return render_bounds;
266 int reduced_width = std::max(1, (render_bounds.
width_tiles * 7) / 10);
267 int reduced_height = std::max(1, (render_bounds.
height_tiles * 7) / 10);
270 int offset_x = (render_bounds.
width_tiles - reduced_width) / 2;
271 int offset_y = (render_bounds.
height_tiles - reduced_height) / 2;
280 return render_bounds;
uint16_t GetTileAt(int x, int y) const
SNES 16-bit tile metadata container.
int GetRoutineIdForObject(int16_t object_id) const
static DrawRoutineRegistry & Get()
Side-car geometry engine that replays draw routines against an off-screen buffer to calculate real ex...
static bool IsDiagonalCeilingRoutine(int routine_id)
Check if a routine ID corresponds to a diagonal ceiling.
std::vector< DrawRoutineInfo > routines_
absl::StatusOr< GeometryBounds > MeasureForLayerCompositing(int routine_id, const RoomObject &object) const
Measure bounds for a BG2 overlay object and mark it for masking.
absl::StatusOr< GeometryBounds > MeasureRoutine(const DrawRoutineInfo &routine, const RoomObject &object) const
std::unordered_map< int, DrawRoutineInfo > routine_map_
absl::StatusOr< GeometryBounds > MeasureByObjectId(const RoomObject &object) const
const DrawRoutineInfo * LookupRoutine(int routine_id) const
absl::StatusOr< GeometryBounds > MeasureByRoutineId(int routine_id, const RoomObject &object) const
static GeometryBounds ApplySelectionBounds(GeometryBounds render_bounds, int routine_id)
Compute tighter selection bounds for diagonal shapes.
static ObjectGeometry & Get()
std::unordered_map< CacheKey, GeometryBounds, CacheKeyHash > cache_
static bool IsLayerOneRoutine(int routine_id)
Get list of routine IDs that draw to BG2 layer.
const std::vector< gfx::TileInfo > & tiles() const
AnchorPos ChooseAnchor(const DrawRoutineInfo &routine, const RoomObject &object)
std::vector< gfx::TileInfo > MakeDummyTiles()
constexpr int kDummyTileCount
Context passed to draw routines containing all necessary state.
static constexpr int kMaxTilesY
gfx::BackgroundBuffer & target_bg
static constexpr int kMaxTilesX
Metadata about a draw routine.
Bounding box result for a draw routine execution.
std::optional< SelectionRect > selection_bounds
Simple rectangle for selection bounds.