ジョイスティックを使おう

HSP3.6β3 から 追加された mod_joystick2.as の jstick について覚書


はじめに...

ここに書かれている事は mod_joystick2.as に記載されている修正の内容を
書いているだけなので、分かる人はそちらを直接参照された方が良いです。
ソースを読んでも分からない人は、以下を読むと参考になるかも程度のことです。
ぶっちゃけ、中の処理が分からなくても使い方さえ理解できれば良いのです。


簡単に...

■mod_joystick2.as の jstick は、mod_joystick.as の jstick に キーボード入力値(stick)も取得できるようにした命令
利点
   ・手軽にキーボード入力(stick)作品をゲームパッドにも対応させることができる
   ・記述が楽。stick から jstick にするだけ(例えば stick key, 15 から jstick key, 15, 0 のように)
   ・(mod_joystick.as版とは違い)非トリガータイプキーの設定も出来る
難点
    ・単純に stick の機能を付けただけなので、キーボード入力は stick で取得できるキーしか無い
    ・ゲームパッドの右側ボタンのキー変更は出来ない
    ・(自分の環境では)TABキーを非トリガータイプにしても対応しなかった(押し続けても最初の1回しか反応しない)
        ・jstick 内の stick の非トリガータイプ指定を $3ff から $3ffff にすれば解決
    ・アナログモード時のスティックの傾き具合などは取得することができない
上記の難点は mod_joystick2.as を自分で修正、または新たにモジュールを作成することで解決できるが、
「PAD設定さん」を利用することで容易に解決できる ゲームパッドを使用したい人は是非チェックすべし
ヘルプブラウザ用ファイルがありがたい!



各種命令

  1. stick
  2. joystick系
  3. joyGetPosEx
  4. jstick_org
  5. jstic(mod_joystick2.as)


1.stick命令

stickについておさらい まずはHELPに書かれてること
キー入力情報取得
stick p1,p2,p3
p1=変数 : 読み込むための変数
p2=0~(0) : 非トリガータイプキー指定
p3=0~1(1) : ウィンドウアクティブチェックON/OFF
p1 では入力されている以下のキー番号の合計(論理和)が整数で変数に入る

stick のキー番号一覧
キーボード入力 値(10進) 値(16進)
カーソルキー左(←) 1 $00001
カーソルキー上(↑) 2 $00002
カーソルキー右(→) 4 $00004
カーソルキー下(↓) 8 $00008
スペースキー 16 $00010
Enterキー 32 $00020
Ctrlキー 64 $00040
ESCキー 128 $00080
マウスの左ボタン 256 $00100
マウスの右ボタン 512 $00200
TABキー 1024 $00400
[Z]キー 2048 $00800
[X]キー 4096 $01000
[C]キー 8192 $02000
[A]キー 16384 $04000
[W]キー 32768 $08000
[D]キー 65536 $10000
[S]キー 131072 $20000
p2 では押しっぱなしでも入力されるキー番号を整数で指定
例えばカーソルキーだけ押しっぱなしOKの場合
1+2+4+8 とか 1|2|4|8 とか $000f とか、これらは全て10進整数で15を表す
指定する数値は、必ず決まったキーの組み合わせになる(一意)
p3 で0(デフォルトは1)を指定した場合、ウィンドウがアクティブじゃないときも入力を受け付ける
例えば、プログラムを実行した後で他のアプリケーションで入力したキー入力が
実行してるプログラムにも反映されるような状態になる
p1 で取得したキー番号は、例えば以下のように判定する
stick key, 15
if key&$00001 : x--
if key&$00002 : y--
if key&$00004 : x++
if key&$00008 : y++
if key&$00800 : gosub *shot
if key&$01000 : gosub *bomb
&は論理積(ビット演算)、詳しくは 小ワザ/ビット操作 - HSP開発wiki


2.joystick系命令

mod_joystick.as

  • joyGetPosEx
    • Win32API winmm.dll joyGetPosEx
    • 実はゲームパッドがアナログ入力の場合、アナログデータ(スティックの傾きの値)はここで取得される
    • stat にエラー値(0:正常,0以外:エラー)が返ってくる
      • MMSYSERR_NODRIVER 6 ドライバが存在しない
      • MMSYSERR_INVALPARAM 11 無効なパラメータ
      • MMSYSERR_BADDEVICEID 2 指定されたデバイス識別子は範囲外
      • JOYERR_UNPLUGGED 167 指定されたジョイスティックはシステムに接続されてない
      • JOYERR_PARMS 165 指定されたジョイスティックデバイスの識別子 uJoyID は無効
  • jstick
    • ここから joyGetPosEx を呼び出している
    • アナログデータを正規化して、stick のカーソルキー番号と同じ数値になるようにしている
    • ボタン番号1~12 は 16~32768
    • 同じ数値を取得できるだけで、前述のようにキーボード入力には対応していない
    • modjoy_err にエラー値(0:正常,1:エラー)が返ってくる

mod_joystick2.as

  • joyGetPosEx
    • mod_joystick.as版と同じ処理
  • jstick_org
    • mod_joystick.as版の jstick とほぼ同じ処理
    • レジューム(復帰)処理とエラー処理が付いてる
    • org は オリジナル(original)の意か?
  • jstick
    • キーボード入力(stick)を付加した jstick_org
    • キーボード入力とゲームパッド入力を合成
    • トリガーと非トリガーの処理
    • 意味不明な2,3行は上記2つの処理


3.joyGetPosEx命令

joyGetPosEx array data, int ポート番号
stat = 0 であれば入力は正常です。
data.0 = 常に 52  が入ります
data.1 = 常に 255 が入ります
data.2 = 第 1 軸の状態(普通のジョイスティックの X 軸)
data.3 = 第 2 軸の状態(普通のジョイスティックの Y 軸)
data.4 = 第 3 軸の状態(スロットル等)
data.5 = 第 4 軸の状態
data.6 = 第 5 軸の状態
data.7 = 第 6 軸の状態
data.8 = ボタンの状態(最大32ボタン)
data.9 = 同時に押されているボタンの数
data.10 = POV スイッチの状態
data.11 = 予備情報1
data.12 = 予備情報2

mod_joystick2.as にコメントアウトされてるサンプルコードを使用し、
取得した joyGetPosEx の実際の値
(使用機器:ELECOM JC-U3312S)

joyGetPosEx [D]デジタルモード(2軸) / [A]アナログモード(4軸)
ゲームパッド入力 [D]dataの添字 [D]値(10進) [A]dataの添字 [A]値(10進)
(十字キー)← 2 0 10 27000
(十字キー)↑ 3 0 10 0
(十字キー)→ 2 65535 10 9000
(十字キー)↓ 3 65535 10 18000
(左スティック)← 2 0 2 0<=x<32767
(左スティック)↑ 3 0 3 0<=y<32767
(左スティック)→ 2 65535 2 32767<x<=65535
(左スティック)↓ 3 65535 3 32767<y<=65535
(右ボタン)1 8 1 同左 同左
(右ボタン)2 8 2 同左 同左
(右ボタン)3 8 4 同左 同左
(右ボタン)4 8 8 同左 同左
(L1)5 8 16 同左 同左
(R1)6 8 32 同左 同左
(L2)7 8 64 同左 同左
(R2)8 8 128 同左 同左
(SELECT)9 8 256 同左 同左
(START)10 8 512 同左 同左
(左スティック)11 8 1024 同左 同左
(右スティック)12 8 2048 同左 同左
(右スティック)← 8 8 4 0<=x<32767
(右スティック)↑ 8 1 5 0<=y<32767
(右スティック)→ 8 2 4 32767<x<=65535
(右スティック)↓ 8 4 5 32767<y<=65535
※ゲームパッドにより値が異なる


4.jstick_org命令

#deffunc jstick_org var p1, int p2
    ;	jstick 変数,ポート番号
    ;	(stick命令互換の値を変数に返す)
    ;
    if modjoy_err@ : goto *jstick_resume
    ;
    jdata.15=0:jdata=52,255
    _joyGetPosEx p2,jdata
    if stat!=0 : goto *jstick_err
    res=(jdata.8)<<4
    if jdata.2<BORDER_LOW : res|=1
    if jdata.2>BORDER_HIGH : res|=4
    if jdata.3<BORDER_LOW : res|=2
    if jdata.3>BORDER_HIGH : res|=8
    p1=res
    return
*jstick_resume
    _joyGetPosEx p2,jdata
    if stat!=0 : goto *jstick_err
    p1=0
    modjoy_err@=0
    return
*jstick_err
    p1=0
    modjoy_err@=1
    return
data の 2,3,8 しか見てないので、アナログ入力のPOVキー(ここでは十字キーと同義)と右スティックが検出できない。
res=(jdata.8)<<4 でボタン入力系(data.8)を 4つ左シフト(16倍)している
つまり p1 の値は、以下の表になる

jstick_org [D]デジタルモード(2軸) / [A]アナログモード(4軸)
ゲームパッド入力 [D]値(10進) [D]値(16進) [A]値(10進) [A]値(16進)
(十字キー)← 1 $00001 - -
(十字キー)↑ 2 $00002 - -
(十字キー)→ 4 $00004 - -
(十字キー)↓ 8 $00008 - -
(左スティック)← 1 $00001 同左 同左
(左スティック)↑ 2 $00002 同左 同左
(左スティック)→ 4 $00004 同左 同左
(左スティック)↓ 8 $00008 同左 同左
(右ボタン)1 16 $00010 同左 同左
(右ボタン)2 32 $00020 同左 同左
(右ボタン)3 64 $00040 同左 同左
(右ボタン)4 128 $00080 同左 同左
(L1)5 256 $00100 同左 同左
(R1)6 512 $00200 同左 同左
(L2)7 1024 $00400 同左 同左
(R2)8 2048 $00800 同左 同左
(SELECT)9 4096 $01000 同左 同左
(START)10 8192 $02000 同左 同左
(左スティック)押下 16384 $04000 同左 同左
(右スティック)押下 32768 $08000 同左 同左
(右スティック)← 128 $00080 - -
(右スティック)↑ 16 $00010 - -
(右スティック)→ 32 $00020 - -
(右スティック)↓ 64 $00040 - -
※ゲームパッドにより値が異なる


5.jstick(mod_joystick2.as)命令

#deffunc jstick var _p1, int _p2, int _p3
    ;	jstick 変数,ポート番号
    ;	(stick命令互換の値を変数に返す)
    ;
    stick@hsp key_now,$3ff
    jstick_org jkey,_p3
    key_now|=jkey
    trg_key=key_now^last_key&key_now
    last_key=key_now
    _p1 = (last_key & _p2) + ( trg_key & (0xffff ^ _p2) )
    return
stick@hsp key_now,$3ff
        非トリガー指定が $3ff なのでTABキーの値以上が対応されなかった
        この値を $3ffff(stickの全キー合計) などに変更すべき?
key_now|=jkey
        キーボード入力(stick)またはゲームパッド入力(jstick_org)があれば key_now に代入される
trg_key=key_now^last_key&key_now
        前回入力が無かった現在のキーを抽出する(このキーは必ず取得しなければならない)
_p1 = (last_key & _p2) + ( trg_key & (0xffff ^ _p2) )
        (last_key & _p2) は非トリガータイプのキー値
        (trg_key & (0xffff ^ _p2) ) はトリガータイプのキー値
        この2つのキー値を合計する(論理和の方が良い気がするが、この式の場合加算でも同じ処理)
        今回12ボタンのゲームパッドだったので大丈夫だったが、0xffff は少ない気がする
        24ボタンとかには対応できないけど、0xfffff(16ボタン対応) は欲しい
        そうすると、stick側でゲームパッドに対応したキーが無くなるのだが...はてさて

jstick [D]デジタルモード(2軸) / [A]アナログモード(4軸)
値(10進) 値(16進) [D]入力キー [A]入力キー
1 $00001 カーソルキー、十字キー、左スティックの← カーソルキー、左スティックの←
2 $00002 カーソルキー、十字キー、左スティックの↑ カーソルキー、左スティックの↑
4 $00004 カーソルキー、十字キー、左スティックの→ カーソルキー、左スティックの→
8 $00008 カーソルキー、十字キー、左スティックの↓ カーソルキー、左スティックの↓
16 $00010 スペースキー、右ボタン1、右スティック↑ スペースキー、右ボタン1
32 $00020 Enterキー、右ボタン2、右スティック→ Enterキー、右ボタン2
64 $00040 Ctrlキー、右ボタン3、右スティック↓ Ctrlキー、右ボタン3
128 $00080 ESCキー、右ボタン4、右スティック← ESCキー、右ボタン4
256 $00100 マウス左ボタン、L1ボタン 同左
512 $00200 マウス右ボタン、R1ボタン 同左
1024 $00400 TABキー、L2ボタン 同左
2048 $00800 [Z]キー、R2ボタン 同左
4096 $01000 [X]キー、SELECTボタン 同左
8192 $02000 [c]キー、STARTボタン 同左
16384 $04000 [A]キー、左スティック押下 同左
32768 $08000 [W]キー、右スティック押下 同左
65536 $10000 [D]キー、(ボタン13) 同左
131072 $20000 [S]キー、(ボタン14) 同左
※ゲームパッドにより異なる
最終更新:2021年06月07日 22:35
添付ファイル