yaze 0.3.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;
227} BgLayer;
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 {
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);
261 // Set to BGRX format (0) for compatibility with SDL_PIXELFORMAT_ARGB8888
262 // Format 0 = BGRX: [B][G][R][A] byte order in memory (little-endian)
264 }
265
266 void Reset();
267 void HandleFrameStart();
268 void RunLine(int line);
269 void HandlePixel(int x, int y);
270
271 void LatchHV() {
272 h_count_ = memory_.h_pos() / 4;
274 counters_latched_ = true;
275 }
276
277 int GetPixel(int x, int y, bool sub, int* r, int* g, int* b);
278
279 void EvaluateSprites(int line);
280
281 void CalculateMode7Starts(int y);
282
283 bool GetWindowState(int layer, int x);
284
285 // if we are overscanning this frame (determined at 0,225)
286 bool frame_overscan_ = false;
287 bool overscan_ = false;
288
289 // settings
291 uint8_t brightness;
292 uint8_t mode;
297 bool frame_interlace; // if we are interlacing this frame (determined at
298 // start vblank)
300
303 return frame_overscan_;
304 }
305
306 void HandleVblank();
307 void HandleOPT(int layer, int* lx, int* ly);
308 uint16_t GetOffsetValue(int col, int row);
309 int GetPixelForBgLayer(int x, int y, int layer, bool priority);
310
311 uint8_t Read(uint8_t adr, bool latch);
312 void Write(uint8_t adr, uint8_t val);
313
314 uint16_t GetVramRemap();
315
316 void PutPixels(uint8_t* pixel_data);
317
318 // Returns the pixel data for the current frame
319 const std::vector<uint8_t>& GetFrameBuffer() const { return frame_buffer_; }
320
321 // Set pixel output format (0 = BGRX, 1 = XBGR)
322 void SetPixelFormat(uint8_t format) { pixelOutputFormat = format; }
323
324 int GetPixelForMode7(int x, int layer, bool priority);
325
326 const int cyclesPerScanline = 341; // SNES PPU has 341 cycles per scanline
327 const int totalScanlines = 262; // SNES PPU has 262 scanlines per frame
328 const int visibleScanlines = 224; // SNES PPU renders 224 visible scanlines
329
331
334
335 // vram access
336 uint16_t vram[0x8000];
337 uint16_t vram_pointer;
342
343 // cgram access
344 uint16_t cgram[0x100];
345
346 private:
347
351
352 // oam access
353 uint16_t oam[0x100];
354 uint8_t high_oam_[0x20];
355 uint8_t oam_adr_;
360 uint8_t oam_buffer_;
361
362 // Objects / Sprites
363 bool time_over_ = false;
364 bool range_over_ = false;
369 uint8_t obj_size_;
370 std::array<uint8_t, 256> obj_pixel_buffer_;
371 std::array<uint8_t, 256> obj_priority_buffer_;
372
373 // Color Math
374 uint8_t clip_mode_ = 0;
376 bool math_enabled_array_[6] = {false, false, false, false, false, false};
377 bool add_subscreen_ = false;
383
384 // layers
386
387 // mode 7
388 int16_t m7matrix[8]; // a, b, c, d, x, y, h, v
389 uint8_t m7prev;
395
396 // mode 7 internal
397 int32_t m7startX;
398 int32_t m7startY;
399
400 // windows
402 uint8_t window1left;
404 uint8_t window2left;
406
407 // Background Layers
408 std::array<BackgroundLayer, 4> bg_layers_;
409 uint8_t mosaic_startline_ = 1;
410
415
416 // pixel buffer (xbgr)
417 // times 2 for even and odd frame
418 uint8_t pixelBuffer[512 * 4 * 239 * 2];
419 uint8_t pixelOutputFormat = 0;
420
421 // latching
422 uint16_t h_count_;
423 uint16_t v_count_;
429
433 uint16_t screen_brightness_ = 0x00;
434
436
439 std::vector<SpriteAttributes> sprites_;
440 std::vector<uint8_t> tile_data_;
441 std::vector<uint8_t> frame_buffer_;
442
443 // PPU registers
447 std::array<BGSC, 4> bgsc_;
448 std::array<BGNBA, 4> bgnba_;
449 std::array<BGHOFS, 4> bghofs_;
450 std::array<BGVOFS, 4> bgvofs_;
451};
452
453} // namespace emu
454} // namespace yaze
455
456#endif // YAZE_APP_EMU_PPU_H
Memory interface.
Definition memory.h:64
virtual auto h_pos() const -> uint16_t=0
virtual auto v_pos() const -> uint16_t=0
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:337
std::vector< uint8_t > tile_data_
Definition ppu.h:440
uint8_t obj_size_
Definition ppu.h:369
void LatchHV()
Definition ppu.h:271
void HandleOPT(int layer, int *lx, int *ly)
Definition ppu.cc:370
void HandlePixel(int x, int y)
Definition ppu.cc:157
void EvaluateSprites(int line)
Definition ppu.cc:486
bool direct_color_
Definition ppu.h:299
std::vector< SpriteAttributes > sprites_
Definition ppu.h:439
bool m7largeField
Definition ppu.h:390
uint16_t obj_tile_adr1_
Definition ppu.h:367
int32_t m7startX
Definition ppu.h:397
uint8_t ppu1_open_bus_
Definition ppu.h:427
uint8_t pixelBuffer[512 *4 *239 *2]
Definition ppu.h:418
uint16_t screen_brightness_
Definition ppu.h:433
uint8_t scroll_prev2_
Definition ppu.h:413
uint8_t vram_remap_mode_
Definition ppu.h:340
int GetPixel(int x, int y, bool sub, int *r, int *g, int *b)
Definition ppu.cc:244
bool enable_forced_blanking_
Definition ppu.h:330
BgLayer bg_layer_[4]
Definition ppu.h:411
uint16_t tilemap_base_address_
Definition ppu.h:432
bool counters_latched_
Definition ppu.h:426
uint8_t oam_buffer_
Definition ppu.h:360
uint8_t oam_adr_
Definition ppu.h:355
void SetPixelFormat(uint8_t format)
Definition ppu.h:322
OAMAddress oam_address_
Definition ppu.h:445
bool m7charFill
Definition ppu.h:391
bool pseudo_hires_
Definition ppu.h:295
bool frame_interlace
Definition ppu.h:297
bool v_count_second_
Definition ppu.h:425
bool m7yFlip
Definition ppu.h:393
bool forced_blank_
Definition ppu.h:290
std::array< BGVOFS, 4 > bgvofs_
Definition ppu.h:450
uint8_t prevent_math_mode_
Definition ppu.h:375
void Reset()
Definition ppu.cc:39
bool GetWindowState(int layer, int x)
Definition ppu.cc:340
void CalculateMode7Starts(int y)
Definition ppu.cc:581
uint8_t m7prev
Definition ppu.h:389
bool subtract_color_
Definition ppu.h:378
uint16_t oam[0x100]
Definition ppu.h:353
uint8_t oam_adr_written_
Definition ppu.h:356
bool vram_increment_on_high_
Definition ppu.h:338
uint8_t scroll_prev_
Definition ppu.h:412
uint8_t clip_mode_
Definition ppu.h:374
uint8_t high_oam_[0x20]
Definition ppu.h:354
uint16_t vram_base_address_
Definition ppu.h:431
Mosaic mosaic_
Definition ppu.h:446
void HandleFrameStart()
Definition ppu.cc:137
void Write(uint8_t adr, uint8_t val)
Definition ppu.cc:747
std::array< BGHOFS, 4 > bghofs_
Definition ppu.h:449
std::array< BGNBA, 4 > bgnba_
Definition ppu.h:448
uint16_t h_count_
Definition ppu.h:422
int current_scanline_
Definition ppu.h:333
std::array< BackgroundLayer, 4 > bg_layers_
Definition ppu.h:408
std::array< uint8_t, 256 > obj_pixel_buffer_
Definition ppu.h:370
uint16_t vram_increment_
Definition ppu.h:339
bool obj_priority_
Definition ppu.h:366
const int totalScanlines
Definition ppu.h:327
void PutPixels(uint8_t *pixel_data)
Definition ppu.cc:1052
std::array< uint8_t, 256 > obj_priority_buffer_
Definition ppu.h:371
bool time_over_
Definition ppu.h:363
uint8_t Read(uint8_t adr, bool latch)
Definition ppu.cc:612
uint8_t mosaic_startline_
Definition ppu.h:409
uint8_t window2left
Definition ppu.h:404
bool frame_overscan_
Definition ppu.h:286
bool CheckOverscan()
Definition ppu.h:301
bool even_frame
Definition ppu.h:294
bool interlace
Definition ppu.h:296
uint16_t obj_tile_adr2_
Definition ppu.h:368
bool oam_in_high_written_
Definition ppu.h:358
void Init()
Definition ppu.h:259
Memory & memory_
Definition ppu.h:435
Layer layer_[5]
Definition ppu.h:385
uint8_t fixed_color_g_
Definition ppu.h:381
bool oam_in_high_
Definition ppu.h:357
bool oam_second_write_
Definition ppu.h:359
bool obj_interlace_
Definition ppu.h:365
bool h_count_second_
Definition ppu.h:424
int cycle_count_
Definition ppu.h:332
uint8_t mode
Definition ppu.h:292
bool m7xFlip
Definition ppu.h:392
Tilemap tilemap_
Definition ppu.h:437
const std::vector< uint8_t > & GetFrameBuffer() const
Definition ppu.h:319
uint8_t window2right
Definition ppu.h:405
uint8_t pixelOutputFormat
Definition ppu.h:419
uint16_t GetOffsetValue(int col, int row)
Definition ppu.cc:405
uint16_t tile_data_size_
Definition ppu.h:430
uint8_t window1left
Definition ppu.h:402
uint16_t vram[0x8000]
Definition ppu.h:336
int16_t m7matrix[8]
Definition ppu.h:388
void HandleVblank()
Definition ppu.cc:602
const int visibleScanlines
Definition ppu.h:328
bool half_color_
Definition ppu.h:379
uint8_t ppu2_open_bus_
Definition ppu.h:428
Ppu(Memory &memory)
Definition ppu.h:256
bool add_subscreen_
Definition ppu.h:377
BackgroundMode bg_mode_
Definition ppu.h:438
uint8_t mosaic_size_
Definition ppu.h:414
bool m7extBg
Definition ppu.h:394
const int cyclesPerScanline
Definition ppu.h:326
std::vector< uint8_t > frame_buffer_
Definition ppu.h:441
uint8_t cgram_buffer_
Definition ppu.h:350
bool range_over_
Definition ppu.h:364
uint8_t fixed_color_b_
Definition ppu.h:382
uint8_t cgram_pointer_
Definition ppu.h:348
std::array< BGSC, 4 > bgsc_
Definition ppu.h:447
bool math_enabled_array_[6]
Definition ppu.h:376
int GetPixelForBgLayer(int x, int y, int layer, bool priority)
Definition ppu.cc:419
bool overscan_
Definition ppu.h:287
int32_t m7startY
Definition ppu.h:398
uint16_t GetVramRemap()
Definition ppu.cc:1037
int GetPixelForMode7(int x, int layer, bool priority)
Definition ppu.cc:321
uint16_t cgram[0x100]
Definition ppu.h:344
uint8_t fixed_color_r_
Definition ppu.h:380
uint8_t window1right
Definition ppu.h:403
uint16_t v_count_
Definition ppu.h:423
OAMSize oam_size_
Definition ppu.h:444
WindowLayer windowLayer[6]
Definition ppu.h:401
uint16_t vram_read_buffer_
Definition ppu.h:341
bool cgram_second_write_
Definition ppu.h:349
void RunLine(int line)
Definition ppu.cc:145
bool bg3priority
Definition ppu.h:293
uint8_t brightness
Definition ppu.h:291
BackgroundMode
Definition ppu.h:25
SpriteSize
Definition ppu.h:38
Main namespace for the application.
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