Breakout

TUTORIAL · BREAKOUT · UNDER THE HOOD CBETA

C · The bat blit

A ROM call costs about 1.7 cs before it draws anything. For one small, fixed shape that moves every frame, four direct stores into screen memory are cheaper.

500 DEF PROCbatclear(x%)                         :REM rub out the 16x4 bat at x% by direct stores
    :bt%=&6E82+2*x%                              :REM screen byte for row 202 at x%: &3000 + 25*640 +
    REM 2 (row 202 is line 2 of character row 25), plus 8 bytes per 4 pixels
    :FOR q%=0 TO 3                               :REM four 4-pixel columns make 16 pixels
    :!bt%=0                                      :REM one 4-byte store clears rows 202-205 of a column
    :bt%=bt%+8:NEXT:ENDPROC                      :REM next column is 8 bytes along
510 DEF PROCbatdraw(x%)                          :REM the same, drawing instead of clearing
    :bt%=&6E82+2*x%
    :FOR q%=0 TO 3
    :!bt%=&FF0F0FFF                              :REM lowest byte first: &FF white for row 202, &0F red
    REM for rows 203 and 204, &FF white for row 205
    :bt%=bt%+8:NEXT:ENDPROC
155 IF cc%<>p% PROCbatclear(cc%)                 :REM same for the bat, by direct screen stores
180 IF cc%<>p%                                   :REM redraw the bat if it moved...
     OR (bb%<=205 AND bb%+7>=202                 :REM ...or if the ball's eraser (line 150)
     AND aa%<=p%+15 AND aa%+7>=p%) PROCbatdraw(p%)   :REM overlapped the bat's rows 202-205

Where the bytes are

A MODE 1 screen is made of character rows of 8 scanlines. Each byte holds 4 pixels, and the bytes for one 4-pixel column of a character row are 8 consecutive addresses. For a pixel (X, Y) with X a multiple of 4:

address = &3000 + (Y DIV 8)*640 + (Y MOD 8) + (X DIV 4)*8

The bat is on scanlines 202–205. 202 DIV 8 is 25 and 202 MOD 8 is 2, so the first byte is &3000+25*640+2 = &6E82, and each step of 4 pixels adds 8 bytes, which is 2*X. Scanlines 202–205 are the 3rd to 6th lines of the same character row, so they are four consecutive bytes.

Four rows in one store

BBC BASIC's ! writes four bytes at once, lowest byte first. !bt%=&FF0F0FFF writes &FF (four white pixels) to scanline 202, &0F (four red pixels) to 203 and 204, and &FF to 205. One statement fills one 4×4 block, and a 16-pixel bat is four of them. The stores land on the page being drawn because the dirty begin has already mapped that page into &3000–&7FFF.

The cost of bypassing the ROM

Try it: make the bat yellow and white with &FFF0F0FF. Make it 24 pixels wide (six stores), and widen the bat test on line 350 to match.

← Repainting only what moved Measuring the frame →