15

古いアーケードの横スクロール ゲームでは、パフォーマンスの高い横スクロールを可能にするために特定のプログラミング ハックが使用されていると聞いたことがあります。

何年も前のマシンは、現在のようにフレームごとに画面全体を再描画するのに十分なほど強力ではなかったことを理解しています. 背景が静止していてスプライトのみが移動する場合に再描画に必要な画面領域を最小限に抑えることができるダーティ レクタングルなどの手法があります。

上記のアプローチは、背景が変化しない場合にのみ機能します (したがって、ほとんどの画面ピクセルは静止したままです)。

古い学校のシューティング ゲームのような垂直スクロール ゲームでは、スクロールによってフレームごとに背景が変化するため、少し難しくなります。ただし、ピクセルがディスプレイに (ラインごとに) 供給される方法を利用することもできます。より大きなバッファを使用して、データポインタをフレームごとに数行「下」にシフトして、別の位置から再描画されるようにすることで、スムーズなスクロールの印象を与えることができると思います。それでもスプライト (および画面の端にある背景の一部) のみを再描画する必要がありますが、これは深刻な最適化です。

ただし、横スクロール ゲームの場合は、それほど単純ではありません。それでも、過去のどこかで、古いマシンがフレームごとに再描画せずに背景を水平にスクロールできるようにする最適化を (いくつかの制限付きで) 行ったことがあることを私は知っています。

IIRC 多くの古いゲーム、主に 80 年代の格闘ゲームやデモシーンの制作で使用されました。

この手法について説明し、作者の名前を教えてください。

4

4 に答える 4

11

私は古き良き C64 向けに、まさにこれを行うゲームを書きました。そして、基本的に次の 2 つの点に注意してください。

  1. これらのゲームはビットマップ グラフィックスを使用していませんでしたが、代わりに「再マップされた」文字フォントを使用していました。

  2. 次に注意すべきことは、画面全体を 7 ピクセル移動するためのハードウェア サポートがあったことです。これはグラフィックスにまったく影響を与えなかったことに注意してください。テレビに送信されるすべてのものを少しずらしただけです。

そのため、2) 7 ピクセル離れた場所へのスムーズなスクロールが可能になりました。次に、すべての文字を移動しました。フルスクリーンの場合、これは正確に 1000 バイトであり、コンピューターが処理できました。同時に、スクロール レジスタを 7 ピクセル戻しました。8 - 7 = 1 は、さらに別の 1 ピクセルをスクロールしたように見えたことを意味します...そして、そのように続きました。したがって、1) と 2) を組み合わせると、真のスムーズ スクロールのような錯覚が生じます。

その後、3 つ目の問題が発生しました。ラスター割り込みです。これは、TV/モニターが指定された位置でスキャン ラインの描画を開始しようとしたときに、CPU が割り込みを受けることを意味します。この手法により、分割画面を作成できるようになり、最初の説明とは対照的に、画面全体をスクロールする必要がなくなりました。

そして、さらに詳しく説明すると、分割画面が必要ない場合でも、ラスター割り込みはとにかく非常に重要でした。なぜなら、それは今日と同じくらい重要だったからです (しかし、今日、フレームワークはこれをあなたから隠しています) 更新する適切なタイミングで画面を表示します。テレビ/モニターが可視領域のどこかを更新しているときに「スクロール レジスタ」を変更すると、「テアリング」と呼ばれる効果が発生します。画面の 2 つの部分が互いに 1 ピクセルずれていることがはっきりとわかります。

これ以上何を言うべきですか?キャラクタ セットをリマップする手法により、いくつかのアニメーションを非常に簡単に実行できるようになりました。たとえば、コンベアや歯車などは、画面上でそれらを表す「キャラクター」の外観を絶えず変更することでアニメーション化できます。そのため、文字マップの 1 バイトを変更するだけで、画面幅全体にわたるコンベアがどこでも回転しているように見えます。

于 2011-11-13T17:22:19.027 に答える
8

私は 90 年代に、2 つの異なるアプローチを使用して、似たようなことをしました。

1 つ目は、VESA SVGA 標準でサポートされている「ウィンドウ処理」に関するものでした。一部のカードは正しく実装されていました。基本的に、フレーム バッファ/ビデオ RAM が表示可能領域よりも大きい場合、大きなビットマップを描画して、表示したい領域内のウィンドウのシステム座標を指定できます。これらの座標を変更することで、フレーム バッファーを再入力することなくスクロールできます。

もう 1 つの方法は、完成したフレームをフレーム バッファに入れるために使用される BLT メソッドの操作に依存していました。画面と同じサイズのフレーム バッファにページをブリットするのは簡単で効率的です。

オフスクリーン ページからビデオ バッファに 64000 バイト (320x200) の画面をコピーする、この古い 286 アセンブラ コード (機能している 17 年前のフロッピーで!) を見つけました。

  Procedure flip; assembler;
    { This copies the entire screen at "source" to destination }
    asm
      push    ds
      mov     ax, [Dest]
      mov     es, ax
      mov     ax, [Source]
      mov     ds, ax
      xor     si, si
      xor     di, di
      mov     cx, 32000
      rep     movsw
      pop     ds
    end;

移動された CX ワード (このrep movsw場合、1 ワードは 2 バイト)。これは基本的に、CPU に全体をできるだけ速く動かすように指示する単一の命令であるため、非常に効率的でした。

ただし、より大きなバッファー (たとえば、サイド スクローラーの場合は 1024*200) がある場合は、ネストされたループを使用して、ループごとに 1 行のピクセルをコピーすることも簡単にできます。たとえば、1024 ピクセル幅のバッファーでは、バイトをコピーできます。

start          count            
0+left         320
1024+left      320 
...
255*1024+left  320

ここleftで、開始したい大きな背景画像内の x 座標 (画面の左側) です。

もちろん、16 ビット モードでは、64KB を超えるバッファ (実際には複数の隣接する 64k バッファ) を取得するために、セグメント ポインタ (ES、DS) のいくつかの魔法と操作が必要でしたが、かなりうまく機能しました。

この問題にはおそらくより良い解決策がありました (そして、今日使用するのに間違いなくより良い解決策) が、私にとってはうまくいきました。

于 2011-11-13T17:28:21.757 に答える
2

アーケード ゲームでは、カスタマイズされたビデオ チップやディスクリート ロジックが頻繁に使用され、CPU が (多くの) 作業を行うことなくスクロールできるようになりました。このアプローチは、ダンビストロムが C-64 について説明していたものと似ています。

基本的に、グラフィックス ハードウェアが細かいスクロール文字 (またはタイル) を処理し、CPU がスクロール レジスタが限界に達すると、すべてのタイルの置き換えを処理しました。私は現在、ハードウェアで複数のスクロール背景を扱う Irem m-52 ボードを見ています。回路図はオンラインで見つけることができます。

于 2012-02-23T22:47:00.037 に答える