chip8/src/main.rs

85 lines
2.5 KiB
Rust

// I used: http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#00E0
// and https://en.wikipedia.org/wiki/CHIP-8#Opcode_table
// for information about how to implement a CHIP-8 Emulator
use chip8::emu::Chip8;
use std::path::Path;
use pixels::{wgpu::Surface, Pixels, SurfaceTexture};
use winit::dpi::LogicalSize;
use winit::event::{Event, VirtualKeyCode};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder};
use winit_input_helper::WinitInputHelper;
static WIDTH: u32 = 64;
static HEIGHT: u32 = 32;
fn main() {
let mut chip8: Chip8 = Default::default();
let mut input = WinitInputHelper::new();
let event_loop = EventLoop::new();
let window = init_window(&event_loop);
let mut pixels = init_pixels(&window);
let rom_path = Path::new("./games/ibm_logo.ch8");
chip8.load_rom(rom_path).expect("Unable to load ROM");
event_loop.run(move |event, _, control_flow| {
if let Event::RedrawRequested(_) = event {
draw(&chip8.display.buf, pixels.get_frame());
if pixels
.render()
.map_err(|e| eprintln!("pixels.render() failed: {}", e))
.is_err()
{
*control_flow = ControlFlow::Exit;
return;
}
}
if input.update(&event) {
if input.key_pressed(VirtualKeyCode::Escape) || input.quit() {
*control_flow = ControlFlow::Exit;
return;
}
if let Some(size) = input.window_resized() {
pixels.resize(size.width, size.height);
}
chip8.execute_cycle();
window.request_redraw();
}
});
}
fn init_pixels(window: &Window) -> Pixels {
let surface = Surface::create(window);
let texture = SurfaceTexture::new(WIDTH, HEIGHT, surface);
Pixels::new(WIDTH, HEIGHT, texture).unwrap()
}
fn init_window(event_loop: &EventLoop<()>) -> Window {
const SCALE: u32 = 10;
let min_size = LogicalSize::new(WIDTH as f64, HEIGHT as f64);
let size = LogicalSize::new((WIDTH * SCALE) as f64, (HEIGHT * SCALE) as f64);
WindowBuilder::new()
.with_title("Chip8 Emulator")
.with_inner_size(size)
.with_min_inner_size(min_size)
.build(event_loop)
.unwrap()
}
fn draw(chip8_gfx: &[u8], frame: &mut [u8]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
let rgba = if chip8_gfx[i] == 1 {
[0xFF; 4]
} else {
[0x00; 4]
};
pixel.copy_from_slice(&rgba);
}
}