debug.rsannotateddebug.rssource149 lines · 5.7 KB · raw
1use crate::ppu;
2use crate::ppu::Ppu;
3use crate::ppu::registers::{BgMode, BitsPerPixel, Registers, TileSize};
4use jgenesis_common::frontend::Color;
5use jgenesis_common::num::GetBit;
6
7impl Ppu {
8    pub fn copy_cgram(&self, out: &mut [Color]) {
9        for (out_color, &cgram_color) in out.iter_mut().zip(self.cgram.as_ref()) {
10            *out_color = ppu::convert_snes_color(cgram_color, ppu::MAX_BRIGHTNESS);
11        }
12    }
13
14    #[allow(clippy::needless_range_loop)]
15    pub fn copy_vram_2bpp(&self, out: &mut [Color], palette: u8, row_len: usize) {
16        let mut registers = Registers::new();
17        registers.bg_mode = BgMode::One;
18        registers.bg_tile_size[0] = TileSize::Small;
19        registers.bg_tile_base_address[0] = 0;
20
21        for tile_number in 0..4096 {
22            let tile = ppu::get_bg_tile(
23                &self.vram,
24                &registers,
25                0,
26                0,
27                0,
28                BitsPerPixel::Two,
29                tile_number as u16,
30                false,
31                false,
32            );
33            let out_tile_idx = tile_number / row_len * row_len * 64 + (tile_number % row_len) * 8;
34
35            for row in 0..8 {
36                for col in 0..8 {
37                    let out_idx = out_tile_idx + row * row_len * 8 + col;
38
39                    let col_idx = 7 - col as u8;
40                    let mut snes_color = 0;
41                    snes_color |= u8::from(tile[row].bit(col_idx));
42                    snes_color |= u8::from(tile[row].bit(col_idx + 8)) << 1;
43
44                    let cgram_idx = (palette << 2) | snes_color;
45                    let color = if snes_color != 0 { self.cgram[cgram_idx as usize] } else { 0 };
46                    out[out_idx] = ppu::convert_snes_color(color, ppu::MAX_BRIGHTNESS);
47                }
48            }
49        }
50    }
51
52    pub fn copy_vram_4bpp(&self, out: &mut [Color], palette: u8, row_len: usize) {
53        let mut registers = Registers::new();
54        registers.bg_mode = BgMode::One;
55        registers.bg_tile_size[0] = TileSize::Small;
56        registers.bg_tile_base_address[0] = 0;
57
58        for tile_number in 0..2048 {
59            let tile = ppu::get_bg_tile(
60                &self.vram,
61                &registers,
62                0,
63                0,
64                0,
65                BitsPerPixel::Four,
66                tile_number as u16,
67                false,
68                false,
69            );
70            let out_tile_idx = tile_number / row_len * row_len * 64 + (tile_number % row_len) * 8;
71
72            for row in 0..8 {
73                for col in 0..8 {
74                    let out_idx = out_tile_idx + row * row_len * 8 + col;
75
76                    let col_idx = 7 - col as u8;
77                    let mut snes_color = 0;
78                    snes_color |= u8::from(tile[row].bit(col_idx));
79                    snes_color |= u8::from(tile[row].bit(col_idx + 8)) << 1;
80                    snes_color |= u8::from(tile[row + 8].bit(col_idx)) << 2;
81                    snes_color |= u8::from(tile[row + 8].bit(col_idx + 8)) << 3;
82
83                    let cgram_idx = (palette << 4) | snes_color;
84                    let color = if snes_color != 0 { self.cgram[cgram_idx as usize] } else { 0 };
85                    out[out_idx] = ppu::convert_snes_color(color, ppu::MAX_BRIGHTNESS);
86                }
87            }
88        }
89    }
90
91    pub fn copy_vram_8bpp(&self, out: &mut [Color], row_len: usize) {
92        let mut registers = Registers::new();
93        registers.bg_mode = BgMode::One;
94        registers.bg_tile_size[0] = TileSize::Small;
95        registers.bg_tile_base_address[0] = 0;
96
97        for tile_number in 0..1024 {
98            let tile = ppu::get_bg_tile(
99                &self.vram,
100                &registers,
101                0,
102                0,
103                0,
104                BitsPerPixel::Eight,
105                tile_number as u16,
106                false,
107                false,
108            );
109            let out_tile_idx = tile_number / row_len * row_len * 64 + (tile_number % row_len) * 8;
110
111            for row in 0..8 {
112                for col in 0..8 {
113                    let out_idx = out_tile_idx + row * row_len * 8 + col;
114
115                    let col_idx = 7 - col as u8;
116                    let mut snes_color = 0;
117                    snes_color |= u8::from(tile[row].bit(col_idx));
118                    snes_color |= u8::from(tile[row].bit(col_idx + 8)) << 1;
119                    snes_color |= u8::from(tile[row + 8].bit(col_idx)) << 2;
120                    snes_color |= u8::from(tile[row + 8].bit(col_idx + 8)) << 3;
121                    snes_color |= u8::from(tile[row + 16].bit(col_idx)) << 4;
122                    snes_color |= u8::from(tile[row + 16].bit(col_idx + 8)) << 5;
123                    snes_color |= u8::from(tile[row + 24].bit(col_idx)) << 6;
124                    snes_color |= u8::from(tile[row + 24].bit(col_idx + 8)) << 7;
125
126                    let color = self.cgram[snes_color as usize];
127                    out[out_idx] = ppu::convert_snes_color(color, ppu::MAX_BRIGHTNESS);
128                }
129            }
130        }
131    }
132
133    pub fn copy_vram_mode7(&self, out: &mut [Color], row_len: usize) {
134        for tile_number in 0..256 {
135            let out_tile_idx = tile_number / row_len * row_len * 64 + (tile_number % row_len) * 8;
136
137            for row in 0..8 {
138                for col in 0..8 {
139                    let out_idx = out_tile_idx + row * row_len * 8 + col;
140
141                    let vram_addr = tile_number * 64 + row * 8 + col;
142                    let snes_color = self.vram[vram_addr] >> 8;
143                    let color = self.cgram[snes_color as usize];
144                    out[out_idx] = ppu::convert_snes_color(color, ppu::MAX_BRIGHTNESS);
145                }
146            }
147        }
148    }
149}