import { StorageUtil } from '../util/storage_util' ; const enum Type { AXIS , BUTTON } const kKeyTable = [ 'A' , 'B' , 'SELECT' , 'START' , 'U' , 'D' , 'L' , 'R' ] ; export class GamepadManager { public static AXIS_THRESHOLD = 0.5 ; private static initialized = false ; private static padSettings : { type : Type ; index : number ; direction ? : number ; } [ ] = [ { type : Type . BUTTON , index : 0 } , { type : Type . BUTTON , index : 1 } , { type : Type . BUTTON , index : 4 } , { type : Type . BUTTON , index : 5 } , { type : Type . AXIS , index : 1 , direction : - 1 } , { type : Type . AXIS , index : 1 , direction : 1 } , { type : Type . AXIS , index : 0 , direction : - 1 } , { type : Type . AXIS , index : 0 , direction : 1 } , { type : Type . BUTTON , index : 2 } , { type : Type . BUTTON , index : 3 } , ] ; public static setUp ( ) { if ( GamepadManager . initialized ) return ; GamepadManager . loadSetting ( ) ; GamepadManager . initialized = true ; } public static isSupported ( ) { return 'Gamepad' in window ; } public static getState ( padNo ) { if ( ! GamepadManager . isSupported ( ) ) return 0 ; const gamepads = navigator . getGamepads ( ) ; if ( padNo >= gamepads . length ) return 0 ; const gamepad = gamepads [ padNo ] ; if ( ! gamepad ) return 0 ; const THRESHOLD = GamepadManager . AXIS_THRESHOLD ; let pad = 0 ; GamepadManager . padSettings . forEach ( ( s , i ) => { switch ( s . type ) { case Type . AXIS : { const axis = gamepad . axes [ s . index ] || 0 ; if ( axis * s . direction ! >= THRESHOLD ) pad |= 1 << i ; } break ; case Type . BUTTON : { const button = gamepad . buttons [ s . index ] ; if ( button && button . pressed ) pad |= 1 << i ; } break ; } } ) ; return pad ; } public static setButton ( padbit , buttonIndex ) { GamepadManager . padSettings [ padbit ] . type = Type . BUTTON ; GamepadManager . padSettings [ padbit ] . index = buttonIndex ; GamepadManager . padSettings [ padbit ] . direction = 1 ; GamepadManager . saveSetting ( ) ; } public static setAxis ( padbit , axisIndex , direction ) { GamepadManager . padSettings [ padbit ] . type = Type . AXIS ; GamepadManager . padSettings [ padbit ] . index = axisIndex ; GamepadManager . padSettings [ padbit ] . direction = direction ; GamepadManager . saveSetting ( ) ; } private static saveSetting ( ) { const data = { } ; GamepadManager . padSettings . forEach ( ( s , i ) => { const key = kKeyTable [ i ] ; switch ( s . type ) { default : break ; case Type . BUTTON : data [ key ] = { button : s . index , } ; break ; case Type . AXIS : data [ key ] = { axis : s . index , direction : s . direction , } ; break ; } } ) ; StorageUtil . putObject ( 'pad0' , data ) ; } private static loadSetting ( ) { const data = StorageUtil . getObject ( 'pad0' , { } ) ; if ( typeof data === 'object' ) { Object . keys ( data ) . forEach ( key => { const index = kKeyTable . indexOf ( key . toUpperCase ( ) ) ; if ( index < 0 ) return ; const d = data [ key ] ; if ( 'button' in d ) { GamepadManager . setButton ( index , d . button ) ; } else if ( 'axis' in d && 'direction' in d ) { GamepadManager . setAxis ( index , d . axis , parseInt ( d . direction , 10 ) ) ; } } ) ; } } }