reafactor code: split tui bin into separated crated

This commit is contained in:
Denis-Cosmin Nutiu 2025-01-11 17:06:59 +02:00
parent a289a10798
commit 337b1ab05b
17 changed files with 94 additions and 70 deletions

View file

@ -2,7 +2,8 @@
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/emulator/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/chip8_core/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/chip8_tui/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />

28
Cargo.lock generated
View file

@ -111,11 +111,23 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chip8_tui"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"crossterm",
"emulator",
"env_logger",
"ratatui",
]
[[package]]
name = "clap"
version = "4.5.23"
version = "4.5.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
dependencies = [
"clap_builder",
"clap_derive",
@ -123,9 +135,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.23"
version = "4.5.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
dependencies = [
"anstream",
"anstyle",
@ -135,9 +147,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.18"
version = "4.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
dependencies = [
"heck",
"proc-macro2",
@ -248,13 +260,9 @@ name = "emulator"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"crossterm",
"env_logger",
"log",
"pretty_assertions",
"rand",
"ratatui",
]
[[package]]

View file

@ -2,5 +2,6 @@
resolver = "2"
members = [
"emulator",
]
"chip8_tui",
"chip8_core",
]

View file

@ -50,7 +50,7 @@ The project is written in Rust and it's organized in the following modules:
│   └── ibm-logo.ch8 # IBM Logo Test ROM
├── src
│   ├── display.rs # The screen / display module.
│   ├── emulator.rs # The emulator logic which emulates the CPU.
│   ├── chip8_core.rs # The chip8_core logic which emulates the CPU.
│   ├── input.rs # The input logic.
│   ├── instruction.rs # The instruction decoding logic.
│   ├── main.rs # The main file. This is the entrypoint.

View file

@ -6,18 +6,10 @@ edition = "2021"
[lints.rust]
dead_code = "allow"
[profile.release]
lto = true
codegen-units = 1
[dependencies]
log = "0.4.22"
env_logger = "0.11.5"
anyhow = "1.0.93"
ratatui = "0.29.0"
crossterm = "0.28.1"
rand = "0.8.5"
clap = { version = "4.5.23", features = ["derive"] }
[dev-dependencies]
pretty_assertions = "1.4.1"

13
chip8_core/src/display.rs Normal file
View file

@ -0,0 +1,13 @@
/// Represents the display's width in pixels.
pub const DISPLAY_WIDTH: usize = 64;
/// Represents the display's height pixels.
pub const DISPLAY_HEIGHT: usize = 32;
/// Display trait
pub trait Display {
/// Re-draws the display.
fn clear(&mut self);
/// Renders the display data on screen.
fn render(&mut self, display_data: &[bool; DISPLAY_WIDTH * DISPLAY_HEIGHT]);
}

View file

@ -42,7 +42,7 @@ where
S: SoundModule,
I: InputModule,
{
/// Memory represents the emulator's memory.
/// Memory represents the chip8_core's memory.
memory: [u8; MEMORY_SIZE],
/// Registers holds the general purpose registers.
registers: [u8; NUMBER_OF_REGISTERS],
@ -63,7 +63,7 @@ where
sound_module: S,
/// The module responsible for receiving user input.
input_module: I,
/// The stack of the emulator.
/// The stack of the chip8_core.
stack: Stack<u16>,
/// Holds the display data, each bit corresponds to a pixel.
display_data: [bool; DISPLAY_WIDTH * DISPLAY_HEIGHT],
@ -467,7 +467,7 @@ where
]))
}
/// Loads the ROM found at the rom path in the emulator's RAM memory.
/// Loads the ROM found at the rom path in the chip8_core's RAM memory.
fn load_rom<T>(&mut self, mut rom: T) -> Result<(), anyhow::Error>
where
T: Read,

16
chip8_core/src/input.rs Normal file
View file

@ -0,0 +1,16 @@
/// InputModule retrieves the keys from the hardware or software input control module.
pub trait InputModule {
/// Returns the key value of the corresponding pressed key.
/// None if no key is pressed.
fn get_key_pressed(&mut self) -> Option<u16>;
}
/// NoInput always returns none when queried for input.
#[derive(Clone)]
pub struct NoInput;
impl InputModule for NoInput {
fn get_key_pressed(&mut self) -> Option<u16> {
None
}
}

6
chip8_core/src/lib.rs Normal file
View file

@ -0,0 +1,6 @@
pub mod display;
pub mod emulator;
pub mod input;
pub mod instruction;
pub mod sound;
pub mod stack;

5
chip8_core/src/sound.rs Normal file
View file

@ -0,0 +1,5 @@
/// SoundModule represents a module which can produce sound.
pub trait SoundModule {
/// beep makes a beep sound.
fn beep(&mut self);
}

16
chip8_tui/Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "chip8_tui"
version = "0.1.0"
edition = "2021"
[profile.release]
lto = true
codegen-units = 1
[dependencies]
emulator = { path = "../chip8_core" }
clap = { version = "4.5.26", features = ["derive"] }
anyhow = "1.0.95"
env_logger = "0.11.6"
ratatui = "0.29.0"
crossterm = "0.28.1"

View file

@ -3,23 +3,12 @@ use ratatui::style::{Style, Stylize};
use ratatui::widgets::{Block, Borders};
use ratatui::DefaultTerminal;
/// Represents the display's width in pixels.
pub const DISPLAY_WIDTH: usize = 64;
use emulator::display::{Display, DISPLAY_HEIGHT, DISPLAY_WIDTH};
/// Represents the display's height pixels.
pub const DISPLAY_HEIGHT: usize = 32;
/// Display trait
pub trait Display {
/// Re-draws the display.
fn clear(&mut self);
/// Renders the display data on screen.
fn render(&mut self, display_data: &[bool; DISPLAY_WIDTH * DISPLAY_HEIGHT]);
}
/// Simple terminal display for the Chip8's emulator.
/// Simple terminal display for the Chip8's chip8_core.
pub struct TerminalDisplay {}
#[allow(dead_code)]
impl TerminalDisplay {
pub fn new() -> TerminalDisplay {
TerminalDisplay {}

View file

@ -1,24 +1,8 @@
use crossterm::event::{poll, read, Event, KeyCode};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use emulator::input::InputModule;
use std::time::Duration;
/// InputModule retrieves the keys from the hardware or software input control module.
pub trait InputModule {
/// Returns the key value of the corresponding pressed key.
/// None if no key is pressed.
fn get_key_pressed(&mut self) -> Option<u16>;
}
/// NoInput always returns none when queried for input.
#[derive(Clone)]
pub struct NoInput;
impl InputModule for NoInput {
fn get_key_pressed(&mut self) -> Option<u16> {
None
}
}
/// CrossTermInput implements input events via the crossterm crate.
#[derive(Clone)]
pub struct CrossTermInput {

View file

@ -1,21 +1,18 @@
mod display;
mod input;
mod sound;
use crate::display::RatatuiDisplay;
use crate::emulator::Emulator;
use crate::input::CrossTermInput;
use crate::sound::TerminalSound;
use clap::Parser;
use emulator::emulator::Emulator;
use std::fs::File;
mod display;
mod emulator;
mod input;
mod instruction;
mod sound;
mod stack;
#[derive(Parser, Debug)]
#[command(
version = "1.0",
about = "A Chip8 emulator.",
about = "A Chip8 chip8_core.",
long_about = "A program which emulates the Chip8 system."
)]
struct CliArgs {

View file

@ -1,8 +1,4 @@
/// SoundModule represents a module which can produce sound.
pub trait SoundModule {
/// beep makes a beep sound.
fn beep(&mut self);
}
use emulator::sound::SoundModule;
/// TerminalSound is a simple module that makes terminal beep sound.
pub struct TerminalSound;