確かにDMMはマウス向きな命令が揃っていますが、通常のゲーム寄りな入力方法ももちろん可能です。
このテキストでは、DMMを使ってキー入力を行う便利な命令を紹介します。
例えばジョイパッドではSTICK関数とSTRIG関数、マウスではPAD関数という風に入力機器に対応するBASICの命令も違いますし、返る値の意味も違います。また、マウスが接続されているポートに向かってジョイパッドのSTICK関数を実行すると、訳の分からない値が返ってきますよね。
それに対してDMMはデバイスの入力と検出方法が一本化されています。たった1回の命令でキーボード、ポート1、ポート2の入力状態をチェックできますので、プログラムが簡潔になり便利です。
また、マウス操作などのプログラムではたった1つの命令を実行するだけでカーソルを自由自在に動かすことができ、しかもボタンをクリックするまでBASICに帰って来ませんので、BASIC側の負担がたいへん軽くなります。
ためしにDMシステム2が起動した状態で
もしあなたがマウスを持ってなくても大丈夫です。同じプログラムで、パッドを使ってマウスカーソルを動かすことができます。もしマウスもパッドも持ってなくても、キーボードのカーソルキーでも同じことができます。
もちろん、DMMの機能はこの程度にとどまるものではありません。すべてを理解するのは容易ではないかもしれませんが、是非このシステムを理解して、自作プログラムなどに役立てていただきたいと、私たちは思っています。
これはカーソルキーやジョイパッド等、STICK関数相当の入力結果をどのように加工するか、というものです。入力結果をマウスのように利用するのが「座標更新モード」、通常のSTICK関数的に利用するのが「戻り値モード」です。どちらのモードが便利なのかは、プログラムの性質によって好みが分かれるでしょう。
ちなみにマウスでSTICK関数相当の入力をすることはできません。どうしてもという場合は、マウスのトリガを押しながらMSXを起動する「ジョイスティックモード」を利用してください。
よってキーボードのみの入力では「座標更新モード」でないとマウスカーソルは満足に動いてくれません。「戻り値モード」では、カーソルキーを押した瞬間にキーの値がDMMへ代入されBASICへ戻ってしまうからです。
制限時間内にデバイス入力が行われた場合はその場でBASICへ戻ります。
まず、CALL DMMON以後デバイス入力は1/60秒単位でバックグラウンド処理されます。バックグラウンド処理されたDMMは、デバイス入力情報を毎秒60回インフォメーションエリアに書き出します。
CALL DMMONは入力結果の書き出しを指示するだけですので、実際はCALL DMMを利用したり、自前でインフォメーションエリアを参照するなどしなければ、入力結果はいつまで経っても得られません。ところがBASICでは処理の遅さから、毎秒60回を事実上取り出せません(MSX2/2+使用時)。よってこの効果は、例えばマシン語ルーチンからインフォメーションエリアを参照して入力関係のプログラム製作を省略するなど、かなりマニア向けな効果と言えます。詳しくは余談の「DMMの奥深さ」をご覧ください。
次に、DMMのトリガ入力が、なんとBASICのON STRIG GOSUB文で検知できます。
これはBPEデータの展開中やCALL VCOPYによる拡大縮小など処理に時間がかかり、且つBASICではトリガ入力が常に検知できない場面で特に有効です。しかもスペースキーだけでなく対応デバイスのトリガ入力でもサブルーチンの呼び出しが可能になるので重宝します。
※ バックグラウンド処理はCALL DMMOFF(後述)を実行するまで継続します。ハード環境やデバイスによっては、デバイス入力を行うことによりプログラムの実行速度が低下しますので、あらかじめご注意ください。
※ ON STRIG GOSUB文ではすべてのトリガ入力を STRIG(0) へ反映させます。
マウスカーソルの移動を快適に行う為、キーボードに「倍速キー」を用意しました。倍速キーを押しながらカーソルを移動させると、2倍速になります。
倍速キーは、デフォルト設定ではSHIFTキーに割り当てられています。倍速キーは後述のキーカスタマイズでキーを変更できます。
また、主にジョイパッドで実現できる3種類の倍速方法が用意されています。
CALL DMMで戻り値変数に返すデフォルト設定での数値は以下の通りです。
カスタマイズテーブルはDMMKEY+0をオフセットとして「マトリクス行」「ビット」の2バイトで1セット、それが8つ並んでいます。ここにMSXシステムの「キーマトリクス」に準じた2バイトのデータを代入します。
※ マトリクスの8行目を超える特殊なキー(テンキーや松下の実行・取消キー等)も割り当てることができます。
DMシステム2ユーティリティーの"DS2.INI"に以下のような項目を追加すると、キー入力を独自で割り当てた状態で他のソフト起動できます。デフォルトの仕様が気に入らなかったり、一部のキーが壊れてて操作できない時などにご利用ください。
次に"Trig**=n"という書式で書いてゆきます。
なお、Trig00〜08は固定値ですので、変更はできません。
※ キーカスタマイズしても、その後起動するソフトで独自にキーを変更する場合があります。
しかしアクションゲームなどでトリガの同時押し、および方向キーの検出が一度に必要な場面も出てくるかもしれません。そういった場合DMMでは役不足ですので、デバイスドライバを「忍者タップドライバ」へ差し替えてください。
「忍者タップドライバ」は、忍者タップによってすべてのパッドが接続された最大8タスクとキーボードから2タスクの計10タスクを一度に検出し、それぞれのタスクの方向4つとトリガA,トリガBの状態を8ビットに整理して出力します。忍者タップが接続されていない場合は通常のパッドとして計4タスクを出力するので、このドライバを組み込んでおくと方向とトリガの情報を一度で取り出すことができ、アクションゲームなどの用途でも不自由しないと思います。
その際、call dmmで返る値はトリガ以外は正常に入らなくなります。入力結果は「忍者タップドライバ」内のワークエリアに保存されているので、そこを直接参照してください。
DMMの原作者のT-kunは残念ながら多忙のため現バージョンのDMM開発には参加しておりませんが、現在のシステムがこれを継承・発展させたものであることから、DMMの名称をそのまま受け継ぐことになりました。
これにより、パッドやマウス以外の新しいハード、あるいはパドルやライトペンのようなturboRで使用できなくなってしまったハードにも、デバイスドライバの差し替えだけで容易に対応することができます。また、そういったドライバがなくてもアセンブラでドライバを自作できます。これがDMMの最大のメリットです。
ちなみにDMシステム2へデフォルトでインストールされているデバイスドライバ「マウス+パッド」は、FM-TOWNSで用いられた4ボタンパッドにさりげなく対応しています。MSXのポートに差すと、パッドのSELECTボタンとSTARTボタンをcall dmmで検出できます。
実際にタイマ割り込みでバックグラウンド処理されるのはマウスの座標更新処理のみです。つまり、トリガ入力やスプライトの表示などの作業はタイマ割り込み外の、一般の処理として行われています。
ですからマウスの移動は必要か否かにかかわらず、1/60秒毎に読み取られ、インフォメーションエリアの座標を更新しますが、その座標位置にスプライトを表示するためにはcall dmm命令を(,sオプションをつけて)実行する必要があるのです。
同様に、トリガやキーボードの入力も、call dmm命令で取り出さなくては、値を得ることは出来ません。または自力でインフォメーションエリアを参照する必要があります。
入力結果の説明の中で「各種デバイスとキーボードの両方で同時に入力があった場合、デバイスが優先される」と説明しましたが、これはDMMがまずデバイスドライバをコールして、結果が得られなかった(何も押されていなかった)場合のみキーボードを調べるからです。
よくBASICプログラムなどで「すべてのSTICKを調べて結果をorする」という手法が使われますが、私はその方法は推奨しません。なぜなら
※ 4はSTICK関数の右下、3は同様に右を示すが、ORした結果は7(左)を示している。
ですからDMMではデバイス入力があった場合は、キーボードを調べずにとっととBASICに帰ってしまいます。また、標準のドライバではポート1に対してポート2が優先されます。ポート2からの入力があれば、ポート1は調べずにBASICへ帰ってしまうのです。
ドライバは簡単なアセンブラが組める人なら誰でも作れるような簡易な設計にしたつもりですが、1つだけ注意するべき点があります。それは、turboRでも、MSX2でもまともに動くように作ってください、ということです。
turboRでは速すぎるとか、逆にMSX2では遅すぎて使い物にならない、というケースも、ハードによっては出てくると思います。とりあえず、MSX2に速度を合わせて作成し、turboRでは一時的にZ80モードに切り替えるのが無難でしょう。
ドライバによっては、マウスを必要としないケースもあるでしょう。そういった場合はマウスのコールエントリでいきなりRETしてしまっても構わないと思います。
第1章 概要
1.1 DMMとは
人間がパソコンへ指示を与える為の周辺機器にはキーボードやジョイパッド、マウスといったものが身近なところに存在しますが、様々な機器から入力情報を得るデバイスドライバと、キーボードからのキー入力とを総合的に管理する機構を、DMシステム2では「DMM(DM-MOUSE)」と呼んでいます。
※ MSX以外の「俗に言う」パソコンの世界でデバイスドライバと言えば「OS上に常駐しているプログラム」を指しますが、DMシステム2では「入力機器からの情報をシステムへ送るプログラム」と解釈してドキュメントで用いています。
DMMは元々"Disk Mail(ディスクメール)"というディスクマガジンがマウス主体の操作系が必要なことから(後述)、マウスの入力はもとより、キーボードのカーソルキーやジョイパッドのようなゲーム向きな入力機器も、マウスのように入力してしまおうという趣旨で開発されました。DMMでそういったマウス主体のプログラムをBASICでさらに簡単に作ろう、というわけです。
1.2 DMMのメリット
MSX-BASICは様々な入力機器に対応しているのですが、機器によって入力の検出方法や結果がバラバラです。2つのデバイス、あるいはキーボードとデバイスの両方の入力を同時に検出するのは非常に面倒です。
100 SCREEN5,0:SPRITE$(0)=STRING$(255,8)
110 CALL DMMINI(0,0)
120 CALL DMM(A),S
130 END
と入力して、実行してみてください。110行はモードの設定、130行はプログラムの終了を行ってるだけですから、実際にマウスの移動とクリックの判定をしているのは120行だけです。しかも、この1命令だけでマウスカーソル用のスプライトまで表示しているのです。
第2章 DMシステム2からの使用方法
デバイスドライバにデフォルト設定の「マウス+パッド」以外を使用している場合でも、プログラムの記述はすべてのドライバにおいて共通します。
2.1 デバイス入力の初期化
デバイス入力を宣言します。情報の入力方法は全部で4種類あります。
CALL DMMINI (入力モード)
ビットは0でoff、1でonになり、8ビット(1バイト)の数値で設定します。×の部分はすべて0(off)になります。
b7 b6 b5 b4 b3 b2 b1 b0
× × × × × × M S
~~ ~~ bit0 スティックの反映先 (0:座標 1:戻り値)
|
+--- bit1 画面の終点 (0:ループ 1:画面端)
スティックの反映先(bit0)
0:座標更新 マウスカーソル座標を更新させ、トリガの入力があるまで処理を続行します。
1:戻り値 MSX-BASICのSTICK関数と同等の数値を変数に返してデバイス入力を終了します。
画面外の移動(bit1)
0:ループ 画面の上下と左右を繋げ、右端の右は左端へ。
1:非ループ 画面外にマウスカーソルが移動しません。
sample program
DMM.BAS (1KB)
ex.)
call dmmini (&B00000010) ← 座標更新&非ループで入力
call dmmini (2) ← 座標更新&非ループで入力 (同上)
call dmmini (3) ← 戻り値&非ループで入力
2.2 マウスカーソルの表示を含めた宣言
デバイス入力時にスプライトの「マウスカーソル」を表示させます。
CALL DMMINI (入力モード)
ここで指定したスプライトは CALL DMM(後述)実行中にマウスカーソルとして移動します。指定した番号とその次の番号のスプライトがマウスカーソルとして使用されますので、MSX2のスプライト2枚重ね技も使えます。なお、スプライトの定義はあらかじめ各自で行ってください。
ex.)
call dmmini (2,4) ← 座標更新&非ループで、スプライト#4をマウスカーソルにする
2.3 デバイス入力の開始
CALL DMMINIで指定したモードで、デバイス入力を開始します。
CALL DMM (戻り値変数)
スペースキーやトリガA等、DMMへ何か入力されるまでBASICへ戻れません。(Ctrl+STOPでの中断はできます)。何か入力されると、入力結果を変数に返しBASICへ戻ります。
ex.)
call dmm (A) ← デバイス入力開始、結果を変数Aに代入
※「座標更新モード」が宣言されている場合は、カーソルキーやパッドの十字キーからの入力ではBASICへ復帰せず、結果を戻り値として取り出すこともできません。
2.4 スプライト付き・デバイス入力
CALL DMMINIで指定したスプライトをマウスカーソルとして常に移動させながら、デバイス入力を開始します。
CALL DMM (戻り値変数)
CALL DMMが実行されている間、デバイス入力された値を座標に更新しスプライトが移動します。DMMに値が代入された瞬間(=トリガが押された瞬間)、スプライトの移動は終了し、BASICへ戻ります。
ex.)
call dmm (A),S ← スプライト移動を有効にして入力開始、結果を変数Aに代入
※ SCREEN 0ではスプライト機能が働かない為、実行できません。
2.5 制限時間付き・デバイス入力
デバイス入力が行われなくても、制限時間になるとBASICへ戻ってしまいます。制限時間を作ることで、キー入力を兼ねた時間待ちとして利用できる便利な機能です。
CALL DMM (戻り値変数)
制限時間は1/60秒単位で設定し、制限時間内に入力が行われなかった場合、戻り値は0になります。
ex.)
call dmm (A,120) ← 2秒間(120/60秒)だけデバイス入力
call dmm (A,120),S ← しかもスプライトを動かしつつ入力
第3章 ちょっとマニアックな活用方法
この章では、更に突っ込んだDMMの活用法について伝授します。基本を押さえた上でよく読んでくださいね。
3.1 バックグラウンド処理
DMシステム2のバックグラウンド処理にデバイス入力を追加します。
CALL DMMON
この命令による効果は以下の2点です。
ON STRIG GOSUB XXX : STRIG (0) ON
を事前にセットしておくことで、BASICプログラムの実行中でも常にトリガ入力を検知し、トリガ入力されれば直後にON STRIG GOSUB文で引っかかるようになります。
ex.)
call dmmon ← バックグラウンド処理に追加する
3.2 バックグラウンド処理の終了
デバイス入力のバックグラウンド処理を終了します。
CALL DMMOFF
CALL DMMONを実行したら、必ずCALL DMMOFFでデバイス入力を終了してください。
ちなみにデバイス入力の終了はCALL SYSONでも代用もできます。
ex.)
call dmmoff ← バックグラウンド処理を終了する
ex.)
call syson ← システムの初期化=バックグラウンド処理を終了する
3.3 マウスカーソル倍速移動
ジョイパッドやカーソルキーでもマウス同様、マウスカーソルを動かすことができます。しかし、ズバリ、遅いのです。それもそのはず、1/60秒につき1ドット、1秒でも60ドットしか動けないからです。
インフォメーションエリアのDMMSPD (4300h+90)に1バイトの数値を代入します。
0 倍速しない
1〜127 ダブルクリック (数値は有効時間)
128〜254 押しっぱなし (-128した数値が有効時間)
255 トリガB
ex.)
call poke (&H4300+90,4) ← 4/60秒の間にダブルクリックすると倍速
call poke (&H4300+90,128+4) ← 4/60秒押し続けると倍速
call poke (&H4300+90,255) ← トリガBを押していると倍速
sample program
DMM2.BAS (2KB)
第4章 補足
4.1 入力結果について
DMシステム2ではデバイスドライバによるデバイスの入力の他にキーボードの入力も検出しています。デバイスとキーボードでの検出結果を合成し、CALL DMMの戻り値変数に代入をしているわけです。
STICKの方向とトリガの両方を一度に検出はできませんが、トリガの入力が7種類検出できます。機能の用途はユーザーやプログラマが決定します。
0 なし
1〜8 移動方向 (STICK関数と同値)
9 キー1 (トリガA, SPACEキー)
10 キー2 (トリガーB, GRAPHキー)
11 キー3 (STOPキー)
12 キー4 (TABキー)
13 キー5 (ESCキー)
14 キー6 (HOMEキー, TOWNSパッドのSTARTボタン)
15 キー7 (SELECTキー, TOWNSパッドのSELECTボタン)
※ 各種デバイスとキーボードの両方で同時に入力があった場合、デバイスが優先されます。
また、DMシステム2のインフォメーションエリアに、デバイス入力の詳しい情報が記載されますので、必要であればCALL PEEKなどでこのエリアを参照してください。
※ キーカスタマイズ(後述)により検出したいキーを変更できます。
ex.)
call peek (&H4300+66,x) ← x座標の検出
call peek (&H4300+67,y) ← y座標の検出
4.2 キーカスタマイズ
DMシステム2のインフォメーションエリアに DMMKEY (4300h+74)が存在します。トリガ番号9〜15の計8つのキーの割り当てはこのカスタマイズテーブルで決められており、ここを変更すると入力キーを独自で割り当てることができます。
1バイト目 マトリクス行 (0〜10)
2バイト目 ビット (0〜7)
※ キーマトリクスは「MSX2テクニカル・ハンドブック(アスキー)」等を参照してください。
---------------------------------------------
[Keyboard]
Trig09=&H80 ;キー1:決定/SPACE
Trig10=&H62 ;キー2:キャンセル/GRAPH
Trig11=&H74 ;キー3:ポーズ/STOP
Trig12=&H73 ;キー4:デバイス再チェック/TAB
Trig13=&H72 ;キー5:終了/ESC
Trig14=&H81 ;キー6:HOME
Trig15=&H76 ;キー7:SELECT
Trig16=&H60 ;高速化キー:SHIFT
---------------------------------------------
まず"[Keyboard]"という行を作ります(Keyboardセクション)。これが無いとカスタマイズできません。
Trig09=&H80というのは「キーマトリクス8行目の0ビットなら戻り値9」という意味です。16進数で書くと分かりやすいのでオススメですが、"&H"を先頭に付けてください。
ex.)
Trig09=&HB1 ← 実行キー(11行目の1ビット)
4.3 ドリガの同時押しを判定したい
DMMはあくまで「ジョイパッドをマウスのように扱う」機構である為、キーやトリガの判定は「最初にクリックされたキー」として1つのトリガしか検出できないよう設計されています。
第5章 余談
5.1 DMMシステムが出来るまで
DMMが始めて登場したのは、DM#7の外部プログラムとしてでした。当時(1992年頃)はまだマウスがさほど普及していなかったため、ジョイパッドでもマウスでも同様の操作が可能な環境が必要だったわけです。
5.2 DMMの奥深さ
DMシステム2でドライバの概念が導入されたことにより、DMMも「ドライバ」と「システム」に分割されました。ドライバ側はさまざまなデバイスに対応可能となり、キーボードなどの常に共通な処理が要求される部分はシステム側に組み込まれたのです。
5.3 DMMをより詳しく
call dmmonの説明の中で「バックグラウンド処理」という言葉が出てきましたが、これは1/60秒のタイマ割り込みのことです。
というように、複数の入力に対して、そのいずれでもない結果しか得られないことがあるからです。
ex.)
4 or 3 = 0100b or 0011b = 0111b = 7
5.4 ドライバ自作への手引き
ここまでの説明をすべて理解した方なら、デバイスドライバを自作するのも容易なことでしょう。本文はドライバの仕様書ではないので、詳しくは「デバイスドライバの作り方」を参照していただきたいと思います。
Copyright (c) 1998 GIGAMIX, All rights reserved.