Prev: BD58 Up: Map Next: BEA7
BD6B: Pick up, or put down
Used by the routine at PLAYER_LEGS.
Called from the legs' update routine (PLAYER_LEGS) every turn. One press does one thing: pick up a valve he is on or beside; failing that, put down the last of the things he carries (CARRIED_LAST), under himself, so that he stands on it; and if there is nothing in that slot, move what he carries one slot along towards it. TAKE_HELD latches the press, so holding the key does nothing more, and every press that gets past the tests below beeps (PLAIN_BEEP). Knight Lore's handle_pickup_drop and the routines after it, joined into one, as in Pentagram.
Nothing happens unless he is inside the room's walls (CHK_PLYR_OOB, not in a doorway), not jumping (bit 3 of +$0C) and standing on something (bit 2). Before anything else it looks for an object in the space he would fill if he were lifted 12 units (DO_ANY_OBJS_INTERSECT): if there is one, NO_HEADROOM is set and nothing is put down, because putting something down lifts him 12 units onto it.
Only the two records at VALVES are looked at, for a thing to pick up and for a record to put one down in: the records that hold what lies in the room from the table of places (PLACES). So only a valve that lies in its place can be picked up, and a thing can be put down only while one of the two is empty: a room holds at most two valves.
He carries up to three things, in the four-byte slots CARRIED (the newest), the one after, and CARRIED_LAST (the oldest, put down next): the graphic, the flags from +7, and the address of the thing's place (PLACES). CARRIED_NEW is a fourth slot in front of them, where a thing just picked up waits for the slots to be moved along. They behave as a queue, and a press that puts nothing down moves them along: one thing carried takes three presses to reach CARRIED_LAST and a fourth to be put down (measured by the build's sessions: see the notes' driving recipe).
Input
IX the robot's legs (OBJECTS)
TAKE_OR_LEAVE BD6B LD A,(TAKE_HELD) the key is still held from the last press: wait for it to go up
BD6E AND A
BD6F JP NZ,WAIT_TAKE_RELEASE
BD72 CALL CHK_PICKUP_DROP not pressed: nothing to do
BD75 RET Z
BD76 CALL CHK_PLYR_OOB only inside the room's walls
BD79 RET NC
BD7A BIT 3,(IX+$0C) not while jumping (bit 3 of +$0C); only when standing on something (bit 2)
BD7E RET NZ
BD7F BIT 2,(IX+$0C)
BD83 RET Z
BD84 XOR A anything in the space he would fill lifted by 12? His Z is raised to look, with the legs as high as the whole robot (PLAYER_LEGS), then put back
BD85 LD (NO_HEADROOM),A
BD88 LD A,(IX+$03)
BD8B LD B,A
BD8C ADD A,$0C
BD8E LD (IX+$03),A
BD91 CALL DO_ANY_OBJS_INTERSECT
BD94 LD (IX+$03),B
BD97 JR NC,TAKE_OR_LEAVE_0
BD99 LD A,$01 yes: there is no room for him to stand on what he puts down
BD9B LD (NO_HEADROOM),A
TAKE_OR_LEAVE_0 BD9E CALL PLAIN_BEEP beep; latch the key, and have the panel's carried things redrawn (SHOW_CARRIED)
BDA1 LD A,$01
BDA3 LD (TAKE_HELD),A
BDA6 LD (PANEL_DUE),A
BDA9 LD B,$02 each half-size 4 more, so that a thing just out of reach counts; the old ones go on the stack
BDAB LD L,(IX+$04)
BDAE LD A,L
BDAF ADD A,$04
BDB1 LD (IX+$04),A
BDB4 LD H,(IX+$05)
BDB7 LD A,H
BDB8 ADD A,$04
BDBA LD (IX+$05),A
BDBD PUSH HL
BDBE LD L,(IX+$06)
BDC1 LD A,L
BDC2 ADD A,$04
BDC4 LD (IX+$06),A
BDC7 PUSH HL
BDC8 LD IY,VALVES the two records of what lies in the room: the first that can be picked up (CAN_PICK_UP) is taken
TAKE_OR_LEAVE_1 BDCC CALL CAN_PICK_UP
BDCF JP C,PICK_UP_VALVE
BDD2 LD DE,$0020
BDD5 ADD IY,DE
BDD7 DJNZ TAKE_OR_LEAVE_1
BDD9 CALL CHK_PICKUP_DROP nothing to pick up. This test cannot fail: INPUT has not changed since the same test at the start
BDDC JR Z,TAKE_DONE
BDDE LD B,$02 the first empty record of the two, to put a thing down in; none: nothing is put down
BDE0 LD IY,VALVES
BDE4 LD DE,$0020
TAKE_OR_LEAVE_2 BDE7 LD A,(IY+$00)
BDEA AND A
BDEB JR Z,PUT_DOWN_LAST
BDED ADD IY,DE
BDEF DJNZ TAKE_OR_LEAVE_2
TAKE_DONE BDF1 POP HL his half-sizes back
BDF2 LD (IX+$06),L
BDF5 POP HL
BDF6 LD (IX+$04),L
BDF9 LD (IX+$05),H
BDFC RET
WAIT_TAKE_RELEASE BDFD CALL CHK_PICKUP_DROP clear the latch once the key is up
BE00 RET NZ
BE01 XOR A
BE02 LD (TAKE_HELD),A
BE05 RET
Put down the last thing he carries, into the empty record at IY.
PUT_DOWN_LAST BE06 LD HL,CARRIED_LAST nothing in the last slot: just move the slots along
BE09 LD A,(HL)
BE0A INC HL
BE0B AND A
BE0C JR Z,SHIFT_CARRIED
BE0E LD A,(NO_HEADROOM) no headroom: put nothing down
BE11 AND A
BE12 JR NZ,TAKE_DONE
BE14 DEC HL the thing's graphic into the empty record; HL on to the slot's flags
BE15 LD A,(HL)
BE16 INC HL
BE17 LD (IY+$00),A
BE1A PUSH HL U, V and Z from the robot's legs, so that it goes down where he stands
BE1B LD BC,$0003
BE1E PUSH IX
BE20 POP HL
BE21 PUSH IY
BE23 POP DE
BE24 INC DE
BE25 INC HL
BE26 LDIR
BE28 LD A,(IX+$03) lift both of his records by 12, the thing's height, so that he stands on it
BE2B ADD A,$0C
BE2D LD (IX+$03),A
BE30 LD A,(IX+$23)
BE33 ADD A,$0C
BE35 LD (IX+$23),A
BE38 CALL CALC_PIXEL_XY_IY its place on the screen (CALC_PIXEL_XY_IY)
Fill in the record of a thing put down: IY the record, its graphic and position already set; the slot's flags byte on the stack.
FILL_PUT_DOWN BE3B LD (IY+$04),$05 half-sizes 5, 5 and 12
BE3F LD (IY+$05),$05
BE43 LD (IY+$06),$0C
BE47 POP HL +7 the flags from the slot; +8 the room, the robot's
BE48 LD A,(HL)
BE49 INC HL
BE4A LD (IY+$07),A
BE4D LD A,(IX+$08)
BE50 LD (IY+$08),A
BE53 LD A,(HL) +$10 and +$11: the address of its place, from the slot. The place itself is not written: when he leaves the room UPDATE_SPECIAL_OBJS copies where the valve now lies into it
BE54 INC HL
BE55 LD (IY+$10),A
BE58 LD A,(HL)
BE59 LD (IY+$11),A
BE5C SET 0,(IY+$0D) bit 0 of +$0D: just put down, which the valve's update routine (LOOSE_VALVE) reads once
Move the carried things one slot along.
SHIFT_CARRIED BE60 LD HL,$5B83 twelve bytes up by four, copied from the top down so that they do not overwrite themselves: CARRIED_NEW moves into CARRIED, and so on to CARRIED_LAST
BE63 LD DE,$5B87
BE66 LD BC,$000C
BE69 LDDR
BE6B LD DE,CARRIED_NEW CARRIED_NEW is empty
BE6E LD B,$04
BE70 CALL ZERO_DE
BE73 JP TAKE_DONE
Pick up the valve at IY.
PICK_UP_VALVE BE76 LD HL,CARRIED_NEW picking something up lets the things on the ceiling drop (DROP_LATCH)
BE79 XOR A
BE7A LD (DROP_LATCH),A
BE7D LD A,(IY+$00) graphic, flags and place's address into CARRIED_NEW; the place's graphic zeroed, so that the valve is not put back in its room when he leaves or comes back
BE80 LD (HL),A
BE81 INC HL
BE82 LD A,(IY+$07)
BE85 LD (HL),A
BE86 INC HL
BE87 LD E,(IY+$10)
BE8A LD D,(IY+$11)
BE8D XOR A
BE8E LD (DE),A
BE8F LD (HL),E
BE90 INC HL
BE91 LD (HL),D
BE92 CALL SET_WIPE_AND_DRAW_IY mark it to be rubbed out (SET_WIPE_AND_DRAW_IY), and make it graphic 1, which the drawing code rubs out and then empties
BE95 LD (IY+$00),$01
BE99 LD HL,CARRIED_LAST carrying nothing in the last slot: move the slots along
BE9C LD A,(HL)
BE9D INC HL
BE9E AND A
BE9F JR Z,SHIFT_CARRIED
BEA1 LD (IY+$00),A three: the oldest goes down where this one was, in the same record -- picking up swaps (this never ran in the build's sessions)
BEA4 PUSH HL
BEA5 JR FILL_PUT_DOWN
Prev: BD58 Up: Map Next: BEA7