Prev: 49147 Up: Map Next: 49522
49166: 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 12 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 49166 LD A,(23475) Fetch the flag that says the control has been pressed and not yet released from PickupDropPressedFlag.
49169 AND A Test it.
49170 JP NZ,HandlePickupAndDrop_WaitForRelease Jump to HandlePickupAndDrop_WaitForRelease if it was pressed on a frame before.
49173 CALL TestPickupDropKey Test whether the control is pressed.
49176 RET Z Return if it is not.
49177 CALL TestPlayerInRoom Test whether the player is in the room.
49180 RET NC Return if the player is out of bounds.
49181 BIT 3,(IX+12) Test whether the player is jumping.
49185 RET NZ Return if so.
49186 BIT 2,(IX+12) Test whether the player has hit something below.
49190 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 12 to see if it hits anything.
49191 XOR A Clear A.
49192 LD (23507),A Flag that an object can be dropped at NoRoomToDropFlag.
49195 LD A,(IX+3) Fetch the Z coordinate of the player.
49198 LD B,A Stash it in B.
49199 ADD A,12 Add 12 to it.
49201 LD (IX+3),A Set it as the Z coordinate of the player.
49204 CALL TestObjectIntersections Test whether the player intersects another object.
49207 LD (IX+3),B Restore the Z coordinate of the player.
49210 JR NC,HandlePickupAndDrop_Pressed Jump to HandlePickupAndDrop_Pressed if there is room.
49212 LD A,1 Get the value that sets a flag.
49214 LD (23507),A Flag that no object can be dropped at NoRoomToDropFlag.
HandlePickupAndDrop_Pressed 49217 CALL PlayLowBeep Play a beep.
49220 LD A,1 Get the value that sets a flag.
49222 LD (23475),A Flag that the control has been pressed at PickupDropPressedFlag.
49225 LD (23476),A Flag that the objects carried have changed at ObjectsCarriedChangedFlag.
Make the player wider, deeper and taller, to find an object to pick up.
49228 LD B,2 Set the number of special objects in the room to 2.
49230 LD L,(IX+4) Fetch the width of the player.
49233 LD A,L Copy it into A.
49234 ADD A,4 Add 4 to it.
49236 LD (IX+4),A Set the new width.
49239 LD H,(IX+5) Fetch the depth of the player.
49242 LD A,H Copy it into A.
49243 ADD A,4 Add 4 to it.
49245 LD (IX+5),A Set the new depth.
49248 PUSH HL Stash the old width and depth on the stack.
49249 LD L,(IX+6) Fetch the height of the player.
49252 LD A,L Copy it into A.
49253 ADD A,4 Add 4 to it.
49255 LD (IX+6),A Set the new height.
49258 PUSH HL Stash the old height on the stack.
49259 LD IY,23624 Point IY at ObjectsTable_FirstSpecial.
HandlePickupAndDrop_LookForObject 49263 CALL TestObjectCanBePickedUp Test whether the object can be picked up.
49266 JP C,HandlePickupAndDrop_PickUp Pick it up if it can.
49269 LD DE,32 Set DE to the size of an object.
49272 ADD IY,DE Point IY at the next special object.
49274 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.
49276 CALL TestPickupDropKey Test whether the control is still pressed.
49279 JR Z,HandlePickupAndDrop_Done Finish if it is not.
49281 LD B,2 Set the number of special objects to look at to 2.
49283 LD A,(IX+8) Fetch the room that the player is in.
49286 CP 136 Jump to HandlePickupAndDrop_LookForSpace if it is another room.
49288 JR NZ,HandlePickupAndDrop_LookForSpace
49290 LD B,1 Set the number of special objects to look at to 1.
HandlePickupAndDrop_LookForSpace 49292 LD IY,23624 Point IY at the first special object of the room, ObjectsTable_FirstSpecial.
49296 LD DE,32 Set DE to the size of an object.
HandlePickupAndDrop_TestSlot 49299 LD A,(IY+0) Fetch the graphic number of the special object.
49302 AND A Test whether it is zero.
49303 JR Z,HandlePickupAndDrop_Drop Jump to HandlePickupAndDrop_Drop if the place is free.
49305 ADD IY,DE Point IY at the next special object.
49307 DJNZ HandlePickupAndDrop_TestSlot Jump to HandlePickupAndDrop_TestSlot until all of them have been tried.
Put the size of the player back.
HandlePickupAndDrop_Done 49309 POP HL Restore the old height from the stack.
49310 LD (IX+6),L Set the height of the player.
49313 POP HL Restore the old width and depth from the stack.
49314 LD (IX+4),L Set the width of the player.
49317 LD (IX+5),H Set the depth of the player.
49320 RET Return.
The control was pressed on a frame before: wait until it is let go.
HandlePickupAndDrop_WaitForRelease 49321 CALL TestPickupDropKey Test whether the control is still pressed.
49324 RET NZ Return if it is.
49325 XOR A Clear A.
49326 LD (23475),A Flag that the control is not pressed at PickupDropPressedFlag.
49329 RET Return.
Drop the object that has been carried longest in the free place.
HandlePickupAndDrop_Drop 49330 LD HL,23524 Point HL at the object that has been carried longest, ObjectsCarried_Oldest.
49333 LD A,(HL) Fetch its graphic number.
49334 INC HL Move on to the flags.
49335 AND A Test whether there is an object.
49336 JR Z,HandlePickupAndDrop_Shift Jump to HandlePickupAndDrop_Shift if there is not.
49338 LD A,(23507) Fetch the flag that says no object can be dropped from NoRoomToDropFlag.
49341 AND A Test it.
49342 JR NZ,HandlePickupAndDrop_Done Finish if there is no room.
49344 DEC HL Point HL at the graphic number.
49345 LD A,(HL) Fetch it.
49346 INC HL Move on to the flags.
49347 LD (IY+0),A Set it as the graphic number of the special object.
49350 LD A,(IX+8) Fetch the room that the player is in.
49353 CP 136 Jump to HandlePickupAndDrop_Place if it is another room.
49355 JR NZ,HandlePickupAndDrop_Place
49357 LD A,(IX+3) Fetch the Z coordinate of the player.
49360 CP 152 Jump to HandlePickupAndDrop_Place if the player is below that.
49362 JR C,HandlePickupAndDrop_Place
49364 SET 3,(IY+0) Make the object drop into the cauldron.
49368 LD A,1 Get the value that sets a flag.
49370 LD (23492),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 49373 PUSH HL Stash the address of the flags of the object carried on the stack.
49374 LD BC,3 Set the number of bytes to copy to 3.
49377 PUSH IX Copy IX to HL (using the stack).
49379 POP HL
49380 PUSH IY Copy IY to DE (using the stack).
49382 POP DE
49383 INC DE Point DE at the X coordinate of the object.
49384 INC HL Point HL at the X coordinate of the player.
49385 LDIR Copy the coordinates of the player to the object.
49387 LD A,(IX+3) Fetch the Z coordinate of the player.
49390 ADD A,12 Add 12 to it.
49392 LD (IX+3),A Set the new Z coordinate of the player.
49395 LD A,(IX+35) Fetch the Z coordinate of the top half of the player.
49398 ADD A,12 Add 12 to it.
49400 LD (IX+35),A Set the new Z coordinate of the top half of the player.
49403 PUSH IX Stash IX on the stack.
49405 PUSH IY Copy IY to IX (using the stack), to point at the object.
49407 POP IX
49409 CALL CalculatePixelCoordinates Work out the pixel coordinates of the object.
49412 POP IX Restore IX from the stack.
Set up the rest of the object.
HandlePickupAndDrop_SetObject 49414 LD (IY+4),5 Set the width of the object to 5.
49418 LD (IY+5),5 Set the depth of the object to 5.
49422 LD (IY+6),12 Set the height of the object to 12.
49426 POP HL Restore the address of the flags of the object carried from the stack.
49427 LD A,(HL) Fetch the flags.
49428 INC HL Move on to the address of the table entry.
49429 LD (IY+7),A Set the flags of the object.
49432 LD A,(IX+8) Fetch the room that the player is in.
49435 LD (IY+8),A Set the room of the object.
49438 LD A,(HL) Fetch the low byte of the address of the table entry.
49439 INC HL Move on to the high byte.
49440 LD (IY+16),A Set the low byte of the address of the table entry of the object.
49443 LD A,(HL) Fetch the high byte of the address of the table entry.
49444 LD (IY+17),A Set the high byte of the address of the table entry of the object.
49447 SET 0,(IY+13) 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 49451 LD HL,23523 Point HL at the last byte of the next to last object carried.
49454 LD DE,23527 Point DE at the last byte of the last object carried.
49457 LD BC,12 Set the number of bytes to move to 12.
49460 LDDR Move the objects.
49462 LD DE,23512 Point DE at ObjectsCarried.
49465 LD B,4 Set the number of bytes to clear to 4.
49467 CALL ClearBytes Clear them.
49470 JP HandlePickupAndDrop_Done Jump to HandlePickupAndDrop_Done to finish.
Pick up the object that IY points at.
HandlePickupAndDrop_PickUp 49473 LD HL,23512 Point HL at the space for a new object carried, ObjectsCarried.
49476 XOR A Clear A.
49477 LD (23488),A Allow the spiked balls to drop again at SpikedBallHoldFlag.
49480 LD A,(IY+0) Fetch the graphic number of the object.
49483 LD (HL),A Store it.
49484 INC HL Move on to the flags.
49485 LD A,(IY+7) Fetch the flags of the object.
49488 LD (HL),A Store them.
49489 INC HL Move on to the address of the table entry.
49490 LD E,(IY+16) Fetch the low byte of the address of the table entry of the object.
49493 LD D,(IY+17) Fetch the high byte.
49496 XOR A Clear A.
49497 LD (DE),A Clear the graphic number of the table entry, so that the object is not built again.
49498 LD (HL),E Store the low byte of the address of the table entry.
49499 INC HL Move on to the high byte.
49500 LD (HL),D Store it.
49501 CALL SetWipeAndDrawFlagsForObject Flag the object to be wiped and drawn.
49504 LD (IY+0),1 Make the graphic of the object one that is not shown.
49508 LD HL,23524 Point HL at ObjectsCarried_Oldest.
49511 LD A,(HL) Fetch its graphic number.
49512 INC HL Move on to the flags.
49513 AND A Test whether there is an object.
49514 JR Z,HandlePickupAndDrop_Shift Jump to HandlePickupAndDrop_Shift if there is not.
49516 LD (IY+0),A Make it the graphic of the object that was picked up.
49519 PUSH HL Stash the address of the flags on the stack.
49520 JR HandlePickupAndDrop_SetObject Jump to HandlePickupAndDrop_SetObject to drop it where the other object was.
View the equivalent code in;
Prev: 49147 Up: Map Next: 49522