yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
object_draw_code.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <set>
5
6#include "rom/rom.h"
7#include "rom/snes.h"
8
9namespace yaze::zelda3 {
10
11namespace {
12
14 uint32_t address;
16 int count;
17};
18
20 {0x018200, 0x000, 0xF8},
21 {0x018470, 0x100, 0x40},
22 {0x0185F0, 0xF80, 0x80},
23};
24constexpr uint32_t kMaxRoutineBytes = 0x100;
25constexpr uint8_t kJsl = 0x22;
26constexpr uint8_t kJml = 0x5C;
27constexpr uint8_t kFirstExpandedBank = 0x20;
28
29} // namespace
30
31std::vector<ObjectDrawCode> ReadObjectDrawCode(const Rom& rom) {
32 const auto& data = rom.vector();
33 auto byte_at = [&](uint32_t snes) -> int {
34 const uint32_t pc = SnesToPc(snes);
35 return pc < data.size() ? data[pc] : -1;
36 };
37
38 std::vector<ObjectDrawCode> out;
39 for (const auto& table : kDispatchTables) {
40 for (int i = 0; i < table.count; ++i) {
41 const uint32_t entry = table.address + static_cast<uint32_t>(i * 2);
42 const int lo = byte_at(entry);
43 const int hi = byte_at(entry + 1);
44 if (lo < 0 || hi < 0) {
45 return {};
46 }
47 ObjectDrawCode code;
48 code.object_id = table.first_object + i;
49 code.routine_start =
50 0x010000 | static_cast<uint32_t>(lo | (hi << 8)); // Bank $01.
51 out.push_back(code);
52 }
53 }
54
55 std::set<uint32_t> starts;
56 for (const auto& code : out) {
57 starts.insert(code.routine_start);
58 }
59 for (auto& code : out) {
60 auto next = starts.upper_bound(code.routine_start);
61 const uint32_t cap = code.routine_start + kMaxRoutineBytes;
62 code.routine_end = next == starts.end() ? cap : std::min(*next, cap);
63
64 const int opcode = byte_at(code.routine_start);
65 const int bank = byte_at(code.routine_start + 3);
66 if ((opcode == kJsl || opcode == kJml) && bank >= kFirstExpandedBank) {
67 code.jumps_to_expanded_code = true;
68 code.jump_target =
69 static_cast<uint32_t>(byte_at(code.routine_start + 1)) |
70 (static_cast<uint32_t>(byte_at(code.routine_start + 2)) << 8) |
71 (static_cast<uint32_t>(bank) << 16);
72 }
73 }
74 return out;
75}
76
77} // namespace yaze::zelda3
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:49
const auto & vector() const
Definition rom.h:205
Zelda 3 specific classes and functions.
std::vector< ObjectDrawCode > ReadObjectDrawCode(const Rom &rom)
uint32_t SnesToPc(uint32_t addr) noexcept
Definition snes.h:8
Where the loaded ROM's code draws one room object.