Jet Set Willy: Routine at 8DD3

| Routines

8DD3: Move Willy (1)

Used by the routine at 89AD. This routine deals with Willy if he's jumping or falling.
8DD3 | LD A,($85D6) | Pick up the rope status indicator from 85D6
8DD6 | DEC A | Is Willy on a rope?
8DD7 | BIT 7,A
8DD9 | JP Z,$8ED4 | Jump if so
8DDC | LD A,($85D1) | Pick up the airborne status indicator from 85D1
8DDF | CP $01 | Is Willy jumping?
8DE1 | JR NZ,$8E36 | Jump if not
Willy is currently jumping. Your browser doesn't support HTML5 audio. Here is a link to the audio instead.
8DE3 | LD A,($85D5) | Pick up the jumping animation counter (0-17) from 85D5
8DE6 | AND $FE | Discard bit 0
8DE8 | SUB $08 | Now -8<=A<=8 (and A is even)
8DEA | LD HL,$85CF | Adjust Willy's y-coordinate at 85CF depending on where Willy is in the jump
8DED | ADD A,(HL)
8DEE | LD (HL),A
8DEF | CP $F0 | Is the new value negative (above the top of the screen)?
8DF1 | JP NC,$94B0 | If so, move Willy into the room above
8DF4 | CALL $8E9C | Adjust Willy's attribute buffer location at 85D3 depending on his y-coordinate
8DF7 | LD A,($80B2) | Pick up the attribute byte of the wall tile for the current room from 80B2
8DFA | CP (HL) | Is the top-left cell of Willy's sprite overlapping a wall tile?
8DFB | JP Z,$8EBC | Jump if so
8DFE | INC HL | Point HL at the top-right cell occupied by Willy's sprite
8DFF | CP (HL) | Is the top-right cell of Willy's sprite overlapping a wall tile?
8E00 | JP Z,$8EBC | Jump if so
8E03 | LD A,($85D5) | Increment the jumping animation counter at 85D5
8E06 | INC A
8E07 | LD ($85D5),A
8E0A | SUB $08 | A=J-8, where J (1-18) is the new value of the jumping animation counter
8E0C | JP P,$8E11 | Jump if J>=8
8E0F | NEG | A=8-J (1<=J<=7, 1<=A<=7)
8E11 | INC A | A=1+ABS(J-8)
8E12 | 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)
8E13 | RLCA
8E14 | RLCA
8E15 | LD D,A
8E16 | LD C,$20 | This value determines the duration of the jumping sound effect
8E18 | LD A,($80DE) | Pick up the border colour for the current room from 80DE
8E1B | OUT ($FE),A | Make a jumping sound effect
8E1D | XOR $18
8E1F | LD B,D
8E20 | DJNZ $8E20
8E22 | DEC C
8E23 | JR NZ,$8E1B
8E25 | LD A,($85D5) | Pick up the jumping animation counter (1-18) from 85D5
8E28 | CP $12 | Has Willy reached the end of the jump?
8E2A | JP Z,$8EB0 | Jump if so
8E2D | CP $10 | Is the jumping animation counter now 16?
8E2F | JR Z,$8E36 | Jump if so
8E31 | CP $0D | Is the jumping animation counter now 13?
8E33 | JP NZ,$8FBC | Jump if not
If we get here, then Willy is standing on the floor or a ramp, 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).
8E36 | LD A,($85CF) | Pick up Willy's y-coordinate from 85CF
8E39 | AND $0E | Is Willy either on a ramp, or occupying only four cells?
8E3B | JR NZ,$8E62 | Jump if not
8E3D | LD HL,($85D3) | Pick up Willy's attribute buffer coordinates from 85D3
8E40 | LD DE,$0040 | Point HL at the left-hand cell below Willy's sprite
8E43 | ADD HL,DE
8E44 | BIT 1,H | Is this location below the floor of the current room?
8E46 | JP NZ,$94D2 | If so, move Willy into the room below
8E49 | LD A,($80BB) | Pick up the attribute byte of the nasty tile for the current room from 80BB
8E4C | CP (HL) | Does the left-hand cell below Willy's sprite contain a nasty?
8E4D | JR Z,$8E62 | Jump if so
8E4F | INC HL | Point HL at the right-hand cell below Willy's sprite
8E50 | LD A,($80BB) | Pick up the attribute byte of the nasty tile for the current room from 80BB (again, redundantly)
8E53 | CP (HL) | Does the right-hand cell below Willy's sprite contain a nasty?
8E54 | JR Z,$8E62 | Jump if so
8E56 | LD A,($80A0) | Pick up the attribute byte of the background tile for the current room from 80A0
8E59 | CP (HL) | Set the zero flag if the right-hand cell below Willy's sprite is empty
8E5A | DEC HL | Point HL at the left-hand cell below Willy's sprite
8E5B | JP NZ,$8ED4 | Jump if the right-hand cell below Willy's sprite is not empty
8E5E | CP (HL) | Is the left-hand cell below Willy's sprite empty?
8E5F | JP NZ,$8ED4 | Jump if not
8E62 | LD A,($85D1) | Pick up the airborne status indicator from 85D1
8E65 | CP $01 | Is Willy jumping?
8E67 | JP Z,$8FBC | 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.
8E6A | LD HL,$85D0 | Reset bit 1 at 85D0: Willy is not moving left or right
8E6D | RES 1,(HL)
8E6F | LD A,($85D1) | Pick up the airborne status indicator from 85D1
8E72 | OR A | Is Willy already falling?
8E73 | JP Z,$8EB6 | Jump if not
8E76 | INC A | Increment the airborne status indicator
8E77 | CP $10 | Is it 16 now?
8E79 | JR NZ,$8E7D | Jump if not
8E7B | LD A,$0C | Decrease the airborne status indicator from 0x10 to 0x0C
8E7D | LD ($85D1),A | Update the airborne status indicator at 85D1
8E80 | RLCA | D=16*A; this value determines the pitch of the falling sound effect
8E81 | RLCA
8E82 | RLCA
8E83 | RLCA
8E84 | LD D,A
8E85 | LD C,$20 | This value determines the duration of the falling sound effect
8E87 | LD A,($80DE) | Pick up the border colour for the current room from 80DE
8E8A | OUT ($FE),A | Make a falling sound effect
8E8C | XOR $18
8E8E | LD B,D
8E8F | DJNZ $8E8F
8E91 | DEC C
8E92 | JR NZ,$8E8A
8E94 | LD A,($85CF) | Add 8 to Willy's y-coordinate at 85CF; this moves Willy downwards by 4 pixels
8E97 | ADD A,$08
8E99 | LD ($85CF),A
This entry point is used by the routine at 91BE to update Willy's attribute buffer location when he's on a rope.
8E9C | AND $F0 | L=16*Y, where Y is Willy's screen y-coordinate (0-14)
8E9E | LD L,A
8E9F | XOR A | Clear A and the carry flag
8EA0 | 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 room (Y>=8)
8EA2 | ADC A,$5C | H=0x5C or 0x5D (MSB of the address of Willy's location in the attribute buffer)
8EA4 | LD H,A
8EA5 | LD A,($85D3) | Pick up Willy's screen x-coordinate (0-30) from bits 0-4 at 85D3
8EA8 | AND $1F
8EAA | OR L | Now L holds the LSB of Willy's attribute buffer address
8EAB | LD L,A
8EAC | LD ($85D3),HL | Store Willy's updated attribute buffer location at 85D3
8EAF | RET |
Willy has just finished a jump.
8EB0 | LD A,$06 | Set the airborne status indicator at 85D1 to 0x06: Willy will continue to fall unless he's landed on a wall or floor block
8EB2 | LD ($85D1),A
8EB5 | RET |
Willy has just started falling.
8EB6 | LD A,$02 | Set the airborne status indicator at 85D1 to 0x02
8EB8 | LD ($85D1),A
8EBB | RET |
The top-left or top-right cell of Willy's sprite is overlapping a wall tile.
8EBC | LD A,($85CF) | Adjust Willy's y-coordinate at 85CF so that the top row of cells of his sprite is just below the wall tile
8EBF | ADD A,$10
8EC1 | AND $F0
8EC3 | LD ($85CF),A
8EC6 | CALL $8E9C | Adjust Willy's attribute buffer location at 85D3 to account for this new y-coordinate
8EC9 | LD A,$02 | Set the airborne status indicator at 85D1 to 0x02: Willy has started falling
8ECB | LD ($85D1),A
8ECE | LD HL,$85D0 | Reset bit 1 at 85D0: Willy is not moving left or right
8ED1 | RES 1,(HL)
8ED3 | RET |