6#include "absl/status/status.h"
7#include "absl/strings/str_format.h"
21 std::vector<gfx::TileInfo> tiles;
25 tiles.push_back(
gfx::TileInfo(
static_cast<uint16_t
>(i + 1), 0,
26 false,
false,
false));
35 (routine.
id == 5 || routine.
id == 17)) {
36 int size =
object.size_ & 0x0F;
37 int count = (routine.
id == 5) ? (size + 7) : (size + 6);
39 int min_anchor = count - 1;
41 if (min_anchor > max_anchor) min_anchor = max_anchor;
42 return std::clamp(min_anchor, 0, max_anchor);
81 int routine_id,
const RoomObject&
object)
const {
83 if (info ==
nullptr) {
84 return absl::InvalidArgumentError(
85 absl::StrFormat(
"Unknown routine id %d", routine_id));
94 adjusted.
x_ = kAnchorX;
95 const int anchor_y = ChooseAnchorY(routine,
object);
96 adjusted.
y_ = anchor_y;
99 static const std::vector<gfx::TileInfo> kTiles = MakeDummyTiles();
107 .
tiles = std::span<const gfx::TileInfo>(kTiles.data(), kTiles.size()),
111 .room_gfx_buffer =
nullptr,
112 .secondary_bg =
nullptr,
122 int min_x = std::numeric_limits<int>::max();
123 int min_y = std::numeric_limits<int>::max();
124 int max_x = std::numeric_limits<int>::min();
125 int max_y = std::numeric_limits<int>::min();
127 for (
int y = 0; y < tiles_h; ++y) {
128 for (
int x = 0; x < tiles_w; ++x) {
130 min_x = std::min(min_x, x);
131 min_y = std::min(min_y, y);
132 max_x = std::max(max_x, x);
133 max_y = std::max(max_y, y);
138 if (max_x == std::numeric_limits<int>::min()) {
152 int routine_id,
const RoomObject&
object)
const {
189 return routine_id >= 75 && routine_id <= 78;
196 return render_bounds;
204 int reduced_width = std::max(1, (render_bounds.
width_tiles * 7) / 10);
205 int reduced_height = std::max(1, (render_bounds.
height_tiles * 7) / 10);
208 int offset_x = (render_bounds.
width_tiles - reduced_width) / 2;
209 int offset_y = (render_bounds.
height_tiles - reduced_height) / 2;
218 return render_bounds;
uint16_t GetTileAt(int x, int y) const
SNES 16-bit tile metadata container.
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_
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()
static bool IsLayerOneRoutine(int routine_id)
Get list of routine IDs that draw to BG2 layer.
const std::vector< gfx::TileInfo > & tiles() const
std::vector< gfx::TileInfo > MakeDummyTiles()
int ChooseAnchorY(const DrawRoutineInfo &routine, const RoomObject &object)
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.