From 84d9dbf8770caff695584173d559330781a13749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sallai=20J=C3=B3zsef?= Date: Thu, 21 Jul 2022 03:19:23 +0300 Subject: [PATCH] remove gilrs dependency for controller support --- Cargo.toml | 1 - src/framework/backend_sdl2.rs | 78 ++++++++- src/framework/gamepad.rs | 224 ++++++++++++++++--------- src/input/gamepad_player_controller.rs | 72 ++++---- src/lib.rs | 30 ---- src/scene/game_scene.rs | 2 +- src/settings.rs | 27 ++- src/shared_game_state.rs | 16 +- 8 files changed, 270 insertions(+), 180 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ef857d4..1c06b37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,6 @@ cpal = "0.13" directories = "3" downcast = "0.11" funty = "=1.1.0" # https://github.com/bitvecto-rs/bitvec/issues/105 -gilrs = { version = "0.9.0", features = ["serde-serialize"] } glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "8dd457b9adb7dbac7ade337246b6356c784272d9", optional = true, default_features = false, features = ["x11"] } imgui = "0.8.0" image = { version = "0.23", default-features = false, features = ["png", "bmp"] } diff --git a/src/framework/backend_sdl2.rs b/src/framework/backend_sdl2.rs index 7fedade..d4ad534 100644 --- a/src/framework/backend_sdl2.rs +++ b/src/framework/backend_sdl2.rs @@ -9,6 +9,7 @@ use std::time::{Duration, Instant}; use imgui::internal::RawWrapper; use imgui::{ConfigFlags, DrawCmd, DrawData, DrawIdx, DrawVert, Key, MouseCursor, TextureId, Ui}; +use sdl2::controller::GameController; use sdl2::event::{Event, WindowEvent}; use sdl2::keyboard::Scancode; use sdl2::mouse::{Cursor, SystemCursor}; @@ -17,7 +18,7 @@ use sdl2::render::{Texture, TextureCreator, TextureQuery, WindowCanvas}; use sdl2::video::GLProfile; use sdl2::video::Window; use sdl2::video::WindowContext; -use sdl2::{keyboard, pixels, EventPump, Sdl, VideoSubsystem}; +use sdl2::{controller, keyboard, pixels, EventPump, GameControllerSubsystem, Sdl, VideoSubsystem}; use crate::common::{Color, Rect}; use crate::framework::backend::{ @@ -25,6 +26,7 @@ use crate::framework::backend::{ }; use crate::framework::context::Context; use crate::framework::error::{GameError, GameResult}; +use crate::framework::gamepad::{Axis, Button}; use crate::framework::graphics::BlendMode; use crate::framework::keyboard::ScanCode; use crate::framework::render_opengl::{GLContext, OpenGLRenderer}; @@ -42,6 +44,8 @@ pub struct SDL2Backend { impl SDL2Backend { pub fn new(size_hint: (u16, u16)) -> GameResult> { + sdl2::hint::set("SDL_JOYSTICK_THREAD", "1"); + let context = sdl2::init().map_err(GameError::WindowError)?; let backend = SDL2Backend { context, size_hint }; @@ -141,12 +145,15 @@ struct SDL2Context { gl_context: Option, blend_mode: sdl2::render::BlendMode, fullscreen_type: sdl2::video::FullscreenType, + game_controller: GameControllerSubsystem, } impl SDL2EventLoop { pub fn new(sdl: &Sdl, size_hint: (u16, u16)) -> GameResult> { let event_pump = sdl.event_pump().map_err(GameError::WindowError)?; let video = sdl.video().map_err(GameError::WindowError)?; + let game_controller = sdl.game_controller().map_err(GameError::GamepadError)?; + let gl_attr = video.gl_attr(); gl_attr.set_context_profile(GLProfile::Compatibility); @@ -160,8 +167,8 @@ impl SDL2EventLoop { window.opengl(); let window = window.build().map_err(|e| GameError::WindowError(e.to_string()))?; - let opengl_available = if let Ok(v) = std::env::var("CAVESTORY_NO_OPENGL") { v != "1" } else { true }; + let event_loop = SDL2EventLoop { event_pump, refs: Rc::new(RefCell::new(SDL2Context { @@ -170,6 +177,7 @@ impl SDL2EventLoop { gl_context: None, blend_mode: sdl2::render::BlendMode::Blend, fullscreen_type: sdl2::video::FullscreenType::Off, + game_controller, })), opengl_available: RefCell::new(opengl_available), }; @@ -293,6 +301,39 @@ impl BackendEventLoop for SDL2EventLoop { ctx.keyboard_context.set_key(drs_scan, false); } } + Event::ControllerDeviceAdded { which, .. } => { + let game_controller = &self.refs.borrow().game_controller; + + if game_controller.is_game_controller(which) { + let controller = game_controller.open(which).unwrap(); + log::info!("Connected gamepad: {} (ID: {})", controller.name(), controller.instance_id()); + + let axis_sensitivity = state.settings.get_gamepad_axis_sensitivity(which); + ctx.gamepad_context.add_gamepad(controller, axis_sensitivity); + } + } + Event::ControllerDeviceRemoved { which, .. } => { + let game_controller = &self.refs.borrow().game_controller; + log::info!("Disconnected gamepad with ID {}", which); + ctx.gamepad_context.remove_gamepad(which); + } + Event::ControllerAxisMotion { which, axis, value, .. } => { + if let Some(drs_axis) = conv_gamepad_axis(axis) { + let new_value = (value as f64) / i16::MAX as f64; + ctx.gamepad_context.set_axis_value(which, drs_axis, new_value); + ctx.gamepad_context.update_axes(which); + } + } + Event::ControllerButtonDown { which, button, .. } => { + if let Some(drs_button) = conv_gamepad_button(button) { + ctx.gamepad_context.set_button(which, drs_button, true); + } + } + Event::ControllerButtonUp { which, button, .. } => { + if let Some(drs_button) = conv_gamepad_button(button) { + ctx.gamepad_context.set_button(which, drs_button, false); + } + } _ => {} } } @@ -1100,6 +1141,39 @@ fn conv_scancode(code: keyboard::Scancode) -> Option { } } +fn conv_gamepad_button(code: controller::Button) -> Option