mirror of
https://github.com/JanNeuendorf/SVC16.git
synced 2025-06-03 01:50:18 +00:00
Moved the controller support into a cargo feature that needs to be turned on explicitely. This makes the emulator more portable.
This commit is contained in:
parent
890c2b7b79
commit
f5ea5b88fe
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1813,7 +1813,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "svc16"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "svc16"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
edition = "2021"
|
||||
authors = ["Jan Neuendorf"]
|
||||
description = "An emulator for a simple virtual computer"
|
||||
@ -9,10 +9,13 @@ license="MIT"
|
||||
[dependencies]
|
||||
anyhow = "1.0.93"
|
||||
clap = { version = "4.5.21", features = ["derive"] }
|
||||
gilrs = { version = "0.11.0"}
|
||||
gilrs = { version = "0.11.0",optional=true}
|
||||
# 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.15"
|
||||
winit-input-map = "0.4.1"
|
||||
winit-input-map = {version="0.4.1",optional=true}
|
||||
winit_input_helper = "0.16.0"
|
||||
|
||||
[features]
|
||||
gamepad = ["gilrs","winit-input-map"]
|
||||
|
@ -15,6 +15,9 @@ This repo contains an emulator to run games or programs. It can be installed wit
|
||||
cargo install --git https://github.com/JanNeuendorf/SVC16
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> For controller support, compile with `--features="gamepad"`. Support varies by platform and it might require additional libraries to be installed.
|
||||
|
||||
You can then run a program from the cli:
|
||||
|
||||
```sh
|
||||
|
@ -6,6 +6,7 @@ use anyhow::{anyhow, Result};
|
||||
use clap::Parser;
|
||||
use cli::Cli;
|
||||
use engine::Engine;
|
||||
#[cfg(feature = "gamepad")]
|
||||
use gilrs::Gilrs;
|
||||
use pixels::{Pixels, SurfaceTexture};
|
||||
use std::time::{Duration, Instant};
|
||||
@ -20,6 +21,7 @@ const FRAMETIME: Duration = Duration::from_nanos((1000000000. / 30.) as u64);
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
#[cfg(feature = "gamepad")]
|
||||
let mut girls = Gilrs::new().expect("Could not read gamepad inputs.");
|
||||
let initial_state = read_u16s_from_file(&cli.program)?;
|
||||
// The initial state is cloned, so we keep it around for a restart.
|
||||
@ -27,6 +29,7 @@ fn main() -> Result<()> {
|
||||
|
||||
let event_loop = EventLoop::new()?;
|
||||
let mut input = WinitInputHelper::new();
|
||||
#[cfg(feature = "gamepad")]
|
||||
let mut gamepad = build_gamepad_map();
|
||||
if cli.scaling < 1 {
|
||||
return Err(anyhow!("The minimal scaling factor is 1"));
|
||||
@ -99,8 +102,12 @@ fn main() -> Result<()> {
|
||||
ipf += 1;
|
||||
}
|
||||
let engine_elapsed = engine_start.elapsed();
|
||||
#[cfg(not(feature = "gamepad"))]
|
||||
let (c1, c2) = get_input_code(&input, &pixels);
|
||||
#[cfg(feature = "gamepad")]
|
||||
gamepad.update_with_gilrs(&mut girls);
|
||||
let (c1, c2) = get_input_code(&input, &gamepad, &pixels);
|
||||
#[cfg(feature = "gamepad")]
|
||||
let (c1, c2) = get_input_code_gamepad(&input, &gamepad, &pixels);
|
||||
engine.perform_sync(c1, c2, &mut raw_buffer);
|
||||
update_image_buffer(pixels.frame_mut(), &raw_buffer);
|
||||
|
||||
|
46
src/utils.rs
46
src/utils.rs
@ -1,16 +1,17 @@
|
||||
use crate::RES;
|
||||
use anyhow::Result;
|
||||
use pixels::Pixels;
|
||||
use std::hash::Hash;
|
||||
use winit::{
|
||||
event::MouseButton,
|
||||
event_loop::EventLoopWindowTarget,
|
||||
keyboard::{Key, KeyCode},
|
||||
};
|
||||
use winit_input_helper::WinitInputHelper;
|
||||
#[cfg(feature = "gamepad")]
|
||||
use winit_input_map::{input_map, GamepadButton, InputMap};
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
||||
#[cfg(feature = "gamepad")]
|
||||
#[derive(Debug, std::hash::Hash, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum NesInput {
|
||||
Up,
|
||||
Down,
|
||||
@ -22,6 +23,7 @@ pub enum NesInput {
|
||||
Select,
|
||||
}
|
||||
|
||||
#[cfg(feature = "gamepad")]
|
||||
pub fn build_gamepad_map() -> InputMap<NesInput> {
|
||||
input_map!(
|
||||
(NesInput::A, GamepadButton::East),
|
||||
@ -67,8 +69,8 @@ pub fn update_image_buffer(imbuff: &mut [u8], screen: &[u16; RES * RES]) {
|
||||
*imbuff.get_mut(4 * i + 3).expect("Error with image buffer") = 255;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_input_code(
|
||||
#[cfg(feature = "gamepad")]
|
||||
pub fn get_input_code_gamepad(
|
||||
input: &WinitInputHelper,
|
||||
gamepad: &InputMap<NesInput>,
|
||||
pxls: &Pixels,
|
||||
@ -129,3 +131,39 @@ pub fn handle_event_loop_error(handle: &EventLoopWindowTarget<()>, msg: impl AsR
|
||||
eprintln!("{}", msg.as_ref());
|
||||
handle.exit();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gamepad"))]
|
||||
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,
|
||||
Err(ev) => pxls.clamp_pixel_pos(ev),
|
||||
};
|
||||
let pos_code = (mp.1 as u16 * 256) + mp.0 as u16;
|
||||
let mut key_code = 0_u16;
|
||||
if input.key_held(KeyCode::Space) || input.mouse_held(MouseButton::Left) {
|
||||
key_code += 1;
|
||||
}
|
||||
if input.key_held_logical(Key::Character("b")) || input.mouse_held(MouseButton::Right) {
|
||||
key_code += 2;
|
||||
}
|
||||
if input.key_held_logical(Key::Character("w")) || input.key_held(KeyCode::ArrowUp) {
|
||||
key_code += 4;
|
||||
}
|
||||
if input.key_held_logical(Key::Character("s")) || input.key_held(KeyCode::ArrowDown) {
|
||||
key_code += 8;
|
||||
}
|
||||
if input.key_held_logical(Key::Character("a")) || input.key_held(KeyCode::ArrowLeft) {
|
||||
key_code += 16;
|
||||
}
|
||||
if input.key_held_logical(Key::Character("d")) || input.key_held(KeyCode::ArrowRight) {
|
||||
key_code += 32;
|
||||
}
|
||||
if input.key_held_logical(Key::Character("n")) {
|
||||
key_code += 64;
|
||||
}
|
||||
if input.key_held_logical(Key::Character("m")) {
|
||||
key_code += 128;
|
||||
}
|
||||
(pos_code, key_code)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user