pub mod filter;
pub mod state;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::time::SystemTime;
use constants::*;
use platform;
use utils;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct Code(pub(crate) platform::EvCode);
impl Display for Code {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
self.0.fmt(f)
}
}
impl Code {
pub fn into_u32(&self) -> u32 {
self.0.into_u32()
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Event {
pub id: usize,
pub event: EventType,
pub time: SystemTime,
}
impl Event {
pub fn new(id: usize, event: EventType) -> Self {
Event {
id,
event,
time: SystemTime::now(),
}
}
pub fn drop(mut self) -> Event {
self.event = EventType::Dropped;
self
}
pub fn dropped() -> Event {
Event {
id: ::std::usize::MAX,
event: EventType::Dropped,
time: SystemTime::now(),
}
}
pub fn is_dropped(&self) -> bool {
self.event == EventType::Dropped
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum EventType {
ButtonPressed(Button, Code),
ButtonRepeated(Button, Code),
ButtonReleased(Button, Code),
ButtonChanged(Button, f32, Code),
AxisChanged(Axis, f32, Code),
Connected,
Disconnected,
Dropped,
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub(crate) struct RawEvent {
pub id: usize,
pub event: RawEventType,
pub time: SystemTime,
}
impl RawEvent {
pub fn new(id: usize, event: RawEventType) -> Self {
RawEvent {
id,
event,
time: SystemTime::now(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) enum RawEventType {
ButtonPressed(platform::EvCode),
ButtonReleased(platform::EvCode),
AxisValueChanged(i32, platform::EvCode),
Connected,
Disconnected,
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Button {
South = BTN_SOUTH,
East = BTN_EAST,
North = BTN_NORTH,
West = BTN_WEST,
C = BTN_C,
Z = BTN_Z,
LeftTrigger = BTN_LT,
LeftTrigger2 = BTN_LT2,
RightTrigger = BTN_RT,
RightTrigger2 = BTN_RT2,
Select = BTN_SELECT,
Start = BTN_START,
Mode = BTN_MODE,
LeftThumb = BTN_LTHUMB,
RightThumb = BTN_RTHUMB,
DPadUp = BTN_DPAD_UP,
DPadDown = BTN_DPAD_DOWN,
DPadLeft = BTN_DPAD_LEFT,
DPadRight = BTN_DPAD_RIGHT,
Unknown = BTN_UNKNOWN,
}
impl Button {
pub fn is_action(self) -> bool {
use Button::*;
match self {
South | East | North | West | C | Z => true,
_ => false,
}
}
pub fn is_trigger(self) -> bool {
use Button::*;
match self {
LeftTrigger | LeftTrigger2 | RightTrigger | RightTrigger2 => true,
_ => false,
}
}
pub fn is_menu(self) -> bool {
use Button::*;
match self {
Select | Start | Mode => true,
_ => false,
}
}
pub fn is_stick(self) -> bool {
use Button::*;
match self {
LeftThumb | RightThumb => true,
_ => false,
}
}
pub fn is_dpad(self) -> bool {
use Button::*;
match self {
DPadUp | DPadDown | DPadLeft | DPadRight => true,
_ => false,
}
}
pub fn to_nec(self) -> Option<Code> {
use platform::native_ev_codes as necs;
match self {
Button::South => Some(necs::BTN_SOUTH),
Button::East => Some(necs::BTN_EAST),
Button::North => Some(necs::BTN_NORTH),
Button::West => Some(necs::BTN_WEST),
Button::C => Some(necs::BTN_C),
Button::Z => Some(necs::BTN_Z),
Button::LeftTrigger => Some(necs::BTN_LT),
Button::LeftTrigger2 => Some(necs::BTN_LT2),
Button::RightTrigger => Some(necs::BTN_RT),
Button::RightTrigger2 => Some(necs::BTN_RT2),
Button::Select => Some(necs::BTN_SELECT),
Button::Start => Some(necs::BTN_START),
Button::Mode => Some(necs::BTN_MODE),
Button::LeftThumb => Some(necs::BTN_LTHUMB),
Button::RightThumb => Some(necs::BTN_RTHUMB),
Button::DPadUp => Some(necs::BTN_DPAD_UP),
Button::DPadDown => Some(necs::BTN_DPAD_DOWN),
Button::DPadLeft => Some(necs::BTN_DPAD_LEFT),
Button::DPadRight => Some(necs::BTN_DPAD_RIGHT),
_ => None,
}.map(|nec| Code(nec))
}
}
impl Default for Button {
fn default() -> Self {
Button::Unknown
}
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Axis {
LeftStickX = AXIS_LSTICKX,
LeftStickY = AXIS_LSTICKY,
LeftZ = AXIS_LEFTZ,
RightStickX = AXIS_RSTICKX,
RightStickY = AXIS_RSTICKY,
RightZ = AXIS_RIGHTZ,
DPadX = AXIS_DPADX,
DPadY = AXIS_DPADY,
Unknown = AXIS_UNKNOWN,
}
impl Axis {
pub fn is_stick(self) -> bool {
use Axis::*;
match self {
LeftStickX | LeftStickY | RightStickX | RightStickY => true,
_ => false,
}
}
pub fn second_axis(self) -> Option<Self> {
use Axis::*;
match self {
LeftStickX => Some(LeftStickY),
LeftStickY => Some(LeftStickX),
RightStickY => Some(RightStickX),
RightStickX => Some(RightStickY),
_ => None,
}
}
}
#[derive(Copy, Clone, Debug)]
pub(crate) struct AxisInfo {
pub min: i32,
pub max: i32,
pub deadzone: u32,
}
impl AxisInfo {
pub fn deadzone(&self) -> f32 {
let range = self.max as f32 - self.min as f32;
if range == 0.0 {
0.0
} else {
self.deadzone as f32 / range * 2.0
}
}
pub(crate) fn axis_value(&self, val: i32, axis: Axis) -> f32 {
let range = (self.max - self.min) as f32;
let mut val = (val - self.min) as f32;
val = val / range * 2.0 - 1.0;
if platform::IS_Y_AXIS_REVERSED
&& (axis == Axis::LeftStickY || axis == Axis::RightStickY || axis == Axis::DPadY)
&& val != 0.0
{
val = -val;
}
utils::clamp(val, -1.0, 1.0)
}
pub(crate) fn btn_value(&self, val: i32) -> f32 {
let range = (self.max - self.min) as f32;
let mut val = (val - self.min) as f32;
val = val / range;
utils::clamp(val, 0.0, 1.0)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum AxisOrBtn {
Axis(Axis),
Btn(Button),
}