[feat] add arg to delete if invalid
This commit is contained in:
16
src/args.rs
16
src/args.rs
@@ -7,6 +7,18 @@ pub struct Porcel8ProgramArgs {
|
|||||||
pub filename: Option<String>,
|
pub filename: Option<String>,
|
||||||
#[arg(short, long, help = "Draw scale of window", default_value_t = 8f32)]
|
#[arg(short, long, help = "Draw scale of window", default_value_t = 8f32)]
|
||||||
pub draw_scale: f32,
|
pub draw_scale: f32,
|
||||||
#[arg(short,long,help = "Emulate new behaviour of instructions (As seen in Chip-48 and SuperChip8)",default_value_t=true)]
|
#[arg(
|
||||||
pub new_chip8_behaviour: bool
|
short,
|
||||||
|
long,
|
||||||
|
help = "Emulate new behaviour of instructions (As seen in Chip-48 and SuperChip8)",
|
||||||
|
default_value_t = true
|
||||||
|
)]
|
||||||
|
pub new_chip8_behaviour: bool,
|
||||||
|
#[arg(
|
||||||
|
short='i',
|
||||||
|
long,
|
||||||
|
help = "Halt on invalid instruction",
|
||||||
|
default_value_t = false
|
||||||
|
)]
|
||||||
|
pub halt_on_invalid: bool,
|
||||||
}
|
}
|
@@ -1,10 +1,9 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
use crate::{device::instruction::Instruction, util::EmulatorError};
|
||||||
use rand::random;
|
|
||||||
use crate::device::instruction::Instruction;
|
|
||||||
use crate::device::keyboard::Keyboard;
|
use crate::device::keyboard::Keyboard;
|
||||||
use crate::device::timer::DeviceTimerManager;
|
use crate::device::timer::DeviceTimerManager;
|
||||||
use crate::util::EmulatorResult;
|
use crate::util::EmulatorResult;
|
||||||
|
use rand::random;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
pub struct Device {
|
pub struct Device {
|
||||||
pub registers: RegisterFile,
|
pub registers: RegisterFile,
|
||||||
@@ -13,6 +12,7 @@ pub struct Device {
|
|||||||
pub stack: Vec<u16>,
|
pub stack: Vec<u16>,
|
||||||
pub frame_buffer: Arc<Mutex<Box<[bool; 64 * 32]>>>,
|
pub frame_buffer: Arc<Mutex<Box<[bool; 64 * 32]>>>,
|
||||||
pub new_chip8_mode: bool,
|
pub new_chip8_mode: bool,
|
||||||
|
pub halt_on_invalid: bool,
|
||||||
pub device_keyboard: Keyboard,
|
pub device_keyboard: Keyboard,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,14 +21,24 @@ impl Device {
|
|||||||
pub const FRAME_BUFFER_WIDTH: usize = 64;
|
pub const FRAME_BUFFER_WIDTH: usize = 64;
|
||||||
pub const FRAME_BUFFER_HEIGHT: usize = 32;
|
pub const FRAME_BUFFER_HEIGHT: usize = 32;
|
||||||
pub const FRAME_BUFFER_SIZE: usize = Self::FRAME_BUFFER_WIDTH * Self::FRAME_BUFFER_HEIGHT;
|
pub const FRAME_BUFFER_SIZE: usize = Self::FRAME_BUFFER_WIDTH * Self::FRAME_BUFFER_HEIGHT;
|
||||||
pub fn new(timer: DeviceTimerManager, fb: Arc<Mutex<Box<[bool; Device::FRAME_BUFFER_SIZE]>>>, device_keyboard: Keyboard, new_chip8_mode: bool) -> Device {
|
pub fn new(
|
||||||
let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE].into_boxed_slice().try_into().unwrap();
|
timer: DeviceTimerManager,
|
||||||
|
fb: Arc<Mutex<Box<[bool; Device::FRAME_BUFFER_SIZE]>>>,
|
||||||
|
device_keyboard: Keyboard,
|
||||||
|
new_chip8_mode: bool,
|
||||||
|
halt_on_invalid: bool
|
||||||
|
) -> Device {
|
||||||
|
let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE]
|
||||||
|
.into_boxed_slice()
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
log::trace!("Successfully initiated device memory");
|
log::trace!("Successfully initiated device memory");
|
||||||
Device {
|
Device {
|
||||||
registers: RegisterFile::new(),
|
registers: RegisterFile::new(),
|
||||||
memory,
|
memory,
|
||||||
frame_buffer: fb,
|
frame_buffer: fb,
|
||||||
stack: Vec::with_capacity(16),
|
stack: Vec::with_capacity(16),
|
||||||
|
halt_on_invalid,
|
||||||
timer,
|
timer,
|
||||||
new_chip8_mode,
|
new_chip8_mode,
|
||||||
device_keyboard,
|
device_keyboard,
|
||||||
@@ -42,8 +52,6 @@ impl Device {
|
|||||||
const FONT_DEFAULT_MEM_LOCATION_END: usize = 0x9F;
|
const FONT_DEFAULT_MEM_LOCATION_END: usize = 0x9F;
|
||||||
const ROM_START: usize = 0x200;
|
const ROM_START: usize = 0x200;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn cycle(&mut self) -> EmulatorResult<()> {
|
pub fn cycle(&mut self) -> EmulatorResult<()> {
|
||||||
self.device_keyboard.update_keyboard()?;
|
self.device_keyboard.update_keyboard()?;
|
||||||
|
|
||||||
@@ -62,11 +70,17 @@ impl Device {
|
|||||||
// thread::sleep(Duration::from_millis(250));
|
// thread::sleep(Duration::from_millis(250));
|
||||||
log::trace!("Executing {:?}, {:?}", &instruction, &self.registers);
|
log::trace!("Executing {:?}, {:?}", &instruction, &self.registers);
|
||||||
match instruction {
|
match instruction {
|
||||||
Instruction::PassThrough => {
|
Instruction::InvalidInstruction => {
|
||||||
log::info!("Executing passthrough");
|
log::info!("Executing passthrough");
|
||||||
|
if self.halt_on_invalid {
|
||||||
|
return Err(EmulatorError::IOError("Caught Invalid Instruction".to_string()));
|
||||||
}
|
}
|
||||||
|
},
|
||||||
Instruction::ClearScreen => {
|
Instruction::ClearScreen => {
|
||||||
let mut frame_buffer = self.frame_buffer.lock().expect("Failed to grab framebuffer for drawing");
|
let mut frame_buffer = self
|
||||||
|
.frame_buffer
|
||||||
|
.lock()
|
||||||
|
.expect("Failed to grab framebuffer for drawing");
|
||||||
for pixel in frame_buffer.iter_mut() {
|
for pixel in frame_buffer.iter_mut() {
|
||||||
*pixel = false;
|
*pixel = false;
|
||||||
}
|
}
|
||||||
@@ -154,7 +168,8 @@ impl Device {
|
|||||||
}
|
}
|
||||||
Instruction::Add(x, y) => {
|
Instruction::Add(x, y) => {
|
||||||
let left = self.registers.v[x];
|
let left = self.registers.v[x];
|
||||||
let (wrapped_addition_result, is_overflow) = left.overflowing_add(self.registers.v[y]);
|
let (wrapped_addition_result, is_overflow) =
|
||||||
|
left.overflowing_add(self.registers.v[y]);
|
||||||
self.registers.v[x] = wrapped_addition_result;
|
self.registers.v[x] = wrapped_addition_result;
|
||||||
self.set_flag_register(is_overflow);
|
self.set_flag_register(is_overflow);
|
||||||
}
|
}
|
||||||
@@ -167,7 +182,8 @@ impl Device {
|
|||||||
}
|
}
|
||||||
Instruction::RSub(x, y) => {
|
Instruction::RSub(x, y) => {
|
||||||
let left = self.registers.v[y];
|
let left = self.registers.v[y];
|
||||||
let (wrapped_subtraction_result, is_overflow) = left.overflowing_sub(self.registers.v[x]);
|
let (wrapped_subtraction_result, is_overflow) =
|
||||||
|
left.overflowing_sub(self.registers.v[x]);
|
||||||
self.registers.v[x] = wrapped_subtraction_result;
|
self.registers.v[x] = wrapped_subtraction_result;
|
||||||
self.set_flag_register(!is_overflow);
|
self.set_flag_register(!is_overflow);
|
||||||
}
|
}
|
||||||
@@ -223,7 +239,8 @@ impl Device {
|
|||||||
}
|
}
|
||||||
Instruction::SetIndexToFontCharacter(x) => {
|
Instruction::SetIndexToFontCharacter(x) => {
|
||||||
let requested_char = self.registers.v[x];
|
let requested_char = self.registers.v[x];
|
||||||
let font_address = Self::FONT_DEFAULT_MEM_LOCATION_START as u16 + Self::FONT_HEIGHT * requested_char as u16;
|
let font_address = Self::FONT_DEFAULT_MEM_LOCATION_START as u16
|
||||||
|
+ Self::FONT_HEIGHT * requested_char as u16;
|
||||||
self.registers.i = font_address;
|
self.registers.i = font_address;
|
||||||
}
|
}
|
||||||
Instruction::DoBCDConversion(x) => {
|
Instruction::DoBCDConversion(x) => {
|
||||||
@@ -267,7 +284,10 @@ impl Device {
|
|||||||
/// Draw a sprite at location at (x,y) for n pixels long and 8 pixels wide.
|
/// Draw a sprite at location at (x,y) for n pixels long and 8 pixels wide.
|
||||||
/// Returns whether any pixel was toggled
|
/// Returns whether any pixel was toggled
|
||||||
fn draw_sprite_at_location(&mut self, x: usize, y: usize, n: u8) -> bool {
|
fn draw_sprite_at_location(&mut self, x: usize, y: usize, n: u8) -> bool {
|
||||||
let mut frame_buffer = self.frame_buffer.lock().expect("Failed to grab framebuffer for drawing");
|
let mut frame_buffer = self
|
||||||
|
.frame_buffer
|
||||||
|
.lock()
|
||||||
|
.expect("Failed to grab framebuffer for drawing");
|
||||||
|
|
||||||
let mut is_pixel_toggled_off = false;
|
let mut is_pixel_toggled_off = false;
|
||||||
for i in 0..n as usize {
|
for i in 0..n as usize {
|
||||||
@@ -286,8 +306,11 @@ impl Device {
|
|||||||
let bit_is_true = (slice_from_memory & (1 << bit_index)) == (1 << bit_index);
|
let bit_is_true = (slice_from_memory & (1 << bit_index)) == (1 << bit_index);
|
||||||
|
|
||||||
// if the pixel is going to be toggled false, set this flag bit to true
|
// if the pixel is going to be toggled false, set this flag bit to true
|
||||||
if frame_buffer[index + (7 - bit_index)] && (bit_is_true) { is_pixel_toggled_off = true; }
|
if frame_buffer[index + (7 - bit_index)] && (bit_is_true) {
|
||||||
frame_buffer[index + (7 - bit_index)] = frame_buffer[index + (7 - bit_index)] ^ (bit_is_true);
|
is_pixel_toggled_off = true;
|
||||||
|
}
|
||||||
|
frame_buffer[index + (7 - bit_index)] =
|
||||||
|
frame_buffer[index + (7 - bit_index)] ^ (bit_is_true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is_pixel_toggled_off
|
is_pixel_toggled_off
|
||||||
@@ -313,10 +336,11 @@ impl Device {
|
|||||||
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
|
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
|
||||||
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
|
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
|
||||||
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
||||||
0xF0, 0x80, 0xF0, 0x80, 0x80 // F
|
0xF0, 0x80, 0xF0, 0x80, 0x80, // F
|
||||||
];
|
];
|
||||||
log::info!("Loaded default font from memory");
|
log::info!("Loaded default font from memory");
|
||||||
self.memory[Self::FONT_DEFAULT_MEM_LOCATION_START..=Self::FONT_DEFAULT_MEM_LOCATION_END].copy_from_slice(&DEFAULT_FONT);
|
self.memory[Self::FONT_DEFAULT_MEM_LOCATION_START..=Self::FONT_DEFAULT_MEM_LOCATION_END]
|
||||||
|
.copy_from_slice(&DEFAULT_FONT);
|
||||||
}
|
}
|
||||||
/// load a rom from bytes
|
/// load a rom from bytes
|
||||||
pub fn load_rom(&mut self, rom: &[u8]) {
|
pub fn load_rom(&mut self, rom: &[u8]) {
|
||||||
|
@@ -2,8 +2,8 @@ use byteorder::{BigEndian, ByteOrder};
|
|||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
pub enum Instruction {
|
pub enum Instruction {
|
||||||
/// Blanket instruction that does nothing
|
/// Invalid instruction that may be skipped or raise error
|
||||||
PassThrough,
|
InvalidInstruction,
|
||||||
/// 00E0 - Clear the screen
|
/// 00E0 - Clear the screen
|
||||||
ClearScreen,
|
ClearScreen,
|
||||||
/// 00EE - Return from procedure
|
/// 00EE - Return from procedure
|
||||||
@@ -83,22 +83,14 @@ impl Instruction {
|
|||||||
let instruction = BigEndian::read_u16(location);
|
let instruction = BigEndian::read_u16(location);
|
||||||
let outer_instruction_nibble = (instruction & 0xF000) >> 12;
|
let outer_instruction_nibble = (instruction & 0xF000) >> 12;
|
||||||
match outer_instruction_nibble {
|
match outer_instruction_nibble {
|
||||||
0x0 if instruction == 0xe0 => {
|
0x0 if instruction == 0xe0 => Instruction::ClearScreen,
|
||||||
Instruction::ClearScreen
|
0x0 if instruction == 0xee => Instruction::ReturnFromProcedure,
|
||||||
}
|
|
||||||
0x0 if instruction == 0xee => {
|
|
||||||
Instruction::ReturnFromProcedure
|
|
||||||
}
|
|
||||||
0x0 => {
|
0x0 => {
|
||||||
log::warn!("Ignoring unsupported instruction {}", instruction);
|
log::warn!("Ignoring unsupported instruction {}", instruction);
|
||||||
Instruction::PassThrough
|
Instruction::InvalidInstruction
|
||||||
}
|
|
||||||
0x1 => {
|
|
||||||
Instruction::JumpTo(instruction & 0xfff)
|
|
||||||
}
|
|
||||||
0x2 => {
|
|
||||||
Instruction::JumpAndLink(instruction & 0xfff)
|
|
||||||
}
|
}
|
||||||
|
0x1 => Instruction::JumpTo(instruction & 0xfff),
|
||||||
|
0x2 => Instruction::JumpAndLink(instruction & 0xfff),
|
||||||
0x3 => {
|
0x3 => {
|
||||||
let register = (instruction & 0xf00) >> 8;
|
let register = (instruction & 0xf00) >> 8;
|
||||||
let val = instruction & 0xff;
|
let val = instruction & 0xff;
|
||||||
@@ -115,24 +107,25 @@ impl Instruction {
|
|||||||
|
|
||||||
Instruction::ConditionalEqRegisterSkipNext(register_x as usize, register_y as usize)
|
Instruction::ConditionalEqRegisterSkipNext(register_x as usize, register_y as usize)
|
||||||
}
|
}
|
||||||
0x6 => {
|
0x6 => Instruction::SetRegister(
|
||||||
Instruction::SetRegister(((instruction & 0x0f00) >> 8) as usize, (instruction & 0xff) as u8)
|
((instruction & 0x0f00) >> 8) as usize,
|
||||||
}
|
(instruction & 0xff) as u8,
|
||||||
0x7 => {
|
),
|
||||||
Instruction::AddValueToRegister(((instruction & 0x0f00) >> 8) as usize, (instruction & 0xff) as u8)
|
0x7 => Instruction::AddValueToRegister(
|
||||||
}
|
((instruction & 0x0f00) >> 8) as usize,
|
||||||
0x8 => {
|
(instruction & 0xff) as u8,
|
||||||
Self::decode_arithmetic_instruction(instruction)
|
),
|
||||||
}
|
0x8 => Self::decode_arithmetic_instruction(instruction),
|
||||||
0x9 => {
|
0x9 => {
|
||||||
let register_x = (instruction & 0xf00) >> 8;
|
let register_x = (instruction & 0xf00) >> 8;
|
||||||
let register_y = (instruction & 0xf0) >> 4;
|
let register_y = (instruction & 0xf0) >> 4;
|
||||||
|
|
||||||
Instruction::ConditionalInEqRegisterSkipNext(register_x as usize, register_y as usize)
|
Instruction::ConditionalInEqRegisterSkipNext(
|
||||||
}
|
register_x as usize,
|
||||||
0xA => {
|
register_y as usize,
|
||||||
Instruction::SetIndex(instruction & 0xfff)
|
)
|
||||||
}
|
}
|
||||||
|
0xA => Instruction::SetIndex(instruction & 0xfff),
|
||||||
0xB => {
|
0xB => {
|
||||||
let register_x = (instruction & 0xf00) >> 8;
|
let register_x = (instruction & 0xf00) >> 8;
|
||||||
let jump_address_base = instruction & 0xfff;
|
let jump_address_base = instruction & 0xfff;
|
||||||
@@ -152,7 +145,7 @@ impl Instruction {
|
|||||||
0xE if (instruction & 0xff) == 0x9e => {
|
0xE if (instruction & 0xff) == 0x9e => {
|
||||||
let x = (instruction & 0xf00) >> 8;
|
let x = (instruction & 0xf00) >> 8;
|
||||||
Instruction::SkipIfKeyPressed(x as usize)
|
Instruction::SkipIfKeyPressed(x as usize)
|
||||||
},
|
}
|
||||||
0xE if (instruction & 0xff) == 0xa1 => {
|
0xE if (instruction & 0xff) == 0xa1 => {
|
||||||
let x = (instruction & 0xf00) >> 8;
|
let x = (instruction & 0xf00) >> 8;
|
||||||
Instruction::SkipIfKeyNotPressed(x as usize)
|
Instruction::SkipIfKeyNotPressed(x as usize)
|
||||||
@@ -206,36 +199,18 @@ impl Instruction {
|
|||||||
let reg_y = ((instruction & 0xf0) >> 4) as usize;
|
let reg_y = ((instruction & 0xf0) >> 4) as usize;
|
||||||
let operation = instruction & 0xf;
|
let operation = instruction & 0xf;
|
||||||
match operation {
|
match operation {
|
||||||
0 => {
|
0 => Instruction::Set(reg_x, reg_y),
|
||||||
Instruction::Set(reg_x, reg_y)
|
1 => Instruction::Or(reg_x, reg_y),
|
||||||
}
|
2 => Instruction::And(reg_x, reg_y),
|
||||||
1 => {
|
3 => Instruction::Xor(reg_x, reg_y),
|
||||||
Instruction::Or(reg_x, reg_y)
|
4 => Instruction::Add(reg_x, reg_y),
|
||||||
}
|
5 => Instruction::Sub(reg_x, reg_y),
|
||||||
2 => {
|
6 => Instruction::RShift(reg_x, reg_y),
|
||||||
Instruction::And(reg_x, reg_y)
|
7 => Instruction::RSub(reg_x, reg_y),
|
||||||
}
|
0xe => Instruction::LShift(reg_x, reg_y),
|
||||||
3 => {
|
|
||||||
Instruction::Xor(reg_x, reg_y)
|
|
||||||
}
|
|
||||||
4 => {
|
|
||||||
Instruction::Add(reg_x, reg_y)
|
|
||||||
}
|
|
||||||
5 => {
|
|
||||||
Instruction::Sub(reg_x, reg_y)
|
|
||||||
}
|
|
||||||
6 => {
|
|
||||||
Instruction::RShift(reg_x, reg_y)
|
|
||||||
}
|
|
||||||
7 => {
|
|
||||||
Instruction::RSub(reg_x, reg_y)
|
|
||||||
}
|
|
||||||
0xe => {
|
|
||||||
Instruction::LShift(reg_x, reg_y)
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
log::error!("Encountered unexpected alu instruction {}", instruction);
|
log::error!("Encountered unexpected alu instruction {}", instruction);
|
||||||
Instruction::PassThrough
|
Instruction::InvalidInstruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,11 +240,10 @@ mod tests {
|
|||||||
for instruction_hex in [0xf0u16, 0x0, 0x1, 0x10] {
|
for instruction_hex in [0xf0u16, 0x0, 0x1, 0x10] {
|
||||||
let instruction_bytes = instruction_hex.to_be_bytes();
|
let instruction_bytes = instruction_hex.to_be_bytes();
|
||||||
let instruction = Instruction::decode_instruction(&instruction_bytes);
|
let instruction = Instruction::decode_instruction(&instruction_bytes);
|
||||||
assert_eq!(instruction, PassThrough)
|
assert_eq!(instruction, InvalidInstruction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_jump_to_instruction_1() {
|
fn test_jump_to_instruction_1() {
|
||||||
let instruction_bytes = 0x1123_u16.to_be_bytes();
|
let instruction_bytes = 0x1123_u16.to_be_bytes();
|
||||||
@@ -361,7 +335,6 @@ mod tests {
|
|||||||
assert_eq!(ins, RandomAnd(0xa, 0xbd));
|
assert_eq!(ins, RandomAnd(0xa, 0xbd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_draw() {
|
fn test_draw() {
|
||||||
let instruction_bytes = 0xdfab_u16.to_be_bytes();
|
let instruction_bytes = 0xdfab_u16.to_be_bytes();
|
||||||
@@ -498,5 +471,4 @@ mod tests {
|
|||||||
let ins = Instruction::decode_instruction(&instruction_bytes);
|
let ins = Instruction::decode_instruction(&instruction_bytes);
|
||||||
assert_eq!(ins, LoadRegistersFromMemory(0b1001))
|
assert_eq!(ins, LoadRegistersFromMemory(0b1001))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -33,7 +33,7 @@ mod rom;
|
|||||||
|
|
||||||
fn main() -> EmulatorResult<()> {
|
fn main() -> EmulatorResult<()> {
|
||||||
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap();
|
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap();
|
||||||
let Porcel8ProgramArgs { filename, new_chip8_behaviour, draw_scale } = Porcel8ProgramArgs::parse();
|
let Porcel8ProgramArgs { filename, new_chip8_behaviour, draw_scale, halt_on_invalid } = Porcel8ProgramArgs::parse();
|
||||||
|
|
||||||
log::info!("Started emulator");
|
log::info!("Started emulator");
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ fn main() -> EmulatorResult<()> {
|
|||||||
|
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
let device = Device::new(timer, frame_buffer_for_device, device_keyboard, new_chip8_behaviour);
|
let device = Device::new(timer, frame_buffer_for_device, device_keyboard, new_chip8_behaviour, halt_on_invalid);
|
||||||
|
|
||||||
let (device_termination_signal_sender, compute_handle) = start_compute_thread(filename, device)?;
|
let (device_termination_signal_sender, compute_handle) = start_compute_thread(filename, device)?;
|
||||||
|
|
||||||
@@ -163,6 +163,3 @@ fn try_initiate_sdl(draw_scale: f32) -> EmulatorResult<(WindowCanvas, EventPump,
|
|||||||
let event_pump = sdl_context.event_pump()?;
|
let event_pump = sdl_context.event_pump()?;
|
||||||
Ok((canvas, event_pump, audio_queue))
|
Ok((canvas, event_pump, audio_queue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user