From 668d2a18d54819d6b16fca2bbb2dabf1838d1372 Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sun, 24 Nov 2024 21:00:32 +0200 Subject: [PATCH] Add terminal display.rs --- Cargo.toml | 3 +++ src/display.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ src/emulator.rs | 16 ++++++++++------ src/main.rs | 4 +++- 4 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 src/display.rs diff --git a/Cargo.toml b/Cargo.toml index 0fa5b53..06b0ba7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,9 @@ name = "Chip8Emulator" version = "0.1.0" edition = "2021" +[lints.rust] +dead_code = "allow" + [dependencies] log = "0.4.22" env_logger = "0.11.5" diff --git a/src/display.rs b/src/display.rs new file mode 100644 index 0000000..9a29593 --- /dev/null +++ b/src/display.rs @@ -0,0 +1,50 @@ + +/// Represents the display's width in pixels. +const DISPLAY_WIDTH: usize = 64; + +/// Represents the display's height pixels. +const DISPLAY_HEIGHT: usize = 32; + +/// Display trait +pub trait Display { + /// Re-draws the display. + fn redraw(&self); + /// Draws the display. + fn draw(&mut self); +} + +/// Display models the Chip8's display. +pub struct TerminalDisplay { + /// Holds the display data, each bit corresponds to a pixel. + display_data: [bool; DISPLAY_WIDTH * DISPLAY_HEIGHT], +} + +impl TerminalDisplay { + pub fn new() -> TerminalDisplay { + TerminalDisplay { + display_data: [false; DISPLAY_WIDTH * DISPLAY_HEIGHT] + } + } +} + +impl Display for TerminalDisplay { + /// Re-draws the display. + fn redraw(&self) { + // ANSI Escape code to move cursor to row 1 column 1 + // See https://stackoverflow.com/a/4062051 + print!("{esc}[2J{esc}[1;1H", esc = 27 as char); + } + /// Draws the display. + fn draw(&mut self) { + for row in 0..32 { + for column in 0..64 { + if self.display_data[row * DISPLAY_WIDTH + column] { + print!("█") + } else { + print!(" ") + } + } + print!("\n") + } + } +} \ No newline at end of file diff --git a/src/emulator.rs b/src/emulator.rs index 17d771a..82c2696 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -2,7 +2,8 @@ use anyhow::anyhow; use log::{debug, info}; use std::fs::File; use std::io::Read; -use std::path::Path; +use std::path::{Path}; +use crate::display::{Display, TerminalDisplay}; const MEMORY_SIZE: usize = 4096; const NUMBER_OF_REGISTERS: usize = 16; @@ -42,15 +43,18 @@ pub struct Emulator { sound_timer: u8, /// The stack pointer register. stack_pointer: u8, + /// The display_data holds all the data associated with the display + display: Box } impl Emulator { /// Creates a new `Emulator` instance. /// - pub fn new() -> Emulator { + pub fn new(display: Box) -> Emulator { let mut emulator = Emulator { - memory: [0; 4096], - registers: [0; 16], + memory: [0; MEMORY_SIZE], + registers: [0; NUMBER_OF_REGISTERS], + display, index_register: 0, program_counter: 0, delay_timer: 0, @@ -113,7 +117,7 @@ mod tests { #[test] fn test_load_font_data() { - let emulator = Emulator::new(); + let emulator = Emulator::new(Box::from(TerminalDisplay::new())); assert_eq!(emulator.memory[0xf0..0xf0 + 80], FONT_SPRITES) } @@ -126,7 +130,7 @@ mod tests { .expect("Failed to read test ROM"); // Test - let mut emulator = Emulator::new(); + let mut emulator = Emulator::new(Box::from(TerminalDisplay::new())); emulator .load_rom("roms/ibm-logo.ch8") .expect("failed to load ROM"); diff --git a/src/main.rs b/src/main.rs index c40446e..f8288ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,14 @@ use crate::emulator::Emulator; use env_logger; +use crate::display::TerminalDisplay; mod emulator; +mod display; fn main() -> Result<(), anyhow::Error> { env_logger::init(); - let mut emulator = Emulator::new(); + let mut emulator = Emulator::new(Box::from(TerminalDisplay::new())); emulator.emulate(String::from("./roms/ibm-logo.ch8"))?;