implement sdl2 display module
This commit is contained in:
parent
86acbf6fc8
commit
86680d85a3
6 changed files with 215 additions and 5 deletions
|
@ -4,6 +4,7 @@
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/chip8_core/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/chip8_core/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/chip8_tui/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/chip8_tui/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/chip8_sdl/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
61
Cargo.lock
generated
61
Cargo.lock
generated
|
@ -78,6 +78,12 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
@ -111,6 +117,18 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chip8_sdl"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"clap",
|
||||||
|
"emulator",
|
||||||
|
"env_logger",
|
||||||
|
"log",
|
||||||
|
"sdl2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chip8_tui"
|
name = "chip8_tui"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -189,7 +207,7 @@ version = "0.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
"mio",
|
"mio",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
@ -396,6 +414,12 @@ version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.169"
|
version = "0.2.169"
|
||||||
|
@ -553,7 +577,7 @@ version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b"
|
checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
"cassowary",
|
"cassowary",
|
||||||
"compact_str",
|
"compact_str",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
@ -574,7 +598,7 @@ version = "0.5.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -612,7 +636,7 @@ version = "0.38.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
|
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
|
@ -637,6 +661,29 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sdl2"
|
||||||
|
version = "0.37.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b498da7d14d1ad6c839729bd4ad6fc11d90a57583605f3b4df2cd709a9cd380"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"sdl2-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sdl2-sys"
|
||||||
|
version = "0.37.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "951deab27af08ed9c6068b7b0d05a93c91f0a8eb16b6b816a5e73452a43521d3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"version-compare",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook"
|
name = "signal-hook"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
|
@ -759,6 +806,12 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version-compare"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -7,4 +7,5 @@ resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"chip8_tui",
|
"chip8_tui",
|
||||||
"chip8_core",
|
"chip8_core",
|
||||||
|
"chip8_sdl",
|
||||||
]
|
]
|
||||||
|
|
|
@ -18,5 +18,5 @@ pub(crate) struct TestingDisplay;
|
||||||
impl Display for TestingDisplay {
|
impl Display for TestingDisplay {
|
||||||
fn clear(&mut self) {}
|
fn clear(&mut self) {}
|
||||||
|
|
||||||
fn render(&mut self, display_data: &[bool; DISPLAY_WIDTH * DISPLAY_HEIGHT]) {}
|
fn render(&mut self, _display_data: &[bool; DISPLAY_WIDTH * DISPLAY_HEIGHT]) {}
|
||||||
}
|
}
|
||||||
|
|
12
chip8_sdl/Cargo.toml
Normal file
12
chip8_sdl/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "chip8_sdl"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
emulator = { path = "../chip8_core" }
|
||||||
|
env_logger = "0.11.6"
|
||||||
|
clap = { version = "4.5.26", features = ["derive"] }
|
||||||
|
anyhow = "1.0.95"
|
||||||
|
sdl2 = { version = "0.37.0", features = ["unsafe_textures"] }
|
||||||
|
log = "0.4.22"
|
143
chip8_sdl/src/main.rs
Normal file
143
chip8_sdl/src/main.rs
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use clap::Parser;
|
||||||
|
use emulator::display::{Display, DISPLAY_HEIGHT, DISPLAY_WIDTH};
|
||||||
|
use emulator::emulator::Emulator;
|
||||||
|
use emulator::input::InputModule;
|
||||||
|
use emulator::sound::SoundModule;
|
||||||
|
use log::error;
|
||||||
|
use sdl2::pixels::Color;
|
||||||
|
use sdl2::rect::Rect;
|
||||||
|
use sdl2::render::WindowCanvas;
|
||||||
|
use sdl2::Sdl;
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
const BACKGROUND_COLOR: Color = Color::RGB(0, 0, 0);
|
||||||
|
const PIXEL_COLOR: Color = Color::RGB(0, 255, 0);
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(
|
||||||
|
version = "1.0",
|
||||||
|
about = "A Chip8 chip8_core.",
|
||||||
|
long_about = "A program which emulates the Chip8 system."
|
||||||
|
)]
|
||||||
|
struct CliArgs {
|
||||||
|
/// The path to the ROM file to emulate.
|
||||||
|
rom_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SDL2 display module for the Chip8 emulator.
|
||||||
|
struct SDLDisplayBackend {
|
||||||
|
canvas: WindowCanvas,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SDLDisplayBackend {
|
||||||
|
fn new(sdl_context: &Sdl) -> Result<Self, anyhow::Error> {
|
||||||
|
let video_subsystem = sdl_context.video().map_err(|s| anyhow!(s))?;
|
||||||
|
|
||||||
|
let window = video_subsystem
|
||||||
|
.window("Chip8 Emulator by nuculabs.dev", 816, 648)
|
||||||
|
.vulkan()
|
||||||
|
.build()
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
.map_err(|s| anyhow!(s))?;
|
||||||
|
|
||||||
|
let canvas = window
|
||||||
|
.into_canvas()
|
||||||
|
.build()
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
.map_err(|s| anyhow!(s))?;
|
||||||
|
|
||||||
|
Ok(SDLDisplayBackend { canvas })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SDLDisplayBackend {
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.canvas.set_draw_color(BACKGROUND_COLOR);
|
||||||
|
self.canvas.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, display_data: &[bool; DISPLAY_WIDTH * DISPLAY_HEIGHT]) {
|
||||||
|
for row in 0..32 {
|
||||||
|
for column in 0..64 {
|
||||||
|
if display_data[row * DISPLAY_WIDTH + column] {
|
||||||
|
self.canvas.set_draw_color(PIXEL_COLOR);
|
||||||
|
let result = self.canvas.fill_rect(Rect::new(
|
||||||
|
column as i32 * 12 + 24,
|
||||||
|
row as i32 * 18 + 18,
|
||||||
|
12,
|
||||||
|
18,
|
||||||
|
));
|
||||||
|
if let Err(error_message) = result {
|
||||||
|
error!("{}", error_message)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.canvas.set_draw_color(BACKGROUND_COLOR);
|
||||||
|
let result = self.canvas.fill_rect(Rect::new(
|
||||||
|
column as i32 * 12 + 24,
|
||||||
|
row as i32 * 18 + 18,
|
||||||
|
12,
|
||||||
|
18,
|
||||||
|
));
|
||||||
|
if let Err(error_message) = result {
|
||||||
|
error!("{}", error_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.canvas.present()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DummySound;
|
||||||
|
|
||||||
|
impl SoundModule for DummySound {
|
||||||
|
fn beep(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct DummyInputHandler;
|
||||||
|
|
||||||
|
impl InputModule for DummyInputHandler {
|
||||||
|
fn get_key_pressed(&mut self) -> Option<u16> {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), anyhow::Error> {
|
||||||
|
env_logger::init();
|
||||||
|
let args = CliArgs::parse();
|
||||||
|
|
||||||
|
let file = File::open(&args.rom_path)?;
|
||||||
|
|
||||||
|
let sdl_context = sdl2::init().map_err(|s| anyhow!(s))?;
|
||||||
|
|
||||||
|
let sdl_display_backend: SDLDisplayBackend = SDLDisplayBackend::new(&sdl_context)?;
|
||||||
|
|
||||||
|
let mut emulator = Emulator::new(sdl_display_backend, DummySound, DummyInputHandler);
|
||||||
|
emulator.emulate(file)?;
|
||||||
|
|
||||||
|
// let event_pump = sdl_context.event_pump().map_err(|s| anyhow!(s))?;
|
||||||
|
|
||||||
|
// Show it on the screen
|
||||||
|
// canvas.present();
|
||||||
|
// let mut index = 0;
|
||||||
|
// 'main: loop {
|
||||||
|
// index += 10;
|
||||||
|
// canvas.fill_rect(Rect::new(index, 100, 10, 10))?;
|
||||||
|
// canvas.present();
|
||||||
|
// thread::sleep(Duration::new(1, 0));
|
||||||
|
// for event in event_pump.poll_iter() {
|
||||||
|
// match event {
|
||||||
|
// Event::Quit { .. }
|
||||||
|
// | Event::KeyDown {
|
||||||
|
// keycode: Some(Keycode::Escape),
|
||||||
|
// ..
|
||||||
|
// } => break 'main,
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in a new issue