メッセージデータの形式が決まれば、次は実際の処理の流れです。スクロールは、1ドット単位で行われます。そのため、画面下部で文字を描いているのが見えるのは、あまりエレガントとは言えません。また、スクロール中は、その追加文字列の表示を壊すわけにもいかずで、意外と複雑な構造が要求されます。さらに、全画面コピーだと処理速度が足りずにたらつきます。2画面切り替えのようなハードの支援がない場合は、コピーの速度はできる限り高速に行う必要があります。今回は、そのような処理の実装に必要な構造を解説していきます。
メッセージデータの解説はこちらを参照してください。
- 処理全体の流れとメモリ構成
スクロールアップは大きく2つの処理に分解できます。まずは画面に表示されている文字を1ドット上にずらす処理です。ハードウェアスクロールの機能がないマシンの場合は、これが案外重いです。そして、上にずらした後の最下行に、新しい文字列の1ラインをコピーする処理が必要です。つまり「スクロール」と描画バッファからの「新しいラインコピー」のセットで初めてエンドロールアップの処理が出来るのです。下記にイメージを掲載します。
※ 数値は参考なので、実際の値と異なる可能性があります。
スクロールは文字の範囲だけをずらす対象に限定します。そのため、各行にコピー開始の左側の座標と、コピーの長さを情報として格納して、その情報を確認しながらコピーしてきます。PC-8001mk2 の場合ですと、横幅80バイトで縦の解像度が200ラインですので、1ラインに2バイトとして、テーブルワークが 400バイト必要となります。改行だけのラインではコピーが不要ですから、それを早い段階で確認するために、テーブルの格納順は、コピーサイズと左側座標としています。コピーサイズが 0 ならそのラインは改行なので、何もせず次のラインに処理を移せば終わるためです。
新しいラインコピーは、少し面倒です。画面のスクロールアップが終わったら、行バッファに文字列を描き直す処理系とした場合、1行毎に処理が集中してカクつきます。スクロールにおいてはたらつきとカクつきは、極力避けるべき見苦しい挙動なのです。これを避けるために、表示用の行バッファと、次のために事前に文字列描画は行う編集バッファの2つを用意します。所謂ダブルバッファです。
描画バッファから実画面の最下位ラインに、1ラインずつコピーしながら、編集バッファにその次のメッセージデータを描画しています。描画バッファから全てのデータを実画面にコピーし尽くしたら、描画バッファと編集バッファを入れ替えて、また描画バッファの先頭から実画面に1ラインずつコピーしながら、編集バッファをクリアして次のメッセージを作成するという流れを文字列の終了まで繰り返しています。
※ 絶対美味しい!続いては、新しい行の描画です。
文字表示処理そのものではなくて、処理分散についての解説がメインとなります。
コメント
コメント一覧 (4)
昔、ゲームプログラマを目指していた一時期がありまして、エンドロールのアルゴリズムを考えていたことがあります。
なので、今回の記事はとても興味深く拝聴させていただいております。
後、もう一つ疑問に思ったことがあるのですが、PC-8001mk2での1ライン移動(スクロールアップ)する処理のタイミング待ち(開始待ち)というのは、vsyncでカウントをとられているのでしょうか?
(PC-9801あたりだと、vsyncを使用して、画面のスクロールアップ速度などの調整をしていると思うのですが。)
後続の記事を拝聴すると、各ライン毎の移動処理自体は水平ブランキング期間に行われているとのことですが、10FPS固定ということは、vsyncで次の画面表示のタイミングを調整しているのではと思ったものですから。
(プログラムを動かすハードが決め打ちの場合、プログラムの消費クロック数にも左右されるので、必要のないケースもあるのかもしれませんが。)
今後、その辺の技術的(フレームレート管理)なことも記事にしていただけると幸いです。
内藤時浩
がしました
2つほどご質問させていただきたいのですが、"そのため、各行にコピー開始の左側の座標と"という文の各行とは、後に続く文章から、グラフィックVRAMの1ラインという意味と解釈しましたが、その認識で正しいのでしょうか?
それと、表示されている文字を1ドット上に移動するとき、ある表示されている文字列があるとして、その一つ下に表示されている文字列の文字数が、その上に表示されている文字数よりも少なかったと仮定すると、1ドット上に移動する対象を文字列の幅分とした場合、1ドット上に移動した時に、以前表示されていた文字列のゴミが残ってしまう気がしたのですが、それは、描画する文字キャラクタの高さ12ドット分に、行間の黒が含まれているので、ゴミが残らないという認識で正しいのでしょうか?
以上ですが、疑問に思ったのでご質問させていただきました。
それにしても、メッセージデータに先頭の表示位置データを持たせるという工夫でも驚きましたが、かなり昔のハードだと、ここまでの最適化を図らないと実行速度が上がらないのですね。
内藤時浩
がしました