[gpu] Add screen
This commit is contained in:
42
Cargo.lock
generated
42
Cargo.lock
generated
@@ -50,12 +50,24 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.1"
|
||||
@@ -173,6 +185,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"clap",
|
||||
"log",
|
||||
"sdl2",
|
||||
"simple_logger",
|
||||
]
|
||||
|
||||
@@ -200,6 +213,29 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sdl2"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8356b2697d1ead5a34f40bcc3c5d3620205fe0c7be0a14656223bfeec0258891"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"sdl2-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sdl2-sys"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26bcacfdd45d539fb5785049feb0038a63931aa896c7763a2a12e125ec58bd29"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
@@ -294,6 +330,12 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
@@ -10,7 +10,7 @@ clap = { version = "4.5", features = ["derive"] }
|
||||
log = "0.4.20"
|
||||
simple_logger = "4.3"
|
||||
byteorder = "1.5"
|
||||
#sdl2 = "0.36.0"
|
||||
sdl2 = "0.36.0"
|
||||
|
||||
[profile.release]
|
||||
#strip = true
|
||||
|
@@ -1,65 +0,0 @@
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use crate::device::cpu::Instruction::{ClearScreen, JumpTo, SetRegister};
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
enum Instruction {
|
||||
ClearScreen,
|
||||
/// Jump to location
|
||||
JumpTo(u16),
|
||||
SetRegister(usize, u8),
|
||||
AddValueToRegister(usize, u8),
|
||||
SetIndex(u16),
|
||||
///
|
||||
DRAW(usize, usize, u8),
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
pub fn parse_fetched_instruction(location: &[u8]) -> Instruction {
|
||||
assert_eq!(location.len(), 2);
|
||||
let instruction = BigEndian::read_u16(location);
|
||||
|
||||
if instruction == 0xe0 {
|
||||
return ClearScreen;
|
||||
} else if (instruction & 0x1000) == 0x1000 {
|
||||
return JumpTo(instruction & 0xfff);
|
||||
} else if (instruction & 0x6000) == 0x6000 {
|
||||
return SetRegister(((instruction & 0x0f00)>>8) as usize, (instruction & 0xff) as u8);
|
||||
} else {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::device::cpu::Instruction;
|
||||
use crate::device::cpu::Instruction::{ClearScreen, JumpTo, SetRegister};
|
||||
|
||||
#[test]
|
||||
fn test_clear_screen() {
|
||||
let instruction_bytes = 0x00e0_u16.to_be_bytes();
|
||||
let ins = Instruction::parse_fetched_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, ClearScreen);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_jump_to_instruction_1() {
|
||||
let instruction_bytes = 0x1123_u16.to_be_bytes();
|
||||
let ins = Instruction::parse_fetched_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, JumpTo(0x123));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_jump_to_instruction_2() {
|
||||
let instruction_bytes = 0x1faf_u16.to_be_bytes();
|
||||
let ins = Instruction::parse_fetched_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, JumpTo(0xfaf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_instruction(){
|
||||
let instruction_bytes = 0x6a00_u16.to_be_bytes();
|
||||
let ins = Instruction::parse_fetched_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, SetRegister(10,0));
|
||||
}
|
||||
}
|
@@ -1,8 +1,10 @@
|
||||
use std::ops::SubAssign;
|
||||
use std::sync::atomic::{AtomicU16, Ordering};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::thread;
|
||||
use std::thread::{JoinHandle, sleep};
|
||||
use std::time::Duration;
|
||||
use crate::device::instruction::Instruction;
|
||||
use crate::device::timer::Timer;
|
||||
|
||||
|
||||
@@ -10,24 +12,30 @@ pub struct Device {
|
||||
pub registers: RegisterFile,
|
||||
pub memory: Box<[u8; Self::DEVICE_MEMORY_SIZE]>,
|
||||
pub timer: Timer,
|
||||
pub stack: Vec<u16>
|
||||
pub stack: Vec<u16>,
|
||||
pub frame_buffer: Arc<Mutex<Box<[u8;64*32]>>>
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub const DEVICE_MEMORY_SIZE: usize = 2 << 12;
|
||||
pub fn new(timer: Timer) -> Device {
|
||||
pub const DEVICE_MEMORY_SIZE: usize = 1 << 12;
|
||||
pub const FRAME_BUFFER_WIDTH: usize = 64;
|
||||
pub const FRAME_BUFFER_HEIGHT: usize = 32;
|
||||
pub const FRAME_BUFFER_SIZE: usize = Self::FRAME_BUFFER_WIDTH*Self::FRAME_BUFFER_HEIGHT;
|
||||
pub fn new(timer: Timer, fb: Arc<Mutex<Box<[u8;64*32]>>>) -> Device {
|
||||
let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE].into_boxed_slice().try_into().unwrap();
|
||||
log::trace!("Successfully initiated device memory");
|
||||
Device {
|
||||
registers: RegisterFile::new(),
|
||||
memory,
|
||||
stack:Vec::with_capacity(16),
|
||||
frame_buffer: fb,
|
||||
stack: Vec::with_capacity(16),
|
||||
timer,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Device{
|
||||
const DEFAULT_FONT:[u8;5*16] = [
|
||||
|
||||
impl Device {
|
||||
const DEFAULT_FONT: [u8; 5 * 16] = [
|
||||
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
|
||||
0x20, 0x60, 0x20, 0x20, 0x70, // 1
|
||||
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
|
||||
@@ -45,30 +53,63 @@ impl Device{
|
||||
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
||||
0xF0, 0x80, 0xF0, 0x80, 0x80 // F
|
||||
];
|
||||
const FONT_DEFAULT_MEM_LOCATION_START:usize = 0x50;
|
||||
const FONT_DEFAULT_MEM_LOCATION_END:usize = 0x9F;
|
||||
const ROM_START:usize = 0x200;
|
||||
pub fn cycle(&mut self){
|
||||
|
||||
const FONT_DEFAULT_MEM_LOCATION_START: usize = 0x50;
|
||||
const FONT_DEFAULT_MEM_LOCATION_END: usize = 0x9F;
|
||||
const ROM_START: usize = 0x200;
|
||||
pub fn cycle(&mut self) {
|
||||
let pc = self.registers.pc as usize;
|
||||
let instr_slice = self.memory.get(pc..pc + 2).expect("Failed to get memory");
|
||||
self.registers.pc += 2;
|
||||
let instruction = Instruction::decode_instruction(instr_slice);
|
||||
self.execute_instruction(instruction);
|
||||
}
|
||||
pub fn execute_instruction(&mut self, instruction: Instruction) {
|
||||
// thread::sleep(Duration::from_millis(250));
|
||||
log::trace!("Executing {:?}, {:?}",&instruction,&self.registers);
|
||||
match instruction{
|
||||
Instruction::PassThrough => {
|
||||
log::info!("Executing passthrough");
|
||||
}
|
||||
Instruction::ClearScreen => {
|
||||
log::info!("ClearScreen")
|
||||
}
|
||||
Instruction::JumpTo(new_pc) => {
|
||||
self.registers.pc = new_pc;
|
||||
}
|
||||
Instruction::SetRegister(reg_location, value) => {
|
||||
self.registers.v[reg_location] = value;
|
||||
}
|
||||
Instruction::AddValueToRegister(reg_location, value) => {
|
||||
self.registers.v[reg_location] += value;
|
||||
}
|
||||
Instruction::SetIndex(value) => {
|
||||
self.registers.i = value;
|
||||
}
|
||||
Instruction::Draw(x, y, n) => {
|
||||
let frame_buffer = self.frame_buffer.lock();
|
||||
log::warn!("Draw call unimplemented");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn set_default_font(&mut self){
|
||||
pub fn set_default_font(&mut self) {
|
||||
log::info!("Loaded default font from memory");
|
||||
self.memory[Self::FONT_DEFAULT_MEM_LOCATION_START..=Self::FONT_DEFAULT_MEM_LOCATION_END].copy_from_slice(&Self::DEFAULT_FONT);
|
||||
}
|
||||
/// load a rom from bytes
|
||||
pub fn load_rom(&mut self,rom: &[u8]){
|
||||
pub fn load_rom(&mut self, rom: &[u8]) {
|
||||
log::info!("Loaded ROM from memory");
|
||||
self.memory[Self::ROM_START..].copy_from_slice(rom);
|
||||
}
|
||||
|
||||
}
|
||||
impl Drop for Device{
|
||||
|
||||
impl Drop for Device {
|
||||
fn drop(&mut self) {
|
||||
self.timer.send_stop_signal()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RegisterFile {
|
||||
pub v: [u8; 0x10],
|
||||
/// program counter - only u12 technically.
|
||||
@@ -78,7 +119,7 @@ pub struct RegisterFile {
|
||||
}
|
||||
|
||||
impl RegisterFile {
|
||||
pub const DEFAULT_PC_VALUE:u16 = Device::ROM_START as u16;
|
||||
pub const DEFAULT_PC_VALUE: u16 = Device::ROM_START as u16;
|
||||
pub fn new() -> RegisterFile {
|
||||
RegisterFile {
|
||||
v: [0; 0x10],
|
||||
|
131
src/device/instruction.rs
Normal file
131
src/device/instruction.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use crate::device::instruction::Instruction::{AddValueToRegister, ClearScreen, Draw, JumpTo, PassThrough, SetIndex, SetRegister};
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub enum Instruction {
|
||||
/// Blanket instruction that does nothing
|
||||
PassThrough,
|
||||
/// 00E0 - Clear the screen
|
||||
ClearScreen,
|
||||
/// 1NNN - Jump to location
|
||||
JumpTo(u16),
|
||||
/// 6XNN - Set register to value
|
||||
SetRegister(usize, u8),
|
||||
/// 7XNN - Add value to register
|
||||
AddValueToRegister(usize, u8),
|
||||
/// ANNN - Set index value
|
||||
SetIndex(u16),
|
||||
///
|
||||
Draw(usize, usize, u8),
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
pub fn decode_instruction(location: &[u8]) -> Instruction {
|
||||
assert_eq!(location.len(), 2);
|
||||
let instruction = BigEndian::read_u16(location);
|
||||
let outer_instruction_nibble = (instruction & 0xF000) >> 12;
|
||||
match outer_instruction_nibble {
|
||||
0x0 if instruction == 0xe0 => {
|
||||
ClearScreen
|
||||
}
|
||||
0x0 => {
|
||||
log::warn!("Ignoring unsupported instruction {}",instruction);
|
||||
PassThrough
|
||||
}
|
||||
0x1 => {
|
||||
JumpTo(instruction & 0xfff)
|
||||
}
|
||||
0x6 => {
|
||||
SetRegister(((instruction & 0x0f00) >> 8) as usize, (instruction & 0xff) as u8)
|
||||
}
|
||||
0x7 => {
|
||||
AddValueToRegister(((instruction & 0x0f00) >> 8) as usize, (instruction & 0xff) as u8)
|
||||
}
|
||||
0xA => {
|
||||
SetIndex(instruction & 0xfff)
|
||||
}
|
||||
0xD => {
|
||||
let x = (instruction & 0xf00) >> 8;
|
||||
let y = (instruction & 0xf0) >> 4;
|
||||
let n = instruction & 0xf;
|
||||
Draw(x as usize, y as usize, n as u8)
|
||||
}
|
||||
0x8 => {
|
||||
todo!("Arithmetic instructions pending")
|
||||
}
|
||||
_ => {
|
||||
todo!("Unimplemented instruction")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::device::instruction::Instruction;
|
||||
use crate::device::instruction::Instruction::{AddValueToRegister, ClearScreen, Draw, JumpTo, SetIndex, SetRegister};
|
||||
|
||||
#[test]
|
||||
fn test_clear_screen() {
|
||||
let instruction_bytes = 0x00e0_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, ClearScreen);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_other_0x0nnn_instructions_panic() {
|
||||
let instruction_bytes = 0x00f0_u16.to_be_bytes();
|
||||
Instruction::decode_instruction(&instruction_bytes);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_jump_to_instruction_1() {
|
||||
let instruction_bytes = 0x1123_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, JumpTo(0x123));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_jump_to_instruction_2() {
|
||||
let instruction_bytes = 0x1faf_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, JumpTo(0xfaf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_register_instruction() {
|
||||
let instruction_bytes = 0x6a00_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, SetRegister(10, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_register_instruction_2() {
|
||||
let instruction_bytes = 0x6f23_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, SetRegister(15, 0x23));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_register_instruction_2() {
|
||||
let instruction_bytes = 0x7f23_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, AddValueToRegister(15, 0x23));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_index() {
|
||||
let instruction_bytes = 0xafaf_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, SetIndex(0xfaf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_draw() {
|
||||
let instruction_bytes = 0xdfab_u16.to_be_bytes();
|
||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||
assert_eq!(ins, Draw(0xf, 0xa, 0xb))
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
pub mod timer;
|
||||
mod device;
|
||||
mod sound;
|
||||
mod cpu;
|
||||
pub mod instruction;
|
||||
|
||||
pub use device::*;
|
||||
|
24
src/kb_map.rs
Normal file
24
src/kb_map.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use sdl2::keyboard::Keycode;
|
||||
|
||||
/// get index of key pressed. 0..9+A..F provides a u8
|
||||
pub fn get_key_index(p0: Keycode) -> Option<u8> {
|
||||
match p0 {
|
||||
Keycode::Kp0 => Some(0x0),
|
||||
Keycode::Kp1 => Some(0x1),
|
||||
Keycode::Kp2 => Some(0x2),
|
||||
Keycode::Kp3 => Some(0x3),
|
||||
Keycode::Kp4 => Some(0x4),
|
||||
Keycode::Kp5 => Some(0x5),
|
||||
Keycode::Kp6 => Some(0x6),
|
||||
Keycode::Kp7 => Some(0x7),
|
||||
Keycode::Kp8 => Some(0x8),
|
||||
Keycode::Kp9 => Some(0x9),
|
||||
Keycode::A => Some(0xA),
|
||||
Keycode::B => Some(0xB),
|
||||
Keycode::C => Some(0xC),
|
||||
Keycode::D => Some(0xD),
|
||||
Keycode::E => Some(0xE),
|
||||
Keycode::F => Some(0xF),
|
||||
_ => None
|
||||
}
|
||||
}
|
126
src/main.rs
126
src/main.rs
@@ -1,10 +1,23 @@
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use log::LevelFilter;
|
||||
use sdl2::audio::{AudioQueue, AudioSpecDesired};
|
||||
use sdl2::event::Event;
|
||||
use sdl2::EventPump;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::pixels::Color;
|
||||
use sdl2::render::{BlendMode, WindowCanvas};
|
||||
use simple_logger::SimpleLogger;
|
||||
use device::timer::Timer;
|
||||
use crate::device::Device;
|
||||
use crate::kb_map::get_key_index;
|
||||
|
||||
mod args;
|
||||
mod device;
|
||||
mod kb_map;
|
||||
|
||||
fn main() {
|
||||
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap();
|
||||
@@ -13,10 +26,117 @@ fn main() {
|
||||
let mut timer = Timer::new();
|
||||
timer.start();
|
||||
|
||||
let mut device = Device::new(timer);
|
||||
device.set_default_font();
|
||||
let mut i = 0;
|
||||
let frame_buffer = get_frame_buffer();
|
||||
let frame_buffer_for_display = Arc::clone(&frame_buffer);
|
||||
|
||||
let (sender,receiver) = std::sync::mpsc::channel();
|
||||
|
||||
let compute_handle = thread::spawn(move ||{
|
||||
|
||||
let mut device = Device::new(timer, frame_buffer);
|
||||
device.set_default_font();
|
||||
{
|
||||
let rom = load_rom();
|
||||
device.load_rom(&rom);
|
||||
}
|
||||
|
||||
loop {
|
||||
let val = receiver.try_recv();
|
||||
if let Ok(()) = val{
|
||||
break;
|
||||
}else if let Err(std::sync::mpsc::TryRecvError::Disconnected) = val{
|
||||
panic!("Disconnected");
|
||||
}
|
||||
device.cycle();
|
||||
}
|
||||
});
|
||||
|
||||
let (mut canvas, mut event_pump) = initiate_sdl(2f32);
|
||||
|
||||
canvas.set_draw_color(Color::BLACK);
|
||||
canvas.clear();
|
||||
'running: loop {
|
||||
for event in event_pump.poll_iter() {
|
||||
match event {
|
||||
Event::Quit { .. } |
|
||||
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
||||
sender.send(()).expect("Could not send");
|
||||
break 'running;
|
||||
}
|
||||
Event::KeyDown { keycode: Some(x), repeat: false, .. } => {
|
||||
if let Some(key_val) = get_key_index(x) {
|
||||
log::info!("Key+ {}",key_val)
|
||||
}
|
||||
}
|
||||
Event::KeyUp { keycode: Some(x), repeat: false, .. } => {
|
||||
if let Some(key_val) = get_key_index(x) {
|
||||
log::info!("Key- {}",key_val)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The rest of the game loop goes here...
|
||||
{
|
||||
let lock = frame_buffer_for_display.lock().expect("Failed to get Display");
|
||||
log::info!("Framebuffer status: {:?}",lock);
|
||||
}
|
||||
canvas.present();
|
||||
|
||||
|
||||
// 60fps - small offset to consider for cpu cycle time
|
||||
std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60 - 2000_000));
|
||||
}
|
||||
|
||||
|
||||
compute_handle.join().unwrap();
|
||||
|
||||
}
|
||||
|
||||
fn get_frame_buffer() -> Arc<Mutex<Box<[u8; 2048]>>> {
|
||||
Arc::new(Mutex::new(vec![0u8; Device::FRAME_BUFFER_SIZE].into_boxed_slice().try_into().unwrap()))
|
||||
}
|
||||
|
||||
const ROM_SIZE:usize = 4096 - 0x200;
|
||||
fn load_rom()->[u8;ROM_SIZE]{
|
||||
let mut rom_slice = [0u8;ROM_SIZE];
|
||||
let mut file = File::open("roms/ibm_logo.ch8").expect("could not open");
|
||||
file.read(&mut rom_slice).expect("Unwrap");
|
||||
rom_slice
|
||||
|
||||
}
|
||||
|
||||
fn initiate_sdl(draw_scale:f32) -> (WindowCanvas, EventPump) {
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let video_subsystem = sdl_context.video().unwrap();
|
||||
// let audio_subsystem = sdl_context.audio().unwrap();
|
||||
// let wanted_spec = AudioSpecDesired {
|
||||
// channels: Some(1),
|
||||
// samples: Some(256),
|
||||
// freq: Some(15360),
|
||||
// };
|
||||
// let audio_queue = audio_subsystem.open_queue::<u8, _>(None, &wanted_spec).unwrap();
|
||||
// audio_queue.resume();
|
||||
let window_width = (Device::FRAME_BUFFER_WIDTH as f32 * draw_scale) as u32;
|
||||
let window_height = (Device::FRAME_BUFFER_HEIGHT as f32 * draw_scale) as u32;
|
||||
|
||||
let window = video_subsystem.window("byte-pusher-emu", window_width,window_height)
|
||||
.position_centered()
|
||||
.build()
|
||||
.unwrap();
|
||||
let mut canvas = window.into_canvas().build().unwrap();
|
||||
|
||||
canvas.set_scale(draw_scale, draw_scale).expect("Setting scale");
|
||||
|
||||
canvas.set_blend_mode(BlendMode::None);
|
||||
canvas.clear();
|
||||
canvas.present();
|
||||
let event_pump = sdl_context.event_pump().unwrap();
|
||||
(canvas, event_pump
|
||||
// , audio_queue
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user