RE: [stella] Ms. Pac Man, Mr. Do, striped playfields, and one-line kernels

Subject: RE: [stella] Ms. Pac Man, Mr. Do, striped playfields, and one-line kernels
From: "Lee Fastenau" <stella@xxxxxxxxxxxxxxx>
Date: Tue, 31 Aug 2004 22:25:52 -0500
> That helped. It may even be sufficient... sort of. But now I've noticed
> something else that has me wanting to know how it's done: both Mr. Do and
> Ms. Pac Man have single-pixel vertical resolution to their sprites!
>
> How the heck did they fit that in? You can't change both GRP0 and GRP1
> to the appropriate rows of two arbitrarily positioned and distinct
> sprites between WSYNC and the end of horizontal retrace. No way.
> Uh-uh. You just... can't.
>
> ... Or can you? And how?

I was doing it in my Reflex game to achieve a detailed ball sprite using two
sprites (ball and highlight) over a non-reflected and non-striped playfield,
but I've since removed that code as it was quite memory hungry.

I was able to get around using skipdraw by page-aligning my sprites and
padding the top (remember, it's stored upside down) with zeroes to fill up
the page.  Each sprite took 256 bytes, but gave me enough cycles to draw my
non-reflected playfield and even change colors... twice.

This is what my ball shape data looked like:
ballShape0   dc.b %00000000            ; Ball highlight
             dc.b %00000000
             dc.b %00010000
             dc.b %00011000
             dc.b %00001000
             dc.b %00000000
             ds.b 250                  ; This space reserved for ball
"negative space"
ballShape1   dc.b %00001000            ; Ball
             dc.b %00010100
             dc.b %00001000
             dc.b %00000100
             dc.b %00010100
             dc.b %00001000
             ds.b 250                  ; This space reserved for ball
"negative space"


And here's a section of my old kernel:
                            ;      -2
        lda ballShape0,x    ;+4    2
        sta GRP0            ;+3    5
        lda ballShape1,x    ;+4    9
        sta GRP1            ;+3    12
        lda block1l,y       ;+4    16
        sta PF1             ;+3    *19*    Update left half of playfield
        lda block2l,y       ;+4    23
        sta PF2             ;+3    26
        lda (tryX),y        ;+5    31
        sta COLUPF          ;+3    *34*    Set board color
        lda block2r,y       ;+4    38
        sleep 7             ;+7    45
        sta PF2             ;+3    *48*    Update right half of playfield
        lda block1r,y       ;+4    52
        sta PF1             ;+3    55
        lda pcol            ;+3    58
        sleep 3             ;+3    61
        sta COLUPF          ;+3    *64*    Set paddle color
        dex                 ;+2    66
        dec lineCount       ;+5    71
        bne .loop2          ;+3/2  *74*/73


At first glance, it doesn't look like there's room to change the sprite row
index (X) for each sprite, but there are a few things that are happening
here that you may not need.  First, note that the write to PF1 for the left
half of the playfield can really happen as late as cycle 25 instead of 19.
I had to get that write done early in order to prepare for a color change
precisely at cycle 34.  Without the playfield color change, that would free
up 6 cycles before the first write to PF1... just enough to load a different
index for each sprite (two LDX's at 3 cycles apiece).

My kernel doesn't use PF0, but neither does the one in Mr. Do.  The reason
for the 8K ROMs may have something to do with the use of page-size sprites,
but I haven't looked at any of the code.

Hope this helped!

-Lee




Current Thread