From c07623e13547a4583777a7ce0f9de46d16e8084d Mon Sep 17 00:00:00 2001 From: Simon Owen Date: Sat, 1 Mar 2014 16:41:53 +0000 Subject: [PATCH] Improved control support for diagonal inputs The original Pac-Man machine uses a 4-way joystick, which makes it impossible to generate more than one direction input. The game does not understand diagonals, and will use the first direction found to be pressed. This can cause frustration when played on the keyboard or with a regular 8-way joystick. We now ignore control input for the direction Pac-Man is currently facing, so changes of direction are always preferred. We also ignore perpendicular inputs on tile entry, to defeat the turn overshoot mechanism that gives a brief window for players to change their mind about a turn. These changes are only active when diagonal inputs are detected, so traditional play with a single input remains true to the original. --- pacemuzx.asm | 54 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/pacemuzx.asm b/pacemuzx.asm index a29e270..a52c97a 100644 --- a/pacemuzx.asm +++ b/pacemuzx.asm @@ -44,6 +44,10 @@ pac_footer: equ &4000 ; credit and fruit display pac_chars: equ &4040 ; start of main Pac-Man display (skipping the score rows) pac_header: equ &43c0 ; 64 bytes containing the score +pac_ypos: equ &4d08 ; Pac-Man y position (as viewed) +pac_xpos: equ &4d09 ; Pac-Man x position (as viewed) +pac_dir: equ &4d30 ; Pac-Man facing direction (0=right, 1=down, 2=left, 3=up) + ; address of saved sprite block followed by the data itself spr_save_2: equ &5b00 spr_save_3: equ spr_save_2+2+2+(3*12) ; attr address, data address, 3 bytes * 12 lines @@ -733,7 +737,7 @@ inp_col_lp: rra bit 3,a ; 7 = white? jr z,got_colour rra - jp c,input_done + jp c,joy_done got_colour: ld a,c ld (attr_colour),a ; set to be picked up by flash_maze @@ -890,25 +894,49 @@ not_fire: cp c ; was it the only bit? jr z,joy_done ; skip if so - ld a,(last_controls); last valid (single) controls - xor c ; check for differences - or %11110000 ; convert to mask - ld c,a - ld a,d ; current controls - or %00001111 ; release all directions - and c ; press the changed key - jr joy_multi ; apply change but don't save + ld a,(pac_dir) ; facing direction (r/d/l/u) + bit 1,a + rra + ld c,&07 ; position mask for tile offset + jr c,face_ud + +face_lr: ld a,(pac_xpos) ; x position + jr z,face_r ; (from bit test above) +face_l: set 1,d ; release left + and c ; mask to tile offset + cp 5 ; entering junction? + jr c,joy_done ; if not we're done +ignore_ud: set 0,d ; release up + set 3,d ; release down + jr joy_done + +face_r: set 2,d ; release right + and c + cp 4 ; entering junction? + jr c,ignore_ud ; if so, ignore up+down + jr joy_done + +face_ud: ld a,(pac_ypos) ; y position + jr z,face_d ; (from bit test above) +face_u: set 0,d ; release up + and c + cp 4 ; entering junction? + jr nc,joy_done ; if not we're done +ignore_lr: set 1,d ; release left + set 2,d ; release right + jr joy_done + +face_d: set 3,d ; release down + and c + cp 5 ; entering junction? + jr nc,ignore_lr ; if so, ignore left+right joy_done: ld a,d - ld (last_controls),a; update last valid controls -input_done: ld a,d ; use original value joy_multi: ld (&5000),a ld a,e ld (&5040),a ret -last_controls: defb 0 - ; Check sprite visibility, returns carry if any visible, no-carry if all hidden is_visible: ld a,&10 ; minimum x/y position to be visible