riscii

An emulator for the RISC II
Log | Files | Refs | LICENSE

commit 339e4bb931f44dd311d51fb7111e6778a6253dff
parent 7d9d33974dbd996748f727e512e9d9f0b7a4bd31
Author: Ryan Jeffrey <ryan@ryanmj.xyz>
Date:   Sun,  9 Oct 2022 21:42:01 -0700

Move debug window to its own file, handle SDL events

Diffstat:
Asrc/debug_window.rs | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/main.rs | 21+++++++++++----------
Msrc/sdl.rs | 45++++++++++++++++++++++++++++++++++-----------
Msrc/windows.rs | 94+++++++++++++++++++++++++++++++------------------------------------------------
4 files changed, 162 insertions(+), 78 deletions(-)

diff --git a/src/debug_window.rs b/src/debug_window.rs @@ -0,0 +1,80 @@ +// RISC II emulator debug window. +// (C) Ryan Jeffrey <ryan@ryanmj.xyz>, 2022 +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. + +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use config::Config; +use sdl::{Context, Drawable, Pane}; +use sdl2::event::{Event, WindowEvent}; +use sdl2::pixels::*; +use system::System; +use util::Result; + +pub struct DebugWindow<'a> { + pane: Pane, + system: &'a System, + config: &'a Config, +} + +impl<'a> DebugWindow<'a> { + pub fn new(config: &'a Config, system: &'a System, context: &mut Context) -> Result<Self> { + Ok(Self { + pane: Pane::new( + config.get_debug_win_width(), + config.get_debug_win_height(), + format!("Debug"), + context, + )?, + system: system, + config: config, + }) + } +} + +impl<'a> Drawable for DebugWindow<'a> { + fn draw(&mut self, context: &mut Context) { + self.pane.canvas.set_draw_color(Color::RGB(0, 0, 0)); + self.pane.canvas.clear(); + + // + self.pane.canvas.present(); + } + fn handle_events(&mut self, context: &mut Context) -> bool { + let event_pump = &mut context.event_pump; + let window_id = self.pane.get_id(); + for event in event_pump.poll_iter() { + match event { + Event::Quit { .. } => { + return true; + } + Event::Window { + win_event: WindowEvent::Close, + window_id: id, + .. + } => { + if id == window_id { + return true; + } + } + Event::KeyDown { + keycode: Some(kc), .. + } => {} + Event::KeyUp { + keycode: Some(kc), .. + } => {} + _ => {} + } + } + return false; + } +} diff --git a/src/main.rs b/src/main.rs @@ -27,6 +27,7 @@ mod main_test; // Modules declared as pub to shut up rust-analyzer about dead code. pub mod config; pub mod cpu; +pub mod debug_window; pub mod decode; pub mod instruction; pub mod memory; @@ -35,14 +36,13 @@ pub mod system; pub mod util; pub mod windows; -use decode::decode_file; -use std::fs; - use config::Config; +use debug_window::DebugWindow; +use sdl::{Context, Drawable}; use std::boxed::Box; use std::error::Error; use system::System; -use windows::{DebugWindow, Drawable, MainWindow}; +use windows::MainWindow; // Struct/enum declarations. fn main() -> Result<(), Box<dyn Error>> { @@ -55,16 +55,17 @@ fn main() -> Result<(), Box<dyn Error>> { ); //println!("Opening binary file {}.", path); //let program = fs::read(path)?; + let mut sdl_context = Context::new()?; - let mut debug_window = Some(DebugWindow::new(&config, &system)?); - let mut main_window = MainWindow::new(&config, &system)?; + let mut main_window = MainWindow::new(&config, &system, &mut sdl_context)?; + let mut debug_window = Some(DebugWindow::new(&config, &system, &mut sdl_context)?); 'running: loop { - if main_window.handle_events() { + if main_window.handle_events(&mut sdl_context) { break 'running; } debug_window = if let Some(mut win) = debug_window { - if win.handle_events() { + if win.handle_events(&mut sdl_context) { None } else { Some(win) @@ -74,12 +75,12 @@ fn main() -> Result<(), Box<dyn Error>> { }; debug_window = if let Some(mut win) = debug_window { - win.draw(); + win.draw(&mut sdl_context); Some(win) } else { None }; - main_window.draw(); + main_window.draw(&mut sdl_context); } Ok(()) } diff --git a/src/sdl.rs b/src/sdl.rs @@ -32,43 +32,66 @@ use util::Result; // Struct definitions. -/// SDL context structs. +pub trait Drawable { + fn draw(&mut self, context: &mut Context); + fn handle_events(&mut self, context: &mut Context) -> bool; +} + pub struct Context { /// SDL context. pub context: Sdl, /// Video context. pub video_system: VideoSubsystem, - /// Window canvas. - pub canvas: Canvas<Window>, /// Event queue. pub event_pump: EventPump, } + +/// SDL context structs. +pub struct Pane { + /// Window canvas. + pub canvas: Canvas<Window>, + /// Id. + window_id: u32, +} // Struct impls. impl Context { + pub fn new() -> Result<Self> { + let sdl = sdl2::init()?; + let event_pump = sdl.event_pump()?; + Ok(Self { + video_system: sdl.video()?, + context: sdl, + event_pump: event_pump, + }) + } +} + +impl Pane { /// Create a new SDL window/context. Return context on success and a /// string on error. - pub fn new(width: u32, height: u32, name: String) -> Result<Self> { - let sdl_context = sdl2::init()?; - let video_subsystem = sdl_context.video()?; - let window = video_subsystem + pub fn new(width: u32, height: u32, name: String, context: &mut Context) -> Result<Self> { + let window = context + .video_system .window(name.as_str(), width, height) .position_centered() .opengl() .build() .map_err(|e| e.to_string())?; + let id = window.id(); let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?; canvas.set_draw_color(Color::RGB(0, 0, 0)); canvas.clear(); canvas.present(); - let event_pump = sdl_context.event_pump()?; Ok(Self { - context: sdl_context, - video_system: video_subsystem, canvas: canvas, - event_pump: event_pump, + window_id: id, }) } + + pub fn get_id(&self) -> u32 { + self.window_id + } } diff --git a/src/windows.rs b/src/windows.rs @@ -1,4 +1,4 @@ -// RISC II emulator windows. +// RISC II emulator window. // (C) Ryan Jeffrey <ryan@ryanmj.xyz>, 2022 // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -16,25 +16,14 @@ // Struct definitions. use config::Config; -use sdl::Context; -use sdl2::event::Event; +use sdl::{Context, Drawable, Pane}; +use sdl2::event::{Event, WindowEvent}; use sdl2::pixels::*; use system::System; use util::Result; -pub trait Drawable { - fn draw(&mut self); - fn handle_events(&mut self) -> bool; -} - -pub struct DebugWindow<'a> { - context: Context, - system: &'a System, - config: &'a Config, -} - pub struct MainWindow<'a> { - context: Context, + pane: Pane, system: &'a System, config: &'a Config, } @@ -42,56 +31,32 @@ pub struct MainWindow<'a> { // Struct impls. impl<'a> Drawable for MainWindow<'a> { - fn draw(&mut self) {} - - fn handle_events(&mut self) -> bool { - false - } -} - -impl<'a> MainWindow<'a> { - pub fn new(config: &'a Config, system: &'a System) -> Result<Self> { - Ok(Self { - context: Context::new( - config.get_win_width(), - config.get_debug_win_height(), - format!("RISC II"), - )?, - system: system, - config: config, - }) - } -} - -impl<'a> DebugWindow<'a> { - pub fn new(config: &'a Config, system: &'a System) -> Result<Self> { - Ok(Self { - context: Context::new( - config.get_debug_win_width(), - config.get_debug_win_height(), - format!("Debug"), - )?, - system: system, - config: config, - }) - } -} - -impl<'a> Drawable for DebugWindow<'a> { - fn draw(&mut self) { - self.context.canvas.set_draw_color(Color::RGB(0, 0, 0)); - self.context.canvas.clear(); + fn draw(&mut self, context: &mut Context) { + self.pane.canvas.set_draw_color(Color::RGB(0, 0, 0)); + self.pane.canvas.clear(); // - self.context.canvas.present(); + self.pane.canvas.present(); } - fn handle_events(&mut self) -> bool { - let event_pump = &mut self.context.event_pump; + + fn handle_events(&mut self, context: &mut Context) -> bool { + // TODO need to segregate events based off of windows ourself in main. + let event_pump = &mut context.event_pump; + let window_id = self.pane.get_id(); for event in event_pump.poll_iter() { match event { Event::Quit { .. } => { return true; } + Event::Window { + win_event: WindowEvent::Close, + window_id: id, + .. + } => { + if id == window_id { + return true; + } + } Event::KeyDown { keycode: Some(kc), .. } => {} @@ -104,3 +69,18 @@ impl<'a> Drawable for DebugWindow<'a> { return false; } } + +impl<'a> MainWindow<'a> { + pub fn new(config: &'a Config, system: &'a System, context: &mut Context) -> Result<Self> { + Ok(Self { + pane: Pane::new( + config.get_win_width(), + config.get_debug_win_height(), + format!("RISC II"), + context, + )?, + system: system, + config: config, + }) + } +}