【Pyxel】GAMEPAD1入力チェッカー

ゲームパッドのアナログ入力ってどうするのかなと思って調べていました。

手元のXboxコントローラー他では、仕様書に書かれている入力コマンドのbtn, btnp, btnrではキー定義一覧の「GAMEPAD1_AXIS_xxx」は認識されませんでした。

はたしてどうやったら認識できるのか。
Pyxelのソースを覗いてみると、

```
fn controller_axis_to_key(axis: i32) -> Key {
    match axis {
        SDL_CONTROLLER_AXIS_LEFTX => GAMEPAD1_AXIS_LEFTX,
        SDL_CONTROLLER_AXIS_LEFTY => GAMEPAD1_AXIS_LEFTY,
        SDL_CONTROLLER_AXIS_RIGHTX => GAMEPAD1_AXIS_RIGHTX,
        SDL_CONTROLLER_AXIS_RIGHTY => GAMEPAD1_AXIS_RIGHTY,
        SDL_CONTROLLER_AXIS_TRIGGERLEFT => GAMEPAD1_AXIS_TRIGGERLEFT,
        SDL_CONTROLLER_AXIS_TRIGGERRIGHT => GAMEPAD1_AXIS_TRIGGERRIGHT,
        _ => KEY_UNKNOWN,
    }
}
```

「SDL_CONTROLLER_AXIS」って何だろう？

検索してみると、[Wiki](https://wiki.libsdl.org/SDL2/SDL_GameControllerAxis)を見つけました。
値は0～8000の値がどうとか？

なんだかよくわからないなと、PyxelのIssuesを見たら同様の書き込みを見つけました。
[About the constant value of gamepad-related #577](https://github.com/kitao/pyxel/issues/577)
何でも、btnvという入力コマンドで拾えるらしい。

※btnvコマンドはそのうちドキュメントに記載されるようです。

そんなわけでGAMEPAD1の入力チェッカーを作ってみました。
アナログ入力の取りうる値は32bit数値で、-32768～+32767（0x8000～0xffff,0～0x7fff)でした。

入力チェッカーでは値0でオフとしてみたけど、下記SSの通り実際に使用するにはある程度の遊びが必要になります。

＜アナログ入力オン→オフの状態のSS＞
![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927925/5e51d7f7-a291-fc6f-a349-c87668f22200.png)

```
import pyxel

SCREEN_WIDTH = 256
SCREEN_HEIGHT = 256
#-----------------------------------------------------------------
#更新
#-----------------------------------------------------------------
def update():
	pass
#-----------------------------------------------------------------
#描画
#※GAMEPAD1_AXIS_xxxはbtnvを使用する
#参考：https://github.com/kitao/pyxel/issues/577
#-----------------------------------------------------------------
def draw():
	#画面クリア
	pyxel.cls(0)

	pyxel.text( (SCREEN_WIDTH/2) - (10*8/2), 10, 'GAMEPAD1 INPUT TEST', 7 )
	_height_pos = 30
	_height_pos_offset = 10
	_col = 7

	_str = 'GAMEPAD1_AXIS_LEFTX'
	_data_lx = pyxel.btnv( pyxel.GAMEPAD1_AXIS_LEFTX )
	if _data_lx != 0:
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str + " " + str(_data_lx), _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_AXIS_LEFTY'
	_data_ly = pyxel.btnv( pyxel.GAMEPAD1_AXIS_LEFTY )
	if _data_ly != 0:
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str + " " + str(_data_ly), _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_AXIS_RIGHTX'
	_data_rx = pyxel.btnv( pyxel.GAMEPAD1_AXIS_RIGHTX )
	if _data_rx != 0:
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str + " " + str(_data_rx), _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_AXIS_RIGHTY'
	_data_ry = pyxel.btnv( pyxel.GAMEPAD1_AXIS_RIGHTY )
	if _data_ry != 0:
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str + " " + str(_data_ry), _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_AXIS_TRIGGERLEFT'
	if pyxel.btnv( pyxel.GAMEPAD1_AXIS_TRIGGERLEFT ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_AXIS_TRIGGERRIGHT'
	if pyxel.btnv( pyxel.GAMEPAD1_AXIS_TRIGGERRIGHT ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_LEFTSTICK'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_LEFTSTICK ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_RIGHTSTICK'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_RIGHTSTICK ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_A'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_A ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_B'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_B ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_X'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_X ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_Y'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_Y ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_BACK'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_BACK ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_GUIDE'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_GUIDE ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_START'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_START ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_LEFTSHOULDER'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_LEFTSHOULDER ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_RIGHTSHOULDER'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_RIGHTSHOULDER ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_DPAD_UP'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_DPAD_UP ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_DPAD_DOWN'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_DPAD_DOWN ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_DPAD_LEFT'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_DPAD_LEFT ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset

	_str = 'GAMEPAD1_BUTTON_DPAD_RIGHT'
	if pyxel.btn( pyxel.GAMEPAD1_BUTTON_DPAD_RIGHT ):
		_col = 10
	else:
		_col = 7
	pyxel.text( (SCREEN_WIDTH/2) - (len(_str)*8/2), _height_pos, _str, _col )
	_height_pos += _height_pos_offset
#-----------------------------------------------------------------
#INIT&RUN
#-----------------------------------------------------------------
pyxel.init(SCREEN_WIDTH, SCREEN_HEIGHT)
pyxel.run(update, draw)
```
Xboxコントローラーのボタン全てが取得できるようになりました。