Manic Miner: Routine at 8ABB

| Routines

8ABB: Move Willy (1)

Used by the routine at 870E. This routine deals with Willy if he's jumping or falling.
8ABB | LD A,($806B) | Pick up the airborne status indicator from 806B
8ABE | CP $01 | Is Willy jumping?
8AC0 | JR NZ,$8B10 | Jump if not
Willy is currently jumping. Your browser doesn't support HTML5 audio. Here is a link to the audio instead.
8AC2 | LD A,($806E) | Pick up the jumping animation counter (0-17) from 806E
8AC5 | RES 0,A | Now -8<=A<=8 (and A is even)
8AC7 | SUB $08
8AC9 | LD HL,$8068 | Adjust Willy's y-coordinate at 8068 depending on where Willy is in the jump
8ACC | ADD A,(HL)
8ACD | LD (HL),A
8ACE | CALL $8B82 | Adjust Willy's attribute buffer location at 806C depending on his y-coordinate
8AD1 | LD A,($803B) | Pick up the attribute byte of the wall tile for the current cavern from 803B
8AD4 | CP (HL) | Is the top-left cell of Willy's sprite overlapping a wall tile?
8AD5 | JP Z,$8BA2 | Jump if so
8AD8 | INC HL | Point HL at the top-right cell occupied by Willy's sprite
8AD9 | CP (HL) | Is the top-right cell of Willy's sprite overlapping a wall tile?
8ADA | JP Z,$8BA2 | Jump if so
8ADD | LD A,($806E) | Increment the jumping animation counter at 806E
8AE0 | INC A
8AE1 | LD ($806E),A
8AE4 | SUB $08 | A=J-8, where J (1-18) is the new value of the jumping animation counter
8AE6 | JP P,$8AEB | Jump if J>=8
8AE9 | NEG | A=8-J (1<=J<=7, 1<=A<=7)
8AEB | INC A | A=1+ABS(J-8)
8AEC | RLCA | D=8*(1+ABS(J-8)); this value determines the pitch of the jumping sound effect (rising as Willy rises, falling as Willy falls)
8AED | RLCA
8AEE | RLCA
8AEF | LD D,A
8AF0 | LD C,$20 | This value determines the duration of the jumping sound effect
8AF2 | LD A,($8073) | Pick up the border colour for the current cavern from 8073
8AF5 | OUT ($FE),A | Make a jumping sound effect
8AF7 | XOR $18
8AF9 | LD B,D
8AFA | DJNZ $8AFA
8AFC | DEC C
8AFD | JR NZ,$8AF5
8AFF | LD A,($806E) | Pick up the jumping animation counter (1-18) from 806E
8B02 | CP $12 | Has Willy reached the end of the jump?
8B04 | JP Z,$8B96 | Jump if so
8B07 | CP $10 | Is the jumping animation counter now 16?
8B09 | JR Z,$8B10 | Jump if so
8B0B | CP $0D | Is the jumping animation counter now 13?
8B0D | JP NZ,$8C83 | Jump if not
If we get here, then Willy is standing on the floor, or he's falling, or his jumping animation counter is 13 (at which point Willy is on his way down and is exactly two cell-heights above where he started the jump) or 16 (at which point Willy is on his way down and is exactly one cell-height above where he started the jump).
8B10 | LD A,($8068) | Pick up Willy's y-coordinate from 8068
8B13 | AND $0F | Does Willy's sprite occupy six cells at the moment?
8B15 | JR NZ,$8B51 | Jump if so
8B17 | LD HL,($806C) | Pick up Willy's attribute buffer coordinates from 806C
8B1A | LD DE,$0040 | Point HL at the left-hand cell below Willy's sprite
8B1D | ADD HL,DE
8B1E | LD A,($8032) | Pick up the attribute byte of the crumbling floor tile for the current cavern from 8032
8B21 | CP (HL) | Does the left-hand cell below Willy's sprite contain a crumbling floor tile?
8B22 | CALL Z,$8BBA | If so, make it crumble
8B25 | LD A,($804D) | Pick up the attribute byte of the first nasty tile for the current cavern from 804D
8B28 | CP (HL) | Does the left-hand cell below Willy's sprite contain a nasty tile?
8B29 | JR Z,$8B51 | Jump if so
8B2B | LD A,($8056) | Pick up the attribute byte of the second nasty tile for the current cavern from 8056
8B2E | CP (HL) | Does the left-hand cell below Willy's sprite contain a nasty tile?
8B2F | JR Z,$8B51 | Jump if so
8B31 | INC HL | Point HL at the right-hand cell below Willy's sprite
8B32 | LD A,($8032) | Pick up the attribute byte of the crumbling floor tile for the current cavern from 8032
8B35 | CP (HL) | Does the right-hand cell below Willy's sprite contain a crumbling floor tile?
8B36 | CALL Z,$8BBA | If so, make it crumble
8B39 | LD A,($804D) | Pick up the attribute byte of the first nasty tile for the current cavern from 804D
8B3C | CP (HL) | Does the right-hand cell below Willy's sprite contain a nasty tile?
8B3D | JR Z,$8B51 | Jump if so
8B3F | LD A,($8056) | Pick up the attribute byte of the second nasty tile for the current cavern from 8056
8B42 | CP (HL) | Does the right-hand cell below Willy's sprite contain a nasty tile?
8B43 | JR Z,$8B51 | Jump if so
8B45 | LD A,($8020) | Pick up the attribute byte of the background tile for the current cavern from 8020
8B48 | CP (HL) | Set the zero flag if the right-hand cell below Willy's sprite is empty
8B49 | DEC HL | Point HL at the left-hand cell below Willy's sprite
8B4A | JP NZ,$8BDD | Jump if the right-hand cell below Willy's sprite is not empty
8B4D | CP (HL) | Is the left-hand cell below Willy's sprite empty?
8B4E | JP NZ,$8BDD | Jump if not
8B51 | LD A,($806B) | Pick up the airborne status indicator from 806B
8B54 | CP $01 | Is Willy jumping?
8B56 | JP Z,$8C83 | Jump if so
If we get here, then Willy is either in the process of falling or just about to start falling. Your browser doesn't support HTML5 audio. Here is a link to the audio instead.
8B59 | LD HL,$806A | Reset bit 1 at 806A: Willy is not moving left or right
8B5C | RES 1,(HL)
8B5E | OR A | Is Willy already falling?
8B5F | JP Z,$8B9C | Jump if not
8B62 | INC A | Increment the airborne status indicator at 806B
8B63 | LD ($806B),A
8B66 | RLCA | The value of D determines the pitch of the falling sound effect
8B67 | RLCA
8B68 | RLCA
8B69 | RLCA
8B6A | LD D,A
8B6B | LD C,$20 | This value determines the duration of the falling sound effect
8B6D | LD A,($8073) | Pick up the border colour for the current cavern from 8073
8B70 | OUT ($FE),A | Make a falling sound effect
8B72 | XOR $18
8B74 | LD B,D
8B75 | DJNZ $8B75
8B77 | DEC C
8B78 | JR NZ,$8B70
8B7A | LD A,($8068) | Add 8 to Willy's y-coordinate at 8068; this moves Willy downwards by 4 pixels
8B7D | ADD A,$08
8B7F | LD ($8068),A
8B82 | AND $F0 | L=16*Y, where Y is Willy's screen y-coordinate (0-14)
8B84 | LD L,A
8B85 | XOR A | Clear A and the carry flag
8B86 | RL L | Now L=32*(Y-8*INT(Y/8)), and the carry flag is set if Willy is in the lower half of the cavern (Y>=8)
8B88 | ADC A,$5C | H=0x5C or 0x5D (MSB of the address of Willy's location in the attribute buffer)
8B8A | LD H,A
8B8B | LD A,($806C) | Pick up Willy's screen x-coordinate (1-29) from bits 0-4 at 806C
8B8E | AND $1F
8B90 | OR L | Now L holds the LSB of Willy's attribute buffer address
8B91 | LD L,A
8B92 | LD ($806C),HL | Store Willy's updated attribute buffer location at 806C
8B95 | RET |
Willy has just finished a jump.
8B96 | LD A,$06 | Set the airborne status indicator at 806B to 0x06: Willy will continue to fall unless he's landed on a wall or floor block
8B98 | LD ($806B),A
8B9B | RET |
Willy has just started falling.
8B9C | LD A,$02 | Set the airborne status indicator at 806B to 0x02
8B9E | LD ($806B),A
8BA1 | RET |
The top-left or top-right cell of Willy's sprite is overlapping a wall tile.
8BA2 | LD A,($8068) | Adjust Willy's y-coordinate at 8068 so that the top row of cells of his sprite is just below the wall tile
8BA5 | ADD A,$10
8BA7 | AND $F0
8BA9 | LD ($8068),A
8BAC | CALL $8B82 | Adjust Willy's attribute buffer location at 806C to account for this new y-coordinate
8BAF | LD A,$02 | Set the airborne status indicator at 806B to 0x02: Willy has started falling
8BB1 | LD ($806B),A
8BB4 | LD HL,$806A | Reset bit 1 at 806A: Willy is not moving left or right
8BB7 | RES 1,(HL)
8BB9 | RET |