Using the same basic code layout as Joust was a great starting point, and made it easy to the game 99% of the way there. The problem, though, was time. Most of the time during gameplay, it worked great. But under a few worst-case conditions, I ran out of processing time, and the screen would roll. It didn't help that there were really 8 objects that had to be dealt with every frame -- 4 tanks and 4 bullets. (as opposed to just the 4 birds from joust) Reading over the code a few times, there wasn't anything grossly inefficient.
Which meant it was time for optimizing.
Because I wrote this all in batari basic to save programmer time, I wasn't sure how efficient the compiled assembly was. Step one was to just read through the assembly that bB generates. Which turned out to be not too bad. Very little that was egregious. But a lot of places where I could do a tiny bit better by hand.
So I tonight I ended up rewriting about half the game into assembly. Having the compiled basic code to work off of made it pretty fast, but it was easy to find places where it was being dumb. For example, I had code like:
temp1 = player0x + 4
temp1 = temp1 / 4
which naively got transformed into:
lda player0x ;3
clc ;2
adc #4 ;2
sta temp1 ;3
lda temp1 ;3
lsr ;2
lsr ;2
sta temp1 ;3
;total: 20 clock cycles
Not terrible, but a bit wasteful. Knowing the state of the carry flag going in, I was able to rewrite it
lda player0x ;3
adc #4 ;2
lsr ;2
lsr ;2
sta temp1 ;3
;total: 12 clock cycles
8 clock cycles isn't much, but doing this sort of thing in a handful of places throughout the game ended up making it work!
Now it's time to test some more....
Don't look too closely, turns out I'm REALLY bad at making holes in plastic boxes. |