Skip to content

Commit

Permalink
Chip-8: Add alternative fonts
Browse files Browse the repository at this point in the history
Those fonts are based on existing fonts from other CHIP-8
implementations, found here:
mattmikolay/chip-8#3

The fonts can be selected via the new --font command line option.
  • Loading branch information
felgru committed Feb 17, 2021
1 parent c064b2b commit 1155339
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 10 deletions.
142 changes: 141 additions & 1 deletion src/chip8/fonts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub const CHIP8_FONT: [u8; 16 * 5] = [
pub const CHIP48_FONT: [u8; 16 * 5] = [
// 0
0xF0, 0x90, 0x90, 0x90, 0xF0,
// 1
Expand Down Expand Up @@ -32,3 +32,143 @@ pub const CHIP8_FONT: [u8; 16 * 5] = [
// F
0xF0, 0x80, 0xF0, 0x80, 0x80,
];

pub const COSMAC_VIP_FONT: [u8; 16 * 5] = [
// 0
0xF0, 0x90, 0x90, 0x90, 0xF0,
// 1
0x60, 0x20, 0x20, 0x20, 0x70,
// 2
0xF0, 0x10, 0xF0, 0x80, 0xF0,
// 3
0xF0, 0x10, 0xF0, 0x10, 0xF0,
// 4
0xA0, 0xA0, 0xF0, 0x20, 0x20,
// 5
0xF0, 0x80, 0xF0, 0x10, 0xF0,
// 6
0xF0, 0x80, 0xF0, 0x90, 0xF0,
// 7
0xF0, 0x10, 0x10, 0x10, 0x10,
// 8
0xF0, 0x90, 0xF0, 0x90, 0xF0,
// 9
0xF0, 0x90, 0xF0, 0x10, 0xF0,
// A
0xF0, 0x90, 0xF0, 0x90, 0x90,
// B
0xF0, 0x50, 0x70, 0x50, 0xF0,
// C
0xF0, 0x80, 0x80, 0x80, 0xF0,
// D
0xF0, 0x50, 0x50, 0x50, 0xF0,
// E
0xF0, 0x80, 0xF0, 0x80, 0xF0,
// F
0xF0, 0x80, 0xF0, 0x80, 0x80,
];

pub const DREAM6800_FONT: [u8; 16 * 5] = [
// 0
0xE0, 0xA0, 0xA0, 0xA0, 0xE0,
// 1
0x40, 0x40, 0x40, 0x40, 0x40,
// 2
0xE0, 0x20, 0xE0, 0x80, 0xE0,
// 3
0xE0, 0x20, 0xE0, 0x20, 0xE0,
// 4
0xA0, 0xA0, 0xE0, 0x20, 0x20,
// 5
0xE0, 0x80, 0xE0, 0x20, 0xE0,
// 6
0xE0, 0x80, 0xE0, 0xA0, 0xE0,
// 7
0xE0, 0x20, 0x20, 0x20, 0x20,
// 8
0xE0, 0xA0, 0xE0, 0xA0, 0xE0,
// 9
0xE0, 0xA0, 0xE0, 0x20, 0xE0,
// A
0xE0, 0xA0, 0xE0, 0xA0, 0xA0,
// B
0x80, 0x80, 0xE0, 0xA0, 0xE0,
// C
0xE0, 0x80, 0x80, 0x80, 0xE0,
// D
0x20, 0x20, 0xE0, 0xA0, 0xE0,
// E
0xE0, 0x80, 0xE0, 0x80, 0xE0,
// F
0xE0, 0x80, 0xE0, 0x80, 0x80,
];

pub const ETI660_FONT: [u8; 16 * 5] = [
// 0
0xE0, 0xA0, 0xA0, 0xA0, 0xE0,
// 1
0x20, 0x20, 0x20, 0x20, 0x20,
// 2
0xE0, 0x20, 0xE0, 0x80, 0xE0,
// 3
0xE0, 0x20, 0xE0, 0x20, 0xE0,
// 4
0xA0, 0xA0, 0xE0, 0x20, 0x20,
// 5
0xE0, 0x80, 0xE0, 0x20, 0xE0,
// 6
0xE0, 0x80, 0xE0, 0xA0, 0xE0,
// 7
0xE0, 0x20, 0x20, 0x20, 0x20,
// 8
0xE0, 0xA0, 0xE0, 0xA0, 0xE0,
// 9
0xE0, 0xA0, 0xE0, 0x20, 0xE0,
// A
0xE0, 0xA0, 0xE0, 0xA0, 0xA0,
// B
0x80, 0x80, 0xE0, 0xA0, 0xE0,
// C
0xE0, 0x80, 0x80, 0x80, 0xE0,
// D
0x20, 0x20, 0xE0, 0xA0, 0xE0,
// E
0xE0, 0x80, 0xE0, 0x80, 0xE0,
// F
0xE0, 0x80, 0xE0, 0x80, 0x80,
];

pub const FISH_N_CHIPS_FONT: [u8; 16 * 5] = [
// 0
0x60, 0xA0, 0xA0, 0xA0, 0xC0,
// 1
0x40, 0xC0, 0x40, 0x40, 0xE0,
// 2
0xC0, 0x20, 0x40, 0x80, 0xE0,
// 3
0xC0, 0x20, 0x40, 0x20, 0xC0,
// 4
0x20, 0xA0, 0xE0, 0x20, 0x20,
// 5
0xE0, 0x80, 0xC0, 0x20, 0xC0,
// 6
0x40, 0x80, 0xC0, 0xA0, 0x40,
// 7
0xE0, 0x20, 0x60, 0x40, 0x40,
// 8
0x40, 0xA0, 0x40, 0xA0, 0x40,
// 9
0x40, 0xA0, 0x60, 0x20, 0x40,
// A
0x40, 0xA0, 0xE0, 0xA0, 0xA0,
// B
0xC0, 0xA0, 0xC0, 0xA0, 0xC0,
// C
0x60, 0x80, 0x80, 0x80, 0x60,
// D
0xC0, 0xA0, 0xA0, 0xA0, 0xC0,
// E
0xE0, 0x80, 0xC0, 0x80, 0xE0,
// F
0xE0, 0x80, 0xC0, 0x80, 0x80,
];
8 changes: 3 additions & 5 deletions src/chip8/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@ use std::io::Read;
use std::fs::File;
use std::ops::{Index, IndexMut};

use super::fonts::CHIP8_FONT;
use super::fonts::CHIP48_FONT;

const FONT_OFFSET: usize = 0x50;

pub struct Memory([u8; 4096]);

impl Default for Memory {
fn default() -> Self {
let mut memory = [0u8; 4096];
memory[FONT_OFFSET..FONT_OFFSET + 16 * 5].copy_from_slice(&CHIP8_FONT);
Self(memory)
Self::with_font(&CHIP48_FONT)
}
}

impl Memory {
fn with_font(font: &[u8; 16 * 5]) -> Self {
pub fn with_font(font: &[u8; 16 * 5]) -> Self {
let mut memory = [0u8; 4096];
memory[FONT_OFFSET..FONT_OFFSET + 16 * 5].copy_from_slice(font);
Self(memory)
Expand Down
22 changes: 19 additions & 3 deletions src/chip8/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,30 @@ impl Chip8 {
"64x128", //< HI-RES CHIP-8
];

pub fn new(display_size: &str) -> Self {
pub const AVAILABLE_FONTS: [&'static str; 5] = [
"chip48",
"cosmacvip",
"dream6800",
"eti660",
"fishnchips",
];

pub fn new(display_size: &str, font: &str) -> Self {
let (width, height) = match display_size {
"64x32" => (64, 32),
"128x64" => (128, 64),
"64x128" => (64, 128),
_ => panic!("Unexpected Chip8 display size: {}", display_size),
_ => panic!("Unexpected CHIP-8 display size: {}", display_size),
};
let font = match font {
"chip48" => &fonts::CHIP48_FONT,
"cosmacvip" => &fonts::COSMAC_VIP_FONT,
"dream6800" => &fonts::DREAM6800_FONT,
"eti660" => &fonts::ETI660_FONT,
"fishnchips" => &fonts::FISH_N_CHIPS_FONT,
_ => panic!("Unknown CHIP-8 font: {}", font),
};
let memory = memory::Memory::default();
let memory = memory::Memory::with_font(font);
let display = display::Display::new(width, height, FRAMERATE);
Self {
cpu: cpu::CPU::default(),
Expand Down
11 changes: 10 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@ fn main() {
.long("display")
.default_value("64x32")
.possible_values(&chip8::Chip8::AVAILABLE_DISPLAY_SIZES)
)
.arg(
Arg::new("font")
.about("font")
.takes_value(true)
.long("font")
.default_value("chip48")
.possible_values(&chip8::Chip8::AVAILABLE_FONTS)
),
)
.get_matches();
match matches.subcommand_name() {
Some("chip8") => {
let subcommand = matches.subcommand_matches("chip8").unwrap();
let display = subcommand.value_of("display").unwrap();
let mut chip8 = chip8::Chip8::new(display);
let font = subcommand.value_of("font").unwrap();
let mut chip8 = chip8::Chip8::new(display, font);
let filename = subcommand.value_of("rom-file").unwrap();
println!("loading {}", filename);
let f = File::open(filename).unwrap();
Expand Down

0 comments on commit 1155339

Please sign in to comment.