diff --git a/emulator/core/src/host/gfx.rs b/emulator/core/src/host/gfx.rs index cee9dfe..60e1fda 100644 --- a/emulator/core/src/host/gfx.rs +++ b/emulator/core/src/host/gfx.rs @@ -5,7 +5,7 @@ use std::collections::VecDeque; use crate::Clock; use crate::Error; -use crate::host::traits::{WindowUpdater, BlitableSurface}; +use crate::host::traits::{WindowUpdater, BlitableSurface, ClockedQueue}; pub const MASK_COLOUR: u32 = 0xFFFFFFFF; @@ -111,23 +111,23 @@ impl WindowUpdater for FrameSwapper { #[derive(Clone)] pub struct FrameQueue { max_size: (u32, u32), - queue: Arc>>, + queue: ClockedQueue, } impl FrameQueue { pub fn new(width: u32, height: u32) -> Self { Self { max_size: (width, height), - queue: Arc::new(Mutex::new(VecDeque::new())), + queue: ClockedQueue::new(), } } pub fn add(&self, clock: Clock, frame: Frame) { - self.queue.lock().unwrap().push_back((clock, frame)); + self.queue.push(clock, frame); } pub fn latest(&self) -> Option<(Clock, Frame)> { - self.queue.lock().unwrap().drain(..).last() + self.queue.pop_latest() } } diff --git a/emulator/core/src/host/traits.rs b/emulator/core/src/host/traits.rs index 7df949e..77dce7a 100644 --- a/emulator/core/src/host/traits.rs +++ b/emulator/core/src/host/traits.rs @@ -1,7 +1,8 @@ +use std::collections::VecDeque; use std::sync::{Arc, Mutex, MutexGuard}; -use crate::error::Error; +use crate::{Clock, Error}; use crate::host::keys::Key; use crate::host::gfx::Frame; use crate::host::controllers::{ControllerDevice, ControllerEvent}; @@ -96,6 +97,24 @@ impl HostData { } } +#[derive(Clone)] +pub struct ClockedQueue(Arc>>); + +impl ClockedQueue { + pub fn new() -> Self { + Self(Arc::new(Mutex::new(VecDeque::new()))) + } + + pub fn push(&self, clock: Clock, data: T) { + self.0.lock().unwrap().push_back((clock, data)); + } + + pub fn pop_latest(&self) -> Option<(Clock, T)> { + self.0.lock().unwrap().drain(..).last() + } +} + + pub struct DummyAudio(); impl Audio for DummyAudio { diff --git a/emulator/frontends/minifb/src/bin/moa-synth.rs b/emulator/frontends/minifb/src/bin/moa-synth.rs index 918c761..8c32815 100644 --- a/emulator/frontends/minifb/src/bin/moa-synth.rs +++ b/emulator/frontends/minifb/src/bin/moa-synth.rs @@ -4,8 +4,8 @@ use std::sync::mpsc; use moa_minifb; use moa_peripherals_yamaha::{Ym2612, Sn76489}; -use moa_core::host::gfx::Frame; -use moa_core::host::{Host, KeyboardUpdater, Key}; +use moa_core::host::gfx::{Frame, FrameQueue}; +use moa_core::host::{Host, WindowUpdater, KeyboardUpdater, Key}; use moa_core::{System, Error, ClockElapsed, Address, Addressable, Steppable, Transmutable, TransmutableBox, wrap_transmutable}; @@ -18,12 +18,14 @@ impl KeyboardUpdater for SynthControlsUpdater { } struct SynthControl { + queue: FrameQueue, receiver: mpsc::Receiver<(Key, bool)>, } impl SynthControl { - pub fn new(receiver: mpsc::Receiver<(Key, bool)>) -> Self { + pub fn new(queue: FrameQueue, receiver: mpsc::Receiver<(Key, bool)>) -> Self { Self { + queue, receiver, } } @@ -49,7 +51,11 @@ impl Steppable for SynthControl { } } - Ok(1_000_000) + let size = self.queue.max_size(); + let frame = Frame::new(size.0, size.1); + self.queue.add(system.clock, frame); + + Ok(33_000_000) } } @@ -88,8 +94,9 @@ fn main() { moa_minifb::run(matches, |host| { let mut system = System::new(); + let queue = FrameQueue::new(384, 128); let (sender, receiver) = mpsc::channel(); - let control = wrap_transmutable(SynthControl::new(receiver)); + let control = wrap_transmutable(SynthControl::new(queue.clone(), receiver)); system.add_device("control", control)?; let ym_sound = wrap_transmutable(Ym2612::create(host)?); @@ -99,8 +106,7 @@ fn main() { let sn_sound = wrap_transmutable(Sn76489::create(host)?); system.add_addressable_device(0x10, sn_sound)?; - let frame = Frame::new_shared(384, 128); - host.add_window(Frame::new_updater(frame.clone()))?; + host.add_window(Box::new(queue.clone()))?; host.register_keyboard(Box::new(SynthControlsUpdater(sender)))?; Ok(system) diff --git a/emulator/frontends/minifb/src/lib.rs b/emulator/frontends/minifb/src/lib.rs index bd7b8fc..58f3ad4 100644 --- a/emulator/frontends/minifb/src/lib.rs +++ b/emulator/frontends/minifb/src/lib.rs @@ -9,6 +9,7 @@ use clap::{App, Arg, ArgMatches}; use moa_core::{System, Error, Clock}; use moa_core::host::{Host, HostData, ControllerUpdater, KeyboardUpdater, WindowUpdater, Audio, ControllerDevice}; +use moa_core::host::gfx::Frame; use moa_common::audio::{AudioOutput, AudioMixer, AudioSource}; @@ -226,6 +227,7 @@ impl MiniFrontend { let mut average_time = 0; let mut update_timer = Instant::now(); + let mut last_frame = Frame::new(size.0, size.1); while window.is_open() && !window.is_key_down(Key::Escape) { let frame_time = update_timer.elapsed().as_micros(); update_timer = Instant::now(); @@ -259,8 +261,9 @@ impl MiniFrontend { if let Some(updater) = self.window.as_mut() { if let Ok(frame) = updater.take_frame() { - window.update_with_buffer(&frame.bitmap, frame.width as usize, frame.height as usize).unwrap(); + last_frame = frame } + window.update_with_buffer(&last_frame.bitmap, last_frame.width as usize, last_frame.height as usize).unwrap(); } } }