yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
ppu.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EMU_PPU_H
2#define YAZE_APP_EMU_PPU_H
3
4#include <array>
5#include <cstdint>
6#include <vector>
7
10#include "app/rom.h"
11
12namespace yaze {
13namespace emu {
14
16 public:
17 virtual ~PpuInterface() = default;
18
19 // Memory Interactions
20 virtual void Write(uint16_t address, uint8_t data) = 0;
21 virtual uint8_t Read(uint16_t address) const = 0;
22};
23
24// Enum representing different background modes
25enum class BackgroundMode {
26 Mode0, // 4 layers, each 2bpp (4 colors)
27 Mode1, // 2 layers, 4bpp (16 colors), 1 layer, 2bpp (4 colors)
28 Mode2, // 2 layers, 4bpp (16 colors), 1 layer for offset-per-tile
29 Mode3, // 1 layer, 8bpp (256 colors), 1 layer, 4bpp (16 colors)
30 Mode4, // 1 layer, 8bpp (256 colors), 1 layer, 2bpp (4 colors)
31 // 1 layer for offset-per-tile
32 Mode5, // 1 layer, 4bpp (16 colors), 1 layer, 2bpp (4 colors) hi-res
33 Mode6, // 1 layer, 4bpp (16 colors), 1 layer for offset-per-tile, hi-res
34 Mode7, // 1 layer, 8bpp (256 colors), rotation/scaling
35};
36
37// Enum representing sprite sizes
39
40// Struct representing a sprite's attributes
42 uint8_t x; // X position of the sprite
43 uint8_t y; // Y position of the sprite
44 uint16_t tile; // Tile number for the sprite
45 uint8_t palette; // Palette number for the sprite
46 uint8_t priority; // Priority for the sprite
47 bool hFlip; // Horizontal flip flag
48 bool vFlip; // Vertical flip flag
49};
50
51// Struct representing a tilemap entry
53 uint16_t tileNumber; // Tile number for the tile
54 uint8_t palette; // Palette number for the tile
55 uint8_t priority; // Priority for the tile
56 bool hFlip; // Horizontal flip flag
57 bool vFlip; // Vertical flip flag
58};
59
60// Struct representing a tilemap
61struct Tilemap {
62 std::vector<TilemapEntry> entries; // Entries for the tilemap
63};
64
65// Struct representing a color
66struct Color {
67 uint8_t r; // Red component
68 uint8_t g; // Green component
69 uint8_t b; // Blue component
70};
71
72// Registers
73struct OAMSize {
74 uint8_t base_selection : 3;
75 uint8_t name_selection : 2;
76 uint8_t object_size : 3;
77};
78
79struct OAMAddress {
80 uint8_t oam_address_low : 8;
81 uint8_t oam_address_msb : 1;
83 uint8_t unused : 6;
84};
85
87 uint8_t SC_size : 2;
88 uint8_t tile_map_address : 5;
89 uint8_t unused : 1;
90};
91
93 uint8_t BG1_address : 4;
94 uint8_t BG2_address : 4;
95 uint8_t BG3_address : 4;
96 uint8_t BG4_address : 4;
97};
98
100 uint8_t increment_rate : 2;
101 uint8_t full_graphic : 2;
102 uint8_t increment_mode : 1;
103 uint8_t unused : 3;
104};
105
107 uint8_t brightness : 4;
108 uint8_t disable_screen : 1;
109 uint8_t unused : 3;
110};
111
114 uint8_t priority : 1;
115 uint8_t BG1_tile_size : 1;
116 uint8_t BG2_tile_size : 1;
117 uint8_t BG3_tile_size : 1;
118 uint8_t BG4_tile_size : 1;
119};
120
122 uint8_t offset : 8;
123 uint8_t mode7_bits : 3;
124 uint8_t unused : 5;
125};
126
128 uint8_t BG1_enable : 1;
129 uint8_t BG2_enable : 1;
130 uint8_t BG3_enable : 1;
131 uint8_t BG4_enable : 1;
132 uint8_t sprites_enable : 1;
133 uint8_t unused : 3;
134};
135
137 uint8_t BG1_clip_in_out : 1;
138 uint8_t BG1_enable : 1;
139 uint8_t BG2_clip_in_out : 1;
140 uint8_t BG2_enable : 1;
141 uint8_t BG3_clip_in_out : 1;
142 uint8_t BG3_enable : 1;
143 uint8_t BG4_clip_in_out : 1;
144 uint8_t BG4_enable : 1;
145};
146
149 uint8_t sprites_enable : 1;
152 uint8_t unused : 4;
153};
154
156 uint8_t position : 8;
157};
158
160 uint8_t BG1_mask_logic : 2;
161 uint8_t BG2_mask_logic : 2;
162 uint8_t BG3_mask_logic : 2;
163 uint8_t BG4_mask_logic : 2;
164};
165
166// Counter/IRQ/NMI Registers
168 uint8_t softwareLatchHvCounter; // Register $2137
169 uint16_t horizontalScanLocation; // Register $213C
170 uint16_t verticalScanLocation; // Register $213D
171 uint8_t counterEnable; // Register $4200
172 uint16_t horizontalIrqTrigger; // Register $4207/$4208
173 uint16_t verticalIrqTrigger; // Register $4209/$420A
174 uint8_t nmiRegister; // Register $4210
175 uint8_t irqRegister; // Register $4211
176 uint8_t statusRegisterIrq; // Register $4212
177};
178
179// Joypad Registers
181 uint16_t joypadData[4]; // Register $4218 to $421F
182 uint8_t oldStyleJoypadRegisters[2]; // Registers $4016/$4217
183};
184
185// DMA Registers
187 uint8_t startDmaTransfer; // Register $420B
188 uint8_t enableHDmaTransfer; // Register $420C
189 uint8_t dmacontrol_register_ister[8]; // Register $43?0
190 uint8_t dmaDestinationAddress[8]; // Register $43?1
191 uint32_t dmaSourceAddress[8]; // Register $43?2/$43?3/$43?4
192 uint16_t bytesToTransfer[8]; // Register $43?5/$43?6/$43?7
193 uint16_t hdmaCountPointer[8]; // Register $43?8/$43?9
194 uint8_t scanlinesLeft[8]; // Register $43?A
195};
196
197// WRAM access Registers
199 uint8_t dataByte; // Register $2180
200 uint32_t address; // Register $2181/$2182/$2183
201};
202
203struct Tile {
204 uint16_t index; // Index of the tile in VRAM
205 uint8_t palette; // Palette number used for this tile
206 bool flip_x; // Horizontal flip flag
207 bool flip_y; // Vertical flip flag
208 uint8_t priority; // Priority of this tile
209};
210
217
218typedef struct BgLayer {
219 uint16_t hScroll;
220 uint16_t vScroll;
223 uint16_t tilemapAdr;
224 uint16_t tileAdr;
228
236
239
240 enum class ColorDepth { BPP_2, BPP_4, BPP_8 };
241
242 Size size; // Size of the background layer
243 ColorDepth color_depth; // Color depth of the background layer
244 std::vector<Tile> tilemap; // Tilemap data
245 std::vector<uint8_t> tile_data; // Tile data in VRAM
246 uint16_t tilemap_base_address; // Base address of the tilemap in VRAM
247 uint16_t tile_data_base_address; // Base address of the tile data in VRAM
248 uint8_t scroll_x; // Horizontal scroll offset
249 uint8_t scroll_y; // Vertical scroll offset
250 bool enabled; // Whether the background layer is enabled
251};
252
253class Ppu : public SharedRom {
254 public:
255 // Initializes the PPU with the necessary resources and dependencies
256 Ppu(Memory& memory) : memory_(memory) {}
257
258 // Initialize the frame buffer
259 void Init() {
260 frame_buffer_.resize(256 * 240, 0);
262 }
263
264 void Reset();
265 void HandleFrameStart();
266 void RunLine(int line);
267 void HandlePixel(int x, int y);
268
269 void LatchHV() {
270 h_count_ = memory_.h_pos() / 4;
271 v_count_ = memory_.v_pos();
272 counters_latched_ = true;
273 }
274
275 int GetPixel(int x, int y, bool sub, int* r, int* g, int* b);
276
277 void EvaluateSprites(int line);
278
279 void CalculateMode7Starts(int y);
280
281 bool GetWindowState(int layer, int x);
282
283 // if we are overscanning this frame (determined at 0,225)
284 bool frame_overscan_ = false;
285 bool overscan_ = false;
286
287 // settings
289 uint8_t brightness;
290 uint8_t mode;
295 bool frame_interlace; // if we are interlacing this frame (determined at
296 // start vblank)
298
301 return frame_overscan_;
302 }
303
304 void HandleVblank();
305 void HandleOPT(int layer, int* lx, int* ly);
306 uint16_t GetOffsetValue(int col, int row);
307 int GetPixelForBgLayer(int x, int y, int layer, bool priority);
308
309 uint8_t Read(uint8_t adr, bool latch);
310 void Write(uint8_t adr, uint8_t val);
311
312 uint16_t GetVramRemap();
313
314 void PutPixels(uint8_t* pixel_data);
315
316 // Returns the pixel data for the current frame
317 const std::vector<uint8_t>& GetFrameBuffer() const { return frame_buffer_; }
318
319 private:
320 int GetPixelForMode7(int x, int layer, bool priority);
321
322 const int cyclesPerScanline = 341; // SNES PPU has 341 cycles per scanline
323 const int totalScanlines = 262; // SNES PPU has 262 scanlines per frame
324 const int visibleScanlines = 224; // SNES PPU renders 224 visible scanlines
325
327
330
331 // vram access
332 uint16_t vram[0x8000];
333 uint16_t vram_pointer;
338
339 // cgram access
340 uint16_t cgram[0x100];
344
345 // oam access
346 uint16_t oam[0x100];
347 uint8_t high_oam_[0x20];
348 uint8_t oam_adr_;
353 uint8_t oam_buffer_;
354
355 // Objects / Sprites
356 bool time_over_ = false;
357 bool range_over_ = false;
362 uint8_t obj_size_;
363 std::array<uint8_t, 256> obj_pixel_buffer_;
364 std::array<uint8_t, 256> obj_priority_buffer_;
365
366 // Color Math
367 uint8_t clip_mode_ = 0;
369 bool math_enabled_array_[6] = {false, false, false, false, false, false};
370 bool add_subscreen_ = false;
376
377 // layers
379
380 // mode 7
381 int16_t m7matrix[8]; // a, b, c, d, x, y, h, v
382 uint8_t m7prev;
388
389 // mode 7 internal
390 int32_t m7startX;
391 int32_t m7startY;
392
393 // windows
395 uint8_t window1left;
397 uint8_t window2left;
399
400 // Background Layers
401 std::array<BackgroundLayer, 4> bg_layers_;
402 uint8_t mosaic_startline_ = 1;
403
408
409 // pixel buffer (xbgr)
410 // times 2 for even and odd frame
411 uint8_t pixelBuffer[512 * 4 * 239 * 2];
412 uint8_t pixelOutputFormat = 0;
413
414 // latching
415 uint16_t h_count_;
416 uint16_t v_count_;
422
426 uint16_t screen_brightness_ = 0x00;
427
429
432 std::vector<SpriteAttributes> sprites_;
433 std::vector<uint8_t> tile_data_;
434 std::vector<uint8_t> frame_buffer_;
435
436 // PPU registers
440 std::array<BGSC, 4> bgsc_;
441 std::array<BGNBA, 4> bgnba_;
442 std::array<BGHOFS, 4> bghofs_;
443 std::array<BGVOFS, 4> bgvofs_;
444};
445
446} // namespace emu
447} // namespace yaze
448
449#endif // YAZE_APP_EMU_PPU_H
SharedRom()=default
Memory interface.
Definition memory.h:64
virtual void Write(uint16_t address, uint8_t data)=0
virtual ~PpuInterface()=default
virtual uint8_t Read(uint16_t address) const =0
uint16_t vram_pointer
Definition ppu.h:333
std::vector< uint8_t > tile_data_
Definition ppu.h:433
uint8_t obj_size_
Definition ppu.h:362
void LatchHV()
Definition ppu.h:269
void HandleOPT(int layer, int *lx, int *ly)
Definition ppu.cc:350
void HandlePixel(int x, int y)
Definition ppu.cc:157
void EvaluateSprites(int line)
Definition ppu.cc:466
bool direct_color_
Definition ppu.h:297
std::vector< SpriteAttributes > sprites_
Definition ppu.h:432
bool m7largeField
Definition ppu.h:383
uint16_t obj_tile_adr1_
Definition ppu.h:360
int32_t m7startX
Definition ppu.h:390
uint8_t ppu1_open_bus_
Definition ppu.h:420
uint8_t pixelBuffer[512 *4 *239 *2]
Definition ppu.h:411
uint16_t screen_brightness_
Definition ppu.h:426
uint8_t scroll_prev2_
Definition ppu.h:406
uint8_t vram_remap_mode_
Definition ppu.h:336
int GetPixel(int x, int y, bool sub, int *r, int *g, int *b)
Definition ppu.cc:224
bool enable_forced_blanking_
Definition ppu.h:326
BgLayer bg_layer_[4]
Definition ppu.h:404
uint16_t tilemap_base_address_
Definition ppu.h:425
bool counters_latched_
Definition ppu.h:419
uint8_t oam_buffer_
Definition ppu.h:353
uint8_t oam_adr_
Definition ppu.h:348
OAMAddress oam_address_
Definition ppu.h:438
bool m7charFill
Definition ppu.h:384
bool pseudo_hires_
Definition ppu.h:293
bool frame_interlace
Definition ppu.h:295
bool v_count_second_
Definition ppu.h:418
bool m7yFlip
Definition ppu.h:386
bool forced_blank_
Definition ppu.h:288
std::array< BGVOFS, 4 > bgvofs_
Definition ppu.h:443
uint8_t prevent_math_mode_
Definition ppu.h:368
void Reset()
Definition ppu.cc:39
bool GetWindowState(int layer, int x)
Definition ppu.cc:320
void CalculateMode7Starts(int y)
Definition ppu.cc:561
uint8_t m7prev
Definition ppu.h:382
bool subtract_color_
Definition ppu.h:371
uint16_t oam[0x100]
Definition ppu.h:346
uint8_t oam_adr_written_
Definition ppu.h:349
bool vram_increment_on_high_
Definition ppu.h:334
uint8_t scroll_prev_
Definition ppu.h:405
uint8_t clip_mode_
Definition ppu.h:367
uint8_t high_oam_[0x20]
Definition ppu.h:347
uint16_t vram_base_address_
Definition ppu.h:424
Mosaic mosaic_
Definition ppu.h:439
void HandleFrameStart()
Definition ppu.cc:137
void Write(uint8_t adr, uint8_t val)
Definition ppu.cc:727
std::array< BGHOFS, 4 > bghofs_
Definition ppu.h:442
std::array< BGNBA, 4 > bgnba_
Definition ppu.h:441
uint16_t h_count_
Definition ppu.h:415
int current_scanline_
Definition ppu.h:329
std::array< BackgroundLayer, 4 > bg_layers_
Definition ppu.h:401
std::array< uint8_t, 256 > obj_pixel_buffer_
Definition ppu.h:363
uint16_t vram_increment_
Definition ppu.h:335
bool obj_priority_
Definition ppu.h:359
const int totalScanlines
Definition ppu.h:323
void PutPixels(uint8_t *pixel_data)
Definition ppu.cc:1032
std::array< uint8_t, 256 > obj_priority_buffer_
Definition ppu.h:364
bool time_over_
Definition ppu.h:356
uint8_t Read(uint8_t adr, bool latch)
Definition ppu.cc:592
uint8_t mosaic_startline_
Definition ppu.h:402
uint8_t window2left
Definition ppu.h:397
bool frame_overscan_
Definition ppu.h:284
bool CheckOverscan()
Definition ppu.h:299
bool even_frame
Definition ppu.h:292
bool interlace
Definition ppu.h:294
uint16_t obj_tile_adr2_
Definition ppu.h:361
bool oam_in_high_written_
Definition ppu.h:351
void Init()
Definition ppu.h:259
Memory & memory_
Definition ppu.h:428
Layer layer_[5]
Definition ppu.h:378
uint8_t fixed_color_g_
Definition ppu.h:374
bool oam_in_high_
Definition ppu.h:350
bool oam_second_write_
Definition ppu.h:352
bool obj_interlace_
Definition ppu.h:358
bool h_count_second_
Definition ppu.h:417
int cycle_count_
Definition ppu.h:328
uint8_t mode
Definition ppu.h:290
bool m7xFlip
Definition ppu.h:385
Tilemap tilemap_
Definition ppu.h:430
const std::vector< uint8_t > & GetFrameBuffer() const
Definition ppu.h:317
uint8_t window2right
Definition ppu.h:398
uint8_t pixelOutputFormat
Definition ppu.h:412
uint16_t GetOffsetValue(int col, int row)
Definition ppu.cc:385
uint16_t tile_data_size_
Definition ppu.h:423
uint8_t window1left
Definition ppu.h:395
uint16_t vram[0x8000]
Definition ppu.h:332
int16_t m7matrix[8]
Definition ppu.h:381
void HandleVblank()
Definition ppu.cc:582
const int visibleScanlines
Definition ppu.h:324
bool half_color_
Definition ppu.h:372
uint8_t ppu2_open_bus_
Definition ppu.h:421
Ppu(Memory &memory)
Definition ppu.h:256
bool add_subscreen_
Definition ppu.h:370
BackgroundMode bg_mode_
Definition ppu.h:431
uint8_t mosaic_size_
Definition ppu.h:407
bool m7extBg
Definition ppu.h:387
const int cyclesPerScanline
Definition ppu.h:322
std::vector< uint8_t > frame_buffer_
Definition ppu.h:434
uint8_t cgram_buffer_
Definition ppu.h:343
bool range_over_
Definition ppu.h:357
uint8_t fixed_color_b_
Definition ppu.h:375
uint8_t cgram_pointer_
Definition ppu.h:341
std::array< BGSC, 4 > bgsc_
Definition ppu.h:440
bool math_enabled_array_[6]
Definition ppu.h:369
int GetPixelForBgLayer(int x, int y, int layer, bool priority)
Definition ppu.cc:399
bool overscan_
Definition ppu.h:285
int32_t m7startY
Definition ppu.h:391
uint16_t GetVramRemap()
Definition ppu.cc:1017
int GetPixelForMode7(int x, int layer, bool priority)
Definition ppu.cc:301
uint16_t cgram[0x100]
Definition ppu.h:340
uint8_t fixed_color_r_
Definition ppu.h:373
uint8_t window1right
Definition ppu.h:396
uint16_t v_count_
Definition ppu.h:416
OAMSize oam_size_
Definition ppu.h:437
WindowLayer windowLayer[6]
Definition ppu.h:394
uint16_t vram_read_buffer_
Definition ppu.h:337
bool cgram_second_write_
Definition ppu.h:342
void RunLine(int line)
Definition ppu.cc:145
bool bg3priority
Definition ppu.h:291
uint8_t brightness
Definition ppu.h:289
SNES Emulation and debugging tools.
Definition apu.cc:13
struct yaze::emu::BgLayer BgLayer
BackgroundMode
Definition ppu.h:25
struct yaze::emu::WindowLayer WindowLayer
struct yaze::emu::Layer Layer
SpriteSize
Definition ppu.h:38
Main namespace for the application.
Definition controller.cc:18
uint16_t tilemap_base_address
Definition ppu.h:246
std::vector< Tile > tilemap
Definition ppu.h:244
ColorDepth color_depth
Definition ppu.h:243
std::vector< uint8_t > tile_data
Definition ppu.h:245
uint16_t tile_data_base_address
Definition ppu.h:247
bool tilemapHigher
Definition ppu.h:222
uint16_t vScroll
Definition ppu.h:220
bool mosaicEnabled
Definition ppu.h:226
uint16_t hScroll
Definition ppu.h:219
bool tilemapWider
Definition ppu.h:221
uint16_t tileAdr
Definition ppu.h:224
uint16_t tilemapAdr
Definition ppu.h:223
uint8_t r
Definition ppu.h:67
uint8_t g
Definition ppu.h:68
uint8_t b
Definition ppu.h:69
uint8_t scanlinesLeft[8]
Definition ppu.h:194
uint8_t startDmaTransfer
Definition ppu.h:187
uint16_t hdmaCountPointer[8]
Definition ppu.h:193
uint16_t bytesToTransfer[8]
Definition ppu.h:192
uint32_t dmaSourceAddress[8]
Definition ppu.h:191
uint8_t dmacontrol_register_ister[8]
Definition ppu.h:189
uint8_t enableHDmaTransfer
Definition ppu.h:188
uint8_t dmaDestinationAddress[8]
Definition ppu.h:190
uint16_t joypadData[4]
Definition ppu.h:181
uint8_t oldStyleJoypadRegisters[2]
Definition ppu.h:182
bool subScreenWindowed
Definition ppu.h:215
bool mainScreenWindowed
Definition ppu.h:214
bool subScreenEnabled
Definition ppu.h:213
bool mainScreenEnabled
Definition ppu.h:212
uint8_t oam_address_low
Definition ppu.h:80
uint8_t unused
Definition ppu.h:83
uint8_t oam_priority_rotation
Definition ppu.h:82
uint8_t oam_address_msb
Definition ppu.h:81
uint8_t name_selection
Definition ppu.h:75
uint8_t object_size
Definition ppu.h:76
uint8_t base_selection
Definition ppu.h:74
uint8_t disable_screen
Definition ppu.h:108
uint8_t general_screen_mode
Definition ppu.h:113
uint8_t BG2_tile_size
Definition ppu.h:116
uint8_t BG1_tile_size
Definition ppu.h:115
uint8_t BG3_tile_size
Definition ppu.h:117
uint8_t BG4_tile_size
Definition ppu.h:118
uint8_t priority
Definition ppu.h:114
uint8_t tile_map_address
Definition ppu.h:88
bool flip_x
Definition ppu.h:206
uint16_t index
Definition ppu.h:204
bool flip_y
Definition ppu.h:207
uint8_t palette
Definition ppu.h:205
uint8_t priority
Definition ppu.h:208
uint16_t tileNumber
Definition ppu.h:53
std::vector< TilemapEntry > entries
Definition ppu.h:62
uint8_t maskLogic
Definition ppu.h:234
uint8_t color_windows_clip_in_out
Definition ppu.h:150