remove gilrs dependency for controller support

This commit is contained in:
Sallai József 2022-07-21 03:19:23 +03:00
parent 9932b1209f
commit 84d9dbf877
8 changed files with 270 additions and 180 deletions

View File

@ -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"] }

View File

@ -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<Box<dyn Backend>> {
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<sdl2::video::GLContext>,
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<Box<dyn BackendEventLoop>> {
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<ScanCode> {
}
}
fn conv_gamepad_button(code: controller::Button) -> Option<Button> {
match code {
controller::Button::A => Some(Button::South),
controller::Button::B => Some(Button::East),
controller::Button::X => Some(Button::West),
controller::Button::Y => Some(Button::North),
controller::Button::Back => Some(Button::Back),
controller::Button::Guide => Some(Button::Guide),
controller::Button::Start => Some(Button::Start),
controller::Button::LeftStick => Some(Button::LeftStick),
controller::Button::RightStick => Some(Button::RightStick),
controller::Button::LeftShoulder => Some(Button::LeftShoulder),
controller::Button::RightShoulder => Some(Button::RightShoulder),
controller::Button::DPadUp => Some(Button::DPadUp),
controller::Button::DPadDown => Some(Button::DPadDown),
controller::Button::DPadLeft => Some(Button::DPadLeft),
controller::Button::DPadRight => Some(Button::DPadRight),
_ => None,
}
}
fn conv_gamepad_axis(code: controller::Axis) -> Option<Axis> {
match code {
controller::Axis::LeftX => Some(Axis::LeftX),
controller::Axis::LeftY => Some(Axis::LeftY),
controller::Axis::RightX => Some(Axis::RightX),
controller::Axis::RightY => Some(Axis::RightY),
controller::Axis::TriggerLeft => Some(Axis::TriggerLeft),
controller::Axis::TriggerRight => Some(Axis::TriggerRight),
_ => None,
}
}
// based on imgui-sdl2 crate
pub struct ImguiSdl2 {
mouse_press: [bool; 5],

View File

@ -1,13 +1,25 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use gilrs::{Axis, Button, Gamepad, GamepadId};
use sdl2::controller::GameController;
use serde::{Deserialize, Serialize};
use crate::{framework::context::Context, settings::PlayerControllerInputType};
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[repr(u32)]
pub enum Axis {
LeftX,
LeftY,
RightX,
RightY,
TriggerLeft,
TriggerRight,
}
#[derive(Clone, Debug)]
pub enum AxisDirection {
None,
Either,
Up,
Left,
Right,
@ -18,107 +30,169 @@ impl AxisDirection {
pub fn compare(&self, value: f64, axis_sensitivity: f64) -> bool {
match self {
AxisDirection::None => false,
AxisDirection::Up => value > axis_sensitivity,
AxisDirection::Left => value < -axis_sensitivity,
AxisDirection::Right => value > axis_sensitivity,
AxisDirection::Down => value < -axis_sensitivity,
AxisDirection::Either => value.abs() > 0.0,
AxisDirection::Down | AxisDirection::Right => value > axis_sensitivity,
AxisDirection::Up | AxisDirection::Left => value < -axis_sensitivity,
}
}
}
#[derive(Clone, Debug)]
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[repr(u32)]
pub enum Button {
South,
East,
West,
North,
Back,
Guide,
Start,
LeftStick,
RightStick,
LeftShoulder,
RightShoulder,
DPadUp,
DPadDown,
DPadLeft,
DPadRight,
}
pub struct GamepadData {
controller: GameController,
left_x: f64,
left_y: f64,
right_x: f64,
right_y: f64,
trigger_left: f64,
trigger_right: f64,
axis_sensitivity: f64,
pressed_buttons_set: HashSet<Button>,
axis_values: HashMap<Axis, f64>,
}
impl GamepadData {
pub(crate) fn new(axis_sensitivity: f64) -> Self {
GamepadData { left_x: 0.0, left_y: 0.0, right_x: 0.0, right_y: 0.0, axis_sensitivity }
pub(crate) fn new(game_controller: GameController, axis_sensitivity: f64) -> Self {
GamepadData {
controller: game_controller,
left_x: 0.0,
left_y: 0.0,
right_x: 0.0,
right_y: 0.0,
trigger_left: 0.0,
trigger_right: 0.0,
axis_sensitivity,
pressed_buttons_set: HashSet::with_capacity(16),
axis_values: HashMap::with_capacity(8),
}
}
}
#[derive(Clone, Debug)]
pub struct GamepadContext {
gamepads: HashMap<GamepadId, GamepadData>,
gamepads: Vec<GamepadData>,
}
impl GamepadContext {
pub(crate) fn new() -> Self {
Self { gamepads: HashMap::new() }
Self { gamepads: Vec::new() }
}
fn gamepad_exists(&self, gamepad: &Gamepad) -> bool {
self.gamepads.contains_key(&gamepad.id())
fn get_gamepad(&self, gamepad_id: u32) -> Option<&GamepadData> {
self.gamepads.iter().find(|gamepad| gamepad.controller.instance_id() == gamepad_id)
}
pub(crate) fn add_gamepad(&mut self, gamepad: &Gamepad, axis_sensitivity: f64) {
self.gamepads.insert(gamepad.id(), GamepadData::new(axis_sensitivity));
fn get_gamepad_by_index(&self, gamepad_index: usize) -> Option<&GamepadData> {
self.gamepads.get(gamepad_index)
}
pub(crate) fn remove_gamepad(&mut self, gamepad: &Gamepad) {
self.gamepads.remove(&gamepad.id());
fn get_gamepad_mut(&mut self, gamepad_id: u32) -> Option<&mut GamepadData> {
self.gamepads.iter_mut().find(|gamepad| gamepad.controller.instance_id() == gamepad_id)
}
pub(crate) fn is_active(
&self,
gamepad: &Gamepad,
input_type: &PlayerControllerInputType,
axis_direction: AxisDirection,
) -> bool {
match input_type {
PlayerControllerInputType::ButtonInput(button) => self.is_button_active(gamepad, *button),
PlayerControllerInputType::AxisInput(axis) => self.is_axis_active(gamepad, *axis, axis_direction),
PlayerControllerInputType::Either(button, axis) => {
self.is_button_active(gamepad, *button) || self.is_axis_active(gamepad, *axis, axis_direction)
pub(crate) fn add_gamepad(&mut self, game_controller: GameController, axis_sensitivity: f64) {
self.gamepads.push(GamepadData::new(game_controller, axis_sensitivity));
}
pub(crate) fn remove_gamepad(&mut self, gamepad_id: u32) {
self.gamepads.retain(|data| data.controller.instance_id() != gamepad_id);
}
pub(crate) fn set_button(&mut self, gamepad_id: u32, button: Button, pressed: bool) {
if let Some(gamepad) = self.get_gamepad_mut(gamepad_id) {
if pressed {
gamepad.pressed_buttons_set.insert(button);
} else {
gamepad.pressed_buttons_set.remove(&button);
}
}
}
pub(crate) fn is_button_active(&self, gamepad: &Gamepad, button: Button) -> bool {
if !self.gamepad_exists(gamepad) {
return false;
}
gamepad.is_pressed(button)
}
pub(crate) fn is_axis_active(&self, gamepad: &Gamepad, axis: Axis, direction: AxisDirection) -> bool {
if !self.gamepad_exists(gamepad) {
return false;
}
let data = self.gamepads.get(&gamepad.id()).unwrap();
match axis {
Axis::LeftStickX => direction.compare(data.left_x, data.axis_sensitivity),
Axis::LeftStickY => direction.compare(data.left_y, data.axis_sensitivity),
Axis::RightStickX => direction.compare(data.right_x, data.axis_sensitivity),
Axis::RightStickY => direction.compare(data.right_y, data.axis_sensitivity),
_ => false,
pub(crate) fn set_axis_value(&mut self, gamepad_id: u32, axis: Axis, value: f64) {
if let Some(gamepad) = self.get_gamepad_mut(gamepad_id) {
gamepad.axis_values.insert(axis, value);
}
}
pub(crate) fn update_axes(&mut self, gamepad: &Gamepad) {
if !self.gamepad_exists(gamepad) {
return;
pub(crate) fn is_active(
&self,
gamepad_index: u32,
input_type: &PlayerControllerInputType,
axis_direction: AxisDirection,
) -> bool {
match input_type {
PlayerControllerInputType::ButtonInput(button) => self.is_button_active(gamepad_index, *button),
PlayerControllerInputType::AxisInput(axis) => self.is_axis_active(gamepad_index, *axis, axis_direction),
PlayerControllerInputType::Either(button, axis) => {
self.is_button_active(gamepad_index, *button)
|| self.is_axis_active(gamepad_index, *axis, axis_direction)
}
}
}
pub(crate) fn is_button_active(&self, gamepad_index: u32, button: Button) -> bool {
if let Some(gamepad) = self.get_gamepad_by_index(gamepad_index as usize) {
return gamepad.pressed_buttons_set.contains(&button);
}
let data = self.gamepads.get_mut(&gamepad.id()).unwrap();
false
}
let mut axes = [
(&mut data.left_x, Axis::LeftStickX),
(&mut data.left_y, Axis::LeftStickY),
(&mut data.right_x, Axis::RightStickX),
(&mut data.right_y, Axis::RightStickY),
];
pub(crate) fn is_axis_active(&self, gamepad_index: u32, axis: Axis, direction: AxisDirection) -> bool {
if let Some(gamepad) = self.get_gamepad_by_index(gamepad_index as usize) {
return match axis {
Axis::LeftX => direction.compare(gamepad.left_x, gamepad.axis_sensitivity),
Axis::LeftY => direction.compare(gamepad.left_y, gamepad.axis_sensitivity),
Axis::RightX => direction.compare(gamepad.right_x, gamepad.axis_sensitivity),
Axis::RightY => direction.compare(gamepad.right_y, gamepad.axis_sensitivity),
Axis::TriggerLeft => direction.compare(gamepad.trigger_left, 0.0),
Axis::TriggerRight => direction.compare(gamepad.trigger_right, 0.0),
};
}
for (axis_val, id) in axes.iter_mut() {
if let Some(axis) = gamepad.axis_data(*id) {
**axis_val = if axis.value().abs() < 0.12 { 0.0 } else { axis.value() } as f64;
false
}
pub(crate) fn update_axes(&mut self, gamepad_id: u32) {
if let Some(gamepad) = self.get_gamepad_mut(gamepad_id) {
let mut axes = [
(&mut gamepad.left_x, Axis::LeftX),
(&mut gamepad.left_y, Axis::LeftY),
(&mut gamepad.right_x, Axis::RightX),
(&mut gamepad.right_y, Axis::RightY),
(&mut gamepad.trigger_left, Axis::TriggerLeft),
(&mut gamepad.trigger_right, Axis::TriggerRight),
];
for (axis_val, id) in axes.iter_mut() {
if let Some(axis) = gamepad.axis_values.get(id) {
**axis_val = if axis.abs() < 0.12 { 0.0 } else { *axis };
}
}
}
}
@ -130,31 +204,27 @@ impl Default for GamepadContext {
}
}
pub fn add_gamepad(context: &mut Context, gamepad: &Gamepad, axis_sensitivity: f64) {
context.gamepad_context.add_gamepad(gamepad, axis_sensitivity);
pub fn add_gamepad(context: &mut Context, game_controller: GameController, axis_sensitivity: f64) {
context.gamepad_context.add_gamepad(game_controller, axis_sensitivity);
}
pub fn remove_gamepad(context: &mut Context, gamepad: &Gamepad) {
context.gamepad_context.remove_gamepad(gamepad);
pub fn remove_gamepad(context: &mut Context, gamepad_id: u32) {
context.gamepad_context.remove_gamepad(gamepad_id);
}
pub fn is_active(
ctx: &Context,
gamepad: &Gamepad,
gamepad_index: u32,
input_type: &PlayerControllerInputType,
axis_direction: AxisDirection,
) -> bool {
ctx.gamepad_context.is_active(gamepad, input_type, axis_direction)
ctx.gamepad_context.is_active(gamepad_index, input_type, axis_direction)
}
pub fn is_button_active(ctx: &Context, gamepad: &Gamepad, button: Button) -> bool {
ctx.gamepad_context.is_button_active(gamepad, button)
pub fn is_button_active(ctx: &Context, gamepad_index: u32, button: Button) -> bool {
ctx.gamepad_context.is_button_active(gamepad_index, button)
}
pub fn is_axis_active(ctx: &Context, gamepad: &Gamepad, axis: Axis, direction: AxisDirection) -> bool {
ctx.gamepad_context.is_axis_active(gamepad, axis, direction)
}
pub fn update_axes(ctx: &mut Context, gamepad: &Gamepad) {
ctx.gamepad_context.update_axes(gamepad);
pub fn is_axis_active(ctx: &Context, gamepad_index: u32, axis: Axis, direction: AxisDirection) -> bool {
ctx.gamepad_context.is_axis_active(gamepad_index, axis, direction)
}

View File

@ -1,13 +1,11 @@
use crate::framework::context::Context;
use crate::framework::error::GameResult;
use crate::framework::gamepad::{self, AxisDirection};
use crate::framework::gamepad::{self, AxisDirection, Button};
use crate::input::player_controller::PlayerController;
use crate::player::TargetPlayer;
use crate::shared_game_state::SharedGameState;
use crate::{bitfield, settings::PlayerControllerInputType};
use gilrs::{Button, GamepadId};
bitfield! {
#[derive(Clone, Copy)]
pub struct KeyState(u16);
@ -31,7 +29,7 @@ bitfield! {
#[derive(Clone)]
pub struct GamepadController {
gamepad_id: GamepadId,
gamepad_id: u32,
target: TargetPlayer,
state: KeyState,
old_state: KeyState,
@ -39,7 +37,7 @@ pub struct GamepadController {
}
impl GamepadController {
pub fn new(gamepad_id: GamepadId, target: TargetPlayer) -> GamepadController {
pub fn new(gamepad_id: u32, target: TargetPlayer) -> GamepadController {
GamepadController { gamepad_id, target, state: KeyState(0), old_state: KeyState(0), trigger: KeyState(0) }
}
}
@ -51,41 +49,35 @@ impl PlayerController for GamepadController {
TargetPlayer::Player2 => &state.settings.player2_controller_button_map,
};
if let Some(gilrs) = &state.gilrs {
if let Some(gamepad) = gilrs.connected_gamepad(self.gamepad_id) {
gamepad::update_axes(ctx, &gamepad);
self.state.set_up(gamepad::is_active(ctx, &gamepad, &button_map.up, AxisDirection::Up));
self.state.set_down(gamepad::is_active(ctx, &gamepad, &button_map.down, AxisDirection::Down));
self.state.set_left(gamepad::is_active(ctx, &gamepad, &button_map.left, AxisDirection::Left));
self.state.set_right(gamepad::is_active(ctx, &gamepad, &button_map.right, AxisDirection::Right));
self.state.set_map(gamepad::is_active(ctx, &gamepad, &button_map.map, AxisDirection::None));
self.state.set_inventory(gamepad::is_active(ctx, &gamepad, &button_map.inventory, AxisDirection::None));
self.state.set_jump(gamepad::is_active(ctx, &gamepad, &button_map.jump, AxisDirection::None));
self.state.set_shoot(gamepad::is_active(ctx, &gamepad, &button_map.shoot, AxisDirection::None));
self.state.set_next_weapon(gamepad::is_active(
ctx,
&gamepad,
&button_map.next_weapon,
AxisDirection::None,
));
self.state.set_prev_weapon(gamepad::is_active(
ctx,
&gamepad,
&button_map.prev_weapon,
AxisDirection::None,
));
self.state.set_escape(gamepad::is_active(
ctx,
&gamepad,
&PlayerControllerInputType::ButtonInput(Button::Start),
AxisDirection::None,
));
self.state.set_enter(gamepad::is_active(ctx, &gamepad, &button_map.jump, AxisDirection::None));
self.state.set_skip(gamepad::is_active(ctx, &gamepad, &button_map.skip, AxisDirection::None));
self.state.set_strafe(gamepad::is_active(ctx, &gamepad, &button_map.strafe, AxisDirection::None));
}
}
self.state.set_up(gamepad::is_active(ctx, self.gamepad_id, &button_map.up, AxisDirection::Up));
self.state.set_down(gamepad::is_active(ctx, self.gamepad_id, &button_map.down, AxisDirection::Down));
self.state.set_left(gamepad::is_active(ctx, self.gamepad_id, &button_map.left, AxisDirection::Left));
self.state.set_right(gamepad::is_active(ctx, self.gamepad_id, &button_map.right, AxisDirection::Right));
self.state.set_map(gamepad::is_active(ctx, self.gamepad_id, &button_map.map, AxisDirection::None));
self.state.set_inventory(gamepad::is_active(ctx, self.gamepad_id, &button_map.inventory, AxisDirection::None));
self.state.set_jump(gamepad::is_active(ctx, self.gamepad_id, &button_map.jump, AxisDirection::None));
self.state.set_shoot(gamepad::is_active(ctx, self.gamepad_id, &button_map.shoot, AxisDirection::None));
self.state.set_next_weapon(gamepad::is_active(
ctx,
self.gamepad_id,
&button_map.next_weapon,
AxisDirection::None,
));
self.state.set_prev_weapon(gamepad::is_active(
ctx,
self.gamepad_id,
&button_map.prev_weapon,
AxisDirection::None,
));
self.state.set_escape(gamepad::is_active(
ctx,
self.gamepad_id,
&PlayerControllerInputType::ButtonInput(Button::Start),
AxisDirection::None,
));
self.state.set_enter(gamepad::is_active(ctx, self.gamepad_id, &button_map.jump, AxisDirection::None));
self.state.set_skip(gamepad::is_active(ctx, self.gamepad_id, &button_map.skip, AxisDirection::Either));
self.state.set_strafe(gamepad::is_active(ctx, self.gamepad_id, &button_map.strafe, AxisDirection::Either));
Ok(())
}

View File

@ -11,8 +11,6 @@ use std::sync::Mutex;
use std::time::{Duration, Instant};
use directories::ProjectDirs;
use framework::gamepad;
use gilrs::EventType;
use lazy_static::lazy_static;
use crate::builtin_fs::BuiltinFS;
@ -112,34 +110,6 @@ impl Game {
}
fn update(&mut self, ctx: &mut Context) -> GameResult {
{
let state_ref = unsafe { &mut *self.state.get() };
if let Some(gilrs) = &mut state_ref.gilrs {
while let Some(e) = gilrs.next_event() {
let gamepad = gilrs.gamepad(e.id);
match e.event {
EventType::Connected => {
log::info!("Gamepad connected: {} (ID: {})", gamepad.name(), gamepad.id());
let axis_sensitivity = state_ref.settings.get_gamepad_axis_sensitivity(gamepad.id());
gamepad::add_gamepad(ctx, &gamepad, axis_sensitivity);
// TODO: replace the controller of all players that use this gamepad from keyboard to gamepad
}
EventType::Disconnected => {
log::info!("Gamepad disconnected: {} (ID: {})", gamepad.name(), gamepad.id());
gamepad::remove_gamepad(ctx, &gamepad);
// TODO: fall back to keyboard for all players that use this gamepad
}
_ => {}
}
}
}
}
if let Some(scene) = &mut self.scene {
let state_ref = unsafe { &mut *self.state.get() };

View File

@ -1773,7 +1773,7 @@ impl Scene for GameScene {
if !state.control_flags.control_enabled() && !state.textscript_vm.flags.cutscene_skip() =>
{
state.touch_controls.control_type = TouchControlType::Dialog;
if self.player1.controller.inventory() {
if self.player1.controller.skip() {
self.skip_counter += 1;
if self.skip_counter >= CUTSCENE_SKIP_WAIT {
state.textscript_vm.flags.set_cutscene_skip(true);

View File

@ -1,8 +1,7 @@
use gilrs::{Axis, Button, GamepadId};
use crate::framework::context::Context;
use crate::framework::error::GameResult;
use crate::framework::filesystem::{user_create, user_open};
use crate::framework::gamepad::{Axis, Button};
use crate::framework::keyboard::ScanCode;
use crate::graphics::VSyncMode;
use crate::input::gamepad_player_controller::GamepadController;
@ -232,7 +231,7 @@ impl Settings {
}
}
pub fn get_gamepad_axis_sensitivity(&self, id: GamepadId) -> f64 {
pub fn get_gamepad_axis_sensitivity(&self, id: u32) -> f64 {
if self.player1_controller_type == ControllerType::Gamepad(id) {
self.player1_controller_axis_sensitivity
} else if self.player2_controller_type == ControllerType::Gamepad(id) {
@ -337,7 +336,7 @@ fn p2_default_keymap() -> PlayerKeyMap {
#[derive(serde::Serialize, serde::Deserialize, Eq, PartialEq)]
pub enum ControllerType {
Keyboard,
Gamepad(GamepadId),
Gamepad(u32),
}
#[derive(serde::Serialize, serde::Deserialize)]
@ -366,16 +365,16 @@ pub struct PlayerControllerButtonMap {
#[inline(always)]
pub fn player_default_controller_button_map() -> PlayerControllerButtonMap {
PlayerControllerButtonMap {
left: PlayerControllerInputType::Either(Button::DPadLeft, Axis::LeftStickX),
up: PlayerControllerInputType::Either(Button::DPadUp, Axis::LeftStickY),
right: PlayerControllerInputType::Either(Button::DPadRight, Axis::LeftStickX),
down: PlayerControllerInputType::Either(Button::DPadDown, Axis::LeftStickY),
prev_weapon: PlayerControllerInputType::ButtonInput(Button::LeftTrigger),
next_weapon: PlayerControllerInputType::ButtonInput(Button::RightTrigger),
jump: PlayerControllerInputType::ButtonInput(Button::East),
shoot: PlayerControllerInputType::ButtonInput(Button::South),
skip: PlayerControllerInputType::ButtonInput(Button::LeftTrigger2),
strafe: PlayerControllerInputType::ButtonInput(Button::RightTrigger2),
left: PlayerControllerInputType::Either(Button::DPadLeft, Axis::LeftX),
up: PlayerControllerInputType::Either(Button::DPadUp, Axis::LeftY),
right: PlayerControllerInputType::Either(Button::DPadRight, Axis::LeftX),
down: PlayerControllerInputType::Either(Button::DPadDown, Axis::LeftY),
prev_weapon: PlayerControllerInputType::ButtonInput(Button::LeftShoulder),
next_weapon: PlayerControllerInputType::ButtonInput(Button::RightShoulder),
jump: PlayerControllerInputType::ButtonInput(Button::South),
shoot: PlayerControllerInputType::ButtonInput(Button::East),
skip: PlayerControllerInputType::AxisInput(Axis::TriggerLeft),
strafe: PlayerControllerInputType::AxisInput(Axis::TriggerRight),
inventory: PlayerControllerInputType::ButtonInput(Button::North),
map: PlayerControllerInputType::ButtonInput(Button::West),
}

View File

@ -15,7 +15,7 @@ use crate::framework::error::GameResult;
use crate::framework::graphics::{create_texture_mutable, set_render_target};
use crate::framework::keyboard::ScanCode;
use crate::framework::vfs::OpenOptions;
use crate::framework::{filesystem, gamepad, graphics};
use crate::framework::{filesystem, graphics};
#[cfg(feature = "hooks")]
use crate::hooks::init_hooks;
use crate::i18n::Locale;
@ -38,8 +38,6 @@ use crate::stage::StageData;
use crate::texture_set::TextureSet;
use crate::vanilla::VanillaExtractor;
use gilrs::Gilrs;
#[derive(PartialEq, Eq, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub enum TimingMode {
_50Hz,
@ -289,7 +287,6 @@ pub struct SharedGameState {
pub super_quake_counter: u16,
pub teleporter_slots: Vec<(u16, u16)>,
pub carets: Vec<Caret>,
pub gilrs: Option<Gilrs>,
pub touch_controls: TouchControls,
pub mod_path: Option<String>,
pub mod_list: ModList,
@ -334,16 +331,6 @@ impl SharedGameState {
let mut sound_manager = SoundManager::new(ctx)?;
let settings = Settings::load(ctx)?;
let mod_requirements = ModRequirements::load(ctx)?;
let mut gilrs = Gilrs::new().ok();
if let Some(gilrs) = &mut gilrs {
for (id, gamepad) in gilrs.gamepads() {
log::info!("Found gamepad {} (ID {})", gamepad.name(), id);
let axis_sensitivity = settings.get_gamepad_axis_sensitivity(id);
gamepad::add_gamepad(ctx, &gamepad, axis_sensitivity);
}
}
let vanilla_extractor = VanillaExtractor::from(ctx, "Doukutsu.exe".to_string());
if vanilla_extractor.is_some() {
@ -437,7 +424,6 @@ impl SharedGameState {
super_quake_counter: 0,
teleporter_slots: Vec::with_capacity(8),
carets: Vec::with_capacity(32),
gilrs,
touch_controls: TouchControls::new(),
mod_path: None,
mod_list,