Files
rabbitc64/play.asm
T
2026-07-15 21:31:51 +02:00

292 lines
5.6 KiB
NASM

; -----------------------------------------------------------
; play.asm - the game: lane movement with key-repeat, rabbit
; spawning with a score-driven interval, arrivals scored or
; counted as a miss, HUD updates
; -----------------------------------------------------------
; ---- start (or restart) a round ----
play_init:
jsr clear_screen
jsr draw_road
; HUD: score on the left, miss slots on the right
+prtext 0, 1, BLACK, txt_score, 5
+prtext 0, 30, BLACK, txt_miss, 4
lda #0
sta score8
sta sc_d0
sta sc_d1
sta sc_d2
sta miss
sta flash
sta spawnt
sta lcnt
sta rcnt
jsr draw_score
lda #0 ; draw_score leaves a digit code in A
ldx #NRABBITS-1
pi_clr:
sta r_act,x
dex
bpl pi_clr
lda #2 ; start in the middle lane
sta player_lane
; player sprite: scooter, fixed row, rabbits come per frame
lda #SPRP_SCOOT
sta SPRPTR
lda #PLAYER_SY
sta SPRPOS+1
lda #1
sta SPR_EN
lda #0
sta SPR_XEX
sta SPR_YEX
+setupd play_update
rts
; ---- one frame of gameplay ----
play_update:
jsr read_joy
; -- left: move on press, then auto-repeat while held --
lda joyb
and #JOY_LEFT
beq pu_lrel
inc lcnt
lda lcnt
cmp #1
beq pu_lmove
cmp #REP_HOLD+REP_PERIOD
bne pu_lend
lda #REP_HOLD
sta lcnt
pu_lmove:
lda player_lane
beq pu_lend
dec player_lane
jmp pu_lend
pu_lrel:
lda #0
sta lcnt
pu_lend:
; -- right, same dance --
lda joyb
and #JOY_RIGHT
beq pu_rrel
inc rcnt
lda rcnt
cmp #1
beq pu_rmove
cmp #REP_HOLD+REP_PERIOD
bne pu_rend
lda #REP_HOLD
sta rcnt
pu_rmove:
lda player_lane
cmp #LANES-1
beq pu_rend
inc player_lane
jmp pu_rend
pu_rrel:
lda #0
sta rcnt
pu_rend:
; -- shadow init: player sprite bit + its x MSB --
ldx player_lane
lda pxlo,x
sta SPRPOS ; sprite 0 x
lda pxhi,x
sta msb_sh ; lane 4 sits past x=255
lda #0
sta xex_sh
sta yex_sh
lda #1
sta en_sh
; -- a hit blinks the scooter for a dozen frames --
lda flash
beq pu_noflash
dec flash
lda framectr
and #4
bne pu_noflash
lda #0
sta en_sh
pu_noflash:
; -- spawn: interval = 70 - score/2, floor 22 (as the original) --
inc spawnt
lda score8
cmp #96
bcc pu_ivcalc
lda #22
jmp pu_ivgot
pu_ivcalc:
lsr
sta rtmp
lda #70
sec
sbc rtmp
pu_ivgot:
cmp spawnt
bcs pu_nospawn
lda #0
sta spawnt
jsr spawn_rabbit
pu_nospawn:
; -- advance every live rabbit --
ldx #NRABBITS-1
pu_rab:
lda r_act,x
beq pu_rnext
lda r_tlo,x ; t += speed (8.8 fixed point)
clc
adc r_splo,x
sta r_tlo,x
lda r_thi,x
adc r_sphi,x
sta r_thi,x
bcc pu_ralive
; arrived at the player line
lda #0
sta r_act,x
lda r_lane,x
cmp player_lane
beq pu_rhit
jsr add_score ; dodged: one point
jmp pu_rnext
pu_rhit:
jsr add_miss ; ran into you
jmp pu_rnext
pu_ralive:
jsr rab_pos
pu_rnext:
dex
bpl pu_rab
jsr write_shadows
; -- third miss ends the round --
lda miss
cmp #MAX_MISS
bcc pu_done
jmp over_init ; its rts returns to the main loop
pu_done:
rts
; ---- claim a free rabbit slot and roll its lane + speed ----
spawn_rabbit:
ldx #NRABBITS-1
sr_find:
lda r_act,x
beq sr_got
dex
bpl sr_find
rts ; every slot busy: skip this spawn
sr_got:
lda #1
sta r_act,x
jsr rand5
sta r_lane,x
lda #0
sta r_tlo,x
sta r_thi,x
; speed = $0260 base + random byte + score ramp (tops out at 64)
jsr rand8
clc
adc #$60
sta rtmp
lda #2
adc #0
sta rtmp2
lda score8
cmp #64
bcc sr_ramp
lda #64
sr_ramp:
tay
lda rtmp
clc
adc sptab_lo,y
sta r_splo,x
lda rtmp2
adc sptab_hi,y
sta r_sphi,x
rts
; ---- score: bump the decimal digits and the difficulty byte ----
add_score:
lda score8
cmp #$ff
beq as_digits
inc score8
as_digits:
inc sc_d2
lda sc_d2
cmp #10
bne draw_score
lda #0
sta sc_d2
inc sc_d1
lda sc_d1
cmp #10
bne draw_score
lda #0
sta sc_d1
inc sc_d0
lda sc_d0
cmp #10
bne draw_score
lda #0
sta sc_d0
; falls through: repaint the three HUD digits
draw_score:
lda sc_d0
ora #48 ; digit screen codes start at 48
sta SCREEN+7
lda sc_d1
ora #48
sta SCREEN+8
lda sc_d2
ora #48
sta SCREEN+9
rts
; ---- miss: X mark on the HUD + blink the scooter ----
add_miss:
inc miss
ldy miss ; Y: the rabbit loop still needs X
lda #24 ; 'x'
sta SCREEN+34,y ; marks land on columns 35-37
lda #12
sta flash
rts
; ---- gameplay variables ----
player_lane: !byte 2
score8: !byte 0 ; score capped at 255, drives the difficulty
sc_d0: !byte 0 ; score digits: hundreds, tens, ones
sc_d1: !byte 0
sc_d2: !byte 0
miss: !byte 0
flash: !byte 0 ; frames left of the post-hit blink
spawnt: !byte 0 ; frames since the last spawn
lcnt: !byte 0 ; held-direction counters for the auto-repeat
rcnt: !byte 0
; ---- rabbit slots (hardware sprites 1-7) ----
r_act: !fill NRABBITS, 0
r_lane: !fill NRABBITS, 0
r_tlo: !fill NRABBITS, 0 ; distance along the lane, 8.8 fixed point
r_thi: !fill NRABBITS, 0
r_splo: !fill NRABBITS, 0 ; per-rabbit speed, 8.8 fixed point
r_sphi: !fill NRABBITS, 0