Re: [stella] Displaying scores - how?

Subject: Re: [stella] Displaying scores - how?
From: Greg Troutman <mor@xxxxxxx>
Date: Tue, 11 Mar 1997 08:03:18 -0800
Erik K Mooney wrote:
> 
> Before I spend a week barking up the wrong tree, can someone reveal how
> 2600 games display scores?  (not playfield like Combat, I mean high-res
> like Missile Command, Millipede, Defender, Pac-man, etc.)  I suspect its
> three copies of each player, rewriting GRP0 and GRP1 between display of
> each copy.. am I right?  This would account for the six-digit limit on
> all 2600 games I've seen except Dark Cavern, which had three dummy zeroes
> anyway.

I've been looking at this and yes, triple-copy sprites in both player
graphics registers are rewritten before the duplication of the image
takes place.  Here's a section from Nick's annotated Defender
disassembly, which I've added to:
   
;=======
   
;//
;We've just scanned down toward the bottom of the screen and will set
;up to draw the score.
;//                

       LDA    #$03 	;triple copy sprites
       STA    NUSIZ0
       STA    NUSIZ1	;for both player objects
       LDY    #$06 	;Y=6 which is the height of the graphics (BPL 			
;makes 7)	
       STX    VDELP0    ;X=1 turn on vertical delay for both players
       STX    VDEL01
       STY    $93 	;memory variable to store current scanline 			
;during draw
       STY    WSYNC	;newline, start counting

;//
;I'm not sure about the actual pixel locs here.  The Stella text is
;confusing on this issue and I need to do some more trial and error to
;really get this down.  I'm only noting the real positions without any
;assumption on TIA re-loading cycles.  I'm counting pixel locs from ;the
beginning of WSYNC, including the 68 off the left side of the ;screen. 
Any correction/clarification would be of great help to me ;here...
;//

LF805: DEY		;14
       BPL    LF805	;20
       NOP		;2	;loop totals 36 cycles

       STA    RESP0	;P0 at pixel 108?
       STA    RESP1	;P1 at pixel 117?
       LDA    #$F0 	;shift P0 one posn to the right (109?)
       STA    HMP0	;load the motion register for P0
       STA    WSYNC	;newline
       STA    HMOVE	;reset both players to new horizontal positions

;//
;If the TIA only processes RESP0 every 15 pixels as has been stated,
;then the above numbers would not make sense to me.  P0 would end up at
;121, and P1 would be 120... ???
;//
  
       LDY    #$FE 	;preload new pattern for PF2
       LDA    $E8	;playfield color 
       STA    COLUPF	;load it
       STA    WSYNC	;newline

;//
;Use center 14 bits of playfield (56 pixels) as a backdrop for the
;score)
;//

       STY    PF2	;by placing %11111110 here (in reflect mode)
       LDX    $EC 	;color for the digits
       STX    COLUP0
       STX    COLUP1	;loaded into each player

;//
;Here's the meat and potatoes.
;
;$EF through $FA is a 12 byte RAM area that holds a sequence of 6 16bit 
;pointers to the digit graphics.  This section of memory can be reused
;for other 6 byte (48 pixel) graphics that want to use this routine by
;reloading it with the necessary pointers.  The Y index reads into the
;graphics to get the bits for the current line being drawn.  
;
;You can see this technique in Okie Dokie, where Bob reloads the game
;title and the Retroware logo (and  presumably the score) into a buffer
;that works just like this--though Defender seems to load that buffer
;in reverse order from Okie Dokie.  
;
;The font is at the end of the source listing and you would use it by
;translating the score and loading the appropriate pointer for each
;digit into the buffer at $EF.  I didn't notice where Defender does
;that, but it's in there somewhere  ;)
;//

LF825: LDY    $93     ;                   (61) +3  ;current line
       LDA    ($F9),Y ;   p0  p1          (64) +5  ;indirect indexed
       STA    GRP0    ;   F9              (69) +3  
       STA    WSYNC   ; Cycle count begins
       LDA    ($F7),Y ;                   (0) +5   
       STA    GRP1    ;       F7          (5) +3
       LDA    ($F5),Y ;                   (8) +5
       STA    GRP0    ;   F5              (13) +3
       LDA    ($F3),Y ;                   (16) +5
       STA    $94     ;                   (21) +3
       LDA    ($F1),Y ;                   (24) +5
       TAX            ;                   (29) +2  ;preload X
       LDA    ($EF),Y ;                   (31) +5
       TAY            ;                   (36) +2  ;and Y
       LDA    $94     ;                   (38) +3  ;and A
       STA    GRP1    ;       F3          (41) +3  ;reload GRP at
pixel 						   ;123?
       STX    GRP0    ;   F1              (44) +3
       STY    GRP1    ;       EF          (47) +3  ;reload GRP at
pixel 						   ;141?
       STA    GRP0    ;   F3              (50) +3
       DEC    $93     ;                   (53) +5
       BPL    LF825   ; Branch taken, so  (58) +3
        ; End six-digit loop

;//
;Wow.  The above loop just drew the score with no cycles to spare.
;//
       LDA    #$00 
       STA    VDELP0  ;Clear vertical delays
       STA    VDEL01 
       STA    GRP0    ;Clear players
       STA    GRP1
       STA    HMP0    ;Clear missiles.

;=========

After resetting stuff, it's done.  This code is re-used by lots of games
and is one of those amazing "tricks" that allowed 2600 games to step up
to the next level in appearance...  I'm not exactly sure how it all
works, but it does, and I've managed to twiddle it to work with
different pixel locs, though I'm still trying to break it down into some
kind of formula that has eluded me so far.  It's pretty impressive
stuff, IMO.  What I really like about this routine is that you don't
have to limit yourself to 6 digits.  You could do some bit diddling and
stuff a sort of proportional font into your 48 bit pixel pattern to
print as many as 8-10-12 characters/digits.

> If I'm right, is there any easy way to rip the font used in one of those
> games so I don't have to reinvent the wheel?  (also, using the same
> typeface might lend an air of classic-game credibility to the program.)

This is a nice font that anyone should recognize, so go for it.

--
mor@xxxxxxx
http://www.crl.com/~mor/

--
Archives available at http://www.biglist.com/lists/stella/archives/
E-mail UNSUBSCRIBE in the body to stella-request@xxxxxxxxxxx to be removed.

Current Thread