OPAS応用編1

多ライン同時スクロール


(1) OPASの基本の復習


 この応用編ではOPASの基本的な使い方はマスターしたけどさらにさまざまに活用したいという人のために書いていきます。

 念のためOPASの基本となるスクロールアニメーションについて復習しておきます。基本編で書いたものをまとめるとOPASにおけるスクロールやアニメーションは下記のようなものになります。

 仮にBF000hからデータが入っているとします。

《 画面幅60ドット×1ラインでスクロールする場合 (1画面60バイト) 》
BF000hBF001hBF002hBF003h・・・・・・BF03BhBF03ChBF03DhBF03Eh
1ターン目         
2ターン目         
3ターン目         
4ターン目         

《 画面幅60ドット×4ライン(60×32)でアニメーションする場合 (1画面240バイト) 》
       ※ただし、アドレス演算簡略化のため256バイト単位で記録
BF000h・・・・・BF0EFh・・・BF100h・・・・・BF1EFh・・・BF200h・・・・・BF2EFh
1ターン目         
2ターン目   使   使   
3ターン目         

 これはメインルーチンを1回動作させるごとにメモリ上のどの部分のデータを画面上に表したものかを示したものですが、例えるならば仮想画面から一部を取り出して表示しているだけという単純なものですね。
 これで、スクロールとアニメーションの基本的な仕組みは分かったと思います。分からない場合はもう一度基本編をじっくり読みサンプルプログラムを改造してその仕組みを理解してください。



(2) 多重スクロールの原理


 基本編ではスクロールは1ライン(縦8ドット)のみとなっていました。
 OPASでは仕様上4ライン同時スクロールをサポートしています。これはスクロール速度を各ライン変えることで4重スクロールも可能となっています。

 そもそもなぜ4ライン同時スクロールが可能かというとPC-E500シリーズではフォントデータが4つの領域に区切られて別々の場所に保存されているからです。20h〜7Fh、80h〜9Fh、A0h〜DFh、E0h〜FFhすべての領域のフォントを書き換えることによって1つのPRINT文で最大4つの独立したアニメーション(※)、もしくは横スクロールが実現可能になります。

 ※独立したアニメーションとはアニメーションのパターンが異なるものを示す。
  RPGの敵キャラのアニメーションなどで使用する場合、パターン数やアニメーション速度が同じであれば複数キャラであっても1つのアニメーションとして計算する。
  ただし、1領域の書き換えで複数キャラのアニメーションをさせる場合には下記のように384バイトのデータ量制限が発生する。

OPASによる4重スクロールの原理
1ライン目20h〜7Fhを書き換えて使用
2ライン目80h〜9Fhを書き換えて使用
3ライン目A0h〜DFhを書き換えて使用
4ライン目E0h〜FFhを書き換えて使用

リスト1 多重スクロール サンプルプログラム
10 CLS :CLEAR :OPEN "SCRN:"FOR OUTPUT AS #1:A$=A$+31:FOR I=0TO 9:A$=A$+CHR$ 29:NEXT
20 FOR I=0TO 3:Z=32+I*32-(I>0)*64-(I>2)*32:FOR J=Z TO Z+9:Z$=Z$+CHR$ J:NEXT :IF I<3THEN Z$=Z$+A$:NEXT
30 Z=&BFC8A:FOR I=0TO 3:POKE Z+I*3,0,&FB,&B:NEXT
40 POKE &BFC90,A:POKE &BFC8A,B:POKE &BFC03,C:POKE &BFC8D,D:LOCATE 0,0:PRINT #1,Z$
50 A=A+0.5:B=B+1:C=C+1.5:D=D+2:IF A<196AND B<196AND C<196AND D<196THEN 40
60 END
70 *SET Z=&BFB00:FOR I=Z TO Z+255:POKE I,0:NEXT :FOR I=Z TO Z+255:I=I+RND 9+4:Y=2^(RND 5-1):POKE I,6*Y,13*Y,15*Y,6*Y:NEXT :GOTO 10
 《 注意 》
 あらかじめマシン語エリアとしてBFB00h以降の256バイトを確保しておいてください。
 [CTRL]+[+/-]ではフォントが元に戻らないため実行前にPFキーにINIT"SCRN:"[RETURN]を登録しておくことをお勧めします。

 実行前に適当なグラフィックをBFB00h〜BFBFFhの256バイト(このデータは各ラインで共用される)に書き込んでいてください。RUN *SETとすればサンプルデータが書き込まれます。
 50行のA、B、C、Dの加算数値を変えることで各ラインのスクロール速度を自由に調整できます。

 このように書き換える領域を変えることによってそれぞれ独立した動きが可能になります。これはスクロールとアニメーションを併用することも可能であり3重スクロール&1アニメーションという感じの使用もできます。
 「シュプール」においては4つの領域をプレイヤーキャラ、近景の疑似3Dスクロール、遠景の横スクロール、スピードメーターで使用しておりそれをPRINT文1つだけで1度にすべて表示しています。そのために非常に高速描画(全体表示が1回あたり約60m秒)が可能になっています。これはGPRINTで8×8のキャラを動かすよりも速いといえばこれがどれだけ高速かということが分かると思います。

 しかし、4つの領域すべてを書き換えるということは通常の文字表示を行うたびに文字を元に戻すということが必要になります。そのため可能な限りは英数字を含む20h〜7Fhの領域は書き換えないようにした方が良いです。ゲーム終了時にフォントを元に戻すのは簡単ですがROMバージョンごとにシステムフォントが格納されているアドレスが異なるためゲームの途中においてそれを行うにはあらかじめシステムフォントが格納されているアドレスを別の変数などに記録しておくなどの工夫が必要になります。また20h〜7Fhを書き換えた場合には通常の[CTRL]+[+/-]ではフォントが元に戻らないという問題もあります。
 そうなるとOPASでは手軽に使えるのは80h〜9Fh、A0h〜DFh、E0h〜FFhを書き換えた3ライン(3重)スクロールまでとなってしまいます。

 ただ、これらの制約は1つのPRINT文で表示を行った場合のみのものです。複数回に分ければ事実上の制約はありません。しかし、一度にたくさんの文字数(グラフィック量)を表示することがOPASの高速化に繋がっているので複数回に分けて表示する場合には速度面でのメリットが少し失われてしまいます。



(3) 1領域で多ライン同時スクロール


 4重スクロールをするには上記のように4つの領域すべてを書き換えないといけないのですが、ライン毎にスクロール速度が変わることのない単純な4ラインスクロールであれば4領域すべてを書き換える必要はないのです。

 それは1つの領域を書き換えることで複数のラインを表示することも可能になるからです。しかし、この方法には少し制約があります。その方法と制約について少し書いていくことにします。

 リアルタイムに管理アドレスを書き換えないフォント書き換えにおいてはカナを書き換え時には64文字分(384バイト分)というデータ量の制限があります。OPASではリアルタイムで書き換えているためこの制限が無くなっているのですが、この制限の範囲内であれば1つのPRINT文で複数ラインの同時スクロール(もしくは複数キャラのアニメーション)が可能となっているのです。
 その制限というのはスクロールする範囲に384バイトの制限があるというものです。ただし、1つのPRINT文で横60ドット×2ラインの表示枠をスクロールさせる場合はスクロール可能な範囲は384バイトから60ドット2画面分を差し引いた264バイト(=264ドット分)となります。

 これはどういうことかというともう少し詳しく書いていきます。
 カナというのはA0h〜DFhを示すのですが、通常であればOPASの場合はフォント書き換えと異なり64文字制限がありません。OPASの原理は全体から一部を取り出すだけであるため全体量(合計データ量)に関してはメモリの許す限りは制限がないということです。その代わり一度に取り出せる量に制限があり、それがフォント書き換えと同様に384バイトの制限があるということです。(これはOPAS自体がフォント書き換えの応用に過ぎないためやむを得ない)
 したがって、384バイトを越えるサイズ、つまり96×32ドットを越える巨大キャラを表示する場合にはカナだけの書き換えでは表示はできません。その巨大キャラを表示する場合に限りカナだけではなく複数領域の書き換えが必要になってきますが表示枠が60ドット×2ライン程度ならば全く問題はありません。
 その余力部分を使ってカナという1領域の書き換えで2ライン同時スクロールを行うというわけです。

 カナという1領域の書き換えで2ラインをスクロールさせる場合、表示枠が横60ドット(10文字分)であるならば領域を最大限に生かすためには表示に使用する文字はその領域の先頭10文字と末尾10文字となります。具体的に言えば1つ目のラインではA0h〜A9hの10文字分(60バイト)を使用し2つ目のラインではD6h〜DFhの10文字分(60バイト)を使用するのです。

カナだけで2ライン同時スクロール
1ライン目A0h〜A9hの10文字を使用
2ライン目D6h〜DFhの10文字を使用

 使用されてないAAh〜D5hの44文字分はどこにいくかというとスクロール用の予約エリアです。
 OPASでは上記のOPASの基本の復習で書いたようにあらかじめ用意されたグラフィックデータの任意の部分を取り出すことによってスクロールやアニメーション処理を行っています。仮にBF900hからスクロール用のグラフィックデータが書き込まれていると仮定した場合には下記のようになります。

1ライン目
BF900hBF901h・・・BF93BhBF93Ch・・・BFA07hBFA08h・・・BFA42hBFA43h
1ターン目           
2ターン目           
(中略)           
264ターン目           
265ターン目           

2ライン目
BFA44hBFA45h・・・BFA7FhBFA80h・・・BFB4BhBFB4Ch・・・BFB86hBFB87h
1ターン目           
2ターン目           
(中略)           
264ターン目           
265ターン目           

メモリマップ
BF900h〜BF93Bh1ライン目の開始時のグラフィックデータ
BF93Ch〜BFA43h1ライン目のスクロール用のグラフィックデータ
BFA44h〜BFA7Fh2ライン目の開始時のグラフィックデータ
BFA80h〜BFB87h2ライン目のスクロール用グラフィックデータ

 このBF03Ch〜BF143hAAh〜D5hの44文字(264バイト)のデータとなるわけです。この方法はそれぞれ動きが独立したもの(1ライン目と2ライン目でスクロール速度の異なるもの)では使用ができませんが同速度で複数ライン同時スクロールする場合はアニメーションの場合と同じく複数ラインであっても1つのライン扱いとなるため1領域の書き換えでまかなえてしまうのです。しかし、384バイト制限があるためにスクロールする範囲が表示画面が横60ドットであればスクロール範囲が264ドット以内の場合に限りA0h〜DFhという1つの領域を書き換えるだけで2ライン同時スクロールが可能になります。

リスト2 カナだけで2ライン同時スクロール サンプルプログラム
10 CLS :CLEAR :OPEN "SCRN:"FOR OUTPUT AS #1:A$=A$+31:FOR I=0TO 9:A$=A$+CHR$ 29:B$=B$+CHR$ (160+I):C$=C$+CHR$ (214+I):NEXT :Z$=B$+A$+C$
20 A=&7900:FOR I=A TO A+263
30 POKE &BFC93,I AND 255,I/256+128,&B:LOCATE 0,0:PRINT #1,Z$:NEXT
40 END
50 *SET Z=&BF900:FOR I=Z TO Z+647:POKE I,0:NEXT :FOR I=Z TO Z+647:I=I+RND 9+4:Y=2^(RND 5-1):POKE I,6*Y,13*Y,15*Y,6*Y:NEXT :FOR I=0TO 325STEP 20:POKE Z+I,255:POKE Z+I+324,255:NEXT :GOTO 10
 《 注意 》
 あらかじめマシン語エリアとしてBF900h以降の768バイトを確保しておいてください。


 実行前に1ライン目のスクロール用データとしてBF900h〜BFA43hの324バイト、2ライン目のスクロール用データとしてBFA44h〜BFB87hの324バイトに適当なグラフィックデータを書き込んでおいてください。RUN *SETとすればサンプルデータが書き込まれます。(※324バイト=表示枠60バイト+スクロール量264バイト)
 このサンプルプログラムを実行すれば1領域の書き換えでも2ライン同時スクロールが可能ということが分かると思います。(20ドットおきに縦線を引いています)

 この方法をさらに応用すれば1領域の書き換えで3ライン同時スクロールも可能になります。しかし、64文字(384バイト)制限のため制約はさらに大きくなります。スクロール画面の表示枠が横60ドット(10文字分)の場合3ライン分のデータで180バイト必要になるため残り204バイトの半分の102バイト分(102ドット分)しかスクロールができません。

カナだけで3ライン同時スクロール
1ライン目A0h〜A9hの10文字を使用
2ライン目BBh〜C4hの10文字を使用
3ライン目D6h〜DFhの10文字を使用

 同様に考えて、4ライン同時では48ドット分のスクロールしかできません。

カナだけで4ライン同時スクロール
1ライン目A0h〜A9hの10文字を使用
2ライン目B2h〜BBhの10文字を使用
3ライン目C4h〜CDhの10文字を使用
4ライン目D6h〜DFhの10文字を使用

 したがって、カナだけの書き換えで3ラインや4ラインのスクロールは可能ですが実用性の面では厳しいでしょう。(※応用編2-(2)の方法を使えばこの制限は無効化可能)
 しかし、2ラインまでならば264ドットのスクロールが可能であるため十分実用レベルはあると思います。カナ(A0h〜DFh)だけで2ライン同時スクロールをして80h〜9FhE0h〜FFhで各1ラインのスクロールを行えば20h〜7Fhを書き換えること無しに4ライン同時スクロールが可能になります。20h〜7Fhを書き換えることがないのでゲーム内で手軽に英数字を表示することができるというのは大きなメリットになるでしょう。

 この多ライン同時スクロールのゲームにおける具体的な使用例に関しては「2LINE UFO GAME」での活用方法を参考にしてみてください。


OPAS応用編1 多ライン同時スクロール
  (1) OPASの基本の復習
  (2) 多重スクロールの原理
  (3) 1領域で多ライン同時スクロール

OPAS応用編2 スクロールとアニメーションの同時使用
  (1) 1領域でスクロールさせながらアニメーション表示
  (2) スクロールの制限を無くす
  (3) 縦スクロール


RETURN

inserted by FC2 system