パット'萃'っち 薮蛇書

4年J科 二次狼

パット'すい 'っち 薮蛇書

使う上ではあまり必要のない、私が書きたいと思ったことを書いていきます。暇な人はどうぞ。

パット'萃'っちを別の表現で説明してみると

説明書の方であれこれ書きましたが、一番しっくり来る表現は

・パット'萃'っち=対戦ゲームに特化した劣化型JoyToKey

だと思います。

JoyToKeyとは、Ryo Ohkubo氏の作成したジョイスティックの入力を、キーボードの入力に変換するソフトです。
(公式サイトに繋がらなかったのでVectorの紹介ページにリンクをはっておきます)
パット'萃'っちがやっていることは、JoyToKeyとほとんど変わりません。
もちろん全く同じソフトを作っても何の意味も無いので、パット'萃'っちにはパット'萃'っちなりのウリが存在します。
それがさっき書いた、『対戦ゲームに特化』という点です。

パット'萃'っちはプレイヤー毎の操作方法を個別に保存することができます。
JoyToKeyはそれができないため、3人が集まって2人用のゲームを1人ずつ交代して遊ぶ…といった状況ではとても困ったことになります。

一方、JoyToKeyはマウスのエミュレーション、複数キーの同時入力、連射機能といったものを実装しています。
パット'萃'っちにはそれがありません。『劣化型』とはそういうことです。

つまり

という条件が全て揃うと、パット'萃'っちの存在意義が発生します。
これがパット'萃'っちの開発コンセプトなので当たり前といえば当たり前なのですが…正直な話、そうちょくちょくありうることではありません。
大会を開くとか、ちょっとしたイベントとか、そういったときに使うことができるソフトです。

開発裏話

どうでもいい裏話のコーナーです。
68部員向け?
07/16
某友人宅にて10名程度が集合し、交代で2人対戦のゲームで遊んでました。
このとき交代ごとにパッドの設定を切り替え煩わしさを感じたことが、このソフトの開発のきっかけです。
07/18
開発開始。
07/19
挫折。
このソフトの一番根元の部分は、「パッドの動作を読み取る→キーボードを擬似的に押す」というところにあります。
パッドのボタンとキーの対応関係とか、その他諸々の設定とか設定の保存とか、その辺の部分は(こう言ってしまうとアレですが) どうでもいいしどうとでもなるところです。
で、この日は「パッドの動作を読み取る」部分で躓きました。

パッドのボタン状態を読み取るには、
の2種類の方法があるのですが、 という状態になり、手が見つからず挫折しました。
DirectXの勉強しろという話なんですが、正直労力の割に合わないだろうと思ったので放置することに。
09/06〜09/09
そのまま2ヶ月弱が過ぎ、68の合宿。
このとき5人程度が部屋に集まり、交代で2人対戦のゲームで遊んでました。
で、07/16と同じ現象が起こりこのソフトのことを思い出しました。完璧に忘れてましたよ。ええ。
09/10
開発再開。とりあえずパッドのボタン状態を読み取れないと話にならないので情報収集…。
WindowsAPIでパッドの情報を得るには、joyGetPosExという関数を使います。

joyGetPosEx

ジョイスティックを照会して、その位置とボタンの状態を取得します。

MMRESULT joyGetPosEx(
  UINT uJoyID,    
  LPJOYINFOEX pji 
);

パラメータ

uJoyID
照会するジョイスティック(JOYSTICKID1 または JOYSTICKID2)の識別子を指定します。
(以下省略。引用元
上で「WindowsAPIはパッドを2つまでしか読み取れない」と書いたのはつまり、
JOYSTICKID1とJOYSTICKID2しか識別子が無いから対応するパッド(1つ目と2つ目のパッド)のボタン状態しか取得できない…ということです。
3つ以上のパッドを使うという状況は十分に考えられるのでやっぱりWindowsAPIは使えません。
DirectInput使うしかないのかなぁ…とか思っていると、ふと本棚に納められた Windows プロフェッショナル ゲームプログラミング という本の存在を思い出しパッド認識のことが書いてないかと調べてみました。
すると。
JOYSTICKID3とかJOYSTICKID4とか指定できても良さそうなのですが、この識別子がdefineされていないのです。そこで、JOYSTICKID1+2とかJOYSTICKID1+3とか やれば、どうなるのかなと疑問に思い、試しにやってみたところ、これで正しく入力できるんですよ(笑)

(引用元:Windows プロフェッショナル ゲームプログラミング 著:やねうらお 発行:株式会社 秀和システム 初版 258ページ)
ヘルプ書いた奴出て来い。←この開発裏話はつまり、この部分が書きたかった
しかも、JOYSTICKID1の値って0なんですよね。なんだそりゃ。

…気を取り直して。
相当にしょんぼりしましたが、まあこれでパッドの情報は読み取ることが出来ます。開発再開。
パッドのボタン状態を取得できるようになったので、次は擬似的にキーを押せばこのソフトの根っこの部分は完成します。
擬似的にキーを押すには、やはりWindowsAPIのkeybd_eventを使います。
たとえば、

    //VK_SNAPSHOT は、 PrintScreenキーに対応する定数
    keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY, 0) ;                 //PrintScreenキーを押す
    keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0) ;//離す
こんなコードを実行すると擬似的にPrintScreenキーが押されたことになり、画面スクリーンショットをクリップボードにコピーできます。
この原理を使い、パッドが押されたら対応するキーを押し、離されたら対応するキーを離す、という風にすればいいわけです。

しかし。
この方法で実際擬似的にキーが押すことはできたのですが(メモ帳上でパッドを動かすとカーソルが動いたりした)、ゲーム上で 試してみるとうんともすんとも言いませんでした。
どうやら、keybd_eventを使ってもDirectInputはキー動作を読み取ってくれない様子。Windows上で動くゲームは大抵DirectInputを使っていますから、 ゲーム用に作ったソフトなのにゲーム上で動かないという素敵な状況になってしまいました。
また挫折。
09/12
現実逃避とGoogleによる情報収集を繰り返していると、SendInputという命令を発見しました。
やっていることはkeybd_eventとほとんど変わらない関数ですが、別の命令が用意されているということはきっとどこかに違いがあるということで…。

………。
……。
…。

動いたぁーっ!(端折りすぎ)
やりました。やりましたよ先生。思い立ってから2ヶ月弱、ついに根元ができました。
なお、SendInputについては正確な情報がいまいち掴めていないので、もしかしたら上手く動いているようでその実裏でなんか悪さしてるかもしれません。
動きゃいいんです。動きゃ。(ダメなプログラマの典型)
それ以降
あとは特に苦労した点も無いので(時間はかかったけど)省略。「パット'萃'っち」という名称はこの段階で決まりました。
それから先は説明書を書くのに頭を悩ませる日々。本当は「擬似的にキーを押している」ということを隠したほうがすんなり使ってもらえると思ったんですが、 どうしても上手く説明できないので書くことにしました。
これにてパット'萃'っちの開発は終了。この駄文も終了。御清聴ありがとうございました。

最後に

自分で使う機会が無いのが辛いなぁ…とか思いつつ開発してました。
とにかく使える状況が限られているこのソフト。誰かに使ってもらえると嬉しいですね。