yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sprite_oam_tables.h
Go to the documentation of this file.
1#ifndef YAZE_ZELDA3_SPRITE_SPRITE_OAM_TABLES_H
2#define YAZE_ZELDA3_SPRITE_SPRITE_OAM_TABLES_H
3
4#include <array>
5#include <cstdint>
6#include <optional>
7#include <span>
8#include <string>
9#include <string_view>
10#include <vector>
11
12namespace yaze {
13namespace zelda3 {
14
22 int8_t x_offset; // X offset relative to sprite origin
23 int8_t y_offset; // Y offset relative to sprite origin
24 uint16_t tile_id; // Tile ID in graphics buffer
25 uint8_t palette; // Palette index (0-7)
26 bool size_16x16; // false = 8x8, true = 16x16
27 bool flip_x; // Horizontal mirror
28 bool flip_y; // Vertical mirror
29};
30
38 uint8_t sprite_id; // Sprite type ID (0x00-0xF2)
39 const char* name; // Display name
40 std::vector<SpriteOamEntry> tiles;
41 std::array<uint8_t, 4> required_sheets; // Graphics sheet IDs needed
42 // Optional raw SNES 4bpp OBJ page 1, relative to the project's assets folder.
43 // A required resource must be present before rendering this static layout.
44 const char* graphics_resource = nullptr;
45};
46
47// Viewer-owned, read-only cache. Context changes discard successes and failures;
48// unchanged frames never reopen files. No process-global project state.
50 public:
51 // Returns true when context changes discard cached resources.
52 bool SetContext(std::string_view project_path, std::string_view assets_path,
53 std::string_view hack_name);
54 std::span<const uint8_t> GetGraphics(const SpriteOamLayout* layout);
55
56 private:
57 std::string project_path_;
58 std::string assets_path_;
59 std::string hack_name_;
60 std::string resource_;
61 std::vector<uint8_t> graphics_;
62};
63
64// ============================================================
65// Common Sprite OAM Layouts
66// ============================================================
67
68// Sprite ID: 0x01 - Vulture
70 .sprite_id = 0x01,
71 .name = "Vulture",
72 .tiles = {{0, 0, 0x20, 2, true, false, false},
73 {0, -16, 0x00, 2, true, false, false}},
74 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
75
76// Sprite ID: 0x08 - Octorok (1-way)
78 .sprite_id = 0x08,
79 .name = "Octorok",
80 .tiles = {{0, 0, 0x80, 6, true, false, false}},
81 .required_sheets = {0x56, 0x57, 0x00, 0x00}};
82
83// Sprite ID: 0x0B - Chicken
85 .sprite_id = 0x0B,
86 .name = "Chicken",
87 .tiles = {{0, 0, 0x60, 2, true, false, false}},
88 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
89
90// Sprite ID: 0x0E - Green Soldier (standing)
92 .sprite_id = 0x0E,
93 .name = "Green Soldier",
94 .tiles = {{0, 8, 0x20, 6, true, false, false}, // Body
95 {0, -8, 0x00, 6, true, false, false}}, // Head
96 .required_sheets = {0x56, 0x57, 0x00, 0x00}};
97
98// Sprite ID: 0x0F - Blue Soldier
100 .sprite_id = 0x0F,
101 .name = "Blue Soldier",
102 .tiles = {{0, 8, 0x20, 1, true, false, false}, // Body
103 {0, -8, 0x00, 1, true, false, false}}, // Head
104 .required_sheets = {0x56, 0x57, 0x00, 0x00}};
105
106// Sprite ID: 0x10 - Red Soldier
108 .sprite_id = 0x10,
109 .name = "Red Soldier",
110 .tiles = {{0, 8, 0x20, 0, true, false, false}, // Body
111 {0, -8, 0x00, 0, true, false, false}}, // Head
112 .required_sheets = {0x56, 0x57, 0x00, 0x00}};
113
114// Sprite ID: 0x29 - Blue Guard
116 .sprite_id = 0x29,
117 .name = "Blue Guard",
118 .tiles = {{0, 8, 0x20, 1, true, false, false}, // Body
119 {0, -8, 0x00, 1, true, false, false}}, // Head
120 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
121
122// Sprite ID: 0x41 - Green Soldier (patrol)
124 .sprite_id = 0x41,
125 .name = "Green Patrol",
126 .tiles = {{0, 8, 0x20, 6, true, false, false}, // Body
127 {0, -8, 0x00, 6, true, false, false}}, // Head
128 .required_sheets = {0x56, 0x57, 0x00, 0x00}};
129
130// Sprite ID: 0x44 - Armos Knight
132 .sprite_id = 0x44,
133 .name = "Armos Knight",
134 .tiles = {{0, 0, 0x82, 4, true, false, false},
135 {0, -16, 0x80, 4, true, false, false}},
136 .required_sheets = {0x58, 0x59, 0x00, 0x00}};
137
138// Sprite ID: 0x4B - Octoballoon
140 .sprite_id = 0x4B,
141 .name = "Octoballoon",
142 .tiles = {{0, 0, 0xE0, 4, true, false, false}},
143 .required_sheets = {0x54, 0x55, 0x00, 0x00}};
144
145// Sprite ID: 0x53 - Red Eyegore
147 .sprite_id = 0x53,
148 .name = "Red Eyegore",
149 .tiles = {{0, 0, 0x84, 0, true, false, false},
150 {0, -16, 0x80, 0, true, false, false}},
151 .required_sheets = {0x58, 0x59, 0x00, 0x00}};
152
153// Sprite ID: 0x54 - Green Eyegore
155 .sprite_id = 0x54,
156 .name = "Green Eyegore",
157 .tiles = {{0, 0, 0x84, 6, true, false, false},
158 {0, -16, 0x80, 6, true, false, false}},
159 .required_sheets = {0x58, 0x59, 0x00, 0x00}};
160
161// Sprite ID: 0x64 - Moblin
163 .sprite_id = 0x64,
164 .name = "Moblin",
165 .tiles = {{0, 0, 0xC6, 5, true, false, false},
166 {0, -16, 0xC4, 5, true, false, false}},
167 .required_sheets = {0x54, 0x55, 0x00, 0x00}};
168
169// Sprite ID: 0x81 - Hinox
171 .sprite_id = 0x81,
172 .name = "Hinox",
173 .tiles = {{-8, 0, 0xCC, 3, true, false, false},
174 {8, 0, 0xCC, 3, true, true, false},
175 {-8, -16, 0xC8, 3, true, false, false},
176 {8, -16, 0xC8, 3, true, true, false}},
177 .required_sheets = {0x5C, 0x5D, 0x00, 0x00}};
178
179// Sprite ID: 0x88 - Link's Uncle (dying)
181 .sprite_id = 0x88,
182 .name = "Uncle",
183 .tiles = {{0, 0, 0xAE, 7, true, false, false},
184 {0, -16, 0x8E, 7, true, false, false}},
185 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
186
187// Sprite ID: 0xD8 - Heart Container
189 .sprite_id = 0xD8,
190 .name = "Heart Container",
191 .tiles = {{0, 0, 0xEE, 0, true, false, false}},
192 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
193
194// Sprite ID: 0xDA - Green Rupee
196 .sprite_id = 0xDA,
197 .name = "Green Rupee",
198 .tiles = {{0, 0, 0xE8, 0, false, false, false}},
199 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
200
201// Sprite ID: 0xDB - Blue Rupee
203 .sprite_id = 0xDB,
204 .name = "Blue Rupee",
205 .tiles = {{0, 0, 0xE8, 1, false, false, false}},
206 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
207
208// Sprite ID: 0xDC - Red Rupee
210 .sprite_id = 0xDC,
211 .name = "Red Rupee",
212 .tiles = {{0, 0, 0xE8, 2, false, false, false}},
213 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
214
215// Sprite ID: 0xDE - Small Heart
217 .sprite_id = 0xDE,
218 .name = "Small Heart",
219 .tiles = {{0, 0, 0xEC, 0, false, false, false}},
220 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
221
222// Sprite ID: 0xDF - Key
224 .sprite_id = 0xDF,
225 .name = "Key",
226 .tiles = {{0, 0, 0xF4, 7, false, false, false}},
227 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
228
229// Sprite ID: 0xE1 - Small Magic
231 .sprite_id = 0xE1,
232 .name = "Small Magic",
233 .tiles = {{0, 0, 0xF0, 6, false, false, false}},
234 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
235
236// Sprite ID: 0xE2 - Large Magic
238 .sprite_id = 0xE2,
239 .name = "Large Magic",
240 .tiles = {{0, 0, 0xF6, 6, false, false, false}},
241 .required_sheets = {0x52, 0x53, 0x00, 0x00}};
242
249 public:
255 static const SpriteOamLayout* GetLayout(uint8_t sprite_id);
256
257 // A loaded project's hack name selects static preview overrides. Empty or
258 // unknown profiles never change vanilla rendering. Some overrides require a
259 // separate graphics resource and cannot use the room-loaded sheets alone.
260 static const SpriteOamLayout* GetPreviewOverride(uint8_t sprite_id,
261 std::string_view hack_name);
262
268 static std::optional<std::array<uint8_t, 4>> GetRequiredSheets(
269 uint8_t sprite_id);
270
276 static bool HasLayout(uint8_t sprite_id);
277
282 static std::vector<const SpriteOamLayout*> GetAllLayouts();
283};
284
285} // namespace zelda3
286} // namespace yaze
287
288#endif // YAZE_ZELDA3_SPRITE_SPRITE_OAM_TABLES_H
Registry of all known sprite OAM layouts.
static const SpriteOamLayout * GetLayout(uint8_t sprite_id)
Get the OAM layout for a sprite ID.
static std::vector< const SpriteOamLayout * > GetAllLayouts()
Get all defined layouts.
static const SpriteOamLayout * GetPreviewOverride(uint8_t sprite_id, std::string_view hack_name)
static std::optional< std::array< uint8_t, 4 > > GetRequiredSheets(uint8_t sprite_id)
Get required graphics sheets for a sprite.
static bool HasLayout(uint8_t sprite_id)
Check if a sprite has a defined layout.
std::span< const uint8_t > GetGraphics(const SpriteOamLayout *layout)
bool SetContext(std::string_view project_path, std::string_view assets_path, std::string_view hack_name)
const SpriteOamLayout kRedEyegoreLayout
const SpriteOamLayout kOctorokLayout
const SpriteOamLayout kBlueGuardLayout
const SpriteOamLayout kLargeMagicLayout
const SpriteOamLayout kBlueSoldierLayout
const SpriteOamLayout kBlueRupeeLayout
const SpriteOamLayout kRedSoldierLayout
const SpriteOamLayout kGreenSoldierLayout
const SpriteOamLayout kSmallMagicLayout
const SpriteOamLayout kGreenRupeeLayout
const SpriteOamLayout kArmosKnightLayout
const SpriteOamLayout kGreenPatrolLayout
const SpriteOamLayout kOctoballoonLayout
const SpriteOamLayout kHinoxLayout
const SpriteOamLayout kHeartContainerLayout
const SpriteOamLayout kMoblinLayout
const SpriteOamLayout kChickenLayout
const SpriteOamLayout kUncleLayout
const SpriteOamLayout kKeyLayout
const SpriteOamLayout kGreenEyegoreLayout
const SpriteOamLayout kSmallHeartLayout
const SpriteOamLayout kVultureLayout
const SpriteOamLayout kRedRupeeLayout
Single OAM entry for sprite rendering.
Complete OAM layout for a vanilla sprite.
std::array< uint8_t, 4 > required_sheets
std::vector< SpriteOamEntry > tiles