ゲームパッドクラスライブラリ for ECMAScript

# GamePadAPI
まず、GamePadAPIとはなんぞやというと、W3Cで勧告されているWebブラウザ上でECMAScriptからゲームパッドにアクセスする機能です。
[GamePadAPI on W3C](https://www.w3.org/TR/gamepad/)

しかし、この機能を使うと、この世の数多あるゲームパッドによって、さらに各Webブラウザによって返ってくる配列の要素に対するボタンの対応が、完全にバラバラになっていて、しかも値の取れ方もてんでバラバラなので、ゲーム毎に各パッド用でWebブラウザによって処理を分けて実装する必要が出てきます。

* 右のA, B, X, Yボタンが配列の0, 1, 2, 3だったり、1、3、2、0だったり、11, 12, 13, 14だったりする
* ゲームパッドのモードによって十字キーの値が取れたり取れなかったりする
* 十字キーの情報がボタン配列に入っていたり、十字キー配列に入っていたり、特定のボタンの値で返ってきたりする

とまぁ、ちょっと挙げただけでも頭が痛くなる有様。
なので、私が作っているゲームライブラリ[enforce](https://github.com/digitarhythm/enforce/)で使おうと思った時に、統一したインターフェースを提供しようとライブラリを作って公開していました（[gamepadprocedure](https://github.com/digitarhythm/gamepadprocedure/))
しかし、このライブラリはFirefoxと、Chrome限定でした。
また私が持っているゲームパッドに限定対応でした（オススメはXbox360ワイヤードコントローラーです）。

ところが、先日、Safari Technology PreviewでGamePadAPIに対応しているというニュースを見ました。
これはもう居ても立ってもいられなくなり、新規にゲームパッドクラスライブラリを作成することにしました（前回はグローバルを汚染していたので、今回はCoffeeScriptでクラス化しました）。
前回は、

* ブラウザとゲームパッドIDの組み合わせで完全一致で振り分けていた（該当しない場合はGamePadAPIで取得したものをそのまま返す）
* ライブラリ関数をグローバルに定義し、結果のオブジェクトもグローバルに定義していた
* Safari未対応

今回は、

* ゲームパッドのベンダーIDとプロダクトIDを取得し、将来的にゲームパッドの追加を容易にした
* CoffeeScriptのクラスを使いカプセル化した
* Safari Technology Preview 16以降に暫定対応

としています。

## サポートしているブラウザ
* Firefox
* Chrome
* Safari 10.2（暫定対応）

## サポートしているコントローラー
* Xbox 360 Wired Controller (STANDARD GAMEPAD Vendor: 045e Product: 028e)  
Xbox360 ワイヤードコントローラー
* JC-U3613M - DirectInput Mode (Vendor: 056e Product: 2003)  
ELECOM ゲーミングコントローラー
* iBUFFALO BSGP1204P Series (Vendor: 1dd8 Product: 0010)  
iBUFFALO ゲーミングコントローラー
* 4Axes 12Key GamePad (Vendor: 0d9d Product: 3013)  
PlayStation2 ゲーミングコントローラー

今のところ、これ以外のコントローラーではバラバラの値を返すと思います。

## ライブラリの使い方（CoffeeScript）
クラスライブラリはここにあります。

[enforceGamepad on github](https://github.com/digitarhythm/enforceGamepad/)

とりあえずWebブラウザからアクセス出来る適当な場所にクローンしてください。
現在接続されているゲームパッドの情報を表示するサンプルになっているので、クローンしたディレクトリにWebブラウザでアクセスしてみてください。
ゲームパッドが接続されていれば値が取れていると思います（Firefoxはゲームパッドを操作しないと接続イベントが発生しません）。
クラスライブラリ自体は、 **enforceGamepad.js** です。
これは、 **enforceGamepad.coffee** をコンパイルしたものです。

自分でコードを書いてクラスライブラリを使用するには以下のようにします。

```CoffeeScript
gamepad = new enforceGamepad()
gamepad.stat()
console.log(gamepad.controllers)
```

クラスインスタンスを生成し、「stat()」メソッドを呼ぶとゲームパッドの情報がインスタンス内の「controllers」という配列に格納されます。

```CoffeeScript
pad = gamepad.controllers[0]
```
上記は、最初に接続されたゲームパッドの情報を取得しています。

```CoffeeScript
buttons = pad.buttons
axes = pad.axes
analog = pad.analog
```

"buttons", "axes", "analog"にゲームパッドのボタン情報、十字キー情報、アナログスティック情報が取得出来ます。
（Xbox360コントローラーでは「LT」と「RT」ボタンの値が0〜1のアナログ値になります）

## 対応表
ボタンの名前はXbox360コントローラーに準拠しています。
  
**Buttons**

|ボタン名         |配列番号            |値                     |
|:---------------|:-----------------|:---------------------:|
|A               |0                 |0 or 1                 |
|B               |1                 |0 or 1                 |
|X               |2                 |0 or 1                 |
|Y               |3                 |0 or 1                 |
|LB              |4                 |0 or 1                 |
|RB              |5                 |0 or 1                 |
|LT              |6                 |0 or 1<br>(Xbox360:0~1)|
|RT              |7                 |0 or 1<br>(Xbox360:0~1)|
|BACK            |8                 |0 or 1                 |
|START           |9                 |0 or 1                 |
|Left stick push |10                |0 or 1                 |
|Right stick push|11                |0 or 1                 |
|HOME            |12                |0 or 1                 |
HOMEボタンのないコントローラーの場合、 "BACK"と "START"を同時に押すとHOMEボタンを押したことになります。

**Axes**  
十字キーは、"axes[0]"に水平座標、"axes[1]"に垂直座標が格納されています。

**Analog stick**  
同様に、アナログスティックは、"analog[0]"に左スティックの値、"analog[1]"に右スティックの値が格納されています。
"analog[n]"には、水平値と垂直値の配列が含まれます。
"analog[n][0]"は水平座標が0〜1の間で、 "analog[n][1]"は垂直座標が0〜1の間で格納されています。