;score eater, a jumpman level ;by Kevin Savetz, October 26-27 2016 *=$2900 vbi1 ;VBI1 handles enemy movement dec counter ;counts down $05-$00 lda counter beq ?moveem ;enemies move every 6 cycles. otherwise, they're too fast. jmp $311b ?moveem lda #$05 sta counter LDA pminit ;Check Are Players Initialzied? byte BEQ initplayers ;Nope: go setup LDX #$02 ;poor derpy Player 3 only moves at 1/2 the speed of Player 2. INC counter2 LDA counter2 AND #$01 BEQ ?nextx LDX #$03 ;1/2 the time skip player 2, start with player 3 ?nextx INX ;FOR X=3 (or 4) TO 4 CPX #$05 BEQ done ;after loop ;first, change animation frame of the enemy lda counter2 ;00-ff and #%1111 ;limit 0-15 lsr ;now its 0-7 clc adc #$01 ;now its 1-8. There are 8 animation frames STA $3073,x ;set image to that frame ;next, move enemy toward Jumpman. Let's do Y first. LDA $306e,x ;enemy Y sec sbc $306f ;subtract Jumpman Y bpl ?up ;if positive, enemy moves up lda #$01 ;down sta temp jmp ?changey ?up lda #$ff ;up sta temp ?changey clc LDA $306e,x ;get enemy current Y ADC temp ;change it STA $306e,x ;store new Y ;next, move enemy X towards Jumpman LDA $3069,x ;enemy X sec sbc $306a ;subtract Jumpman X bpl ?left lda #$01 ;if positive, enemy moves right sta temp jmp ?changex ?left lda #$ff sta temp ?changex clc LDA $3069,x ;enemy X ADC temp STA $3069,x ;Save Player X JMP ?nextx ;NEXT X done JMP $311b initplayers ;set up Players. This only happens once LDX #$02 STX pminit ;Set Are Players Initialized flag ;there's no significance to the 2 for the flag, except that ;we need X = 2 for the next thing. ?initnextx INX ;FOR X=3 TO 4 — using Players 3 and 4 for enemies. Things are ;a little more complicated if you're using the Combined Missile ;Player for an extra enemy, but for this level Missiles are plain ol' ;bullets CPX #$05 BEQ ?initdone ;Exit after Loop LDA #pmart STA $305f,x ;Player image data set HB LDA #$08 STA $3064,x ;there are 8 bytes per image STA $3082,x ;stuff anything other than the startup image (01) as the "old" image LDA #$01 STA $3073,x ;Start with Image 1 STA $3055,x ;Activate Player JMP ?initnextx ;loop around to set up the other Player ?initdone LDA #$26 STA $3071 ;Y position of Player 2 LDA #$A9 STA $306c ;X position of Player 2 LDA #$60 STA $3072 ;Y position of Player 3 LDA #$35 STA $306d ;X position of Player 3 JMP $311b ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vbi4 ;VBI4 does hit detection ;this replaces the typical Jumpman enemy/bullet hit detection ;Overriding the default because unlike most levels, touching the enemy ;doesn't kill Jumpman LDA $30be ;If JM is dead, exit. There are two ways to check for JM death. CMP #$08 ;They differ slightly. This exits if he's not onscreen. BCS ?exit LDA $30bd ;and this exits he he's Dead at Bottom With Birdies CMP #$02 BNE ?checkbullets ?exit JMP $311b ?checkbullets ;if any of the 4 missiles have touched Jumpman... lda $3098 ora $3099 ora $309a ora $309b and #$01 beq ?wubwub STA $30bd ;...kill Jumpman ?wubwub ;make the background noise inc counter3 ;counter3 just counts $0-$ff every VBI lda counter3 and #$0f ;every 16 cycles, play a wub sound bne ?checktouch LDA #wubwubsound STA $3041 LDA #$ea ;note length JSR $32b0 ;run sound player routine ?checktouch ;is Jumpman touching an enemy (P2 or P3)? lda $309c ;copy of $d00c — use this, not $d00c and #$0c ;mask for P2/P3 beq ?nottouching ;yes. Does he have any points? LDA $30F5 ORA $30F6 ORA $30F7 BEQ ?nopointssound ;yes. remove one point. LDA $30F5 SEC SBC #$01 STA $30F5 LDA $30F6 SBC #$00 STA $30F6 LDA $30F7 SBC #$00 STA $30F7 JSR $46E9 ;force score display to update ;if eating score, cycle the enemys' color LDA counter2 AND #$07 CLC ADC #$86 STA $2c2 STA $2c3 ;and make the eating noise LDA #eatingsound STA $3041 LDA #$ea JSR $32b0 JMP ?done ?nopointssound ;touching enemy but no points, play hungry sound LDA #hungrysound STA $3041 LDA #$ea JSR $32b0 ?nottouching ;enemy is not touching Jumpman, or it is but Jumpman has no points, so ;set enemy colors back to default lda #$1e sta $02c2 ;P2 color lda #$1b sta $02c3 ;P3 color ?done JMP $311b ;;;;;;;;;;;;;;;;;;;;;;;; pmart ;graphics for enemy players, borrowed from Glover's Freeze level .BYTE $00,$00,$24,$18,$18,$24,$00,$00 .BYTE $00,$42,$24,$18,$18,$24,$42,$00 .BYTE $04,$42,$a4,$18,$18,$25,$42,$20 .BYTE $0c,$42,$a4,$98,$19,$25,$42,$30 .BYTE $0c,$52,$a4,$9a,$59,$25,$4a,$30 .BYTE $0c,$42,$a4,$98,$19,$25,$42,$30 .BYTE $04,$42,$a4,$18,$18,$25,$42,$20 .BYTE $00,$42,$24,$18,$18,$24,$42,$00 wubwubsound ;I borrowed this sound from Freeze too .BYTE $01,$a2,$f0,$01,$01,$a4,$dc,$01,$01,$a6 .BYTE $c8,$02,$01,$a4,$f0,$01,$01,$a2,$f0,$01,$00 hungrysound .BYTE $01 ; sound data .BYTE $e6 ; .BYTE $79 ; note .BYTE $01 ; sound priority (1=low, 4=high) .BYTE $00 ; end of sound eatingsound .BYTE $01 ; sound data .BYTE $e6 ; .BYTE $a9 ; note .BYTE $01 ; sound priority (1=low, 4=high) .BYTE $00 ; end of sound temp .BYTE $00 ; temporary storage pminit .BYTE $00 ; are Players initialized? 0=no counter .BYTE $02 counter2 .BYTE $00 counter3 .BYTE $00