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