[stella] Player Animation Basics Take 1

Subject: [stella] Player Animation Basics Take 1
From: Ruffin Bailey <rufbo1@xxxxxxxxxxx>
Date: Sun, 14 Jul 2002 23:59:12 -0400
Welp, finally got some time to hack up a little animation for player0. It's just four frames right now, and I don't know that the graphics are like I like them (looks a little like the guy has the palsy when he moves), but the concept appears to be sound and I thought I'd run it by the list. If you have comments or if it's useful for the newbie FAQ, shoot away!

Basically I tried to keep the graphics down to 16 scans (single scan resolution) so that it'd be easy to change frames. Add 16 decimal ($10) to the least significant byte of the address of the first frame of your graphic to get to the second, $20 to get to the third, etc. This method craps out after fifteen frames, of course, without capturing the carry flag and messing with the most significant byte, etc. But who wants more than fifteen frames (I think the sixteenth would start dealing with page boundaries -- it's late)?

I used a little neat trick with AND and EOR (for someone of my vast Stella programming experience it's neat, anyhow!) with SWCHA to figure out if I needed to change frames so that the guy doesn't run in place like 2600 Pac-Man. I also used some fancy AND'ing to make sure the frames were increased every 8/60th (?? - every 8th frame written to the NTSC screen) of a second. I had every the animation on every 1/60th at first and, well, it gave me a good laugh. Poor guy'd been hit by lightning or something.

Here's all the code you'd need to add to get this to work. Stick it in your main kernel, and assign one byte to the variable p0FrameCount (though I'm only using 3 bits so Thomas will probably shoot me for sacrilege):
; let's see if we need to increase the frame counters
; by checking SWCHA. If D7-4 have a zero anywhere, player0
; has moved.
and #%11110000 ; get rid of D3-0 for now -- we're just checking P0 now
eor #%11110000 ; swap 1s for 0s
beq dontIncreaseFrame ; if all 0's, skip frame increase

; if all we've got are 0's after anding and checking SWCHA, p0 is about
; to move, and will need its framecount increased
lda p0FrameCount
adc #%00001000 ; ... increase the frame count "by one frame" (16 dec, $10)
and #%00111000 ; but don't let it get over "three frames" (48 dec, $30)
sta p0FrameCount ; put back into p0FrameCount

and #%00110000
adc #$08 ; #$08 is the least significant byte for the address of
; player0's first frame of animation
sta grp0lsb ; store in least significant byte of the address for player0's graphics


In this case, the lsb of the first frame of p0's animation is $08. If yours is different, that line would change. Again, p0 needs to be 15 scans tall (assuming one scan of #%00000000 in the 16th to "zero him out" down the screen after he's painted & single scan resolution) or less and you can have only eight frames of animation or less.

Phew, enough ramble. So anyhow I feel sufficiently happy with the way that I did that that I'm betting there's a better way. Go ahead and bring me off of my high. :^) The attached demo shows the code in context. P0 is moved by the first joystick, missile0 by the first joystick when the button's pressed. P1 is, um, in "debug mode" and isn't completely hooked up yet. More fun to play with graphics.

Had to split the screen draw logic into three parts to check for p0 & p1 & one other item each scan line (can optimize that since they move up and down 2 lines at a time). I check for m0 in part 1, m1 in part 2, and nothing (later the PF) in 3. This means the missile changes height sometimes by one scan as things stand. Also haven't bothered with timing yet, so make sure the little dude runs in the right-hand side of the screen.


Ruffin Bailey

Attachment: withAnimation.asm
Description: Binary data

Current Thread