diff --git a/core/src/emulator/mod.rs b/core/src/emulator/mod.rs index daf9af8..2519040 100644 --- a/core/src/emulator/mod.rs +++ b/core/src/emulator/mod.rs @@ -203,7 +203,11 @@ impl Tickable for Emulator { self.last_update = Instant::now(); self.status_update()?; } - self.step()?; + + // Batch 10000 steps for performance reasons + for _ in 0..10000 { + self.step()?; + } } else { thread::sleep(Duration::from_millis(100)); } diff --git a/frontend_tui/src/main.rs b/frontend_tui/src/main.rs index df7d715..f42da96 100644 --- a/frontend_tui/src/main.rs +++ b/frontend_tui/src/main.rs @@ -19,7 +19,6 @@ use snow_core::tickable::Tickable; use ui::UserInterface; use std::panic::{set_hook, take_hook}; -use std::time::{Duration, Instant}; use std::{fs, thread}; use renderer_sdl::{SDLEventPump, SDLRenderer}; @@ -175,11 +174,11 @@ fn main() -> Result<()> { }); 'mainloop: loop { - let t_start = Instant::now(); - // Render frame to SDL window - if let Ok(frame) = frame_recv.try_recv() { - renderer.update_from(&frame)?; + if !frame_recv.is_empty() { + while let Ok(frame) = frame_recv.try_recv() { + renderer.update_from(&frame)?; + } } // Draw TUI @@ -188,7 +187,7 @@ fn main() -> Result<()> { } // Process SDL events - while let Some(event) = eventpump.poll() { + while let Some(event) = eventpump.wait(10) { match event { Event::KeyDown { keycode: Some(Keycode::Escape), @@ -257,9 +256,6 @@ fn main() -> Result<()> { _ => (), } } - - // Sync to roughly 120 iterations per second - thread::sleep(Duration::from_millis(10).saturating_sub(t_start.elapsed())); } // Terminate emulator diff --git a/frontend_tui/src/renderer_sdl.rs b/frontend_tui/src/renderer_sdl.rs index ab45d24..63a5225 100644 --- a/frontend_tui/src/renderer_sdl.rs +++ b/frontend_tui/src/renderer_sdl.rs @@ -119,10 +119,19 @@ impl SDLEventPump { Self {} } + #[allow(dead_code)] pub fn poll(&self) -> Option { SDL.with(|cell| { let mut sdls = cell.borrow_mut(); sdls.pump.poll_event() }) } + + #[allow(dead_code)] + pub fn wait(&self, ms: u32) -> Option { + SDL.with(|cell| { + let mut sdls = cell.borrow_mut(); + sdls.pump.wait_event_timeout(ms) + }) + } } diff --git a/frontend_tui/src/ui/mod.rs b/frontend_tui/src/ui/mod.rs index e398597..44a1437 100644 --- a/frontend_tui/src/ui/mod.rs +++ b/frontend_tui/src/ui/mod.rs @@ -118,64 +118,66 @@ impl UserInterface { self.draw(terminal)?; // TUI events - if event::poll(std::time::Duration::from_millis(50))? { - if let event::Event::Key(key) = event::read()? { - if key.kind == KeyEventKind::Press { - if self.cmd.is_some() { - match key.code { - KeyCode::Char(c) => self.cmd.as_mut().unwrap().push(c), - KeyCode::Backspace => { - self.cmd.as_mut().unwrap().pop(); - } - KeyCode::Enter => { - let cmd = self.cmd.take().unwrap(); - if let Err(e) = self.handle_command(&cmd) { - error!("Command failed: {:?}", e); - } - } - _ => (), - } - } + while event::poll(std::time::Duration::from_millis(0))? { + let event::Event::Key(key) = event::read()? else { + break; + }; - match (self.view, key.code) { - (_, KeyCode::Char('/')) => self.cmd = Some("".to_string()), - (_, KeyCode::F(10)) => return Ok(false), - (_, KeyCode::F(1)) => self.view = View::Log, - (_, KeyCode::F(2)) => self.view = View::Debugger, - (_, KeyCode::F(5)) if self.emustatus.running => { - self.cmdsender.send(EmulatorCommand::Stop)?; - } - (_, KeyCode::F(5)) => self.cmdsender.send(EmulatorCommand::Run)?, - (_, KeyCode::F(9)) => self.cmdsender.send(EmulatorCommand::Step)?, - (View::Log, KeyCode::PageUp) => { - self.state_log.transition(TuiWidgetEvent::PrevPageKey); - } - (View::Log, KeyCode::PageDown) => { - self.state_log.transition(TuiWidgetEvent::NextPageKey); - } - (View::Log, KeyCode::Down) => { - self.state_log.transition(TuiWidgetEvent::DownKey); - } - (View::Log, KeyCode::Up) => { - self.state_log.transition(TuiWidgetEvent::UpKey); - } - (View::Log, KeyCode::End) => { - self.state_log.transition(TuiWidgetEvent::SpaceKey); - } - (View::Debugger, KeyCode::Up) => { - self.debug_sel = self.debug_sel.saturating_sub(1); - } - (View::Debugger, KeyCode::Down) => { - self.debug_sel = self.debug_sel.saturating_add(1); + if key.kind == KeyEventKind::Press { + if self.cmd.is_some() { + match key.code { + KeyCode::Char(c) => self.cmd.as_mut().unwrap().push(c), + KeyCode::Backspace => { + self.cmd.as_mut().unwrap().pop(); } - (View::Debugger, KeyCode::F(7)) => { - let addr = self.disassembly[self.debug_sel].addr; - self.cmdsender - .send(EmulatorCommand::ToggleBreakpoint(addr))?; + KeyCode::Enter => { + let cmd = self.cmd.take().unwrap(); + if let Err(e) = self.handle_command(&cmd) { + error!("Command failed: {:?}", e); + } } _ => (), } } + + match (self.view, key.code) { + (_, KeyCode::Char('/')) => self.cmd = Some("".to_string()), + (_, KeyCode::F(10)) => return Ok(false), + (_, KeyCode::F(1)) => self.view = View::Log, + (_, KeyCode::F(2)) => self.view = View::Debugger, + (_, KeyCode::F(5)) if self.emustatus.running => { + self.cmdsender.send(EmulatorCommand::Stop)?; + } + (_, KeyCode::F(5)) => self.cmdsender.send(EmulatorCommand::Run)?, + (_, KeyCode::F(9)) => self.cmdsender.send(EmulatorCommand::Step)?, + (View::Log, KeyCode::PageUp) => { + self.state_log.transition(TuiWidgetEvent::PrevPageKey); + } + (View::Log, KeyCode::PageDown) => { + self.state_log.transition(TuiWidgetEvent::NextPageKey); + } + (View::Log, KeyCode::Down) => { + self.state_log.transition(TuiWidgetEvent::DownKey); + } + (View::Log, KeyCode::Up) => { + self.state_log.transition(TuiWidgetEvent::UpKey); + } + (View::Log, KeyCode::End) => { + self.state_log.transition(TuiWidgetEvent::SpaceKey); + } + (View::Debugger, KeyCode::Up) => { + self.debug_sel = self.debug_sel.saturating_sub(1); + } + (View::Debugger, KeyCode::Down) => { + self.debug_sel = self.debug_sel.saturating_add(1); + } + (View::Debugger, KeyCode::F(7)) => { + let addr = self.disassembly[self.debug_sel].addr; + self.cmdsender + .send(EmulatorCommand::ToggleBreakpoint(addr))?; + } + _ => (), + } } }