Jet Set Willy: Routine at 95C8

| Routines

95C8: Check and set the attribute bytes for Willy's sprite in the buffer at 5C00

Used by the routine at 89AD. Sets the attribute bytes in the buffer at 5C00 for the six cells (in three rows of two) occupied by or under Willy's sprite, or kills Willy if any of the cells contains a nasty.
95C8 | LD HL,($85D3) | Pick up Willy's attribute buffer coordinates from 85D3
95CB | LD B,$00 | Initialise B to 0 (in case Willy is not standing on a ramp)
95CD | LD A,($80DA) | Pick up the direction byte of the ramp definition for the current room from 80DA
95D0 | AND $01 | Point HL at one of the cells under Willy's feet (the one on the left if the ramp goes up to the left, the one on the right if the ramp goes up to the right)
95D2 | ADD A,$40
95D4 | LD E,A
95D5 | LD D,$00
95D7 | ADD HL,DE
95D8 | LD A,($80C4) | Pick up the ramp's attribute byte from 80C4
95DB | CP (HL) | Is Willy on or just above the ramp?
95DC | JR NZ,$95F8 | Jump if not
95DE | LD A,($85D1) | Pick up the airborne status indicator from 85D1
95E1 | OR A | Is Willy airborne?
95E2 | JR NZ,$95F8 | Jump if so
Willy is standing on a ramp. Calculate the offset that needs to be added to the y-coordinate stored at 85CF to obtain Willy's true y-coordinate.
95E4 | LD A,($85D2) | Pick up Willy's current animation frame (0-3) from 85D2
95E7 | AND $03 | B=0, 4, 8 or 12
95E9 | RLCA
95EA | RLCA
95EB | LD B,A
95EC | LD A,($80DA) | Pick up the direction byte of the ramp definition for the current room from 80DA
95EF | AND $01 | A=B (if the ramp goes up to the left) or 12-B (if the ramp goes up to the right)
95F1 | DEC A
95F2 | XOR $0C
95F4 | XOR B
95F5 | AND $0C
95F7 | LD B,A | Copy this value to B
Now B holds a y-coordinate offset of 0, 4, 8 or 12 if Willy is standing on a ramp, or 0 otherwise.
95F8 | LD HL,($85D3) | Pick up Willy's attribute buffer coordinates from 85D3
95FB | LD DE,$001F | Prepare DE for later addition
95FE | LD C,$0F | Set C=0x0F for the top two rows of cells (to make the routine at 961E force white INK)
9600 | CALL $961E | Check and set the attribute byte for the top-left cell
9603 | INC HL | Move HL to the next cell to the right
9604 | CALL $961E | Check and set the attribute byte for the top-right cell
9607 | ADD HL,DE | Move HL down a row and back one cell to the left
9608 | CALL $961E | Check and set the attribute byte for the mid-left cell
960B | INC HL | Move HL to the next cell to the right
960C | CALL $961E | Check and set the attribute byte for the mid-right cell
960F | LD A,($85CF) | Pick up Willy's y-coordinate from 85CF
9612 | ADD A,B | Add the y-coordinate offset calculated earlier (to get Willy's true y-coordinate if he's standing on a ramp) and transfer the result to C
9613 | LD C,A
9614 | ADD HL,DE | Move HL down a row and back one cell to the left; at this point HL may be pointing at one of the cells in the top row of the buffer at 5E00, which is a bug
9615 | CALL $961E | Check and set the attribute byte for the bottom-left cell
9618 | INC HL | Move HL to the next cell to the right
9619 | CALL $961E | Check and set the attribute byte for the bottom-right cell
961C | JR $9637 | Draw Willy to the screen buffer at 6000