use std::sync::Arc; use baseview::{ Event, EventStatus, MouseButton, MouseEvent, Size, Window, WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions, }; use nih_plug::prelude::*; use pixels::{Pixels, SurfaceTexture}; use crate::{HEIGHT, WIDTH}; pub struct Emulator {} impl Emulator { pub fn new() -> Self { Self {} } } impl Editor for Emulator { fn spawn( &self, parent: ParentWindowHandle, _context: Arc, ) -> Box { Window::open_parented( &parent, WindowOpenOptions { title: String::from("gb-emu"), size: Size::new(WIDTH as f64, HEIGHT as f64), scale: baseview::WindowScalePolicy::SystemScaleFactor, }, EmulatorWindow::new, ); Box::new(Self::new()) } fn size(&self) -> (u32, u32) { (WIDTH, HEIGHT) } fn set_scale_factor(&self, _factor: f32) -> bool { true } fn param_value_changed(&self, _id: &str, _normalized_value: f32) {} fn param_modulation_changed(&self, _id: &str, _modulation_offset: f32) {} fn param_values_changed(&self) {} } pub struct EmulatorWindow { pix: Pixels, current_colour: [u8; 4], } impl EmulatorWindow { fn new(window: &mut Window) -> Self { let info = WindowInfo::from_logical_size(Size::new(WIDTH as f64, HEIGHT as f64), 1.); let mut pix = init_pixbuf(info, window); let current_colour: [u8; 4] = [0xFF, 0x0, 0x0, 0xFF]; for pixel in pix.get_frame_mut().chunks_exact_mut(4) { pixel.copy_from_slice(¤t_colour); } Self { pix, current_colour, } } fn update_pixbuf(&mut self) { self.current_colour = rotate_colour(&self.current_colour); self.render_pixbuf(); println!("colour now {:#?}", self.current_colour); } fn render_pixbuf(&mut self) { for pixel in self.pix.get_frame_mut().chunks_exact_mut(4) { pixel.copy_from_slice(&self.current_colour); } } } fn init_pixbuf(info: WindowInfo, window: &mut Window) -> Pixels { let physical_size = info.physical_size(); pixels::Pixels::new( physical_size.width, physical_size.height, SurfaceTexture::new(physical_size.width, physical_size.height, window), ) .unwrap() } fn rotate_colour(current: &[u8; 4]) -> [u8; 4] { [current[1], current[2], current[0], current[3]] } impl WindowHandler for EmulatorWindow { fn on_frame(&mut self, _window: &mut Window) { self.pix.render().unwrap(); } fn on_event(&mut self, window: &mut Window, event: baseview::Event) -> EventStatus { if let Event::Window(WindowEvent::Resized(info)) = event { self.pix = init_pixbuf(info, window); self.update_pixbuf(); return EventStatus::Captured; } if let Event::Mouse(MouseEvent::ButtonPressed { button: MouseButton::Left, .. }) = event { println!("click!"); self.update_pixbuf(); return EventStatus::Captured; } EventStatus::Ignored } }