scale framebuffer in place
This commit is contained in:
parent
66f7518bb0
commit
52fe997e28
|
@ -8,7 +8,7 @@ use baseview::{
|
|||
};
|
||||
use gb_emu_lib::{
|
||||
connect::{JoypadButtons, JoypadState, Renderer, HEIGHT, WIDTH},
|
||||
util::scale_buffer,
|
||||
util::scale_buffer_in_place,
|
||||
};
|
||||
use keyboard_types::{Code, KeyState};
|
||||
use nih_plug::prelude::*;
|
||||
|
@ -74,6 +74,7 @@ impl Editor for Emulator {
|
|||
pub struct EmulatorWindow {
|
||||
pix: Pixels,
|
||||
scale: usize,
|
||||
scaled_buf: Vec<[u8; 4]>,
|
||||
frame_receiver: Arc<FrameReceiver>,
|
||||
joypad_sender: Arc<JoypadSender>,
|
||||
}
|
||||
|
@ -86,20 +87,22 @@ impl EmulatorWindow {
|
|||
) -> Self {
|
||||
let info = WindowInfo::from_logical_size(Size::new(WIDTH as f64, HEIGHT as f64), 1.);
|
||||
|
||||
let (pix, scale) = init_pixbuf(info, window);
|
||||
let (pix, scale, scaled_buf) = init_pixbuf(info, window);
|
||||
|
||||
Self {
|
||||
pix,
|
||||
scale,
|
||||
scaled_buf,
|
||||
frame_receiver,
|
||||
joypad_sender,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init_pixbuf(info: WindowInfo, window: &mut Window) -> (Pixels, usize) {
|
||||
fn init_pixbuf(info: WindowInfo, window: &mut Window) -> (Pixels, usize, Vec<[u8; 4]>) {
|
||||
let physical_size = info.physical_size();
|
||||
let scale = (physical_size.width as usize / WIDTH).min(physical_size.height as usize / HEIGHT);
|
||||
let scaled_buf = vec![[0, 0, 0, 0xFF]; WIDTH * scale * HEIGHT * scale];
|
||||
(
|
||||
pixels::Pixels::new(
|
||||
physical_size.width,
|
||||
|
@ -108,21 +111,24 @@ fn init_pixbuf(info: WindowInfo, window: &mut Window) -> (Pixels, usize) {
|
|||
)
|
||||
.unwrap(),
|
||||
scale,
|
||||
scaled_buf,
|
||||
)
|
||||
}
|
||||
|
||||
impl WindowHandler for EmulatorWindow {
|
||||
fn on_frame(&mut self, _window: &mut Window) {
|
||||
if let Some(ref mut receiver) = *self.frame_receiver.lock().expect("failed to lock mutex") {
|
||||
if let Some(buf) = receiver.try_iter().last() {
|
||||
let scaled_buf = if self.scale != 1 {
|
||||
scale_buffer(&buf, WIDTH, HEIGHT, self.scale)
|
||||
} else {
|
||||
buf
|
||||
};
|
||||
for (pixel, source) in self.pix.get_frame_mut().chunks_exact_mut(4).zip(scaled_buf)
|
||||
if let Some(ref buf) = receiver.try_iter().last() {
|
||||
if self.scale != 1 {
|
||||
scale_buffer_in_place(buf, &mut self.scaled_buf, WIDTH, HEIGHT, self.scale);
|
||||
}
|
||||
for (pixel, source) in self
|
||||
.pix
|
||||
.get_frame_mut()
|
||||
.chunks_exact_mut(4)
|
||||
.zip(&self.scaled_buf)
|
||||
{
|
||||
pixel.copy_from_slice(&source);
|
||||
pixel.copy_from_slice(source);
|
||||
}
|
||||
self.pix.render().unwrap();
|
||||
}
|
||||
|
@ -132,7 +138,7 @@ impl WindowHandler for EmulatorWindow {
|
|||
fn on_event(&mut self, window: &mut Window, event: baseview::Event) -> EventStatus {
|
||||
match event {
|
||||
Event::Window(WindowEvent::Resized(info)) => {
|
||||
(self.pix, self.scale) = init_pixbuf(info, window);
|
||||
(self.pix, self.scale, self.scaled_buf) = init_pixbuf(info, window);
|
||||
EventStatus::Captured
|
||||
}
|
||||
Event::Keyboard(event) => {
|
||||
|
|
|
@ -143,3 +143,22 @@ pub fn scale_buffer<T: From<Colour> + Copy>(
|
|||
}
|
||||
v
|
||||
}
|
||||
|
||||
pub fn scale_buffer_in_place<T: From<Colour> + Copy>(
|
||||
buffer: &[T],
|
||||
target: &mut [T],
|
||||
width: usize,
|
||||
height: usize,
|
||||
factor: usize,
|
||||
) {
|
||||
for y in 0..height {
|
||||
for y_2 in 0..factor {
|
||||
for x in 0..width {
|
||||
for x_2 in 0..factor {
|
||||
target[(((y * factor) + y_2) * (width * factor)) + (x * factor) + x_2] =
|
||||
buffer[(y * width) + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue