extern crate num_traits;
extern crate uuid;
use self::num_traits::{Signed, Num, ToPrimitive};
use self::uuid::Uuid as Guid;
use std;
use std::time::Instant;
use Semver;
use Knowledge;
use Timeout;
use BatteryState;
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[allow(missing_docs)]
pub struct Vec3<T> {
pub x: T,
pub y: T,
pub z: T,
}
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[allow(missing_docs)]
pub struct Vec2<T> {
pub x: T,
pub y: T,
}
#[allow(missing_docs)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Minmax<T> {
pub min: T,
pub max: T,
}
pub trait SignedAxis: Signed {
fn normalized_axis_bounds() -> Minmax<Self>;
}
impl SignedAxis for f32 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: -1_f32,
max: 1_f32,
}
}
}
impl SignedAxis for i8 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: std::i8::MIN,
max: std::i8::MAX,
}
}
}
impl SignedAxis for i16 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: std::i16::MIN,
max: std::i16::MAX,
}
}
}
impl SignedAxis for i32 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: std::i32::MIN,
max: std::i32::MAX,
}
}
}
pub trait UnsignedAxis: Num {
fn normalized_axis_bounds() -> Minmax<Self>;
}
impl UnsignedAxis for f32 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: 0_f32,
max: 1_f32,
}
}
}
impl UnsignedAxis for u8 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: 0,
max: std::u8::MAX,
}
}
}
impl UnsignedAxis for u16 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: 0,
max: std::u16::MAX,
}
}
}
impl UnsignedAxis for u32 {
fn normalized_axis_bounds() -> Minmax<Self> {
Minmax {
min: 0,
max: std::u32::MAX,
}
}
}
#[allow(missing_docs)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Dpad {
pub up: bool,
pub down: bool,
pub left: bool,
pub right: bool,
}
impl Dpad {
pub fn to_axes<T: SignedAxis>(&self) -> Vec2<T> {
let Minmax { min, max } = T::normalized_axis_bounds();
let x = if self.down { min } else if self.up { max } else { T::zero() };
let Minmax { min, max } = T::normalized_axis_bounds();
let y = if self.left { min } else if self.right { max } else { T::zero() };
Vec2 { x, y }
}
}
pub const MAX_JOYSTICK_HATS: usize = 4;
pub const MAX_JOYSTICK_BASE_BUTTONS: usize = 6;
pub const MAX_NUMBERED_BUTTONS: usize = 16;
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct AxisInfo<T> {
pub dead_zone: Knowledge<Minmax<T>>,
pub resolution: Knowledge<T>,
pub fuzz: Knowledge<T>,
pub actual_value_type_bits: Knowledge<u8>,
pub is_actual_integer: Knowledge<bool>,
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GenericIAxis<T: SignedAxis>(pub T);
pub type IAxis = GenericIAxis<i32>;
impl<T: SignedAxis + ToPrimitive> GenericIAxis<T> {
pub fn to_normalized_f32(&self) -> f32 {
let Minmax { min, max } = T::normalized_axis_bounds();
self.0.to_f32().unwrap() / if self.0.is_positive() { max } else { min }.to_f32().unwrap()
}
pub fn to_normalized_signed_axis<S: SignedAxis>(&self) -> T {
unimplemented!()
}
pub fn to_normalized_unsigned_axis<U: UnsignedAxis>(&self) -> T {
unimplemented!()
}
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GenericUAxis<T>(pub T);
pub type UAxis = GenericUAxis<u32>;
impl UAxis {
pub fn to_normalized_f32(&self) -> f32 { unimplemented!() }
pub fn to_normalized_signed_axis<T: SignedAxis>(&self) -> T {
unimplemented!()
}
pub fn to_normalized_unsigned_axis<T: UnsignedAxis>(&self) -> T {
unimplemented!()
}
}
macro_rules! state {
(st btn) => { bool };
(st numbered_btns) => { [bool; MAX_NUMBERED_BUTTONS] };
(st uaxis) => { UAxis };
(st iaxis) => { IAxis };
(st iaxis3) => { Vec3<IAxis> };
(st hats) => { [Vec2<UAxis>; MAX_JOYSTICK_HATS] };
(st Dpad) => { Dpad };
(cap btn) => { Knowledge<Option<()>> };
(cap numbered_btns) => { [Knowledge<Option<()>>; MAX_NUMBERED_BUTTONS] };
(cap uaxis) => { Knowledge<Option<AxisInfo<UAxis>>> };
(cap iaxis) => { Knowledge<Option<AxisInfo<IAxis>>> };
(cap iaxis3) => { Knowledge<Vec3<Option<AxisInfo<IAxis>>>> };
(cap hats) => { [ Knowledge<Option<AxisInfo<IAxis>>>; MAX_JOYSTICK_HATS] };
(cap Dpad) => { Knowledge<Option<()>> };
($($(#[$attr:meta])* => $name:ident: $ty:ident),+) => {
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct State {
$(
$(#[$attr])*
pub $name: state!(st $ty),
)+
}
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Capabilities {
$(
$(#[$attr])*
pub $name: state!(cap $ty),
)+
}
};
}
state!{
=> numbered_button: numbered_btns,
#[allow(missing_docs)]
=> a: btn,
#[allow(missing_docs)]
=> b: btn,
#[allow(missing_docs)]
=> c: btn,
#[allow(missing_docs)]
=> x: btn,
#[allow(missing_docs)]
=> y: btn,
#[allow(missing_docs)]
=> z: btn,
#[allow(missing_docs)]
=> l_shoulder: btn,
#[allow(missing_docs)]
=> r_shoulder: btn,
#[allow(missing_docs)]
=> l_shoulder_2: btn, #[allow(missing_docs)]
=> r_shoulder_2: btn, #[allow(missing_docs)]
=> l_trigger: uaxis, #[allow(missing_docs)]
=> r_trigger: uaxis, #[allow(missing_docs)]
=> select: btn,
#[allow(missing_docs)]
=> mode: btn,
#[allow(missing_docs)]
=> start: btn,
#[allow(missing_docs)]
=> l_thumb: btn,
#[allow(missing_docs)]
=> r_thumb: btn,
#[allow(missing_docs)]
=> dpad: Dpad,
=> l_stick: iaxis3,
=> r_stick: iaxis3,
#[allow(missing_docs)]
=> throttle: uaxis,
#[allow(missing_docs)]
=> rudder: iaxis,
#[allow(missing_docs)]
=> wheel: iaxis,
#[allow(missing_docs)]
=> hwheel: iaxis,
#[allow(missing_docs)]
=> gas: uaxis,
#[allow(missing_docs)]
=> brake: uaxis,
=> joystick_hats: hats,
#[allow(missing_docs)]
=> joystick_trigger: btn,
#[allow(missing_docs)]
=> joystick_thumb1: btn,
#[allow(missing_docs)]
=> joystick_thumb2: btn,
#[allow(missing_docs)]
=> joystick_top1: btn,
#[allow(missing_docs)]
=> joystick_top2: btn,
#[allow(missing_docs)]
=> joystick_pinkie: btn,
#[allow(missing_docs)]
=> joystick_dead: btn
}
macro_rules! buttons {
($($(#[$attr:meta])* => $name:ident),+) => {
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ButtonPressed {
$($(#[$attr])* $name { is_repeat: bool },)+
#[allow(missing_docs)]
JoystickBase { index: u8, is_repeat: bool },
#[allow(missing_docs)]
NumberedButton { index: u8, is_repeat: bool },
}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ButtonReleased {
$($(#[$attr])* $name,)+
#[allow(missing_docs)]
JoystickBase { index: u8 },
#[allow(missing_docs)]
NumberedButton { index: u8 },
}
}
}
buttons!{
=> A,
=> B,
=> C,
=> X,
=> Y,
=> Z,
=> LShoulder,
=> RShoulder,
=> LShoulder2,
=> RShoulder2,
=> Back,
=> Menu,
=> Start,
=> LThumb,
=> RThumb,
#[allow(missing_docs)]
=> DpadUp,
#[allow(missing_docs)]
=> DpadDown,
#[allow(missing_docs)]
=> DpadLeft,
#[allow(missing_docs)]
=> DpadRight,
#[allow(missing_docs)]
=> JoystickTrigger,
#[allow(missing_docs)]
=> JoystickThumb1,
#[allow(missing_docs)]
=> JoystickThumb2,
#[allow(missing_docs)]
=> JoystickTop1,
#[allow(missing_docs)]
=> JoystickTop2,
#[allow(missing_docs)]
=> JoystickPinkie,
=> JoystickDead
}
#[allow(missing_docs)]
pub type Button = ButtonReleased;
macro_rules! rel_axis {
($($(#[$attr:meta])* => $name:ident),+) => {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum RelativeAxisMotion {
$($(#[$attr])* $name(IAxis),)+
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum RelativeAxis {
$($(#[$attr])* $name,)+
}
}
}
rel_axis!(
=> X,
=> Y,
=> Z,
=> RX,
=> RY,
=> RZ,
=> HWheel,
=> Wheel,
=> Dial
);
macro_rules! abs_axis {
($($(#[$attr:meta])* => $name:ident),+) => {
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum AbsoluteAxisMotion {
$($(#[$attr])* $name(IAxis),)+
HatX {
index: u8,
#[allow(missing_docs)]
value: IAxis
},
HatY {
index: u8,
#[allow(missing_docs)]
value: IAxis
},
}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum AbsoluteAxis {
$($(#[$attr])* $name,)+
HatX {
index: u8,
},
HatY {
index: u8,
},
}
}
}
abs_axis!(
=> X,
=> Y,
=> Z,
=> RX,
=> RY,
=> RZ,
=> LTrigger,
=> RTrigger,
=> Throttle,
=> Rudder,
=> Wheel,
=> Gas,
=> Brake
);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum Error {
Disconnected,
SysError(i32),
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum JoystickModel {
Generic,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum SteeringWheelModel {
Generic,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum GamepadModel {
Generic,
Xbox360,
Dualshock,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum Model {
Joystick(JoystickModel),
Gamepad(GamepadModel),
SteeringWheel(SteeringWheelModel),
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum Bus {
Pci,
Usb,
Hil,
Bluetooth,
Virtual,
}
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
pub struct Info<'dev> {
pub max_simultaneous_haptic_effects: Knowledge<u8>,
pub capabilities: Capabilities,
pub model: Knowledge<Model>,
pub guid: Knowledge<Guid>,
pub name: Knowledge<&'dev str>,
pub product_name: Knowledge<&'dev str>, pub product_id: Knowledge<u32>, pub vendor_name: Knowledge<&'dev str>,
pub vendor_id: Knowledge<u32>,
pub driver_version: Knowledge<Semver>,
pub serial: Knowledge<&'dev str>,
pub plug_time: Knowledge<Instant>,
pub bus: Knowledge<Bus>,
}
#[derive(Debug, Eq, PartialEq)]
pub struct GameInputDevice<'dev> {
info: Info<'dev>,
pub mappings: Vec<mapping::Mapping>,
}
impl<'dev> GameInputDevice<'dev> {
pub fn is_connected() -> bool {
unimplemented!()
}
pub fn query_state(&self) -> Result<State, Error> {
unimplemented!()
}
pub fn query_battery(&self) -> BatteryState {
unimplemented!()
}
pub fn info(&self) -> &Info<'dev> {
&self.info
}
pub fn upload_haptic_effect<E: haptic::Effect>(&mut self, _effect: E)
-> Result<haptic::UploadedEffect, haptic::Error>
{
unimplemented!()
}
pub fn rumble(&mut self, _rumble: &haptic::RumbleEffect) -> Result<(), haptic::Error> {
unimplemented!()
}
pub fn stop_rumble(&mut self) -> Result<(), haptic::Error> {
unimplemented!()
}
pub fn poll_iter<'a>(&'a mut self) -> PollIter<'dev, 'a> {
PollIter { _dev: self }
}
pub fn wait_iter<'a, T: Into<Timeout>>(&'a mut self, timeout: T) -> WaitIter<'dev, 'a> {
WaitIter { _dev: self, _timeout: timeout.into() }
}
}
impl<'dev> Drop for GameInputDevice<'dev> {
fn drop(&mut self) {
unimplemented!()
}
}
#[derive(Debug)]
pub struct PollIter<'a, 'dev:'a> {
_dev: &'a mut GameInputDevice<'dev>,
}
#[derive(Debug)]
pub struct WaitIter<'a, 'dev:'a> {
_dev: &'a mut GameInputDevice<'dev>,
_timeout: Timeout,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Event {
Disconnected,
ButtonPressed(ButtonPressed),
ButtonReleased(ButtonReleased),
AbsoluteAxisMotion(AbsoluteAxisMotion),
RelativeAxisMotion(RelativeAxisMotion),
}
impl<'a,'dev:'a> Iterator for PollIter<'dev, 'a> {
type Item = Event;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
impl<'a,'dev:'a> Iterator for WaitIter<'dev, 'a> {
type Item = Event;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
pub mod monitor {
use super::*;
#[derive(Debug)]
pub struct PollIter<'a> {
_monitor: &'a mut Monitor,
}
#[derive(Debug)]
pub struct WaitIter<'a> {
_monitor: &'a mut Monitor,
_timeout: Timeout,
}
impl<'a> Iterator for PollIter<'a> {
type Item = GameInputDevice<'a>;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
impl<'a> Iterator for WaitIter<'a> {
type Item = GameInputDevice<'a>;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
#[derive(Debug)]
pub struct Monitor;
impl Monitor {
pub fn create<'dev>() -> (Self, Vec<GameInputDevice<'dev>>) {
unimplemented!()
}
pub fn poll_iter<'a>(&'a mut self) -> PollIter<'a> {
PollIter { _monitor: self }
}
pub fn wait_iter<'a, T: Into<Timeout>>(&'a mut self, timeout: T) -> WaitIter<'a> {
WaitIter { _monitor: self, _timeout: timeout.into() }
}
}
}
pub use self::monitor::Monitor;
pub mod mapping {
use super::Event;
use ::std::collections::HashMap;
use ::std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Mapping(HashMap<Event, Event>);
impl FromStr for Mapping {
type Err = ();
fn from_str(_s: &str) -> Result<Self, Self::Err> {
unimplemented!()
}
}
impl Mapping {
pub fn from_sdl2_mapping_str(_s: &str) -> Result<Self,()> {
unimplemented!()
}
}
impl From<HashMap<Event,Event>> for Mapping {
fn from(map: HashMap<Event, Event>) -> Self {
Mapping(map)
}
}
}
pub use self::mapping::Mapping;
pub mod haptic {
use super::*;
use ::std::time::Duration;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum Error {
DeviceNotConnected,
EffectNotSupported,
SysError(i32),
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct UploadedEffect<'a,'dev:'a> {
_dev: &'a GameInputDevice<'dev>,
_code: i32,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct PlayingEffect<'a,'b:'a,'dev:'b> {
_fx: &'a UploadedEffect<'b, 'dev>,
}
impl<'a,'dev:'a> UploadedEffect<'a, 'dev> {
pub fn play(&self) -> Result<PlayingEffect,()> {
unimplemented!()
}
}
impl<'a,'b:'a,'dev:'a> PlayingEffect<'a, 'b, 'dev> {
pub fn stop(&self) -> Result<(),()> {
unimplemented!()
}
pub fn is_playing(&self) -> Knowledge<bool> {
unimplemented!()
}
}
impl<'a,'dev:'a> Drop for UploadedEffect<'a, 'dev> {
fn drop(&mut self) {
unimplemented!()
}
}
pub trait Effect {}
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct RumbleEffect {
#[allow(missing_docs)]
pub duration: Duration,
#[allow(missing_docs)]
pub delay_before_start: Duration,
pub magnitude_for_weak_motor: u16,
pub magnitude_for_strong_motor: u16,
}
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Envelope {
#[allow(missing_docs)]
pub attack_duration: Duration,
pub attack_level: u16,
#[allow(missing_docs)]
pub fade_duration: Duration,
pub fade_level: u16,
}
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct ConstantEffect {
#[allow(missing_docs)]
pub duration: Duration,
#[allow(missing_docs)]
pub delay_before_start: Duration,
pub level: i16,
#[allow(missing_docs)]
pub envelope: Envelope,
}
impl Effect for ConstantEffect {}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Waveform {
Square,
Triangle,
Sine,
SawUp,
SawDown,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub struct PeriodicEffect {
#[allow(missing_docs)]
pub duration: Duration,
#[allow(missing_docs)]
pub delay_before_start: Duration,
#[allow(missing_docs)]
pub waveform: Waveform,
#[allow(missing_docs)]
pub period: Duration,
pub magnitude: i16,
pub offset: i16,
pub phase: u16,
#[allow(missing_docs)]
pub envelope: Envelope,
}
impl Effect for PeriodicEffect {}
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct RampEffect {
#[allow(missing_docs)]
pub duration: Duration,
#[allow(missing_docs)]
pub delay_before_start: Duration,
#[allow(missing_docs)]
pub start_level: i16,
#[allow(missing_docs)]
pub end_level: i16,
#[allow(missing_docs)]
pub envelope: Envelope,
}
impl Effect for RampEffect {}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct ConditionEffect {
#[allow(missing_docs)]
pub duration: Duration,
#[allow(missing_docs)]
pub delay_before_start: Duration,
pub button: Button,
pub saturation: (u16, u16),
pub coeff: (i16, i16),
pub deadzone_diameter: u16,
pub deadzone_center: i16,
}
impl Effect for ConditionEffect {}
}
pub use self::haptic::{
UploadedEffect,
PlayingEffect,
Effect,
RumbleEffect,
Envelope,
ConstantEffect,
Waveform,
PeriodicEffect,
RampEffect,
ConditionEffect,
};