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:
A | src/debug_window.rs | | | 80 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/main.rs | | | 21 | +++++++++++---------- |
M | src/sdl.rs | | | 45 | ++++++++++++++++++++++++++++++++++----------- |
M | src/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,
+ })
+ }
+}