3

さて、私はAssembly x86(8086)でSpace Invadersゲームを作成していますが、これまでのところかなりうまく動作しています。グラフィックモードでアセンブリを使用しています13h。つまり、320x200ピクセルと256色です。

描画にはサブ関数を使用しています0ch。つまり、ピクセルごとに描画しています。問題は、画面がかなり速くクリアされ、視覚的な不具合が発生することです。

私は以前にいくつかのゲームをプログラムしましたが、解決策は二重バッファ描画である可能性があります。Assembly x86でこれを実現するにはどうすればよいですか?

編集

私はWindows8X64を使用して、コードDOSBox Portable、tasm、およびtlinkをテストおよび実行しています。

4

2 に答える 2

1

RAMにバッファが必要です(320 * 200 = 64000バイト)。このバッファはセグメントをほぼいっぱいにするので、バッファの開始アドレスが「segment:0x0000」であることを確認するのがおそらく最善です。RAMのこのバッファにピクセル/バイトを設定することで描画します。たとえば、(x、y)のピクセルをカラーcに設定するには、次のようにします。

mov ax,[y]
mov dx,320
mul dx               ;dx:ax = y * 320
mov di,[x]           ;di = x
add di,ax            ;di = y * 320 + x
mov bx,[bufferSeg]   ;bx = segment of video buffer
mov es,bx            ;es:di = address of pixel
mov al,[c]           ;al = colour
mov [es:di],al       ;Store colour in buffer at (x,y)

ご覧のとおり、この計算は面倒で遅いです。そして、あなたはすべての単一のピクセルに対してそれをしたくないでしょう。幸い、個々のピクセルを描画する必要はほとんどありません(通常は線や文字、または「スプライト」を描画します)。通常、最初のピクセルのアドレスを計算し、それに何かを追加して次のピクセルのアドレスを見つけることができます。次のピクセルのアドレスを最初から計算します。たとえば、垂直線を描画する場合、次のピクセルのアドレスは前のピクセルのアドレス+320です。

グラフィックモード0x13の場合。ディスプレイメモリは物理アドレス0x000A0000(または0xA000:0x0000)にあります。すべてを描画した後、バッファから表示メモリにすべてをコピーします。例えば:

mov ds,ax              ;ds = segment for buffer
xor si,si              ;si:si = address for buffer
mov ax,0xA000          ;ax = segment for display memory
mov di,ax              ;di = segment for display memory
mov es,ax              ;es:di = address for display memory
mov cx,320*200/2       ;cx = number of words to copy
cld                    ;Make sure direction flag is clear
rep movsw              ;Copy 320*200/2 words from buffer to display memory
于 2012-11-06T01:51:06.813 に答える
0

mov es、[bufferSeg]は機能します。セグメント/メモリおよびメモリ/セグメントの移動を行うときに、追加のレジスタを使用する必要はありません。

于 2013-03-20T13:13:52.640 に答える