Re: [stella] Qb/Demo background animation (semi-playable)

Subject: Re: [stella] Qb/Demo background animation (semi-playable)
From: Manuel Polik <manuel.polik@xxxxxxxxxxx>
Date: Tue, 06 Feb 2001 10:35:34 +0100
Andrew Davie wrote:
> Here's my latest version.  Mucho thanks to Eckhard re the sprite
> positioning!
> I've still got the screen wobbles (incorrect # lines), but will fix that
> sometime soon.  Just thought I'd send an update to the list.  I've decided
> to (for the while, anyway) share my fabulous source code ;)   I'm especially
> pleased with the efficient use of the single kernal for most of the screen,
> so have a look at how all that is done. (routine is called MTargetArea)
> You also can get a bit of a feel for what gameplay will be like, in this
> one.
> RAM: $80->$e7, ROM $F000->$Fab7, so I have about 10 bytes of RAM and 1300
> bytes of ROM.
> Comments, anyone?.... the list is very quiet?

Surprisingly quiet, yes.

Ok, I said that I'll look again at your source, but I didn't have the
time during weekend, maybe on wednesday.

But I had some thoughts about RAM usage in QB:

I know that you're very proud about your single line kernel, but let me
suggest at least *thinking* about a lower PF resolution. I'll give you
as an example the PF score routine of 'Outlaw', I recently analyzed. It
can display two different 2-digit numbers, the actual graphical data is
10 Bytes, but the RAM usage is only 2 Bytes(!). There's two blank lines
at the beginning, then every line creates the data for the next line on
the fly. Simple principle. You'd have up to 6 lines for calculations.

So, here's the routine, hopefully commented enough:
(the whole Outlaw source will follow later, if I may post it :-))

; Draw 12 lines displaying scores
; First 2 lines are blank, each line calculates next line on the fly
; (tempVar03 & tempVar04 are initialized with '0')

                    LDX #$06            ; six lines to draw
DrawScores:         STA WSYNC           ; Finsih current line
                    LDA tempVar03       ; A-> starting score 1 value
                    STA PF1             ; store in PF1
                    LDY ScoreshapeHi01  ; Y-> score hi offset 1
                    LDA scoreshapedata,Y; A-> score shape data
                    AND #$F0            ; mask higher nibble
                    STA tempVar03       ; store temporary
                    LDY ScoreshapeLow01 ; Y-> score low offset 1
                    LDA scoreshapedata,Y; A-> score shape data
                    AND #$0F            ; mask lower nibble
                    ORA tempVar03       ; OR in stored higher nibble
                    STA tempVar03       ; store score 1 temporary
                    LDA tempVar04       ; A-> starting score 2 value
                    STA PF1             ; store in PF1
                    LDY ScoreshapeHi02  ; Y-> score hi offset 2
                    LDA scoreshapedata,Y; A-> score shape data
                    AND #$F0            ; mask higher nibble
                    STA tempVar04       ; store temporary
                    LDY ScoreshapeLow02 ; Y-> score low offset 2
                    LDA scoreshapedata,Y; A-> score shape data
                    AND $97             ; mask lower nibble
                    STA WSYNC           ; Finish current line
                    ORA tempVar04       ; OR in stored higher nibble
                    STA tempVar04       ; store score 2 temporary
                    LDA tempVar03       ; write score 1 again for 
                    STA PF1             ; second line
                    DEX                 ; next score line?
                    BEQ QuitScoreLoop   ; N: Quit score loop
                    INC ScoreshapeLow01 ; adjust all four...
                    INC ScoreshapeHi01  ;
                    INC ScoreshapeLow02 ;
                    INC ScoreshapeHi02  ; ...score offsets
                    LDA tempVar04       ; write score 2 again for
                    STA PF1             ; second line
                    JMP DrawScores      ; draw next score line

I hope this gives you at least the idea. For example I could imagine
that you precalculate 2 PF bytes during the overscan and do one on the
fly. If you could do it all on the fly, you might free lots of bytes. 
I haven't yet too deeply analyzed _how_ you calculate the PF, but _you_
know what's possible :-) With just X/Y values of all blocks you might be
able to render it completely during drawing. (Ok,ok, it might be very
complicated, since you've to do the sprites, too)

Then I'd another thought, I won't tell you know, let me ask something
You have this situation:

|   |
| B2|-->
|   |
| B1|

In your demo the blocks B1 & B2 would overlap. How did you prevent this
in the Atari 800 version? Are there any movement restrictions in the
gameplay? If yes, which?

And yet another thought: You simply could do only 3*3 blocks instead of
4*4, then you'd have only 15 bits horizontal resolution and you'd just
need to calculate 2 PF values for 15 lines -> 30 bytes for the whole
action field.

And one final thought: Maybe it'd work to just do a grid and the target
with the PF. Let players ride on missiles or vice-versa :-)

Ok, all RAM thoughts done. You might not need 'em, they're just in case

Comments on the source code follow,

Archives (includes files) at
Unsub & more at

Current Thread