Prev: BFFB Up: Map Next: C172
C00E: Handle Pickup And Drop
Used by the routine at HandlePlayerLegs.
Picks up or drops an object when the player presses the control for it. A special object that is close enough is picked up. If the player carries three objects already, the one that has been carried longest is dropped in the place of the new one. Otherwise, if the player is carrying something and there is a free place for a special object in the room, the object that has been carried longest is dropped where the player stands, and the player is lifted up by 0C to stand on it. If the player is in the cauldron room and jumping above the cauldron, the object is dropped into the cauldron.
The routine looks for objects by making the player a little wider, deeper and taller, which is put right when the routine ends.
Input
IX Address of the bottom half of the player
HandlePickupAndDrop C00E LD A,($5BB3) Fetch the flag that says the control has been pressed and not yet released from PickupDropPressedFlag.
C011 AND A Test it.
C012 JP NZ,HandlePickupAndDrop_WaitForRelease Jump to HandlePickupAndDrop_WaitForRelease if it was pressed on a frame before.
C015 CALL TestPickupDropKey Test whether the control is pressed.
C018 RET Z Return if it is not.
C019 CALL TestPlayerInRoom Test whether the player is in the room.
C01C RET NC Return if the player is out of bounds.
C01D BIT 3,(IX+$0C) Test whether the player is jumping.
C021 RET NZ Return if so.
C022 BIT 2,(IX+$0C) Test whether the player has hit something below.
C026 RET Z Return if the player is in the air.
Find out whether there is room to drop an object, by raising the player by 0C to see if it hits anything.
C027 XOR A Clear A.
C028 LD ($5BD3),A Flag that an object can be dropped at NoRoomToDropFlag.
C02B LD A,(IX+$03) Fetch the Z coordinate of the player.
C02E LD B,A Stash it in B.
C02F ADD A,$0C Add 0C to it.
C031 LD (IX+$03),A Set it as the Z coordinate of the player.
C034 CALL TestObjectIntersections Test whether the player intersects another object.
C037 LD (IX+$03),B Restore the Z coordinate of the player.
C03A JR NC,HandlePickupAndDrop_Pressed Jump to HandlePickupAndDrop_Pressed if there is room.
C03C LD A,$01 Get the value that sets a flag.
C03E LD ($5BD3),A Flag that no object can be dropped at NoRoomToDropFlag.
HandlePickupAndDrop_Pressed C041 CALL PlayLowBeep Play a beep.
C044 LD A,$01 Get the value that sets a flag.
C046 LD ($5BB3),A Flag that the control has been pressed at PickupDropPressedFlag.
C049 LD ($5BB4),A Flag that the objects carried have changed at ObjectsCarriedChangedFlag.
Make the player wider, deeper and taller, to find an object to pick up.
C04C LD B,$02 Set the number of special objects in the room to 02.
C04E LD L,(IX+$04) Fetch the width of the player.
C051 LD A,L Copy it into A.
C052 ADD A,$04 Add 04 to it.
C054 LD (IX+$04),A Set the new width.
C057 LD H,(IX+$05) Fetch the depth of the player.
C05A LD A,H Copy it into A.
C05B ADD A,$04 Add 04 to it.
C05D LD (IX+$05),A Set the new depth.
C060 PUSH HL Stash the old width and depth on the stack.
C061 LD L,(IX+$06) Fetch the height of the player.
C064 LD A,L Copy it into A.
C065 ADD A,$04 Add 04 to it.
C067 LD (IX+$06),A Set the new height.
C06A PUSH HL Stash the old height on the stack.
C06B LD IY,$5C48 Point IY at ObjectsTable_FirstSpecial.
HandlePickupAndDrop_LookForObject C06F CALL TestObjectCanBePickedUp Test whether the object can be picked up.
C072 JP C,HandlePickupAndDrop_PickUp Pick it up if it can.
C075 LD DE,$0020 Set DE to the size of an object.
C078 ADD IY,DE Point IY at the next special object.
C07A DJNZ HandlePickupAndDrop_LookForObject Jump to HandlePickupAndDrop_LookForObject until both have been tried.
There is nothing to pick up. Look for a free place to drop an object.
C07C CALL TestPickupDropKey Test whether the control is still pressed.
C07F JR Z,HandlePickupAndDrop_Done Finish if it is not.
C081 LD B,$02 Set the number of special objects to look at to 02.
C083 LD A,(IX+$08) Fetch the room that the player is in.
C086 CP $88 Jump to HandlePickupAndDrop_LookForSpace if it is another room.
C088 JR NZ,HandlePickupAndDrop_LookForSpace
C08A LD B,$01 Set the number of special objects to look at to 01.
HandlePickupAndDrop_LookForSpace C08C LD IY,$5C48 Point IY at the first special object of the room, ObjectsTable_FirstSpecial.
C090 LD DE,$0020 Set DE to the size of an object.
HandlePickupAndDrop_TestSlot C093 LD A,(IY+$00) Fetch the graphic number of the special object.
C096 AND A Test whether it is zero.
C097 JR Z,HandlePickupAndDrop_Drop Jump to HandlePickupAndDrop_Drop if the place is free.
C099 ADD IY,DE Point IY at the next special object.
C09B DJNZ HandlePickupAndDrop_TestSlot Jump to HandlePickupAndDrop_TestSlot until all of them have been tried.
Put the size of the player back.
HandlePickupAndDrop_Done C09D POP HL Restore the old height from the stack.
C09E LD (IX+$06),L Set the height of the player.
C0A1 POP HL Restore the old width and depth from the stack.
C0A2 LD (IX+$04),L Set the width of the player.
C0A5 LD (IX+$05),H Set the depth of the player.
C0A8 RET Return.
The control was pressed on a frame before: wait until it is let go.
HandlePickupAndDrop_WaitForRelease C0A9 CALL TestPickupDropKey Test whether the control is still pressed.
C0AC RET NZ Return if it is.
C0AD XOR A Clear A.
C0AE LD ($5BB3),A Flag that the control is not pressed at PickupDropPressedFlag.
C0B1 RET Return.
Drop the object that has been carried longest in the free place.
HandlePickupAndDrop_Drop C0B2 LD HL,$5BE4 Point HL at the object that has been carried longest, ObjectsCarried_Oldest.
C0B5 LD A,(HL) Fetch its graphic number.
C0B6 INC HL Move on to the flags.
C0B7 AND A Test whether there is an object.
C0B8 JR Z,HandlePickupAndDrop_Shift Jump to HandlePickupAndDrop_Shift if there is not.
C0BA LD A,($5BD3) Fetch the flag that says no object can be dropped from NoRoomToDropFlag.
C0BD AND A Test it.
C0BE JR NZ,HandlePickupAndDrop_Done Finish if there is no room.
C0C0 DEC HL Point HL at the graphic number.
C0C1 LD A,(HL) Fetch it.
C0C2 INC HL Move on to the flags.
C0C3 LD (IY+$00),A Set it as the graphic number of the special object.
C0C6 LD A,(IX+$08) Fetch the room that the player is in.
C0C9 CP $88 Jump to HandlePickupAndDrop_Place if it is another room.
C0CB JR NZ,HandlePickupAndDrop_Place
C0CD LD A,(IX+$03) Fetch the Z coordinate of the player.
C0D0 CP $98 Jump to HandlePickupAndDrop_Place if the player is below that.
C0D2 JR C,HandlePickupAndDrop_Place
C0D4 SET 3,(IY+$00) Make the object drop into the cauldron.
C0D8 LD A,$01 Get the value that sets a flag.
C0DA LD ($5BC4),A Flag that an object is being put into the cauldron at ObjectInCauldronFlag.
Put the object where the player is, and lift the player on top of it.
HandlePickupAndDrop_Place C0DD PUSH HL Stash the address of the flags of the object carried on the stack.
C0DE LD BC,$0003 Set the number of bytes to copy to 03.
C0E1 PUSH IX Copy IX to HL (using the stack).
C0E3 POP HL
C0E4 PUSH IY Copy IY to DE (using the stack).
C0E6 POP DE
C0E7 INC DE Point DE at the X coordinate of the object.
C0E8 INC HL Point HL at the X coordinate of the player.
C0E9 LDIR Copy the coordinates of the player to the object.
C0EB LD A,(IX+$03) Fetch the Z coordinate of the player.
C0EE ADD A,$0C Add 0C to it.
C0F0 LD (IX+$03),A Set the new Z coordinate of the player.
C0F3 LD A,(IX+$23) Fetch the Z coordinate of the top half of the player.
C0F6 ADD A,$0C Add 0C to it.
C0F8 LD (IX+$23),A Set the new Z coordinate of the top half of the player.
C0FB PUSH IX Stash IX on the stack.
C0FD PUSH IY Copy IY to IX (using the stack), to point at the object.
C0FF POP IX
C101 CALL CalculatePixelCoordinates Work out the pixel coordinates of the object.
C104 POP IX Restore IX from the stack.
Set up the rest of the object.
HandlePickupAndDrop_SetObject C106 LD (IY+$04),$05 Set the width of the object to 05.
C10A LD (IY+$05),$05 Set the depth of the object to 05.
C10E LD (IY+$06),$0C Set the height of the object to 0C.
C112 POP HL Restore the address of the flags of the object carried from the stack.
C113 LD A,(HL) Fetch the flags.
C114 INC HL Move on to the address of the table entry.
C115 LD (IY+$07),A Set the flags of the object.
C118 LD A,(IX+$08) Fetch the room that the player is in.
C11B LD (IY+$08),A Set the room of the object.
C11E LD A,(HL) Fetch the low byte of the address of the table entry.
C11F INC HL Move on to the high byte.
C120 LD (IY+$10),A Set the low byte of the address of the table entry of the object.
C123 LD A,(HL) Fetch the high byte of the address of the table entry.
C124 LD (IY+$11),A Set the high byte of the address of the table entry of the object.
C127 SET 0,(IY+$0D) Flag that the object has just been dropped.
Remove the object that was carried longest from the list, by moving the others along.
HandlePickupAndDrop_Shift C12B LD HL,$5BE3 Point HL at the last byte of the next to last object carried.
C12E LD DE,$5BE7 Point DE at the last byte of the last object carried.
C131 LD BC,$000C Set the number of bytes to move to 0C.
C134 LDDR Move the objects.
C136 LD DE,$5BD8 Point DE at ObjectsCarried.
C139 LD B,$04 Set the number of bytes to clear to 04.
C13B CALL ClearBytes Clear them.
C13E JP HandlePickupAndDrop_Done Jump to HandlePickupAndDrop_Done to finish.
Pick up the object that IY points at.
HandlePickupAndDrop_PickUp C141 LD HL,$5BD8 Point HL at the space for a new object carried, ObjectsCarried.
C144 XOR A Clear A.
C145 LD ($5BC0),A Allow the spiked balls to drop again at SpikedBallHoldFlag.
C148 LD A,(IY+$00) Fetch the graphic number of the object.
C14B LD (HL),A Store it.
C14C INC HL Move on to the flags.
C14D LD A,(IY+$07) Fetch the flags of the object.
C150 LD (HL),A Store them.
C151 INC HL Move on to the address of the table entry.
C152 LD E,(IY+$10) Fetch the low byte of the address of the table entry of the object.
C155 LD D,(IY+$11) Fetch the high byte.
C158 XOR A Clear A.
C159 LD (DE),A Clear the graphic number of the table entry, so that the object is not built again.
C15A LD (HL),E Store the low byte of the address of the table entry.
C15B INC HL Move on to the high byte.
C15C LD (HL),D Store it.
C15D CALL SetWipeAndDrawFlagsForObject Flag the object to be wiped and drawn.
C160 LD (IY+$00),$01 Make the graphic of the object one that is not shown.
C164 LD HL,$5BE4 Point HL at ObjectsCarried_Oldest.
C167 LD A,(HL) Fetch its graphic number.
C168 INC HL Move on to the flags.
C169 AND A Test whether there is an object.
C16A JR Z,HandlePickupAndDrop_Shift Jump to HandlePickupAndDrop_Shift if there is not.
C16C LD (IY+$00),A Make it the graphic of the object that was picked up.
C16F PUSH HL Stash the address of the flags on the stack.
C170 JR HandlePickupAndDrop_SetObject Jump to HandlePickupAndDrop_SetObject to drop it where the other object was.
View the equivalent code in;
Prev: BFFB Up: Map Next: C172