yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_limits.h
Go to the documentation of this file.
1#ifndef YAZE_SRC_ZELDA3_DUNGEON_DUNGEON_LIMITS_H_
2#define YAZE_SRC_ZELDA3_DUNGEON_DUNGEON_LIMITS_H_
3
4// Canonical dungeon entity limits for ALTTP.
5//
6// All interaction handlers, validators, and tests should reference these
7// constants instead of defining their own copies.
8
9#include <cstddef>
10#include <limits>
11#include <map>
12#include <vector>
13
14namespace yaze::zelda3 {
15
16// Active sprites rendered per frame (SNES hardware/engine constraint).
17inline constexpr size_t kMaxActiveSprites = 16;
18
19// Total sprites in a room's sprite list (safety limit for ROM encoding).
20inline constexpr size_t kMaxTotalSprites = 64;
21
22// Maximum chests per room (item collection flag constraint).
23inline constexpr size_t kMaxChests = 6;
24
25// Maximum door objects per room (practical ROM encoding limit).
26inline constexpr size_t kMaxDoors = 16;
27
28// Maximum tile objects before processing lag on original hardware.
29inline constexpr size_t kMaxTileObjects = 400;
30
31// BG3-layer object guardrail for unstable rendering on real SNES.
32inline constexpr size_t kMaxBg3Objects = 128;
33
34// Sentinel for categories that are counted but intentionally not hard-limited.
35inline constexpr int kNoHardLimit = std::numeric_limits<int>::max();
36
37// Entity limit category for room validation queries.
38enum class DungeonLimit {
41 kDoors,
42 kChests,
44 // Extended categories used by Room::GetLimitedObjectCounts().
48 Blocks,
49 Torches,
55};
56
57// User-facing label for a limit category.
58inline constexpr const char* GetDungeonLimitLabel(DungeonLimit limit) {
59 switch (limit) {
61 return "Tile Objects";
63 return "Sprites";
65 return "Doors";
67 return "Chests";
69 return "BG3 Objects";
71 return "Overlords";
73 return "Special Doors";
75 return "Stairs (Transition)";
77 return "Blocks";
79 return "Torches";
81 return "Star Tiles";
83 return "Somaria Line";
85 return "Stairs North";
87 return "Stairs South";
89 return "General Manipulable";
90 }
91 return "Unknown";
92}
93
94// Info about a specific exceeded limit (for UI display).
99 const char* label;
100};
101
102// Get the maximum for a given limit category.
103inline constexpr int GetDungeonLimitMax(DungeonLimit limit) {
104 switch (limit) {
106 return static_cast<int>(kMaxTileObjects);
108 return static_cast<int>(kMaxTotalSprites);
110 return static_cast<int>(kMaxDoors);
112 return static_cast<int>(kMaxChests);
114 return static_cast<int>(kMaxBg3Objects);
125 return kNoHardLimit;
126 }
127 return kNoHardLimit;
128}
129
130// Create a zero-initialized limit counter map.
131inline std::map<DungeonLimit, int> CreateLimitCounter() {
132 return {
138 };
139}
140
141// Check if any limit in the counter map is exceeded.
142inline bool HasExceededLimits(const std::map<DungeonLimit, int>& counts) {
143 for (const auto& [limit, count] : counts) {
144 const int max_val = GetDungeonLimitMax(limit);
145 if (max_val == kNoHardLimit) {
146 continue;
147 }
148 if (count > max_val) {
149 return true;
150 }
151 }
152 return false;
153}
154
155// Get details for all exceeded limits.
156inline std::vector<DungeonLimitInfo> GetExceededLimits(
157 const std::map<DungeonLimit, int>& counts) {
158 std::vector<DungeonLimitInfo> result;
159 for (const auto& [limit, count] : counts) {
160 const int max_val = GetDungeonLimitMax(limit);
161 if (max_val == kNoHardLimit) {
162 continue;
163 }
164 if (count > max_val) {
165 result.push_back({limit, count, max_val, GetDungeonLimitLabel(limit)});
166 }
167 }
168 return result;
169}
170
171} // namespace yaze::zelda3
172
173#endif // YAZE_SRC_ZELDA3_DUNGEON_DUNGEON_LIMITS_H_
Zelda 3 specific classes and functions.
constexpr size_t kMaxBg3Objects
std::vector< DungeonLimitInfo > GetExceededLimits(const std::map< DungeonLimit, int > &counts)
constexpr int kNoHardLimit
constexpr size_t kMaxTileObjects
constexpr int GetDungeonLimitMax(DungeonLimit limit)
bool HasExceededLimits(const std::map< DungeonLimit, int > &counts)
constexpr size_t kMaxDoors
constexpr size_t kMaxActiveSprites
constexpr const char * GetDungeonLimitLabel(DungeonLimit limit)
std::map< DungeonLimit, int > CreateLimitCounter()
constexpr size_t kMaxChests
constexpr size_t kMaxTotalSprites