Prev: E820 Up: Map Next: E9D9
E821: Handler: Lifts
Used by the routine at InitialiseGame.
Only action lifts every other frame.
Handler_Lifts E821 LD A,($F334) A=*LiftsPiratesFrameSkip (lifts/ pirates frame skip).
E824 INC A Increment A by one.
E825 AND %00000001 Ensure A is either 00 or 01.
E827 LD ($F334),A Write A back to *LiftsPiratesFrameSkip.
E82A CP $01 Return if this is a skipped frame.
E82C RET NZ
Point the UDG graphics at the lift frames.
E82D LD HL,$F17B Write F17B to *CHARS.
E830 LD ($5C36),HL
Walk the lift table.
E833 LD IX,($5BE4) IX=*ReferenceLifts.
Walk each lift in *ReferenceLifts.
Handler_Lifts_Loop E837 LD A,(IX+$00) Return if this lift entry is the terminator (FF).
E83A CP $FF
E83C RET Z
E83D LD A,(IX+$04) Jump to Handler_Lifts_Stationary if this lift is not moving horizontally.
E840 CP $00
E842 JP Z,Handler_Lifts_Stationary
Test whether the player is standing on this lift.
E845 LD A,($F240) Jump to Handler_Lifts_Next if the player's previous vertical offset is not 03.
E848 CP $03
E84A JR NZ,Handler_Lifts_Next
E84C LD E,(IX+$07) E=the lift width.
E84F LD C,(IX+$00) C=the lift horizontal co-ordinate.
E852 LD B,(IX+$01) B=the lift vertical co-ordinate.
E855 LD A,($F23F) A=the player's previous vertical co-ordinate.
E858 SUB $03 Move up three rows to the player's feet.
E85A CP B Jump to Handler_Lifts_Next if the player is not on this lift's row.
E85B JR NZ,Handler_Lifts_Next
E85D LD C,(IX+$00) C=the lift horizontal co-ordinate.
E860 LD B,(IX+$01) B=the lift vertical co-ordinate.
E863 PUSH BC Stash the lift co-ordinates on the stack.
E864 CALL $0DD9 Call CL_SET.
E867 LD HL,($5C84) HL=*DF_CC.
E86A POP BC Restore the lift co-ordinates from the stack.
E86B INC B Move one row down.
E86C PUSH HL Stash the first screen address on the stack.
E86D CALL $0DD9 Call CL_SET.
E870 POP HL Restore the first screen address from the stack.
E871 LD DE,($5C84) DE=*DF_CC.
E875 LD A,D Move DE down seven pixel rows.
E876 ADD A,$07
E878 LD D,A
E879 LD B,(IX+$07) B=the lift width.
E87C LD A,(IX+$02) Jump to Handler_Lifts_OverlapLoop if the lift horizontal offset is higher than 02.
E87F CP $02
E881 JR NC,Handler_Lifts_OverlapLoop
E883 INC B Widen the overlap test by one.
Handler_Lifts_OverlapLoop E884 LD A,(DE) A=a byte from the lower scanline.
E885 AND (HL) AND it with the matching byte from the lift.
E886 JR NZ,Handler_Lifts_PlayerOnLift Jump to Handler_Lifts_PlayerOnLift if the player overlaps this lift.
E888 INC HL Advance the lift screen pointer.
E889 INC DE Advance the player screen pointer.
E88A DJNZ Handler_Lifts_OverlapLoop Decrease counter by one and loop back to Handler_Lifts_OverlapLoop until the whole lift width has been tested.
E88C JR Handler_Lifts_Next Jump to Handler_Lifts_Next.
Handler_Lifts_PlayerOnLift E88E LD A,$02 Set *FlagLiftCollision; the player is on this lift.
E890 LD ($E820),A
E893 LD A,(IX+$04) Jump to Handler_Lifts_NudgeVertical if this lift is not moving horizontally.
E896 CP $00
E898 JR Z,Handler_Lifts_NudgeVertical
E89A CP $FF Compare the overlap byte with FF.
E89C PUSH AF Stash AF on the stack.
E89D CALL Z,Handler_Lifts_NudgePlayerRight Nudge the player right if the overlap is solid.
E8A0 POP AF Restore AF from the stack.
E8A1 CALL NZ,Handler_Lifts_NudgePlayerLeft Nudge the player left if the overlap is not solid.
Handler_Lifts_NudgeVertical E8A4 LD A,(IX+$05) Jump to Handler_Lifts_Next if this lift is not moving vertically.
E8A7 CP $00
E8A9 JR Z,Handler_Lifts_Next
E8AB CP $FF Compare the overlap byte with FF.
E8AD PUSH AF Stash AF on the stack.
E8AE CALL Z,Handler_Lifts_NudgePlayerDown Nudge the player down if the overlap is solid.
E8B1 POP AF Restore AF from the stack.
E8B2 CALL NZ,Handler_Lifts_NudgePlayerUp Nudge the player up if the overlap is not solid.
Handler_Lifts_Next E8B5 CALL ApplyMovementDeltas Apply this lift's movement deltas.
E8B8 LD A,(IX+$04) Test whether the lift is moving horizontally.
E8BB CP $00
E8BD PUSH AF Stash AF on the stack.
E8BE CALL Z,Handler_Lifts_ReverseVertical Reverse or clamp horizontal travel if it is stationary.
E8C1 POP AF Restore AF from the stack.
E8C2 CALL NZ,Handler_Lifts_ReverseHorizontal Reverse or clamp horizontal travel if it is moving.
E8C5 LD (IX+$00),C Write the new horizontal co-ordinate back to the lift.
E8C8 LD (IX+$01),B Write the new vertical co-ordinate back to the lift.
E8CB LD (IX+$02),E Write the new horizontal offset back to the lift.
E8CE LD (IX+$03),D Write the new vertical offset back to the lift.
E8D1 CALL PrintShiftedSprite Print the lift.
E8D4 LD DE,$0010 Move IX on to the next sixteen-byte lift entry.
E8D7 ADD IX,DE
E8D9 JP Handler_Lifts_Loop Jump to Handler_Lifts_Loop.
Reverse horizontal travel when the lift hits a bound.
Handler_Lifts_ReverseHorizontal E8DC LD A,(IX+$04) Jump to Handler_Lifts_ReverseHorizontalRight if the lift is moving right.
E8DF CP $FF
E8E1 JR Z,Handler_Lifts_ReverseHorizontalRight
E8E3 LD A,(IX+$0A) Return if the horizontal co-ordinate is not the left bound.
E8E6 CP C
E8E7 RET NZ
E8E8 LD A,(IX+$0B) Return if the horizontal offset is not the left bound.
E8EB CP E
E8EC RET NZ
E8ED LD (IX+$04),$FF Reverse horizontal movement to the right.
E8F1 RET Return.
Handler_Lifts_ReverseHorizontalRight E8F2 LD A,(IX+$0C) Return if the horizontal co-ordinate is not the right bound.
E8F5 CP C
E8F6 RET NZ
E8F7 LD A,(IX+$0D) Return if the horizontal offset is not the right bound.
E8FA CP E
E8FB RET NZ
E8FC LD (IX+$04),$01 Reverse horizontal movement to the left.
E900 RET Return.
Reverse vertical travel when the lift hits a bound.
Handler_Lifts_ReverseVertical E901 LD A,(IX+$05) Jump to Handler_Lifts_ReverseVerticalDown if the lift is moving down.
E904 CP $FF
E906 JR Z,Handler_Lifts_ReverseVerticalDown
E908 LD A,(IX+$0A) Return if the vertical co-ordinate is not the top bound.
E90B CP B
E90C RET NZ
E90D LD A,(IX+$0B) Return if the vertical offset is not the top bound.
E910 CP D
E911 RET NZ
E912 LD (IX+$05),$FF Reverse vertical movement to down.
E916 RET Return.
Handler_Lifts_ReverseVerticalDown E917 LD A,(IX+$0C) Return if the vertical co-ordinate is not the bottom bound.
E91A CP B
E91B RET NZ
E91C LD A,(IX+$0D) Return if the vertical offset is not the bottom bound.
E91F CP D
E920 RET NZ
E921 LD (IX+$05),$01 Reverse vertical movement to up.
E925 RET Return.
Handler_Lifts_NudgePlayerLeft E926 LD A,($F235) Nudge the player's horizontal movement left.
E929 INC A
E92A LD ($F235),A
E92D RET Return.
Handler_Lifts_NudgePlayerRight E92E LD A,($F235) Nudge the player's horizontal movement right.
E931 DEC A
E932 LD ($F235),A
E935 RET Return.
Handler_Lifts_NudgePlayerUp E936 LD A,($F236) Nudge the player's vertical movement up.
E939 INC A
E93A LD ($F236),A
E93D RET Return.
Handler_Lifts_NudgePlayerDown E93E LD A,($F236) Nudge the player's vertical movement down.
E941 DEC A
E942 LD ($F236),A
E945 RET Return.
Stationary lift: still test whether the player is standing on it.
Handler_Lifts_Stationary E946 LD A,($F240) A=the player's previous vertical offset.
E949 INC A Increment A by one.
E94A AND %00000011 Keep only bits 0-1.
E94C CP (IX+$03) Jump to Handler_Lifts_Next if A is not equal to *IX+03.
E94F JP NZ,Handler_Lifts_Next
E952 LD C,(IX+$00) C=*IX+00.
E955 LD B,(IX+$01) B=*IX+01.
E958 LD A,(IX+$03) A=*IX+03.
Handler_Lifts_StationaryCompareOffset E95B CP $00 Compare A with 00.
E95D LD A,($F23F) A=*PlayerPreviousVerticalCoordinate.
E960 JR Z,Handler_Lifts_StationaryCompareRow Jump to Handler_Lifts_StationaryCompareRow if A was equal to 00 on line Handler_Lifts_StationaryCompareOffset.
E962 DEC A Decrease A by one.
Handler_Lifts_StationaryCompareRow E963 SUB $02 A-=02.
E965 CP B Jump to Handler_Lifts_Next if A is not equal to B.
E966 JP NZ,Handler_Lifts_Next
E969 LD A,(IX+$03) A=*IX+03.
E96C LD C,(IX+$00) C=*IX+00.
E96F LD B,(IX+$01) B=*IX+01.
E972 PUSH AF Stash AF on the stack.
E973 CP $03 Call Handler_Lifts_ScanlineOffsetThree if A is equal to 03.
E975 CALL Z,Handler_Lifts_ScanlineOffsetThree
E978 POP AF Restore AF from the stack.
E979 PUSH AF Stash AF on the stack.
E97A CP $02 Call Handler_Lifts_ScanlineOffsetTwo if A is equal to 02.
E97C CALL Z,Handler_Lifts_ScanlineOffsetTwo
E97F POP AF Restore AF from the stack.
E980 PUSH AF Stash AF on the stack.
E981 CP $01 Call Handler_Lifts_ScanlineOffsetOne if A is equal to 01.
E983 CALL Z,Handler_Lifts_ScanlineOffsetOne
E986 POP AF Restore AF from the stack.
E987 CP $00 Call Handler_Lifts_ScanlineOffsetZero if A is equal to 00.
E989 CALL Z,Handler_Lifts_ScanlineOffsetZero
E98C LD B,(IX+$07) B=*IX+07.
Handler_Lifts_StationaryOverlapLoop E98F LD A,(DE) A=*DE.
E990 AND (HL) Merge the bits from *HL.
E991 JP NZ,Handler_Lifts_PlayerOnLift Jump to Handler_Lifts_PlayerOnLift if the result is not zero.
E994 INC HL Increment HL by one.
E995 INC DE Increment DE by one.
E996 DJNZ Handler_Lifts_StationaryOverlapLoop Decrease counter by one and loop back to Handler_Lifts_StationaryOverlapLoop until counter is zero.
E998 JP Handler_Lifts_Next Jump to Handler_Lifts_Next.
Handler_Lifts_ScanlineOffsetOne E99B CALL $0DD9 Call CL_SET.
E99E LD HL,($5C84) HL=*DF_CC.
E9A1 INC H Increment H by five.
E9A2 INC H
E9A3 INC H
E9A4 INC H
E9A5 INC H
E9A6 PUSH HL DE=HL (using the stack).
E9A7 POP DE
E9A8 INC H Increment H by one.
E9A9 RET Return.
Handler_Lifts_ScanlineOffsetTwo E9AA CALL $0DD9 Call CL_SET.
E9AD LD HL,($5C84) HL=*DF_CC.
E9B0 INC H Increment H by three.
E9B1 INC H
E9B2 INC H
E9B3 PUSH HL DE=HL (using the stack).
E9B4 POP DE
E9B5 INC H Increment H by one.
E9B6 RET Return.
Handler_Lifts_ScanlineOffsetThree E9B7 CALL $0DD9 Call CL_SET.
E9BA LD HL,($5C84) HL=*DF_CC.
E9BD INC H Increment H by one.
E9BE PUSH HL DE=HL (using the stack).
E9BF POP DE
E9C0 INC H Increment H by one.
E9C1 RET Return.
Handler_Lifts_ScanlineOffsetZero E9C2 PUSH BC Stash BC on the stack.
E9C3 CALL $0DD9 Call CL_SET.
E9C6 POP BC Restore BC from the stack.
E9C7 LD DE,($5C84) DE=*DF_CC.
E9CB LD A,D D+=07.
E9CC ADD A,$07
E9CE LD D,A
E9CF PUSH DE Stash DE on the stack.
E9D0 DEC B Decrease B by one.
E9D1 CALL $0DD9 Call CL_SET.
E9D4 POP DE Restore DE from the stack.
E9D5 LD HL,($5C84) HL=*DF_CC.
E9D8 RET Return.
Prev: E820 Up: Map Next: E9D9