yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
draw_routine_registry.cc
Go to the documentation of this file.
2
3#include "core/features.h"
9
10namespace yaze {
11namespace zelda3 {
12
14 static DrawRoutineRegistry instance;
15 if (!instance.initialized_) {
16 instance.Initialize();
17 }
18 return instance;
19}
20
22 if (initialized_)
23 return;
25 initialized_ = true;
26}
27
35
54
56 int routine_id) const {
57 auto it = routine_map_.find(routine_id);
58 if (it == routine_map_.end()) {
59 return nullptr;
60 }
61 return it->second;
62}
63
65 const DrawRoutineInfo* info = GetRoutineInfo(routine_id);
66 return info != nullptr && info->draws_to_both_bgs;
67}
68
69bool DrawRoutineRegistry::GetRoutineDimensions(int routine_id, int* base_width,
70 int* base_height) const {
71 const DrawRoutineInfo* info = GetRoutineInfo(routine_id);
72 if (info == nullptr) {
73 return false;
74 }
75 if (base_width)
76 *base_width = info->base_width;
77 if (base_height)
78 *base_height = info->base_height;
79 return true;
80}
81
82int DrawRoutineRegistry::GetRoutineIdForObject(int16_t object_id) const {
83 auto it = object_to_routine_map_.find(object_id);
84 if (it != object_to_routine_map_.end()) {
85 return it->second;
86 }
87 return -1;
88}
89
92
93 // Subtype 1 Object Mappings (0x00-0xFF)
94 // Based on bank_01.asm routine table at $018200
95 object_to_routine_map_[0x00] = 0;
96 for (int id = 0x01; id <= 0x02; id++) {
98 }
99 for (int id = 0x03; id <= 0x04; id++) {
101 }
102 for (int id = 0x05; id <= 0x06; id++) {
104 }
105 for (int id = 0x07; id <= 0x08; id++) {
107 }
108 object_to_routine_map_[0x09] = 5;
109 for (int id = 0x0A; id <= 0x0B; id++) {
111 }
112
113 // Diagonal walls (0x0C-0x20)
114 for (int id : {0x0C, 0x0D, 0x10, 0x11, 0x14}) {
116 }
117 for (int id : {0x0E, 0x0F, 0x12, 0x13}) {
119 }
120 for (int id : {0x15, 0x18, 0x19, 0x1C, 0x1D, 0x20}) {
121 object_to_routine_map_[id] = 17;
122 }
123 for (int id : {0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F}) {
124 object_to_routine_map_[id] = 18;
125 }
126
127 // Edge and Corner Objects (0x21-0x30)
128 object_to_routine_map_[0x21] = 20;
129 object_to_routine_map_[0x22] = 21;
130 for (int id = 0x23; id <= 0x2E; id++) {
131 object_to_routine_map_[id] = 22;
132 }
133 object_to_routine_map_[0x2F] = 23;
134 object_to_routine_map_[0x30] = 24;
135
136 // Oracle fixed custom-object families (0x31, 0x32, 0x54).
141 } else {
145 }
146 object_to_routine_map_[0x33] = 16;
147 object_to_routine_map_[0x34] = 25;
148 object_to_routine_map_[0x35] = 26;
149 object_to_routine_map_[0x36] = 27;
150 object_to_routine_map_[0x37] = 27;
151 object_to_routine_map_[0x38] = 28;
152 object_to_routine_map_[0x39] = 29;
153 object_to_routine_map_[0x3A] = 30;
154 object_to_routine_map_[0x3B] = 30;
155 object_to_routine_map_[0x3C] = 31;
156 object_to_routine_map_[0x3D] = 29;
157 object_to_routine_map_[0x3E] = 32;
158
159 for (int id = 0x3F; id <= 0x46; id++) {
160 object_to_routine_map_[id] = 22;
161 }
162 object_to_routine_map_[0x47] = 111;
163 object_to_routine_map_[0x48] = 112;
164 object_to_routine_map_[0x49] = 40;
165 object_to_routine_map_[0x4A] = 40;
166 object_to_routine_map_[0x4B] = 32;
167 object_to_routine_map_[0x4C] = 52;
168 object_to_routine_map_[0x4D] = 53;
169 object_to_routine_map_[0x4E] = 53;
170 object_to_routine_map_[0x4F] = 53;
171
172 object_to_routine_map_[0x50] = 51;
173 object_to_routine_map_[0x51] = 42;
174 object_to_routine_map_[0x52] = 42;
175 object_to_routine_map_[0x53] = 4;
176 object_to_routine_map_[0x55] = 41;
177 object_to_routine_map_[0x56] = 41;
178 object_to_routine_map_[0x57] = 38;
179 object_to_routine_map_[0x58] = 38;
180 object_to_routine_map_[0x59] = 38;
181 object_to_routine_map_[0x5A] = 38;
182 object_to_routine_map_[0x5B] = 42;
183 object_to_routine_map_[0x5C] = 42;
184 object_to_routine_map_[0x5D] = 54;
185 object_to_routine_map_[0x5E] = 55;
188
189 // Vertical (0x60-0x6F)
190 object_to_routine_map_[0x60] = 7;
191 for (int id = 0x61; id <= 0x62; id++) {
193 }
194 for (int id = 0x63; id <= 0x64; id++) {
196 }
197 for (int id = 0x65; id <= 0x66; id++) {
198 object_to_routine_map_[id] = 10;
199 }
200 for (int id = 0x67; id <= 0x68; id++) {
201 object_to_routine_map_[id] = 11;
202 }
203 object_to_routine_map_[0x69] = 12;
204 for (int id = 0x6A; id <= 0x6B; id++) {
205 object_to_routine_map_[id] = 13;
206 }
207 object_to_routine_map_[0x6C] = 14;
208 object_to_routine_map_[0x6D] = 15;
209 object_to_routine_map_[0x6E] = 38;
210 object_to_routine_map_[0x6F] = 38;
211
212 // 0x70-0x7F
213 object_to_routine_map_[0x70] = 43;
214 object_to_routine_map_[0x71] = 44;
215 object_to_routine_map_[0x72] = 38;
216 object_to_routine_map_[0x73] = 45;
217 object_to_routine_map_[0x74] = 45;
218 object_to_routine_map_[0x75] = 46;
219 object_to_routine_map_[0x76] = 47;
220 object_to_routine_map_[0x77] = 47;
221 object_to_routine_map_[0x78] = 48;
222 object_to_routine_map_[0x79] = 13;
223 object_to_routine_map_[0x7A] = 13;
224 object_to_routine_map_[0x7B] = 48;
225 object_to_routine_map_[0x7C] = 49;
226 object_to_routine_map_[0x7D] = 11;
227 object_to_routine_map_[0x7E] = 38;
228 object_to_routine_map_[0x7F] = 50;
229
230 // 0x80-0x8F
231 object_to_routine_map_[0x80] = 50;
232 object_to_routine_map_[0x81] = 65;
233 object_to_routine_map_[0x82] = 65;
234 object_to_routine_map_[0x83] = 65;
235 object_to_routine_map_[0x84] = 65;
236 object_to_routine_map_[0x85] = 68;
237 object_to_routine_map_[0x86] = 68;
238 object_to_routine_map_[0x87] = 46;
239 object_to_routine_map_[0x88] = 66;
240 object_to_routine_map_[0x89] = 67;
241 // USDASM $018314-$018318: 0x8A is the long capped rail, while 0x8B/0x8C
242 // are single-tile jump ledges repeated for size + 8 rows.
247 object_to_routine_map_[0x8D] = 13;
248 object_to_routine_map_[0x8E] = 13;
249 object_to_routine_map_[0x8F] = 69;
250
251 // 0x90-0x9F
252 object_to_routine_map_[0x90] = 8;
253 object_to_routine_map_[0x91] = 8;
254 object_to_routine_map_[0x92] = 7;
255 object_to_routine_map_[0x93] = 7;
256 object_to_routine_map_[0x94] = 43;
257 object_to_routine_map_[0x95] = 70;
258 object_to_routine_map_[0x96] = 71;
259 for (int id = 0x97; id <= 0x9F; id++) {
260 object_to_routine_map_[id] = 38;
261 }
262
263 // 0xA0-0xAF (diagonal ceilings and big hole)
264 object_to_routine_map_[0xA0] = 75;
265 object_to_routine_map_[0xA5] = 75;
266 object_to_routine_map_[0xA9] = 75;
267 object_to_routine_map_[0xA1] = 76;
268 object_to_routine_map_[0xA6] = 76;
269 object_to_routine_map_[0xAA] = 76;
270 object_to_routine_map_[0xA2] = 77;
271 object_to_routine_map_[0xA7] = 77;
272 object_to_routine_map_[0xAB] = 77;
273 object_to_routine_map_[0xA3] = 78;
274 object_to_routine_map_[0xA8] = 78;
275 object_to_routine_map_[0xAC] = 78;
276 object_to_routine_map_[0xA4] = 61;
277 object_to_routine_map_[0xAD] = 38;
278 object_to_routine_map_[0xAE] = 38;
279 object_to_routine_map_[0xAF] = 38;
280
281 // 0xB0-0xBF
282 object_to_routine_map_[0xB0] = 72;
283 object_to_routine_map_[0xB1] = 72;
284 object_to_routine_map_[0xB2] = 16;
285 object_to_routine_map_[0xB3] = 22;
286 object_to_routine_map_[0xB4] = 22;
288 object_to_routine_map_[0xB6] = 1;
289 object_to_routine_map_[0xB7] = 1;
290 object_to_routine_map_[0xB8] = 0;
291 object_to_routine_map_[0xB9] = 0;
292 object_to_routine_map_[0xBA] = 16;
293 object_to_routine_map_[0xBB] = 55;
294 object_to_routine_map_[0xBC] = 73;
295 object_to_routine_map_[0xBD] = 74;
296 object_to_routine_map_[0xBE] = 38;
297 object_to_routine_map_[0xBF] = 38;
298
299 // 0xC0-0xCF (SuperSquare)
300 object_to_routine_map_[0xC0] = 56;
301 object_to_routine_map_[0xC1] = 79;
302 object_to_routine_map_[0xC2] = 56;
303 object_to_routine_map_[0xC3] = 57;
304 object_to_routine_map_[0xC4] = 59;
305 for (int id = 0xC5; id <= 0xCA; id++) {
306 object_to_routine_map_[id] = 58;
307 }
308 object_to_routine_map_[0xCB] = 38;
309 object_to_routine_map_[0xCC] = 38;
310 object_to_routine_map_[0xCD] = 80;
311 object_to_routine_map_[0xCE] = 81;
312 object_to_routine_map_[0xCF] = 38;
313
314 // 0xD0-0xDF
315 object_to_routine_map_[0xD0] = 38;
316 object_to_routine_map_[0xD1] = 58;
317 object_to_routine_map_[0xD2] = 58;
318 object_to_routine_map_[0xD3] = 38;
319 object_to_routine_map_[0xD4] = 38;
320 object_to_routine_map_[0xD5] = 38;
321 object_to_routine_map_[0xD6] = 38;
322 object_to_routine_map_[0xD7] = 57;
323 object_to_routine_map_[0xD8] = 64;
324 object_to_routine_map_[0xD9] = 58;
325 object_to_routine_map_[0xDA] = 64;
326 object_to_routine_map_[0xDB] = 60;
327 object_to_routine_map_[0xDC] = 82;
328 object_to_routine_map_[0xDD] = 63;
329 object_to_routine_map_[0xDE] = 62;
330 object_to_routine_map_[0xDF] = 58;
331
332 // 0xE0-0xEF
333 for (int id = 0xE0; id <= 0xE8; id++) {
334 object_to_routine_map_[id] = 58;
335 }
336 for (int id = 0xE9; id <= 0xEF; id++) {
337 object_to_routine_map_[id] = 38;
338 }
339
340 // 0xF0-0xFF (complete subtype 1 coverage)
341 for (int id = 0xF0; id <= 0xF7; id++) {
342 object_to_routine_map_[id] = 38;
343 }
344 object_to_routine_map_[0xF8] = 39; // Chest variant
345 for (int id = 0xF9; id <= 0xFD; id++) {
346 object_to_routine_map_[id] = 39;
347 }
348 object_to_routine_map_[0xFE] = 38; // Unused in vanilla
349 object_to_routine_map_[0xFF] = 38; // Unused in vanilla
350
351 // Subtype 2 Object Mappings (0x100-0x13F)
352 for (int id = 0x100; id <= 0x107; id++) {
354 }
355 for (int id = 0x108; id <= 0x10F; id++) {
356 object_to_routine_map_[id] = 35;
357 }
358 for (int id = 0x110; id <= 0x113; id++) {
359 object_to_routine_map_[id] = 36;
360 }
361 for (int id = 0x114; id <= 0x117; id++) {
362 object_to_routine_map_[id] = 37;
363 }
364 for (int id = 0x118; id <= 0x11B; id++) {
366 }
368 object_to_routine_map_[0x11D] = 28;
369 object_to_routine_map_[0x11E] = 4;
372 object_to_routine_map_[0x121] = 28;
373 object_to_routine_map_[0x122] = 98;
374 object_to_routine_map_[0x123] = 30;
377 object_to_routine_map_[0x126] = 28;
378 object_to_routine_map_[0x127] = 4;
379 object_to_routine_map_[0x128] = 98;
382 object_to_routine_map_[0x12B] = 4;
383 object_to_routine_map_[0x12C] = 99;
384 object_to_routine_map_[0x12D] = 83;
385 object_to_routine_map_[0x12E] = 84;
386 object_to_routine_map_[0x12F] = 85;
387 for (int id = 0x130; id <= 0x133; id++) {
388 object_to_routine_map_[id] = 86;
389 }
390 object_to_routine_map_[0x134] = 4;
394 object_to_routine_map_[0x138] = 88;
395 object_to_routine_map_[0x139] = 89;
396 object_to_routine_map_[0x13A] = 90;
397 object_to_routine_map_[0x13B] = 91;
399 object_to_routine_map_[0x13D] = 30;
400 object_to_routine_map_[0x13E] = 100;
402
403 // Subtype 3 Object Mappings (0xF80-0xFFF)
404 object_to_routine_map_[0xF80] = 94;
405 object_to_routine_map_[0xF81] = 95;
406 object_to_routine_map_[0xF82] = 96;
407 for (int id = 0xF83; id <= 0xF89; id++) {
408 object_to_routine_map_[id] = 33;
409 }
410 for (int id = 0xF8A; id <= 0xF8C; id++) {
411 object_to_routine_map_[id] = 33;
412 }
413 object_to_routine_map_[0xF8D] = 97;
414 object_to_routine_map_[0xF8E] = 33;
415 object_to_routine_map_[0xF8F] = 33;
416 object_to_routine_map_[0xF90] = 110;
417 object_to_routine_map_[0xF91] = 110;
418 object_to_routine_map_[0xF92] = 115;
419 object_to_routine_map_[0xF93] = 110;
420 object_to_routine_map_[0xF94] = 30;
421 object_to_routine_map_[0xF95] = 106;
423 object_to_routine_map_[0xF97] = 97;
424 object_to_routine_map_[0xF98] = 92;
425 object_to_routine_map_[0xF99] = 39;
426 object_to_routine_map_[0xF9A] = 39;
427 for (int id = 0xF9B; id <= 0xF9D; id++) {
428 object_to_routine_map_[id] = 86;
429 }
430 for (int id = 0xF9E; id <= 0xFA1; id++) {
431 object_to_routine_map_[id] = 87;
432 }
433 for (int id = 0xFA2; id <= 0xFA5; id++) {
434 object_to_routine_map_[id] = 110;
435 }
436 for (int id = 0xFA6; id <= 0xFA9; id++) {
437 object_to_routine_map_[id] = 87;
438 }
439 object_to_routine_map_[0xFAA] = 16;
440 object_to_routine_map_[0xFAB] = 110;
443 object_to_routine_map_[0xFAE] = 16;
444 object_to_routine_map_[0xFAF] = 110;
445 object_to_routine_map_[0xFB0] = 110;
446 object_to_routine_map_[0xFB1] = 114;
447 object_to_routine_map_[0xFB2] = 114;
448 object_to_routine_map_[0xFB3] = 86;
449 for (int id = 0xFB4; id <= 0xFB9; id++) {
450 object_to_routine_map_[id] = 16;
451 }
452 object_to_routine_map_[0xFBA] = 102;
453 object_to_routine_map_[0xFBB] = 102;
454 object_to_routine_map_[0xFBC] = 103;
455 object_to_routine_map_[0xFBD] = 103;
456 for (int id = 0xFBE; id <= 0xFC6; id++) {
457 object_to_routine_map_[id] = 110;
458 }
459 object_to_routine_map_[0xFC7] = 93;
460 object_to_routine_map_[0xFC8] = 16;
461 object_to_routine_map_[0xFC9] = 110;
462 object_to_routine_map_[0xFCA] = 110;
465 object_to_routine_map_[0xFCD] = 100;
466 object_to_routine_map_[0xFCE] = 30;
467 for (int id = 0xFCF; id <= 0xFD3; id++) {
468 object_to_routine_map_[id] = 110;
469 }
471 object_to_routine_map_[0xFD5] = 101;
472 for (int id = 0xFD6; id <= 0xFD9; id++) {
473 object_to_routine_map_[id] = 110;
474 }
476 object_to_routine_map_[0xFDB] = 101;
477 object_to_routine_map_[0xFDC] = 103;
478 object_to_routine_map_[0xFDD] = 100;
479 object_to_routine_map_[0xFDE] = 110;
480 object_to_routine_map_[0xFDF] = 110;
481 object_to_routine_map_[0xFE0] = 108;
482 object_to_routine_map_[0xFE1] = 108;
483 object_to_routine_map_[0xFE2] = 16;
484 for (int id = 0xFE3; id <= 0xFE5; id++) {
485 object_to_routine_map_[id] = 110;
486 }
487 object_to_routine_map_[0xFE6] = 116;
488 object_to_routine_map_[0xFE7] = 30;
489 object_to_routine_map_[0xFE8] = 30;
490 object_to_routine_map_[0xFE9] = 107;
491 object_to_routine_map_[0xFEA] = 107;
492 object_to_routine_map_[0xFEB] = 113;
493 object_to_routine_map_[0xFEC] = 114;
494 object_to_routine_map_[0xFED] = 114;
495 object_to_routine_map_[0xFEE] = 107;
496 object_to_routine_map_[0xFEF] = 107;
497 object_to_routine_map_[0xFF0] = 104;
498 object_to_routine_map_[0xFF1] = 105;
499 object_to_routine_map_[0xFF2] = 106;
500 object_to_routine_map_[0xFF3] = 38;
502 object_to_routine_map_[0xFF5] = 110;
505 object_to_routine_map_[0xFF8] = 109;
506 object_to_routine_map_[0xFF9] = 30;
507 object_to_routine_map_[0xFFA] = 16;
509 for (int id = 0xFFC; id <= 0xFFE; id++) {
510 object_to_routine_map_[id] = 110;
511 }
512 object_to_routine_map_[0xFFF] = 38;
513}
514
515} // namespace zelda3
516} // namespace yaze
static Flags & get()
Definition features.h:119
Unified draw routine registry.
const DrawRoutineInfo * GetRoutineInfo(int routine_id) const
bool GetRoutineDimensions(int routine_id, int *base_width, int *base_height) const
std::unordered_map< int16_t, int > object_to_routine_map_
bool RoutineDrawsToBothBGs(int routine_id) const
std::unordered_map< int, const DrawRoutineInfo * > routine_map_
int GetRoutineIdForObject(int16_t object_id) const
std::vector< DrawRoutineInfo > routines_
static DrawRoutineRegistry & Get()
void RegisterDiagonalRoutines(std::vector< DrawRoutineInfo > &registry)
Register all diagonal draw routines to the registry.
void RegisterCornerRoutines(std::vector< DrawRoutineInfo > &registry)
Register all corner draw routines to the registry.
void RegisterDownwardsRoutines(std::vector< DrawRoutineInfo > &registry)
Register all downwards draw routines to the registry.
void RegisterRightwardsRoutines(std::vector< DrawRoutineInfo > &registry)
Register all rightwards draw routines to the registry.
void RegisterSpecialRoutines(std::vector< DrawRoutineInfo > &registry)
Register all special/miscellaneous draw routines to the registry.
Metadata about a draw routine.