Hit the bricks!
This is an extension of my brick-buster kernel demo, with some collision-detection code added. As you move your player left and right, the program will highlight the bricks you're over on rows 1, 3, and 5. The collision-detect code is presently a bit too slow to be practical (though it does manage to run three times in vblank, which would be barely enough to allow for three balls bouncing, the timing is really very tight). The technique is nonetheless interesting and may be useful elsewhere.Each row of bricks is stored as two variable-length sections of code, starting $39 bytes apart. The code consists of some initialization, then a mixture of the following instructions:
$7A nop$84 sty COLUPF$85 sta COLUPF$86 stx COLUPF$87 sax COLUPF$8C sty.w COLUPF$8D sta.w COLUPF$8E stx.w COLUPF$8F sax.w COLUPF
Note that every opcode is >= $7A, all of the operands $08 or less, and the number of cycles for each instruction is equal to the number of bytes plus one.The most interesting loop of my brick-finder routine looks like this; the accumulator must hold $3F + the number of cycles corresponding to the ball's position.
ldy #1BrickFindLp: cmp (hitptr),y iny sbc #1 ; Subtract 1 or 2 cmp #$40 bcs BrickFindLp
It's unfortunate that I have to waste two cycles on the CMP, but I can't figure any way to make the loop end someplace "nicer" since the accumulator has to be kept between $08 and $7A. If the sense of carry on the compare were reversed, I could have the loop count up to $80, but that doesn't work here--the loop has to count down.Anyway, after the loop finds what instruction the CPU will be executing when it reaches the proper position, it then searches backward to find the last "store" opcode. Here, the use of $7A as a NOP comes in handy, since all the stores are >= $84 while the NOPs and operands aren't.Although this loop iterates rather quickly, it has to run an iteration for every operand byte in addition to the opcode bytes. The worst case is running 36 iterations (to parse through to the end of twelve st?.w instructions). Next rev I'll rewrite the code to parse based upon opcodes which ends up with a worst-case time about 100 cycles faster.Update 060205Changed colors some. Should be less flicker, but some of the colors are no longer as distinct.There are now three bouncing balls. One of them has a "comb" surrounding it to demonstrate that the 1lk is free of tearing. The bouncing balls highlight bricks. Note that when all three balls are in the top half of the screen near the right hand side the vertical timing will slip slightly because this version still uses the slow collision detect.The planned fix is to use a faster collision detect which won't identify the code spot to be patched but will determine if there's a collision. I'll then queue up collisions so the appropriate blocks can be erased (limit one erasure per frame). Note that blocks will be removed from the small bitmap immediately even if their erasure is delayed a frame or two, so the delay shouldn't affect gameplay.The score is maybe a tease; it would be nice to make score digits look like that, but the 200+ bytes it would require could probably be better spent on other things.Update 060206Changed colors. See note below.

5 Comments
Recommended Comments