Add analogue stick support for controllers in SDL2
Former-commit-id: b3ccff53ded59930a0fe997f1bbbf83fd5e356d8 Former-commit-id: c3c286d1fccf6d9fc5478cd9f6b13d6a7d670b4b
This commit is contained in:
parent
59111ee062
commit
10bed1087a
|
@ -1,5 +1,6 @@
|
||||||
use sdl2::keyboard::Scancode;
|
use sdl2::controller::Axis;
|
||||||
use sdl2::controller::Button;
|
use sdl2::controller::Button;
|
||||||
|
use sdl2::keyboard::Scancode;
|
||||||
|
|
||||||
use rustboyadvance_core::keypad as gba_keypad;
|
use rustboyadvance_core::keypad as gba_keypad;
|
||||||
use rustboyadvance_core::InputInterface;
|
use rustboyadvance_core::InputInterface;
|
||||||
|
@ -9,11 +10,12 @@ use bit::BitIndex;
|
||||||
|
|
||||||
pub struct Sdl2Input {
|
pub struct Sdl2Input {
|
||||||
keyinput: u16,
|
keyinput: u16,
|
||||||
|
axis_keyinput: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputInterface for Sdl2Input {
|
impl InputInterface for Sdl2Input {
|
||||||
fn poll(&mut self) -> u16 {
|
fn poll(&mut self) -> u16 {
|
||||||
self.keyinput
|
!(!self.keyinput | !self.axis_keyinput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +43,31 @@ impl Sdl2Input {
|
||||||
self.keyinput.set_bit(key as usize, true);
|
self.keyinput.set_bit(key as usize, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_axis_motion(&mut self, axis: Axis, val: i16) {
|
||||||
|
use gba_keypad::Keys as GbaKeys;
|
||||||
|
let keys = match axis {
|
||||||
|
Axis::LeftX => (GbaKeys::Left, GbaKeys::Right),
|
||||||
|
Axis::LeftY => (GbaKeys::Up, GbaKeys::Down),
|
||||||
|
Axis::TriggerLeft => (GbaKeys::ButtonL, GbaKeys::ButtonL),
|
||||||
|
Axis::TriggerRight => (GbaKeys::ButtonR, GbaKeys::ButtonR),
|
||||||
|
_ => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Axis motion is an absolute value in the range
|
||||||
|
// [-32768, 32767]. Let's simulate a very rough dead
|
||||||
|
// zone to ignore spurious events.
|
||||||
|
let dead_zone = 10_000;
|
||||||
|
if val > dead_zone || val < -dead_zone {
|
||||||
|
let key = if val < 0 { keys.0 } else { keys.1 };
|
||||||
|
self.axis_keyinput.set_bit(key as usize, false);
|
||||||
|
} else {
|
||||||
|
self.axis_keyinput.set_bit(keys.0 as usize, true);
|
||||||
|
self.axis_keyinput.set_bit(keys.1 as usize, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scancode_to_keypad(scancode: Scancode) -> Option<gba_keypad::Keys> {
|
fn scancode_to_keypad(scancode: Scancode) -> Option<gba_keypad::Keys> {
|
||||||
|
@ -78,5 +105,6 @@ fn controller_button_to_keypad(button: Button) -> Option<gba_keypad::Keys> {
|
||||||
pub fn create_input() -> Sdl2Input {
|
pub fn create_input() -> Sdl2Input {
|
||||||
Sdl2Input {
|
Sdl2Input {
|
||||||
keyinput: gba_keypad::KEYINPUT_ALL_RELEASED,
|
keyinput: gba_keypad::KEYINPUT_ALL_RELEASED,
|
||||||
|
axis_keyinput: gba_keypad::KEYINPUT_ALL_RELEASED,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
canvas.set_logical_size(CANVAS_WIDTH, CANVAS_HEIGHT)?;
|
canvas.set_logical_size(CANVAS_WIDTH, CANVAS_HEIGHT)?;
|
||||||
|
|
||||||
let controller_subsystem = sdl_context.game_controller()?;
|
let controller_subsystem = sdl_context.game_controller()?;
|
||||||
let controller_mappings = include_str!("../../../external/SDL_GameControllerDB/gamecontrollerdb.txt");
|
let controller_mappings =
|
||||||
|
include_str!("../../../external/SDL_GameControllerDB/gamecontrollerdb.txt");
|
||||||
controller_subsystem.load_mappings_from_read(&mut Cursor::new(controller_mappings))?;
|
controller_subsystem.load_mappings_from_read(&mut Cursor::new(controller_mappings))?;
|
||||||
|
|
||||||
let available_controllers = (0..controller_subsystem.num_joysticks()?)
|
let available_controllers = (0..controller_subsystem.num_joysticks()?)
|
||||||
|
@ -205,11 +206,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let controller = controller_subsystem.open(id)?;
|
let controller = controller_subsystem.open(id)?;
|
||||||
info!("Found game controller: {}", controller.name());
|
info!("Found game controller: {}", controller.name());
|
||||||
Some(controller)
|
Some(controller)
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
info!("No game controllers were found");
|
info!("No game controllers were found");
|
||||||
None
|
None
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut rom_path = match matches.value_of("game_rom") {
|
let mut rom_path = match matches.value_of("game_rom") {
|
||||||
|
@ -320,10 +321,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
},
|
},
|
||||||
Event::ControllerButtonDown { button, .. } => {
|
Event::ControllerButtonDown { button, .. } => {
|
||||||
input.borrow_mut().on_controller_button_down(button);
|
input.borrow_mut().on_controller_button_down(button);
|
||||||
},
|
}
|
||||||
Event::ControllerButtonUp { button, .. } => {
|
Event::ControllerButtonUp { button, .. } => {
|
||||||
input.borrow_mut().on_controller_button_up(button);
|
input.borrow_mut().on_controller_button_up(button);
|
||||||
},
|
}
|
||||||
|
Event::ControllerAxisMotion { axis, value, .. } => {
|
||||||
|
input.borrow_mut().on_axis_motion(axis, value);
|
||||||
|
}
|
||||||
Event::Quit { .. } => break 'running,
|
Event::Quit { .. } => break 'running,
|
||||||
Event::DropFile { filename, .. } => {
|
Event::DropFile { filename, .. } => {
|
||||||
// load the new rom
|
// load the new rom
|
||||||
|
|
Reference in a new issue