Rerender VRAM graphics every frame (slow in debug)
This commit is contained in:
+36
-30
@@ -1,8 +1,8 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use egui::{
|
||||
Align, CentralPanel, Checkbox, Color32, ColorImage, Context, Image, ScrollArea, Slider,
|
||||
TextEdit, TextureOptions, Ui, ViewportBuilder, ViewportId,
|
||||
Align, CentralPanel, Checkbox, Color32, Context, Image, ScrollArea, Slider, TextEdit,
|
||||
TextureOptions, Ui, ViewportBuilder, ViewportId,
|
||||
};
|
||||
use egui_extras::{Column, Size, StripBuilder, TableBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
emulator::SimId,
|
||||
memory::{MemoryMonitor, MemoryView},
|
||||
vram::{VramImageLoader, VramResource as _, VramTextureLoader},
|
||||
vram::{VramImage, VramImageLoader, VramResource as _, VramTextureLoader},
|
||||
window::{utils::UiExt, AppWindow},
|
||||
};
|
||||
|
||||
@@ -242,7 +242,7 @@ impl BgMapLoader {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_bgmap(&self, bgmap_index: usize, generic_palette: bool) -> Option<ColorImage> {
|
||||
fn update_bgmap(&self, image: &mut VramImage, bgmap_index: usize, generic_palette: bool) {
|
||||
let chardata = self.chardata.borrow();
|
||||
let bgmaps = self.bgmaps.borrow();
|
||||
let brightness = self.brightness.borrow();
|
||||
@@ -265,7 +265,6 @@ impl BgMapLoader {
|
||||
]
|
||||
};
|
||||
|
||||
let mut data = vec![0u8; 512 * 512];
|
||||
for (i, cell) in bgmaps
|
||||
.range::<u16>(bgmap_index * 4096, 4096)
|
||||
.iter()
|
||||
@@ -275,21 +274,17 @@ impl BgMapLoader {
|
||||
let char = chardata.range::<u16>(char_index * 8, 8);
|
||||
let palette = &colors[palette_index];
|
||||
|
||||
let mut target_idx = (i % 64) * 8 + (i / 64) * 8 * 512;
|
||||
for row in 0..8 {
|
||||
let dests = &mut data[target_idx..target_idx + 8];
|
||||
let pixels = self.read_char_row(char, hflip, vflip, row);
|
||||
for (dest, pixel) in dests.iter_mut().zip(pixels) {
|
||||
*dest = palette[pixel as usize];
|
||||
let y = row + (i / 64) * 8;
|
||||
for (col, pixel) in self.read_char_row(char, hflip, vflip, row).enumerate() {
|
||||
let x = col + (i % 64) * 8;
|
||||
image.write((x, y), palette[pixel as usize]);
|
||||
}
|
||||
target_idx += 512;
|
||||
}
|
||||
}
|
||||
|
||||
Some(ColorImage::from_gray([512, 512], &data))
|
||||
}
|
||||
|
||||
fn load_bgmap_cell(&self, index: usize, generic_palette: bool) -> Option<ColorImage> {
|
||||
fn update_bgmap_cell(&self, image: &mut VramImage, index: usize, generic_palette: bool) {
|
||||
let chardata = self.chardata.borrow();
|
||||
let bgmaps = self.bgmaps.borrow();
|
||||
let brightness = self.brightness.borrow();
|
||||
@@ -297,7 +292,6 @@ impl BgMapLoader {
|
||||
|
||||
let brts = brightness.range::<u8>(0, 8);
|
||||
|
||||
let mut data = vec![0u8; 8 * 8];
|
||||
let cell = bgmaps.read::<u16>(index);
|
||||
|
||||
let (char_index, vflip, hflip, palette_index) = parse_cell(cell);
|
||||
@@ -308,17 +302,11 @@ impl BgMapLoader {
|
||||
parse_palette(palettes.read(palette_index * 2), brts)
|
||||
};
|
||||
|
||||
let mut target_idx = 0;
|
||||
for row in 0..8 {
|
||||
let dests = &mut data[target_idx..target_idx + 8];
|
||||
let pixels = self.read_char_row(char, hflip, vflip, row);
|
||||
for (dest, pixel) in dests.iter_mut().zip(pixels) {
|
||||
*dest = palette[pixel as usize];
|
||||
for (col, pixel) in self.read_char_row(char, hflip, vflip, row).enumerate() {
|
||||
image.write((col, row), palette[pixel as usize]);
|
||||
}
|
||||
target_idx += 8;
|
||||
}
|
||||
|
||||
Some(ColorImage::from_gray([8, 8], &data))
|
||||
}
|
||||
|
||||
fn read_char_row(
|
||||
@@ -343,24 +331,42 @@ impl VramImageLoader for BgMapLoader {
|
||||
concat!(module_path!(), "::BgMapLoader")
|
||||
}
|
||||
|
||||
fn add(&self, resource: &Self::Resource) -> Option<ColorImage> {
|
||||
fn add(&self, resource: &Self::Resource) -> Option<VramImage> {
|
||||
match resource {
|
||||
BgMapResource::BgMap {
|
||||
index,
|
||||
generic_palette,
|
||||
} => self.load_bgmap(*index, *generic_palette),
|
||||
} => {
|
||||
let mut image = VramImage::new(64 * 8, 64 * 8);
|
||||
self.update_bgmap(&mut image, *index, *generic_palette);
|
||||
Some(image)
|
||||
}
|
||||
BgMapResource::Cell {
|
||||
index,
|
||||
generic_palette,
|
||||
} => self.load_bgmap_cell(*index, *generic_palette),
|
||||
} => {
|
||||
let mut image = VramImage::new(8, 8);
|
||||
self.update_bgmap_cell(&mut image, *index, *generic_palette);
|
||||
Some(image)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update<'a>(
|
||||
&'a self,
|
||||
resources: impl Iterator<Item = &'a Self::Resource>,
|
||||
) -> Vec<(&'a Self::Resource, ColorImage)> {
|
||||
let _ = resources;
|
||||
vec![]
|
||||
resources: impl Iterator<Item = (&'a Self::Resource, &'a mut VramImage)>,
|
||||
) {
|
||||
for (resource, image) in resources {
|
||||
match resource {
|
||||
BgMapResource::BgMap {
|
||||
index,
|
||||
generic_palette,
|
||||
} => self.update_bgmap(image, *index, *generic_palette),
|
||||
BgMapResource::Cell {
|
||||
index,
|
||||
generic_palette,
|
||||
} => self.update_bgmap_cell(image, *index, *generic_palette),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-28
@@ -1,8 +1,8 @@
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
|
||||
use egui::{
|
||||
Align, CentralPanel, Color32, ColorImage, ComboBox, Context, Image, ScrollArea, Slider,
|
||||
TextEdit, TextureOptions, Ui, Vec2, ViewportBuilder, ViewportId,
|
||||
Align, CentralPanel, Color32, ComboBox, Context, Image, ScrollArea, Slider, TextEdit,
|
||||
TextureOptions, Ui, Vec2, ViewportBuilder, ViewportId,
|
||||
};
|
||||
use egui_extras::{Column, Size, StripBuilder, TableBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
emulator::SimId,
|
||||
memory::{MemoryMonitor, MemoryView},
|
||||
vram::{VramImageLoader, VramResource as _, VramTextureLoader},
|
||||
vram::{VramImage, VramImageLoader, VramResource as _, VramTextureLoader},
|
||||
window::{utils::UiExt as _, AppWindow},
|
||||
};
|
||||
|
||||
@@ -294,38 +294,34 @@ impl CharDataLoader {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_character(&self, palette: VramPalette, index: usize) -> Option<ColorImage> {
|
||||
fn update_character(&self, image: &mut VramImage, palette: VramPalette, index: usize) {
|
||||
if index >= 2048 {
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
let palette = self.load_palette(palette);
|
||||
let chardata = self.chardata.borrow();
|
||||
let character = chardata.range::<u16>(index * 8, 8);
|
||||
let mut buffer = Vec::with_capacity(8 * 8);
|
||||
for row in character {
|
||||
for offset in (0..16).step_by(2) {
|
||||
let char = (row >> offset) & 0x3;
|
||||
buffer.push(palette[char as usize]);
|
||||
for (row, pixels) in character.iter().enumerate() {
|
||||
for col in 0..8 {
|
||||
let char = (pixels >> (col * 2)) & 0x03;
|
||||
image.write((col, row), palette[char as usize]);
|
||||
}
|
||||
}
|
||||
Some(ColorImage::from_gray([8, 8], &buffer))
|
||||
}
|
||||
|
||||
fn load_character_data(&self, palette: VramPalette) -> Option<ColorImage> {
|
||||
fn update_character_data(&self, image: &mut VramImage, palette: VramPalette) {
|
||||
let palette = self.load_palette(palette);
|
||||
let chardata = self.chardata.borrow();
|
||||
let mut buffer = vec![0; 8 * 8 * 2048];
|
||||
for (i, row) in chardata.range::<u16>(0, 8 * 2048).iter().enumerate() {
|
||||
let bytes =
|
||||
[0, 2, 4, 6, 8, 10, 12, 14].map(|off| palette[(*row as usize >> off) & 0x3]);
|
||||
let char_index = i / 8;
|
||||
let row_index = i % 8;
|
||||
for (row, pixels) in chardata.range::<u16>(0, 8 * 2048).iter().enumerate() {
|
||||
let char_index = row / 8;
|
||||
let row_index = row % 8;
|
||||
let x = (char_index % 16) * 8;
|
||||
let y = (char_index / 16) * 8 + row_index;
|
||||
let write_index = (y * 16 * 8) + x;
|
||||
buffer[write_index..write_index + 8].copy_from_slice(&bytes);
|
||||
for col in 0..8 {
|
||||
let char = (pixels >> (col * 2)) & 0x03;
|
||||
image.write((x + col, y), palette[char as usize]);
|
||||
}
|
||||
}
|
||||
Some(ColorImage::from_gray([8 * 16, 8 * 128], &buffer))
|
||||
}
|
||||
|
||||
fn load_palette(&self, palette: VramPalette) -> [u8; 4] {
|
||||
@@ -346,18 +342,34 @@ impl VramImageLoader for CharDataLoader {
|
||||
concat!(module_path!(), "::CharDataLoader")
|
||||
}
|
||||
|
||||
fn add(&self, resource: &Self::Resource) -> Option<ColorImage> {
|
||||
fn add(&self, resource: &Self::Resource) -> Option<VramImage> {
|
||||
match resource {
|
||||
CharDataResource::Character { palette, index } => self.load_character(*palette, *index),
|
||||
CharDataResource::CharacterData { palette } => self.load_character_data(*palette),
|
||||
CharDataResource::Character { palette, index } => {
|
||||
let mut image = VramImage::new(8, 8);
|
||||
self.update_character(&mut image, *palette, *index);
|
||||
Some(image)
|
||||
}
|
||||
CharDataResource::CharacterData { palette } => {
|
||||
let mut image = VramImage::new(8 * 16, 8 * 128);
|
||||
self.update_character_data(&mut image, *palette);
|
||||
Some(image)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update<'a>(
|
||||
&'a self,
|
||||
resources: impl Iterator<Item = &'a Self::Resource>,
|
||||
) -> Vec<(&'a Self::Resource, ColorImage)> {
|
||||
let _ = resources;
|
||||
vec![]
|
||||
resources: impl Iterator<Item = (&'a Self::Resource, &'a mut VramImage)>,
|
||||
) {
|
||||
for (resource, image) in resources {
|
||||
match resource {
|
||||
CharDataResource::Character { palette, index } => {
|
||||
self.update_character(image, *palette, *index)
|
||||
}
|
||||
CharDataResource::CharacterData { palette } => {
|
||||
self.update_character_data(image, *palette)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user