multiplayer support
This commit is contained in:
@@ -10,12 +10,18 @@ that passes in any other lane is a **point**. Three misses end the round.
|
||||
The spawn rate and the rabbits' speed ramp up with your score, just like
|
||||
in the original.
|
||||
|
||||
In **multiplayer** the rabbits still spawn on their own, but player 2
|
||||
steers the closest one left and right, trying to run the scooter down.
|
||||
|
||||
## Controls
|
||||
|
||||
| Input | Action |
|
||||
|-------|--------|
|
||||
| Joystick port 2 left/right, or `A` / `D` | change lane (auto-repeats while held) |
|
||||
| Fire (or `SPACE`) | start / retry |
|
||||
| Menu: joystick up/down, or the `S` / `M` keys | pick single player / multiplayer |
|
||||
| Menu: fire (or `SPACE`); the `1` / `2` keys pick and start at once | start the picked mode |
|
||||
| P1: joystick port 2 left/right, or `A` / `D` | move the scooter (auto-repeats while held) |
|
||||
| P2: joystick port 1 left/right, or `J` / `L` | steer the closest rabbit (multiplayer) |
|
||||
| Fire (or `SPACE`) | start; on the game over screen: back to the menu |
|
||||
|
||||
## How it works
|
||||
|
||||
|
||||
+48
-5
@@ -206,11 +206,49 @@ rj_noright:
|
||||
lda joyb
|
||||
rts
|
||||
|
||||
; fire or space held? returns A != 0 when pressed
|
||||
; read joystick port 1 merged with the j/l keys (player 2),
|
||||
; return active-high bits in A and joyb2
|
||||
read_joy2:
|
||||
lda #$ff ; no column selected: port B = joystick 1
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
eor #$ff
|
||||
and #$1f
|
||||
sta joyb2
|
||||
and #$0f ; a held direction grounds the same port B
|
||||
bne rj2_done ; lines the key rows use: skip the scan
|
||||
lda #$ef ; 'j' = left: keyboard column 4, row bit 2
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
and #$04
|
||||
bne rj2_noleft
|
||||
lda joyb2
|
||||
ora #JOY_LEFT
|
||||
sta joyb2
|
||||
rj2_noleft:
|
||||
lda #$df ; 'l' = right: keyboard column 5, row bit 2
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
and #$04
|
||||
bne rj2_done
|
||||
lda joyb2
|
||||
ora #JOY_RIGHT
|
||||
sta joyb2
|
||||
rj2_done:
|
||||
lda joyb2
|
||||
rts
|
||||
|
||||
; fire on either stick or space held? returns A != 0 when pressed
|
||||
start_pressed:
|
||||
jsr read_joy
|
||||
and #JOY_FIRE
|
||||
bne sp_done
|
||||
lda #$ff ; deselect the columns: port B = joystick 1
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
eor #$ff
|
||||
and #JOY_FIRE
|
||||
bne sp_done
|
||||
lda #$7f ; space: keyboard column 7, row bit 4
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
@@ -546,12 +584,14 @@ txt_score: !scr "score"
|
||||
txt_miss: !scr "miss"
|
||||
txt_rabbit: !scr "rabbit"
|
||||
txt_scooter: !scr "scooter"
|
||||
txt_press: !scr "fire = start game"
|
||||
txt_info: !scr "joystick 2 or a/d moves"
|
||||
txt_1p: !scr "single player"
|
||||
txt_2p: !scr "multiplayer"
|
||||
txt_info: !scr "p1: joystick 2 or a/d"
|
||||
txt_info2: !scr "p2: joystick 1 or j/l"
|
||||
txt_ttgname: !scr "teletype games"
|
||||
txt_presents:!scr "presents"
|
||||
txt_over: !scr "game over"
|
||||
txt_retry: !scr "fire = retry"
|
||||
txt_return: !scr "fire = return"
|
||||
txt_blank: !fill 19, $20
|
||||
|
||||
washtbl: ; gold glow ramp (16 entries, cyclic)
|
||||
@@ -565,7 +605,10 @@ bg_top: !byte COL_SKY ; background color above / below the
|
||||
bg_bot: !byte COL_GRASS ; horizon raster split
|
||||
seed: !byte $a7 ; rand8 LFSR state
|
||||
fheld: !byte 0 ; fire/space edge detection state
|
||||
joyb: !byte 0 ; joystick bits from read_joy (active high)
|
||||
joyb: !byte 0 ; player 1 input bits from read_joy
|
||||
joyb2: !byte 0 ; player 2 input bits from read_joy2
|
||||
mp_mode: !byte 0 ; 0 = single player, 1 = multiplayer
|
||||
k12held: !byte 0 ; menu '1'/'2' key edge detection state
|
||||
en_sh: !byte 0 ; per-frame sprite register shadows
|
||||
msb_sh: !byte 0
|
||||
xex_sh: !byte 0
|
||||
|
||||
@@ -32,17 +32,17 @@ over_init:
|
||||
rts
|
||||
|
||||
over_update:
|
||||
; blink the retry prompt
|
||||
; blink the return prompt
|
||||
lda framectr
|
||||
and #32
|
||||
bne ou_hide
|
||||
+prtext 16, 14, YELLOW, txt_retry, 12
|
||||
+prtext 16, 13, YELLOW, txt_return, 13
|
||||
jmp ou_start
|
||||
ou_hide:
|
||||
+prtext 16, 14, YELLOW, txt_blank, 12
|
||||
+prtext 16, 13, YELLOW, txt_blank, 13
|
||||
ou_start:
|
||||
jsr start_edge
|
||||
beq ou_done
|
||||
jmp play_init ; its rts returns to the main loop
|
||||
jmp title_init ; back to the menu, mode can be re-picked
|
||||
ou_done:
|
||||
rts
|
||||
|
||||
@@ -27,6 +27,8 @@ play_init:
|
||||
sta spawnt
|
||||
sta lcnt
|
||||
sta rcnt
|
||||
sta p2lcnt
|
||||
sta p2rcnt
|
||||
jsr draw_score
|
||||
|
||||
lda #0 ; draw_score leaves a digit code in A
|
||||
@@ -113,6 +115,52 @@ pu_rrel:
|
||||
sta rcnt
|
||||
pu_rend:
|
||||
|
||||
; -- multiplayer: player 2 steers the closest rabbit --
|
||||
lda mp_mode
|
||||
beq pu_nop2
|
||||
jsr read_joy2
|
||||
lda joyb2
|
||||
and #JOY_LEFT
|
||||
beq pu_p2lrel
|
||||
inc p2lcnt
|
||||
lda p2lcnt
|
||||
cmp #1
|
||||
beq pu_p2lmove
|
||||
cmp #REP_HOLD+REP_PERIOD
|
||||
bne pu_p2lend
|
||||
lda #REP_HOLD
|
||||
sta p2lcnt
|
||||
pu_p2lmove:
|
||||
lda #$ff ; one lane to the left
|
||||
sta rtmp2
|
||||
jsr steer_closest
|
||||
jmp pu_p2lend
|
||||
pu_p2lrel:
|
||||
lda #0
|
||||
sta p2lcnt
|
||||
pu_p2lend:
|
||||
lda joyb2
|
||||
and #JOY_RIGHT
|
||||
beq pu_p2rrel
|
||||
inc p2rcnt
|
||||
lda p2rcnt
|
||||
cmp #1
|
||||
beq pu_p2rmove
|
||||
cmp #REP_HOLD+REP_PERIOD
|
||||
bne pu_p2rend
|
||||
lda #REP_HOLD
|
||||
sta p2rcnt
|
||||
pu_p2rmove:
|
||||
lda #1 ; one lane to the right
|
||||
sta rtmp2
|
||||
jsr steer_closest
|
||||
jmp pu_p2rend
|
||||
pu_p2rrel:
|
||||
lda #0
|
||||
sta p2rcnt
|
||||
pu_p2rend:
|
||||
pu_nop2:
|
||||
|
||||
; -- shadow init: player sprite bit + its x MSB --
|
||||
ldx player_lane
|
||||
lda pxlo,x
|
||||
@@ -197,6 +245,36 @@ pu_rnext:
|
||||
pu_done:
|
||||
rts
|
||||
|
||||
; ---- shift the closest live rabbit's lane by rtmp2 (+/-1) ----
|
||||
steer_closest:
|
||||
ldx #$ff ; best slot so far
|
||||
lda #0
|
||||
sta rtmp ; best t so far
|
||||
ldy #NRABBITS-1
|
||||
stc_find:
|
||||
lda r_act,y
|
||||
beq stc_next
|
||||
lda r_thi,y
|
||||
cmp rtmp
|
||||
bcc stc_next
|
||||
sta rtmp
|
||||
tya
|
||||
tax
|
||||
stc_next:
|
||||
dey
|
||||
bpl stc_find
|
||||
cpx #$ff
|
||||
beq stc_done ; no rabbit on the road
|
||||
lda r_lane,x
|
||||
clc
|
||||
adc rtmp2
|
||||
bmi stc_done ; already on the leftmost lane
|
||||
cmp #LANES
|
||||
bcs stc_done ; ... or the rightmost one
|
||||
sta r_lane,x
|
||||
stc_done:
|
||||
rts
|
||||
|
||||
; ---- claim a free rabbit slot and roll its lane + speed ----
|
||||
spawn_rabbit:
|
||||
ldx #NRABBITS-1
|
||||
@@ -298,6 +376,8 @@ 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
|
||||
p2lcnt: !byte 0 ; the same for player 2's steering
|
||||
p2rcnt: !byte 0
|
||||
|
||||
; ---- rabbit slots (hardware sprites 1-7) ----
|
||||
r_act: !fill NRABBITS, 0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
; -----------------------------------------------------------
|
||||
; title.asm - full-screen menu card: big RABBIT / SCOOTER
|
||||
; logo flanked by two hopping rabbits, the scooter waiting at
|
||||
; the bottom, blinking "fire = start game"
|
||||
; logo flanked by two hopping rabbits, single/multiplayer
|
||||
; picker (joystick up/down + fire, or the 1 / 2 keys)
|
||||
; -----------------------------------------------------------
|
||||
|
||||
title_init:
|
||||
@@ -12,7 +12,8 @@ title_init:
|
||||
|
||||
+prbig 2, 8, RED, txt_rabbit, 6
|
||||
+prbig 8, 6, WHITE, txt_scooter, 7
|
||||
+prtext 18, 8, WHITE, txt_info, 23
|
||||
+prtext 18, 9, LGREY, txt_info, 21
|
||||
+prtext 19, 9, LGREY, txt_info2, 21
|
||||
|
||||
; decoration: white rabbits flank the logo (sprites 1-2,
|
||||
; double-sized), the red scooter waits at the bottom
|
||||
@@ -65,17 +66,99 @@ title_update:
|
||||
adc #SPRP_BIG
|
||||
sta SPRPTR+2
|
||||
|
||||
; blink the start line
|
||||
; joystick up/down picks the mode
|
||||
jsr read_joy
|
||||
lda joyb
|
||||
and #1 ; up
|
||||
beq tu_noup
|
||||
lda #0
|
||||
sta mp_mode
|
||||
tu_noup:
|
||||
lda joyb
|
||||
and #2 ; down
|
||||
beq tu_nodown
|
||||
lda #1
|
||||
sta mp_mode
|
||||
tu_nodown:
|
||||
|
||||
; the 's' / 'm' keys pick the mode (fire still starts)
|
||||
lda #$fd ; 's': keyboard column 1, row bit 5
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
and #$20
|
||||
bne tu_nos
|
||||
lda #0
|
||||
sta mp_mode
|
||||
tu_nos:
|
||||
lda #$ef ; 'm': keyboard column 4, row bit 4
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
and #$10
|
||||
bne tu_nom
|
||||
lda #1
|
||||
sta mp_mode
|
||||
tu_nom:
|
||||
|
||||
; the 1 / 2 keys pick and start right away (edge detected)
|
||||
lda #$7f ; keyboard column 7: '1' = bit 0, '2' = bit 3
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
and #$09
|
||||
cmp #$09
|
||||
beq tu_keyup ; neither key held
|
||||
ldx k12held
|
||||
bne tu_menu ; still held from an earlier frame
|
||||
inx
|
||||
stx k12held
|
||||
and #$01
|
||||
bne tu_key2
|
||||
lda #0
|
||||
sta mp_mode
|
||||
jmp title_go
|
||||
tu_key2:
|
||||
lda #1
|
||||
sta mp_mode
|
||||
jmp title_go
|
||||
tu_keyup:
|
||||
lda #0
|
||||
sta k12held
|
||||
tu_menu:
|
||||
|
||||
; the two options: the picked line is yellow
|
||||
lda mp_mode
|
||||
bne tm_multi
|
||||
+prtext 14, 14, YELLOW, txt_1p, 13
|
||||
+prtext 16, 14, WHITE, txt_2p, 11
|
||||
jmp tm_cursor
|
||||
tm_multi:
|
||||
+prtext 14, 14, WHITE, txt_1p, 13
|
||||
+prtext 16, 14, YELLOW, txt_2p, 11
|
||||
tm_cursor:
|
||||
; blinking '>' cursor in front of the picked line
|
||||
lda #$20
|
||||
sta SCREEN+14*40+12
|
||||
sta SCREEN+16*40+12
|
||||
lda framectr
|
||||
and #32
|
||||
bne tu_hide
|
||||
+prtext 15, 11, YELLOW, txt_press, 17
|
||||
and #16
|
||||
bne tu_start
|
||||
lda mp_mode
|
||||
bne tm_cur2
|
||||
lda #62 ; '>'
|
||||
sta SCREEN+14*40+12
|
||||
lda #YELLOW
|
||||
sta COLRAM+14*40+12
|
||||
jmp tu_start
|
||||
tu_hide:
|
||||
+prtext 15, 11, YELLOW, txt_blank, 17
|
||||
tm_cur2:
|
||||
lda #62
|
||||
sta SCREEN+16*40+12
|
||||
lda #YELLOW
|
||||
sta COLRAM+16*40+12
|
||||
|
||||
tu_start:
|
||||
; fire or space starts the picked mode
|
||||
jsr start_edge
|
||||
beq tu_done
|
||||
title_go:
|
||||
jmp play_init ; its rts returns to the main loop
|
||||
tu_done:
|
||||
rts
|
||||
|
||||
Reference in New Issue
Block a user