6#include "absl/status/status.h"
7#include "absl/strings/str_format.h"
30 : water_face_active_(water_face_active) {}
41 return water_face_active_;
50 bool water_face_active_ =
false;
60 return &kActiveWaterFaceState;
66 std::vector<gfx::TileInfo> tiles;
70 tiles.push_back(
gfx::TileInfo(
static_cast<uint16_t
>(i + 1), 0,
71 false,
false,
false));
83 const int size_nibble =
object.size_ & 0x0F;
87 (routine.
id == 5 || routine.
id == 17)) {
88 const int count = size_nibble + 6;
89 const int max_anchor =
91 anchor.
y = std::clamp(count - 1, 0, std::max(0, max_anchor));
98 routine.
id >= 75 && routine.
id <= 78) {
99 const int side = size_nibble + 4;
100 if (routine.
id == 78) {
151 int routine_id,
const RoomObject&
object)
const {
153 if (info ==
nullptr) {
154 return absl::InvalidArgumentError(
155 absl::StrFormat(
"Unknown routine id %d", routine_id));
161 uint8_t size_byte)
const {
162 const int routine_id =
164 if (routine_id < 0) {
168 if (info ==
nullptr) {
171 RoomObject probe(object_id, 0, 0, size_byte, 0);
172 AnchorPos anchor = ChooseAnchor(*info, probe);
173 return {anchor.x, anchor.y};
179 SelectMeasurementState(routine));
187 const AnchorPos anchor = ChooseAnchor(routine,
object);
188 adjusted.
x_ = anchor.x;
189 adjusted.
y_ = anchor.y;
197 static const std::vector<gfx::TileInfo> kTiles = MakeDummyTiles();
198 const uint16_t object_id =
static_cast<uint16_t
>(
object.id_);
200 (object_id == 0x0F99 || object_id == 0x0F9A);
201 const size_t measurement_tile_count =
202 is_small_chest ?
static_cast<size_t>(routine.
min_tiles) : kTiles.size();
211 std::span<const gfx::TileInfo>(kTiles.data(), measurement_tile_count),
215 .room_gfx_buffer =
nullptr,
216 .secondary_bg =
nullptr,
226 int min_x = std::numeric_limits<int>::max();
227 int min_y = std::numeric_limits<int>::max();
228 int max_x = std::numeric_limits<int>::min();
229 int max_y = std::numeric_limits<int>::min();
231 for (
int y = 0; y < tiles_h; ++y) {
232 for (
int x = 0; x < tiles_w; ++x) {
235 min_x = std::min(min_x, x);
236 min_y = std::min(min_y, y);
237 max_x = std::max(max_x, x);
238 max_y = std::max(max_y, y);
243 if (max_x == std::numeric_limits<int>::min()) {
259 if (routine_id < 0) {
260 return absl::NotFoundError(
261 absl::StrFormat(
"No routine mapping for object 0x%03X",
object.id_));
265 CacheKey key{routine_id,
object.id_,
object.size_,
267 auto cache_it =
cache_.find(key);
268 if (cache_it !=
cache_.end()) {
269 return cache_it->second;
282 const int routine_id =
284 if (routine_id < 0) {
285 return absl::NotFoundError(
286 absl::StrFormat(
"No routine mapping for object 0x%03X",
object.id_));
290 if (routine ==
nullptr) {
291 return absl::InvalidArgumentError(
292 absl::StrFormat(
"Unknown routine id %d", routine_id));
303 int routine_id,
const RoomObject&
object)
const {
uint16_t GetTileAt(int x, int y) const
SNES 16-bit tile metadata container.
uint64_t asset_generation() const
static CustomObjectManager & Get()
int GetRoutineIdForObject(int16_t object_id) const
static DrawRoutineRegistry & Get()
Interface for accessing dungeon game state.
Side-car geometry engine that replays draw routines against an off-screen buffer to calculate real ex...
std::pair< int, int > ResolveAnchor(int16_t object_id, uint8_t size_byte) const
Resolve the canvas anchor (x, y) for a given object's draw routine.
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 > MeasureByObjectIdForState(const RoomObject &object, const DungeonState *state) const
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 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.
absl::StatusOr< GeometryBounds > MeasureRoutineForState(const DrawRoutineInfo &routine, const RoomObject &object, const DungeonState *state) const
const std::vector< gfx::TileInfo > & tiles() const
bool IsFloorBombable(int) const override
bool IsDamFloodgateOpen(int) const override
bool IsWallMoved(int) const override
bool IsDoorOpen(int, int) const override
bool IsWaterFaceActive(int) const override
bool IsDoorSwitchActive(int) const override
MeasurementDungeonState(bool water_face_active)
bool IsCrystalSwitchBlue() const override
bool IsChestOpen(int, int) const override
bool IsRupeeFloorCleared(int) const override
bool IsBigChestOpen() const override
constexpr int kMovingWallWest
constexpr int kEmptyWaterFace
AnchorPos ChooseAnchor(const DrawRoutineInfo &routine, const RoomObject &object)
std::vector< gfx::TileInfo > MakeDummyTiles()
const DungeonState * SelectMeasurementState(const DrawRoutineInfo &routine)
constexpr int kDummyTileCount
constexpr int ObjectCountForSize(int size)
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.