Got new emulator running correctly

This commit is contained in:
jan 2024-12-19 12:03:27 +01:00
parent 8300a6ea96
commit b577260d43
6 changed files with 86 additions and 348 deletions

323
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "ab_glyph"
@ -260,7 +260,7 @@ dependencies = [
"calloop",
"rustix",
"wayland-backend",
"wayland-client 0.31.7",
"wayland-client",
]
[[package]]
@ -498,12 +498,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "foreign-types"
version = "0.5.0"
@ -531,95 +525,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-macro"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]]
name = "futures-sink"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
[[package]]
name = "futures-util"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "gethostname"
version = "0.4.3"
@ -795,18 +700,6 @@ dependencies = [
"hashbrown 0.15.2",
]
[[package]]
name = "instant"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
@ -870,12 +763,6 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.164"
@ -959,15 +846,6 @@ dependencies = [
"libc",
]
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
name = "metal"
version = "0.27.0"
@ -983,32 +861,6 @@ dependencies = [
"paste",
]
[[package]]
name = "minifb"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c470a74618b43cd182c21b3dc1e6123501249f3bad9a0085e95d1304ca2478"
dependencies = [
"cc",
"dlib",
"futures",
"instant",
"js-sys",
"lazy_static",
"libc",
"orbclient",
"raw-window-handle",
"serde",
"serde_derive",
"tempfile",
"wasm-bindgen-futures",
"wayland-client 0.29.5",
"wayland-cursor 0.29.5",
"wayland-protocols 0.29.5",
"winapi",
"x11-dl",
]
[[package]]
name = "naga"
version = "0.19.2"
@ -1059,18 +911,6 @@ dependencies = [
"jni-sys",
]
[[package]]
name = "nix"
version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
name = "num-traits"
version = "0.2.19"
@ -1154,10 +994,7 @@ version = "0.3.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43"
dependencies = [
"libc",
"libredox",
"sdl2",
"sdl2-sys",
]
[[package]]
@ -1210,12 +1047,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pixels"
version = "0.14.0"
@ -1402,29 +1233,6 @@ dependencies = [
"tiny-skia",
]
[[package]]
name = "sdl2"
version = "0.35.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a"
dependencies = [
"bitflags 1.3.2",
"lazy_static",
"libc",
"sdl2-sys",
]
[[package]]
name = "sdl2-sys"
version = "0.35.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0"
dependencies = [
"cfg-if",
"libc",
"version-compare",
]
[[package]]
name = "serde"
version = "1.0.215"
@ -1491,12 +1299,12 @@ dependencies = [
"rustix",
"thiserror 1.0.69",
"wayland-backend",
"wayland-client 0.31.7",
"wayland-client",
"wayland-csd-frame",
"wayland-cursor 0.31.7",
"wayland-protocols 0.31.2",
"wayland-cursor",
"wayland-protocols",
"wayland-protocols-wlr",
"wayland-scanner 0.31.5",
"wayland-scanner",
"xkeysym",
]
@ -1542,7 +1350,6 @@ version = "0.4.0"
dependencies = [
"anyhow",
"clap",
"minifb",
"pixels",
"thiserror 2.0.3",
"winit",
@ -1571,19 +1378,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "tempfile"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]]
name = "termcolor"
version = "1.4.1"
@ -1736,12 +1530,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "version-compare"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
[[package]]
name = "version_check"
version = "0.9.5"
@ -1842,23 +1630,7 @@ dependencies = [
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys 0.31.5",
]
[[package]]
name = "wayland-client"
version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
dependencies = [
"bitflags 1.3.2",
"downcast-rs",
"libc",
"nix",
"scoped-tls",
"wayland-commons",
"wayland-scanner 0.29.5",
"wayland-sys 0.29.5",
"wayland-sys",
]
[[package]]
@ -1870,19 +1642,7 @@ dependencies = [
"bitflags 2.6.0",
"rustix",
"wayland-backend",
"wayland-scanner 0.31.5",
]
[[package]]
name = "wayland-commons"
version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
dependencies = [
"nix",
"once_cell",
"smallvec",
"wayland-sys 0.29.5",
"wayland-scanner",
]
[[package]]
@ -1896,17 +1656,6 @@ dependencies = [
"wayland-backend",
]
[[package]]
name = "wayland-cursor"
version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661"
dependencies = [
"nix",
"wayland-client 0.29.5",
"xcursor",
]
[[package]]
name = "wayland-cursor"
version = "0.31.7"
@ -1914,22 +1663,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c"
dependencies = [
"rustix",
"wayland-client 0.31.7",
"wayland-client",
"xcursor",
]
[[package]]
name = "wayland-protocols"
version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
dependencies = [
"bitflags 1.3.2",
"wayland-client 0.29.5",
"wayland-commons",
"wayland-scanner 0.29.5",
]
[[package]]
name = "wayland-protocols"
version = "0.31.2"
@ -1938,8 +1675,8 @@ checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
"wayland-client 0.31.7",
"wayland-scanner 0.31.5",
"wayland-client",
"wayland-scanner",
]
[[package]]
@ -1950,9 +1687,9 @@ checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
"wayland-client 0.31.7",
"wayland-protocols 0.31.2",
"wayland-scanner 0.31.5",
"wayland-client",
"wayland-protocols",
"wayland-scanner",
]
[[package]]
@ -1963,20 +1700,9 @@ checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
"wayland-client 0.31.7",
"wayland-protocols 0.31.2",
"wayland-scanner 0.31.5",
]
[[package]]
name = "wayland-scanner"
version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
dependencies = [
"proc-macro2",
"quote",
"xml-rs",
"wayland-client",
"wayland-protocols",
"wayland-scanner",
]
[[package]]
@ -1990,17 +1716,6 @@ dependencies = [
"quote",
]
[[package]]
name = "wayland-sys"
version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4"
dependencies = [
"dlib",
"lazy_static",
"pkg-config",
]
[[package]]
name = "wayland-sys"
version = "0.31.5"
@ -2467,8 +2182,8 @@ dependencies = [
"wasm-bindgen",
"wasm-bindgen-futures",
"wayland-backend",
"wayland-client 0.31.7",
"wayland-protocols 0.31.2",
"wayland-client",
"wayland-protocols",
"wayland-protocols-plasma",
"web-sys",
"web-time 0.2.4",

View File

@ -9,7 +9,7 @@ license="MIT"
[dependencies]
anyhow = "1.0.93"
clap = { version = "4.5.21", features = ["derive"] }
minifb = "0.27.0"
# There seems to be some incompatibility with the latest crates.io version of pixels?
pixels = { git = "https://github.com/parasyte/pixels.git", rev = "d4df286"}
thiserror = "2.0.3"
winit = "0.29.5"

View File

@ -5,17 +5,23 @@ use clap::Parser;
pub struct Cli {
pub program: String,
#[arg(short, long, default_value = "1", help = "Set the window scaling")]
#[arg(short, long, default_value = "1", help = "Set initial window scaling")]
pub scaling: u32,
#[arg(
short,
long,
default_value = "3000000",
help = "Set the maximum instructions per frame"
default_value_t = false,
help = "Show cursor on the window"
)]
pub max_ipf: usize,
pub cursor: bool,
#[arg(
short,
long,
default_value_t = false,
help = "Start in fullscreen mode"
)]
pub fullscreen: bool,
#[arg(
short,
long,
@ -26,9 +32,8 @@ pub struct Cli {
#[arg(
short,
long,
help = "Output instructions and value at the given address"
default_value = "3000000",
help = "Change the maximum instructions per frame"
)]
pub debug: Option<Vec<u16>>,
#[arg(short, long, help = "Show cursor on window")]
pub cursor: bool,
pub max_ipf: usize,
}

View File

@ -67,9 +67,6 @@ impl Engine {
pub fn wants_to_sync(&self) -> bool {
return self.sync_called;
}
pub fn get_instruction_pointer(&self) -> u16 {
self.instruction_pointer
}
pub fn set_input(&mut self, pos_code: u16, key_code: u16) {
self.pos_code = pos_code;
self.key_code = key_code;

View File

@ -2,22 +2,20 @@ mod cli;
mod engine;
mod utils;
use anyhow::{anyhow, Context, Result};
use anyhow::{anyhow, Result};
use clap::Parser;
use cli::Cli;
use engine::Engine;
use pixels::{Error, Pixels, SurfaceTexture};
use std::time::Instant;
use pixels::{Pixels, SurfaceTexture};
use std::time::{Duration, Instant};
use utils::*;
use winit::dpi::LogicalSize;
use winit::error::EventLoopError;
use winit::event::{Event, WindowEvent};
use winit::event_loop::EventLoop;
use winit::keyboard::Key;
use winit::keyboard::KeyCode;
use winit::window::WindowBuilder;
use winit_input_helper::WinitInputHelper;
const RES: usize = 256;
const FRAMETIME: Duration = Duration::from_nanos((1000000000. / 30.) as u64);
fn main() -> Result<()> {
let cli = Cli::parse();
@ -26,6 +24,9 @@ fn main() -> Result<()> {
let event_loop = EventLoop::new()?;
let mut input = WinitInputHelper::new();
if cli.scaling < 1 {
return Err(anyhow!("The minimal scaling factor is 1"));
}
let window = {
let size = LogicalSize::new(
(RES as u32 * cli.scaling) as f64,
@ -38,52 +39,63 @@ fn main() -> Result<()> {
.with_min_inner_size(min_size)
.build(&event_loop)?
};
window.set_cursor_visible(cli.cursor);
if cli.fullscreen {
window.set_fullscreen(Some(winit::window::Fullscreen::Borderless(None)));
}
let mut pixels = {
let window_size = window.inner_size();
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
Pixels::new(RES as u32, RES as u32, surface_texture)?
};
let res = event_loop.run(|event, elwt| {
// Draw the current frame
if let Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} = event
{
// world.draw(pixels.frame_mut());
if let Err(_) = pixels.render() {
elwt.exit();
return;
}
}
event_loop.run(|event, elwt| {
let start_time = Instant::now();
if input.update(&event) {
// Close events
if input.key_pressed(KeyCode::Escape) || input.close_requested() {
elwt.exit();
return;
}
// Resize the window
if let Some(size) = input.window_resized() {
if let Err(_) = pixels.resize_surface(size.width, size.height) {
elwt.exit();
handle_event_loop_error(&elwt, "Resize error");
return;
}
}
// Update internal state and request a redraw
// world.update();
while !engine.wants_to_sync() {
engine.step().unwrap();
let mut ipf = 0;
while !engine.wants_to_sync() && ipf <= cli.max_ipf {
match engine.step() {
Err(_) => {
handle_event_loop_error(&elwt, "Invalid operation");
return;
}
_ => {}
}
ipf += 1;
}
let (c1, c2) = get_input_code(&input, &pixels).unwrap();
let (c1, c2) = get_input_code(&input, &pixels);
let nb = engine.perform_sync(c1, c2);
update_image_buffer(pixels.frame_mut(), &nb);
let elapsed = start_time.elapsed();
if cli.verbose {
println!("Instructions: {} Frametime: {}ms", ipf, elapsed.as_millis());
}
if elapsed < FRAMETIME {
std::thread::sleep(FRAMETIME - elapsed);
}
window.request_redraw();
match pixels.render() {
Err(_) => {
handle_event_loop_error(&elwt, "Rendering error");
return;
}
_ => {}
};
}
});
})?;
Ok(())
}

View File

@ -1,7 +1,11 @@
use crate::RES;
use anyhow::Result;
use pixels::Pixels;
use winit::{event::MouseButton, keyboard::Key, keyboard::KeyCode};
use winit::{
event::MouseButton,
event_loop::EventLoopWindowTarget,
keyboard::{Key, KeyCode},
};
use winit_input_helper::WinitInputHelper;
pub fn read_u16s_from_file(file_path: &str) -> Result<Vec<u16>> {
@ -37,7 +41,7 @@ pub fn update_image_buffer(imbuff: &mut [u8], screen: &[u16; RES * RES]) {
}
}
pub fn get_input_code(input: &WinitInputHelper, pxls: &Pixels) -> Result<(u16, u16)> {
pub fn get_input_code(input: &WinitInputHelper, pxls: &Pixels) -> (u16, u16) {
let raw_mp = input.cursor().unwrap_or((0., 0.));
let mp = match pxls.window_pos_to_pixel(raw_mp) {
Ok(p) => p,
@ -69,5 +73,10 @@ pub fn get_input_code(input: &WinitInputHelper, pxls: &Pixels) -> Result<(u16, u
if input.key_held_logical(Key::Character("m")) {
key_code += 128;
}
Ok((pos_code, key_code))
(pos_code, key_code)
}
pub fn handle_event_loop_error(handle: &EventLoopWindowTarget<()>, msg: impl AsRef<str>) {
eprintln!("{}", msg.as_ref());
handle.exit();
}