#![feature(likely_unlikely, widening_mul)] #![deny(clippy::all)] use std::env::args; use std::process::exit; use std::sync::atomic::AtomicU32; use std::sync::{Arc, Mutex}; use std::thread::{scope, sleep}; use std::time::Duration; use pixels::{Error, Pixels, SurfaceTexture}; use winit::dpi::LogicalSize; use winit::event::{Event, WindowEvent}; use winit::event_loop::EventLoop; use winit::platform::scancode::PhysicalKeyExtScancode; use winit::window::Window; use winit_input_helper::WinitInputHelper; use crate::cpu::Computer; const WIDTH: u32 = 640; const HEIGHT: u32 = 480; mod cpu; fn main() -> Result<(), Error> { let event_loop = EventLoop::new().unwrap(); let mut input = WinitInputHelper::new(); let window = { let size = LogicalSize::new((WIDTH * 3) as f64, (HEIGHT * 3) as f64); #[allow(deprecated)] Arc::new( event_loop .create_window( Window::default_attributes() .with_title("bisare screen") .with_inner_size(size) .with_min_inner_size(size), ) .unwrap(), ) }; let pixels = Mutex::new({ let window_size = window.inner_size(); let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); Pixels::new(WIDTH, HEIGHT, surface_texture)? }); let keyboard = AtomicU32::new(0); let program = args() .nth(1) .expect("you must supply the exec name as the first argument"); let kbref = &keyboard; let pixelref = &pixels; scope(|sc| { sc.spawn(|| { let mut simulation = Computer::new(program, pixelref, kbref); loop { simulation.step(); } }); #[allow(deprecated)] let res = event_loop.run(|event, elwt| { match event { Event::Resumed => {} Event::NewEvents(_) => input.step(), Event::AboutToWait => input.end_step(), Event::DeviceEvent { event, .. } => { input.process_device_event(&event); } Event::WindowEvent { event, .. } => { // Draw the current frame if event == WindowEvent::RedrawRequested { if let Err(_) = pixels.lock().unwrap().render() { elwt.exit(); return; } sleep(Duration::from_millis(30)); } if let WindowEvent::KeyboardInput { device_id: _, ref event, is_synthetic: _, } = event { match event.state { winit::event::ElementState::Pressed => { if let Some(val) = event.physical_key.to_scancode() { kbref.store(val + 8, std::sync::atomic::Ordering::Relaxed); } } winit::event::ElementState::Released => { kbref.store(0, std::sync::atomic::Ordering::Relaxed) } } } // Handle input events if input.process_window_event(&event) { // Close events if input.close_requested() { elwt.exit(); return; } // Resize the window if let Some(size) = input.window_resized() { if let Err(_) = pixels .lock() .unwrap() .resize_surface(size.width, size.height) { elwt.exit(); return; } } // Update internal state and request a redraw window.request_redraw(); } } _ => {} } }); match res { Ok(_) => exit(0), Err(e) => { println!("{e}"); exit(1); } } }) }