initial (bad) gamepad support

This commit is contained in:
Alex Janka 2023-02-13 09:56:41 +11:00
parent 0fde806f62
commit 5bb098bfa4
6 changed files with 176 additions and 14 deletions

130
Cargo.lock generated
View file

@ -78,6 +78,22 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]] [[package]]
name = "cty" name = "cty"
version = "0.2.2" version = "0.2.2"
@ -129,6 +145,12 @@ dependencies = [
"instant", "instant",
] ]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.26" version = "0.3.26"
@ -223,6 +245,7 @@ name = "gb-emu"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"gilrs",
"minifb", "minifb",
"rand", "rand",
"spin_sleep", "spin_sleep",
@ -239,6 +262,39 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "gilrs"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d0342acdc7b591d171212e17c9350ca02383b86d5f9af33c6e3598e03a6c57e"
dependencies = [
"fnv",
"gilrs-core",
"log",
"uuid",
"vec_map",
]
[[package]]
name = "gilrs-core"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6789d356476c3280a4e15365d23f62b4b4f1bcdac81fdd552f65807bce4666dd"
dependencies = [
"core-foundation",
"io-kit-sys",
"js-sys",
"libc",
"libudev-sys",
"log",
"nix 0.25.1",
"uuid",
"vec_map",
"wasm-bindgen",
"web-sys",
"windows",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.4.0" version = "0.4.0"
@ -266,6 +322,16 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "io-kit-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7789f7f3c9686f96164f5109d69152de759e76e284f736bd57661c6df5091919"
dependencies = [
"core-foundation-sys",
"mach",
]
[[package]] [[package]]
name = "io-lifetimes" name = "io-lifetimes"
version = "1.0.4" version = "1.0.4"
@ -319,6 +385,16 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "libudev-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
dependencies = [
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.1.4" version = "0.1.4"
@ -334,6 +410,15 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.5.0"
@ -393,6 +478,18 @@ dependencies = [
"memoffset", "memoffset",
] ]
[[package]]
name = "nix"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
dependencies = [
"autocfg",
"bitflags",
"cfg-if",
"libc",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -700,6 +797,18 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "uuid"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]] [[package]]
name = "version-compare" name = "version-compare"
version = "0.1.1" version = "0.1.1"
@ -793,7 +902,7 @@ dependencies = [
"bitflags", "bitflags",
"downcast-rs", "downcast-rs",
"libc", "libc",
"nix", "nix 0.24.3",
"scoped-tls", "scoped-tls",
"wayland-commons", "wayland-commons",
"wayland-scanner", "wayland-scanner",
@ -806,7 +915,7 @@ version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
dependencies = [ dependencies = [
"nix", "nix 0.24.3",
"once_cell", "once_cell",
"smallvec", "smallvec",
"wayland-sys", "wayland-sys",
@ -818,7 +927,7 @@ version = "0.29.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661"
dependencies = [ dependencies = [
"nix", "nix 0.24.3",
"wayland-client", "wayland-client",
"xcursor", "xcursor",
] ]
@ -898,6 +1007,21 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.42.0" version = "0.42.0"

View file

@ -9,4 +9,5 @@ edition = "2021"
clap = {version = "4.1.1", features = ["derive"]} clap = {version = "4.1.1", features = ["derive"]}
spin_sleep = "1.1.1" spin_sleep = "1.1.1"
minifb = "0.23" minifb = "0.23"
rand = "0.8.5" rand = "0.8.5"
gilrs = "0.10.1"

View file

@ -4,6 +4,7 @@ mod processor;
mod util; mod util;
use clap::{ArgGroup, Parser}; use clap::{ArgGroup, Parser};
use gilrs::Gilrs;
use minifb::{Window, WindowOptions}; use minifb::{Window, WindowOptions};
use processor::{ use processor::{
memory::{rom::Rom, Memory}, memory::{rom::Rom, Memory},
@ -117,6 +118,7 @@ fn main() {
window, window,
args.tile_window, args.tile_window,
args.run_bootrom, args.run_bootrom,
Gilrs::new().unwrap(),
); );
let mut cycle_num = 0; let mut cycle_num = 0;

View file

@ -151,7 +151,12 @@ impl Cpu {
} }
fn enter_vblank(&mut self) { fn enter_vblank(&mut self) {
if self.memory.update_pressed_keys(self.window.get_keys()) { // let gamepad = self.gamepad_handler.gamepads().last();
while self.gamepad_handler.next_event().is_some() {}
if self
.memory
.update_pressed_keys(self.window.get_keys(), self.gamepad_handler.gamepads())
{
self.memory.set(0xFF0F, set_bit(self.memory.get(0xFF0F), 4)); self.memory.set(0xFF0F, set_bit(self.memory.get(0xFF0F), 4));
} }
self.gpu.mode = DrawMode::VBlank; self.gpu.mode = DrawMode::VBlank;

View file

@ -3,6 +3,7 @@ use crate::{
processor::{clear_bit, get_bit, SplitRegister}, processor::{clear_bit, get_bit, SplitRegister},
verbose_println, verbose_println,
}; };
use gilrs::{Button, ConnectedGamepadsIterator, Gamepad, GamepadId};
use minifb::Key; use minifb::Key;
use std::io::{stdout, Write}; use std::io::{stdout, Write};
@ -280,16 +281,41 @@ impl Memory {
self.io[addr_l] = (self.io[addr_l] & (!mask)) | (data & mask); self.io[addr_l] = (self.io[addr_l] & (!mask)) | (data & mask);
} }
pub fn update_pressed_keys(&mut self, keys: Vec<Key>) -> bool { pub fn update_pressed_keys(
&mut self,
keys: Vec<Key>,
gamepads: ConnectedGamepadsIterator,
) -> bool {
let old = self.joypad; let old = self.joypad;
self.joypad.down = keys.contains(&Key::Down) || keys.contains(&Key::S); self.joypad = Joypad {
self.joypad.up = keys.contains(&Key::Up) || keys.contains(&Key::W); bank_sel: self.joypad.bank_sel,
self.joypad.left = keys.contains(&Key::Left) || keys.contains(&Key::A); down: false,
self.joypad.right = keys.contains(&Key::Right) || keys.contains(&Key::D); up: false,
self.joypad.start = keys.contains(&Key::Equal); left: false,
self.joypad.select = keys.contains(&Key::Minus); right: false,
self.joypad.a = keys.contains(&Key::Apostrophe); start: false,
self.joypad.b = keys.contains(&Key::Semicolon); select: false,
b: false,
a: false,
};
for (_, pad) in gamepads {
self.joypad.down |= pad.is_pressed(Button::DPadDown);
self.joypad.up |= pad.is_pressed(Button::DPadUp);
self.joypad.left |= pad.is_pressed(Button::DPadLeft);
self.joypad.right |= pad.is_pressed(Button::DPadRight);
self.joypad.start |= pad.is_pressed(Button::Start);
self.joypad.select |= pad.is_pressed(Button::Select);
self.joypad.a |= pad.is_pressed(Button::East);
self.joypad.b |= pad.is_pressed(Button::South);
}
self.joypad.down |= keys.contains(&Key::Down) || keys.contains(&Key::S);
self.joypad.up |= keys.contains(&Key::Up) || keys.contains(&Key::W);
self.joypad.left |= keys.contains(&Key::Left) || keys.contains(&Key::A);
self.joypad.right |= keys.contains(&Key::Right) || keys.contains(&Key::D);
self.joypad.start |= keys.contains(&Key::Equal);
self.joypad.select |= keys.contains(&Key::Minus);
self.joypad.a |= keys.contains(&Key::Apostrophe);
self.joypad.b |= keys.contains(&Key::Semicolon);
self.joypad != old self.joypad != old
} }

View file

@ -3,6 +3,7 @@ use crate::{
util::{clear_bit, get_bit}, util::{clear_bit, get_bit},
verbose_println, verbose_println,
}; };
use gilrs::Gilrs;
use minifb::Window; use minifb::Window;
pub mod gpu; pub mod gpu;
@ -33,6 +34,7 @@ pub struct Cpu {
gpu: Gpu, gpu: Gpu,
halted: bool, halted: bool,
timers: Timers, timers: Timers,
gamepad_handler: Gilrs,
} }
// Hz // Hz
@ -46,6 +48,7 @@ impl Cpu {
window: Window, window: Window,
enable_tile_window: bool, enable_tile_window: bool,
run_bootrom: bool, run_bootrom: bool,
gamepad_handler: Gilrs,
) -> Self { ) -> Self {
if run_bootrom { if run_bootrom {
memory.cpu_ram_init(); memory.cpu_ram_init();
@ -59,6 +62,7 @@ impl Cpu {
gpu: Gpu::new(enable_tile_window), gpu: Gpu::new(enable_tile_window),
halted: false, halted: false,
timers: Timers::init(), timers: Timers::init(),
gamepad_handler,
} }
} }