yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
object_renderer.cc
Go to the documentation of this file.
2
3#include "app/gfx/arena.h"
4
5namespace yaze {
6namespace zelda3 {
7
8void DungeonObjectRenderer::LoadObject(uint32_t routine_ptr,
9 std::array<uint8_t, 16>& sheet_ids) {
10 vram_.sheets = sheet_ids;
11
12 rom_data_ = rom()->vector();
13 snes_.memory().Initialize(rom_data_);
14
15 // Configure the object based on the fetched information
17
18 // Run the CPU emulation for the object's draw routines
19 RenderObject(routine_ptr);
20}
21
23 snes_.cpu().A = 0x03D8;
24 snes_.cpu().X = 0x03D8;
25 snes_.cpu().DB = 0x7E;
26 // VRAM target destinations
27 snes_.cpu().WriteLong(0xBF, 0x7E2000);
28 snes_.cpu().WriteLong(0xCB, 0x7E2080);
29 snes_.cpu().WriteLong(0xC2, 0x7E2002);
30 snes_.cpu().WriteLong(0xCE, 0x7E2082);
31 snes_.cpu().SetAccumulatorSize(false);
32 snes_.cpu().SetIndexSize(false);
33}
34
62void DungeonObjectRenderer::RenderObject(uint32_t routine_ptr) {
63 snes_.cpu().PB = 0x01;
64 snes_.cpu().PC = routine_ptr;
65
66 // Set up initial state for object drawing
67 snes_.cpu().Y = 0; // Start at the beginning of the tilemap
68 snes_.cpu().D = 0x7E; // Direct page register for memory access
69
70 // Push return address to stack
71 snes_.cpu().PushLong(0x01 << 16 | 0xFFFF); // Push a dummy return address
72
73 // Set up a maximum instruction count to prevent infinite loops
74 const int MAX_INSTRUCTIONS = 10000;
75 int instruction_count = 0;
76
77 // Execute instructions until we hit a return instruction or max count
78 while (instruction_count < MAX_INSTRUCTIONS) {
79 uint8_t opcode =
80 snes_.cpu().ReadByte(snes_.cpu().PB << 16 | snes_.cpu().PC);
81
82 // Check for RTS (Return from Subroutine) instruction
83 if (opcode == 0x60) {
84 // Execute the RTS instruction
85 snes_.cpu().ExecuteInstruction(opcode);
86 break; // Exit the loop after RTS
87 }
88
89 // Execute the instruction
90 snes_.cpu().ExecuteInstruction(opcode);
91 instruction_count++;
92 }
93
94 // If we hit the max instruction count, log a warning
95 if (instruction_count >= MAX_INSTRUCTIONS) {
96 std::cerr << "Warning: Object rendering hit maximum instruction count"
97 << std::endl;
98 }
99
101}
102
103// In the underworld, this holds a copy of the entire BG tilemap for
104// Layer 1 (BG2) in TILEMAPA
105// Layer 2 (BG1) in TILEMAPB
107 // Initialize the tilemap with zeros
108 tilemap_.resize(0x2000, 0);
109
110 // Iterate over tilemap in memory to read tile IDs
111 for (int tile_index = 0; tile_index < 512; tile_index++) {
112 // Read the tile ID from memory
113 uint16_t tile_id = snes_.memory().ReadWord(0x7E2000 + tile_index * 2);
114
115 // Skip empty tiles (0x0000)
116 if (tile_id == 0) continue;
117
118 // Calculate sheet number (each sheet contains 32 tiles)
119 int sheet_number = tile_id / 32;
120
121 // Ensure sheet number is valid
122 if (sheet_number >= vram_.sheets.size()) {
123 std::cerr << "Warning: Invalid sheet number " << sheet_number
124 << std::endl;
125 continue;
126 }
127
128 // Calculate position in the tilemap
129 int tile_x = (tile_index % 32) * 8;
130 int tile_y = (tile_index / 32) * 8;
131
132 // Get the graphics sheet
133 auto& sheet =
134 gfx::Arena::Get().mutable_gfx_sheets()->at(vram_.sheets[sheet_number]);
135
136 // Calculate the offset in the tilemap
137 int tilemap_offset = tile_y * 256 + tile_x;
138
139 // Copy the tile from the graphics sheet to the tilemap
140 sheet.Get8x8Tile(tile_id % 32, 0, 0, tilemap_, tilemap_offset);
141 }
142}
143
144} // namespace zelda3
145} // namespace yaze
auto mutable_gfx_sheets()
Definition arena.h:32
static Arena & Get()
Definition arena.cc:10
void UpdateObjectBitmap()
Updates the bitmap with the rendered object.
void RenderObject(uint32_t routine_ptr)
Executes the object drawing routine.
void LoadObject(uint32_t routine_ptr, std::array< uint8_t, 16 > &sheet_ids)
Loads and renders a dungeon object.
void ConfigureObject()
Configures the CPU state for object rendering.
Zelda 3 specific classes and functions.
Main namespace for the application.
Definition controller.cc:18