mirror of
https://github.com/FranLMSP/snes.git
synced 2026-08-03 08:30:01 -04:00
wip 2bpp tileset render
This commit is contained in:
@@ -111,7 +111,7 @@ pub enum BgSize {
|
||||
T32x32,
|
||||
T64x32, // V Mirror
|
||||
T32x64, // H Mirror
|
||||
T64x64, // H Mirror
|
||||
T64x64, // H/V Mirror
|
||||
}
|
||||
|
||||
impl BgSize {
|
||||
@@ -266,10 +266,10 @@ impl PPURegisters {
|
||||
pub fn get_bg_tile_size(&self, background: Background) -> TileSize {
|
||||
let byte = self._read(BGMODE);
|
||||
let bit = match background {
|
||||
Background::Bg1 => byte >> 3 & 0b1 == 1, // Bit 4
|
||||
Background::Bg2 => byte >> 4 & 0b1 == 1, // Bit 5
|
||||
Background::Bg3 => byte >> 5 & 0b1 == 1, // Bit 6
|
||||
Background::Bg4 => byte >> 6 & 0b1 == 1, // Bit 7
|
||||
Background::Bg1 => byte >> 4 & 0b1 == 1, // Bit 4
|
||||
Background::Bg2 => byte >> 5 & 0b1 == 1, // Bit 5
|
||||
Background::Bg3 => byte >> 6 & 0b1 == 1, // Bit 6
|
||||
Background::Bg4 => byte >> 7 & 0b1 == 1, // Bit 7
|
||||
};
|
||||
match bit {
|
||||
true => TileSize::P16x16,
|
||||
|
||||
@@ -2,7 +2,7 @@ use eframe::epaint::{Vec2, TextureHandle};
|
||||
use eframe::{egui::Context, epaint::ColorImage};
|
||||
|
||||
use eframe::egui::{self, TextureOptions, Ui};
|
||||
use snes_core::ppu::registers::{PPURegisters, Background};
|
||||
use snes_core::ppu::registers::{PPURegisters, Background, MAX_BG_WIDTH, MAX_BG_HEIGHT};
|
||||
use crate::emu_state::debug_options::BgDebug;
|
||||
|
||||
|
||||
@@ -25,8 +25,9 @@ fn build_bg_preview_window(ctx: &Context, bgdebug: &mut BgDebug, registers: &PPU
|
||||
ui.label("Charset");
|
||||
compute_2bpp_bg_char_framebuffer(bgdebug.background, &mut bgdebug.char_framebuffer, registers);
|
||||
paint_texture(ui, &mut bgdebug.char_texture, &bgdebug.char_framebuffer, 16 * 8, 8 * 8);
|
||||
// ui.label("Background");
|
||||
// paint_texture(ui, &mut bgdebug.bg_texture, &mut bgdebug.bg_framebuffer, MAX_BG_WIDTH, MAX_BG_HEIGHT);
|
||||
ui.label("Background");
|
||||
compute_2bpp_bg_background_framebuffer(bgdebug.background, &mut bgdebug.bg_framebuffer, registers);
|
||||
paint_texture(ui, &mut bgdebug.bg_texture, &mut bgdebug.bg_framebuffer, MAX_BG_WIDTH, MAX_BG_HEIGHT);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -122,6 +123,101 @@ fn compute_2bpp_bg_char_framebuffer(background: Background, framebuffer: &mut [u
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_2bpp_bg_background_framebuffer(background: Background, framebuffer: &mut [u8], registers: &PPURegisters) {
|
||||
let tileset_vram_base_address = registers.get_bg_tile_base_address(background) as usize;
|
||||
let charset_vram_base_address = registers.get_bg_char_base_address(background) as usize;
|
||||
let (bg_size_width, bg_size_height) = registers.get_bg_size(background).to_usize();
|
||||
let (tile_size_width, tile_size_height) = registers.get_bg_tile_size(background).to_usize();
|
||||
let vram = registers.vram();
|
||||
let width: usize = bg_size_width * tile_size_width;
|
||||
let height: usize = bg_size_height * tile_size_height;
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
let current_tile = (x / tile_size_width) + ((y / tile_size_height) * bg_size_width);
|
||||
let char_index = vram[(tileset_vram_base_address + current_tile) & 0x7FFF] & 0b11_11111111;
|
||||
let current_char_column = x.rem_euclid(tile_size_width);
|
||||
let current_char_row = y.rem_euclid(tile_size_height);
|
||||
// 8x8 pixels, 2 bitplanes, each word (16bit) holds 8 pixels
|
||||
// so 1 char is 8 bytes x 2
|
||||
let effective_vram_address =
|
||||
charset_vram_base_address +
|
||||
((char_index as usize) * tile_size_width) +
|
||||
current_char_row;
|
||||
|
||||
let vram_word = vram[effective_vram_address];
|
||||
let lsb_bitplane= vram_word as u8;
|
||||
let msb_bitplane= (vram_word >> 8) as u8;
|
||||
let pixels = [
|
||||
(
|
||||
(lsb_bitplane >> 7) |
|
||||
((msb_bitplane >> 7) << 1)
|
||||
),
|
||||
(
|
||||
((lsb_bitplane >> 6) & 1) |
|
||||
(((msb_bitplane >> 6) & 1) << 1)
|
||||
),
|
||||
(
|
||||
((lsb_bitplane >> 5) & 1) |
|
||||
(((msb_bitplane >> 5) & 1) << 1)
|
||||
),
|
||||
(
|
||||
((lsb_bitplane >> 4) & 1) |
|
||||
(((msb_bitplane >> 4) & 1) << 1)
|
||||
),
|
||||
(
|
||||
((lsb_bitplane >> 3) & 1) |
|
||||
(((msb_bitplane >> 3) & 1) << 1)
|
||||
),
|
||||
(
|
||||
((lsb_bitplane >> 2) & 1) |
|
||||
(((msb_bitplane >> 2) & 1) << 1)
|
||||
),
|
||||
(
|
||||
((lsb_bitplane >> 1) & 1) |
|
||||
(((msb_bitplane >> 1) & 1) << 1)
|
||||
),
|
||||
(
|
||||
(lsb_bitplane & 1) |
|
||||
((msb_bitplane & 1) << 1)
|
||||
),
|
||||
];
|
||||
let effective_pixel = pixels[current_char_column];
|
||||
|
||||
let current_fb_pixel = x + (y * MAX_BG_WIDTH);
|
||||
let fb_index = current_fb_pixel * 4;
|
||||
let r = fb_index;
|
||||
let g = fb_index + 1;
|
||||
let b = fb_index + 2;
|
||||
let a = fb_index + 3;
|
||||
|
||||
framebuffer[a] = 0xFF;
|
||||
match effective_pixel {
|
||||
0b00 => {
|
||||
framebuffer[r] = 0xFF;
|
||||
framebuffer[g] = 0xFF;
|
||||
framebuffer[b] = 0xFF;
|
||||
},
|
||||
0b01 => {
|
||||
framebuffer[r] = 0xAC;
|
||||
framebuffer[g] = 0xAC;
|
||||
framebuffer[b] = 0xAC;
|
||||
},
|
||||
0b10 => {
|
||||
framebuffer[r] = 0x56;
|
||||
framebuffer[g] = 0x56;
|
||||
framebuffer[b] = 0x56;
|
||||
},
|
||||
0b11 => {
|
||||
framebuffer[r] = 0x00;
|
||||
framebuffer[g] = 0x00;
|
||||
framebuffer[b] = 0x00;
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_texture(ui: &mut Ui, texture: &mut Option<TextureHandle>, framebuffer: &[u8], width: usize, height: usize) {
|
||||
if let Some(txt) = texture {
|
||||
txt.set(
|
||||
|
||||
Reference in New Issue
Block a user