Speeding bullets

Let's take a break from coding. Put this in ASHMUPD.

PROGRAM:ASHMUPD
:..DATA
:[18183C7E66FF9981]→GDB0
:[C0C0C0C000000000]→Pic0

That's the sprite for the bullet, of course (2×4).

All right, break's over. Back to the code!

PROGRAM:ASHMUPM
:..MOVEMENT
:If B
:For(I,1,B)
:If {{I*4+L4-1→J}-{J-2}→{J}}>64
:sub(RSB,I-1→I)
:End :End

That goes in a new program called ASHMUPM (you can check in the main program to see where it'll be used).

It might look confusing at first, but that's only because it's optimized. [Insert self-congratulatory remarks here.] First of all, the For( loop goes from 1 to L, not 0 to L-1, unlike most indices, which start at zero. This is because since I is checked against the maximum value (either L or L-1) every pass of the loop, there's a speed optimization in using L. We'll be taking care of that extra 1 in the actual code.

The next line is a gigantic if statement that already moves the bullet. It looks complicated, but just look at the inside first: {I*4+L4-1→J}. It takes I (the current index being parsed), multiplies it by four (the number of bytes per element), and adds L4−1. Why L4−1? If you just add L4, you get the next element's first byte (since we're starting the loop at 1), so if you subtract one from that, it would be the current element's Y-value. The pointer to that is stored to J for later reference.

Then the {J−2} is subtracted. Since J points to the current Y-value, two bytes before it would be the speed of the bullet. And since our bullets go upwards, we subtract. All of this gets stored back to {J}.

Now here's the (über1337) optimization: Since the store statement is storing to a non-constant pointer (thanks to the J), it returns the pointer stored to, which you can use for further operations. In this case we wrap the whole thing with braces to get the value again and test if it's greater than 127 (because if its signed value is less than zero, its unsigned value is greater than 127; we actually save a few bytes by not having to use sign{). If it did, we call Lbl RSB, which we'll set up next.

+ Tweet