diff --git a/Cargo.lock b/Cargo.lock index dfe58520c2..123e7d01b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -697,22 +697,6 @@ dependencies = [ "encase_derive_impl", ] -[[package]] -name = "bevy_gilrs" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65f4d79c55829f8016014593a42453f61a564ffb06ef79460d25696ccdfac67b" -dependencies = [ - "bevy_app", - "bevy_ecs 0.11.3", - "bevy_input", - "bevy_log", - "bevy_time", - "bevy_utils 0.11.3", - "gilrs", - "thiserror", -] - [[package]] name = "bevy_gizmos" version = "0.11.3" @@ -775,7 +759,6 @@ dependencies = [ "bevy_derive", "bevy_diagnostic", "bevy_ecs 0.11.3", - "bevy_gilrs", "bevy_gizmos", "bevy_hierarchy", "bevy_input", @@ -1480,6 +1463,7 @@ dependencies = [ "fluent-langneg", "futures-lite 2.3.0", "ggrs", + "gilrs", "glam 0.24.2", "hex", "image 0.24.9", @@ -1496,6 +1480,7 @@ dependencies = [ "postcard", "rcgen", "rustls 0.21.12", + "send_wrapper", "serde", "serde_yaml", "smallvec", @@ -1933,6 +1918,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1946,7 +1941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", "foreign-types 0.3.2", "libc", @@ -1959,7 +1954,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", "foreign-types 0.5.0", "libc", @@ -1972,7 +1967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] @@ -3196,9 +3191,9 @@ dependencies = [ [[package]] name = "gilrs" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb8c78963a8856a5b10015c9349176ff5edbc8095384d52aada467a848bc03a" +checksum = "bbb2c998745a3c1ac90f64f4f7b3a54219fd3612d7705e7798212935641ed18f" dependencies = [ "fnv", "gilrs-core", @@ -3209,12 +3204,12 @@ dependencies = [ [[package]] name = "gilrs-core" -version = "0.5.15" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732dadc05170599ddec9a89653f10d7a2af54da9181b3fa6e2bd49907ec8f7e4" +checksum = "495af945e45efd6386227613cd9fb7bd7c43d3c095040e30c5304c489e6abed5" dependencies = [ - "core-foundation", - "inotify 0.10.2", + "core-foundation 0.10.0", + "inotify 0.11.0", "io-kit-sys", "js-sys", "libc", @@ -3858,11 +3853,11 @@ dependencies = [ [[package]] name = "inotify" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd168d97690d0b8c412d6b6c10360277f4d7ee495c5d0d5d5fe0854923255cc" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "inotify-sys", "libc", ] @@ -6462,7 +6457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "security-framework-sys", @@ -7148,7 +7143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -8000,7 +7995,7 @@ version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b" dependencies = [ - "core-foundation", + "core-foundation 0.9.4", "home", "jni", "log", @@ -8581,7 +8576,7 @@ dependencies = [ "android-activity", "bitflags 1.3.2", "cfg_aliases 0.1.1", - "core-foundation", + "core-foundation 0.9.4", "core-graphics 0.22.3", "dispatch", "instant", diff --git a/framework_crates/bones_bevy_renderer/Cargo.toml b/framework_crates/bones_bevy_renderer/Cargo.toml index a3607171c9..5f3055e328 100644 --- a/framework_crates/bones_bevy_renderer/Cargo.toml +++ b/framework_crates/bones_bevy_renderer/Cargo.toml @@ -26,7 +26,7 @@ anyhow = "1.0" [dependencies.bevy] default-features = false -features = ["bevy_render", "bevy_core_pipeline", "bevy_sprite", "x11", "bevy_gilrs"] +features = ["bevy_render", "bevy_core_pipeline", "bevy_sprite", "x11"] version = "0.11" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/framework_crates/bones_bevy_renderer/src/input.rs b/framework_crates/bones_bevy_renderer/src/input.rs index 9ee889c5ab..77b28b1e59 100644 --- a/framework_crates/bones_bevy_renderer/src/input.rs +++ b/framework_crates/bones_bevy_renderer/src/input.rs @@ -1,13 +1,13 @@ use super::*; use bevy::{ input::{ - gamepad::GamepadEvent, keyboard::KeyboardInput, mouse::{MouseButtonInput, MouseMotion, MouseWheel}, }, window::PrimaryWindow, }; use bones::{MouseScreenPosition, MouseWorldPosition}; +use bones_framework::input::gilrs::process_gamepad_events; pub fn insert_bones_input( In((mouse_inputs, keyboard_inputs, gamepad_inputs)): In<( @@ -28,7 +28,6 @@ pub fn get_bones_input( mut mouse_motion_events: EventReader, mut mouse_wheel_events: EventReader, mut keyboard_events: EventReader, - mut gamepad_events: EventReader, ) -> ( bones::MouseInputs, bones::KeyboardInputs, @@ -67,35 +66,7 @@ pub fn get_bones_input( }) .collect(), }, - bones::GamepadInputs { - gamepad_events: gamepad_events - .iter() - .map(|event| match event { - GamepadEvent::Connection(c) => { - bones::GamepadEvent::Connection(bones::GamepadConnectionEvent { - gamepad: c.gamepad.id as u32, - event: if c.connected() { - bones::GamepadConnectionEventKind::Connected - } else { - bones::GamepadConnectionEventKind::Disconnected - }, - }) - } - GamepadEvent::Button(b) => { - bones::GamepadEvent::Button(bones::GamepadButtonEvent { - gamepad: b.gamepad.id as u32, - button: b.button_type.into_bones(), - value: b.value, - }) - } - GamepadEvent::Axis(a) => bones::GamepadEvent::Axis(bones::GamepadAxisEvent { - gamepad: a.gamepad.id as u32, - axis: a.axis_type.into_bones(), - value: a.value, - }), - }) - .collect(), - }, + process_gamepad_events(), ) } diff --git a/framework_crates/bones_framework/Cargo.toml b/framework_crates/bones_framework/Cargo.toml index e8112d3f29..69df9563f7 100644 --- a/framework_crates/bones_framework/Cargo.toml +++ b/framework_crates/bones_framework/Cargo.toml @@ -101,6 +101,9 @@ instant = { version = "0.1", features = ["wasm-bindgen"] } noise = "0.9" once_cell = "1.17" thiserror = "1.0" +gilrs = "0.11.0" +send_wrapper = "0.6.0" + # Tracing tracing = "0.1" diff --git a/framework_crates/bones_framework/src/input.rs b/framework_crates/bones_framework/src/input.rs index bf1189d72b..8cbaa8bb90 100644 --- a/framework_crates/bones_framework/src/input.rs +++ b/framework_crates/bones_framework/src/input.rs @@ -5,6 +5,7 @@ use bones_schema::HasSchema; use self::prelude::{GamepadInputs, KeyboardInputs}; pub mod gamepad; +pub mod gilrs; pub mod keyboard; pub mod mouse; pub mod window; diff --git a/framework_crates/bones_framework/src/input/gilrs.rs b/framework_crates/bones_framework/src/input/gilrs.rs new file mode 100644 index 0000000000..ce9662713b --- /dev/null +++ b/framework_crates/bones_framework/src/input/gilrs.rs @@ -0,0 +1,109 @@ +//! Gilrs integration. +use crate::prelude::*; +use gilrs::{ev::filter::axis_dpad_to_button, EventType, Filter, Gilrs as GilrsContext}; +use once_cell::sync::Lazy; +use send_wrapper::SendWrapper; +use std::sync::{Arc, Mutex}; + +/// Lazy-initialized GilrsContext +static GILRS_CONTEXT: Lazy>>> = Lazy::new(|| { + Arc::new(Mutex::new(SendWrapper::new( + GilrsContext::new().expect("Failed to initialize GilrsContext"), + ))) +}); + +/// Processes gilrs gamepad events into Bones-native GamepadInputs +pub fn process_gamepad_events() -> GamepadInputs { + let mut gamepad_inputs = GamepadInputs::default(); + let mut gilrs = GILRS_CONTEXT.lock().unwrap(); + while let Some(gilrs_event) = gilrs + .next_event() + .filter_ev(&axis_dpad_to_button, &mut gilrs) + { + gilrs.update(&gilrs_event); + + let gamepad = usize::from(gilrs_event.id) as u32; + match gilrs_event.event { + EventType::Connected => { + let _pad = gilrs.gamepad(gilrs_event.id); + gamepad_inputs.gamepad_events.push(GamepadEvent::Connection( + GamepadConnectionEvent { + gamepad, + event: GamepadConnectionEventKind::Connected, + }, + )); + } + EventType::Disconnected => { + gamepad_inputs.gamepad_events.push(GamepadEvent::Connection( + GamepadConnectionEvent { + gamepad, + event: GamepadConnectionEventKind::Disconnected, + }, + )); + } + EventType::ButtonChanged(gilrs_button, value, _) => { + if let Some(button) = convert_button(gilrs_button) { + gamepad_inputs + .gamepad_events + .push(GamepadEvent::Button(GamepadButtonEvent { + gamepad, + button, + value, + })); + } + } + EventType::AxisChanged(gilrs_axis, value, _) => { + if let Some(axis) = convert_axis(gilrs_axis) { + gamepad_inputs + .gamepad_events + .push(GamepadEvent::Axis(GamepadAxisEvent { + gamepad, + axis, + value, + })); + } + } + _ => (), + }; + } + gamepad_inputs +} + +/// Converts a gilrs button to a bones-native button +fn convert_button(button: gilrs::Button) -> Option { + match button { + gilrs::Button::South => Some(GamepadButton::South), + gilrs::Button::East => Some(GamepadButton::East), + gilrs::Button::North => Some(GamepadButton::North), + gilrs::Button::West => Some(GamepadButton::West), + gilrs::Button::C => Some(GamepadButton::C), + gilrs::Button::Z => Some(GamepadButton::Z), + gilrs::Button::LeftTrigger => Some(GamepadButton::LeftTrigger), + gilrs::Button::LeftTrigger2 => Some(GamepadButton::LeftTrigger2), + gilrs::Button::RightTrigger => Some(GamepadButton::RightTrigger), + gilrs::Button::RightTrigger2 => Some(GamepadButton::RightTrigger2), + gilrs::Button::Select => Some(GamepadButton::Select), + gilrs::Button::Start => Some(GamepadButton::Start), + gilrs::Button::Mode => Some(GamepadButton::Mode), + gilrs::Button::LeftThumb => Some(GamepadButton::LeftThumb), + gilrs::Button::RightThumb => Some(GamepadButton::RightThumb), + gilrs::Button::DPadUp => Some(GamepadButton::DPadUp), + gilrs::Button::DPadDown => Some(GamepadButton::DPadDown), + gilrs::Button::DPadLeft => Some(GamepadButton::DPadLeft), + gilrs::Button::DPadRight => Some(GamepadButton::DPadRight), + gilrs::Button::Unknown => None, + } +} + +/// Converts a gilrs axis to a bones-native axis +fn convert_axis(axis: gilrs::Axis) -> Option { + match axis { + gilrs::Axis::LeftStickX => Some(GamepadAxis::LeftStickX), + gilrs::Axis::LeftStickY => Some(GamepadAxis::LeftStickY), + gilrs::Axis::LeftZ => Some(GamepadAxis::LeftZ), + gilrs::Axis::RightStickX => Some(GamepadAxis::RightStickX), + gilrs::Axis::RightStickY => Some(GamepadAxis::RightStickY), + gilrs::Axis::RightZ => Some(GamepadAxis::RightZ), + gilrs::Axis::Unknown | gilrs::Axis::DPadX | gilrs::Axis::DPadY => None, + } +}