Prev: 90C0 Up: Map Next: 93BB
91BE: Draw the rope, arrows and guardians in the current room
Used by the routine at 89AD. Draws the rope, arrows and guardians in the current room to the screen buffer at 6000.
91BE LD IX,$8100 Point IX at the first byte of the first entity buffer at 8100
The drawing loop begins here.
91C2 LD A,(IX+$00) Pick up the first byte of the current entity's buffer
91C5 CP $FF Have we already dealt with every entity?
91C7 RET Z Return if so
91C8 AND $07 Keep only bits 0-2 (which determine the type of entity)
91CA JP Z,$93B3 Jump to consider the next entity buffer if this one is not being used
91CD CP $03 Is this a rope?
91CF JP Z,$92A4 Jump if so
91D2 CP $04 Is this an arrow?
91D4 JR Z,$9237 Jump if so
We are dealing with a horizontal or vertical guardian.
91D6 LD E,(IX+$03) Point DE at the entry in the screen buffer address lookup table at 8200 that corresponds to the guardian's y-coordinate
91D9 LD D,$82
91DB LD A,(DE) Copy the LSB of the screen buffer address to L
91DC LD L,A
91DD LD A,(IX+$02) Pick up the guardian's x-coordinate from bits 0-4 of the third byte of its buffer
91E0 AND $1F
91E2 ADD A,L Adjust the LSB of the screen buffer address in L for the guardian's x-coordinate
91E3 LD L,A
91E4 LD A,E Copy the fourth byte of the guardian's buffer to A
91E5 RLCA H=0x5C or 0x5D; now HL holds the address of the guardian's current location in the attribute buffer at 5C00
91E6 AND $01
91E8 OR $5C
91EA LD H,A
91EB LD DE,$001F Prepare DE for later addition
91EE LD A,(IX+$01) Pick up the second byte of the guardian's buffer
91F1 AND $0F Keep only bits 0-2 (INK colour) and 3 (BRIGHT value)
91F3 ADD A,$38 Push bit 3 up to bit 6
91F5 AND $47 Keep only bits 0-2 (INK colour) and 6 (BRIGHT value)
91F7 LD C,A Save this value in C temporarily
91F8 LD A,(HL) Pick up the room attribute byte at the guardian's location from the buffer at 5C00
91F9 AND $38 Keep only bits 3-5 (PAPER colour)
91FB XOR C Merge the INK colour and BRIGHT value from C
91FC LD C,A Copy this attribute value to C
91FD LD (HL),C Set the attribute bytes in the buffer at 5C00 for the top two rows of cells occupied by the guardian's sprite
91FE INC HL
91FF LD (HL),C
9200 ADD HL,DE
9201 LD (HL),C
9202 INC HL
9203 LD (HL),C
9204 LD A,(IX+$03) Pick up the fourth byte of the guardian's buffer
9207 AND $0E Does the guardian's sprite occupy only two rows of cells at the moment?
9209 JR Z,$920F Jump if so
920B ADD HL,DE Set the attribute bytes in the buffer at 5C00 for the third row of cells occupied by the guardian's sprite
920C LD (HL),C
920D INC HL
920E LD (HL),C
920F LD C,$01 Prepare C for the call to 9456 later on
9211 LD A,(IX+$01) Now bits 5-7 of A hold the animation frame mask
9214 AND (IX+$00) 'AND' on the current animation frame (bits 5-7)
9217 OR (IX+$02) 'OR' on the base sprite index (bits 5-7)
921A AND $E0 Keep only bits 5-7
921C LD E,A Point DE at the graphic data for the guardian's current animation frame (see AB00)
921D LD D,(IX+$05)
9220 LD H,$82 Point HL at the guardian's current location in the screen buffer at 6000
9222 LD L,(IX+$03)
9225 LD A,(IX+$02)
9228 AND $1F
922A OR (HL)
922B INC HL
922C LD H,(HL)
922D LD L,A
922E CALL $9456 Draw the guardian
9231 JP NZ,$90B7 Kill Willy if the guardian collided with him
9234 JP $93B3 Jump to consider the next entity
We are dealing with an arrow.
9237 BIT 7,(IX+$00) Is the arrow travelling left to right?
923B JR NZ,$9244 Jump if so
923D DEC (IX+$04) Decrement the arrow's x-coordinate
9240 LD C,$2C The sound effect for an arrow travelling right to left is made when the x-coordinate is 44
9242 JR $9249
9244 INC (IX+$04) Increment the arrow's x-coordinate
9247 LD C,$F4 The sound effect for an arrow travelling left to right is made when the x-coordinate is 244
9249 LD A,(IX+$04) Pick up the arrow's x-coordinate (0-255)
924C CP C Is it time to make the arrow sound effect?
924D JR NZ,$9262 Jump if not
924F LD BC,$0280 Prepare the delay counters (B=0x02, C=0x80) for the arrow sound effect
9252 LD A,($80DE) Pick up the border colour for the current room from 80DE
9255 OUT ($FE),A Produce the arrow sound effect
9257 XOR $18
9259 DJNZ $9259
925B LD B,C
925C DEC C
925D JR NZ,$9255
925F JP $93B3 Jump to consider the next entity
9262 AND $E0 Is the arrow's x-coordinate in the range 0-31 (i.e. on-screen)?
9264 JP NZ,$93B3 If not, jump to consider the next entity
9267 LD E,(IX+$02) Point DE at the entry in the screen buffer address lookup table at 8200 that corresponds to the arrow's y-coordinate
926A LD D,$82
926C LD A,(DE) Pick up the LSB of the screen buffer address
926D ADD A,(IX+$04) Adjust it for the arrow's x-coordinate
9270 LD L,A Point HL at the arrow's current location in the attribute buffer at 5C00
9271 LD A,E
9272 AND $80
9274 RLCA
9275 OR $5C
9277 LD H,A
9278 LD (IX+$05),$00 Initialise the collision detection byte (0x00=off, 0xFF=on)
927C LD A,(HL) Pick up the room attribute byte at the arrow's location
927D AND $07 Keep only bits 0-2 (INK colour)
927F CP $07 Is the INK white?
9281 JR NZ,$9286 Jump if not
9283 DEC (IX+$05) Activate collision detection
9286 LD A,(HL) Set the INK colour to white at the arrow's location
9287 OR $07
9289 LD (HL),A
928A INC DE Pick up the MSB of the screen buffer address for the arrow's location
928B LD A,(DE)
928C LD H,A Point HL at the top pixel row of the arrow's location in the screen buffer at 6000
928D DEC H
928E LD A,(IX+$06) Draw the top pixel row of the arrow
9291 LD (HL),A
9292 INC H Point HL at the middle pixel row of the arrow's location in the screen buffer at 6000
9293 LD A,(HL) Pick up the graphic byte that's already here
9294 AND (IX+$05) Has the arrow hit anything that has white INK (e.g. Willy)?
9297 JP NZ,$90B7 If so, kill Willy
929A LD (HL),$FF Draw the shaft of the arrow
929C INC H Point HL at the bottom pixel row of the arrow's location in the screen buffer at 6000
929D LD A,(IX+$06) Draw the bottom pixel row of the arrow
92A0 LD (HL),A
92A1 JP $93B3 Jump to consider the next entity
We are dealing with a rope.
92A4 LD IY,$8200 Point IY at the first byte of the screen buffer address lookup table at 8200
92A8 LD (IX+$09),$00 Initialise the second byte in the following entity buffer to zero; this will count the segments of rope to draw
92AC LD A,(IX+$02) Initialise the fourth byte of the rope's buffer; this holds the x-coordinate of the cell in which the segment of rope under consideration will be drawn
92AF LD (IX+$03),A
92B2 LD (IX+$05),$80 Initialise the sixth byte of the rope's buffer to 0x80 (bit 7 set); the value held here is used to draw the segment of rope under consideration
The following loop draws each segment of the rope from top to bottom.
92B6 LD A,(IY+$00) Point HL at the location of the segment of rope under consideration in the screen buffer at 6000
92B9 ADD A,(IX+$03)
92BC LD L,A
92BD LD H,(IY+$01)
92C0 LD A,($85D6) Pick up the rope status indicator at 85D6
92C3 OR A Is Willy on the rope, or has he recently jumped or dropped off it?
92C4 JR NZ,$92D6 Jump if so
92C6 LD A,(IX+$05) Pick up the drawing byte
92C9 AND (HL) Is this segment of rope touching anything else that's been drawn so far (e.g. Willy)?
92CA JR Z,$930E Jump if not
92CC LD A,(IX+$09) Copy the segment counter into the rope status indicator at 85D6
92CF LD ($85D6),A
92D2 SET 0,(IX+$0B) Signal: Willy is on the rope
92D6 CP (IX+$09) Does the rope status indicator at 85D6 match the segment counter?
92D9 JR NZ,$930E Jump if not
92DB BIT 0,(IX+$0B) Is Willy on the rope (and clinging to this particular segment)?
92DF JR Z,$930E Jump if not
92E1 LD B,(IX+$03) Copy the x-coordinate of the cell containing the segment of rope under consideration to B
92E4 LD A,(IX+$05) Pick up the drawing byte in A
92E7 LD C,$01 The value in C will specify Willy's next animation frame; initialise it to 1
92E9 CP $04 Is the set bit of the drawing byte in bit 0 or 1?
92EB JR C,$92FC Jump if so
92ED LD C,$00 Assume that Willy's next animation frame will be 0
92EF CP $10 Is the set bit of the drawing byte in bit 2 or 3?
92F1 JR C,$92FC Jump if so
92F3 DEC B Decrement the x-coordinate
92F4 LD C,$03 Assume that Willy's next animation frame will be 3
92F6 CP $40 Is the set bit of the drawing byte in bit 4 or 5?
92F8 JR C,$92FC Jump if so
92FA LD C,$02 Willy's next animation frame will be 2 (the set bit of the drawing byte is in bit 6 or 7)
92FC LD ($85D2),BC Set Willy's animation frame at 85D2, and temporarily store his x-coordinate at 85D3
9300 LD A,IYl Update Willy's y-coordinate at 85CF to account for his change of location as the rope moves
9302 SUB $10
9304 LD ($85CF),A
9307 PUSH HL Save HL briefly
9308 CALL $8E9C Update Willy's attribute buffer address at 85D3 to account for his change of location as the rope moves
930B POP HL Restore the screen buffer address of the segment of rope under consideration to HL
930C JR $930E Make a redundant jump to the next instruction
930E LD A,(IX+$05) Draw a pixel of the rope to the screen buffer at 6000
9311 OR (HL)
9312 LD (HL),A
9313 LD A,(IX+$09) Point HL at the relevant entry in the second half of the rope animation table at 8300
9316 ADD A,(IX+$01)
9319 LD L,A
931A SET 7,L
931C LD H,$83
931E LD E,(HL) Add its value to IY; now IY points at the entry in the screen buffer address lookup table at 8200 that corresponds to the next segment of rope to consider
931F LD D,$00
9321 ADD IY,DE
9323 RES 7,L Point HL at the relevant entry in the first half of the rope animation table at 8300
9325 LD A,(HL) Pick up its value
9326 OR A Is it zero?
9327 JR Z,$9350 Jump if so
9329 LD B,A Copy the rope animation table entry value to B; this will count the rotations of the drawing byte
932A BIT 7,(IX+$01) Is the rope currently right of centre?
932E JR Z,$9341 Jump if so
9330 RLC (IX+$05) Rotate the drawing byte left once
9334 BIT 0,(IX+$05) Did that push the set bit from bit 7 into bit 0?
9338 JR Z,$933D Jump if not
933A DEC (IX+$03) Decrement the x-coordinate for the cell containing this segment of rope
933D DJNZ $9330 Jump back until the drawing byte has been rotated as required
933F JR $9350 Jump to consider the next segment of rope
9341 RRC (IX+$05) Rotate the drawing byte right once
9345 BIT 7,(IX+$05) Did that push the set bit from bit 0 into bit 7?
9349 JR Z,$934E Jump if not
934B INC (IX+$03) Increment the x-coordinate for the cell containing this segment of rope
934E DJNZ $9341 Jump back until the drawing byte has been rotated as required
9350 LD A,(IX+$09) Pick up the segment counter
9353 CP (IX+$04) Have we drawn every segment of the rope yet?
9356 JR Z,$935E Jump if so
9358 INC (IX+$09) Increment the segment counter
935B JP $92B6 Jump back to draw the next segment of rope
Now that the entire rope has been drawn, deal with Willy's movement along it.
935E LD A,($85D6) Pick up the rope status indicator at 85D6
9361 BIT 7,A Has Willy recently jumped off the rope or dropped off the bottom of it (A>=0xF0)?
9363 JR Z,$936F Jump if not
9365 INC A Update the rope status indicator at 85D6
9366 LD ($85D6),A
9369 RES 0,(IX+$0B) Signal: Willy is not on the rope
936D JR $93B3 Jump to consider the next entity
936F BIT 0,(IX+$0B) Is Willy on the rope?
9373 JR Z,$93B3 If not, jump to consider the next entity
9375 LD A,($85D0) Pick up Willy's direction and movement flags from 85D0
9378 BIT 1,A Is Willy moving up or down the rope?
937A JR Z,$93B3 If not, jump to consider the next entity
937C RRCA XOR Willy's direction bit (0=facing right, 1=facing left) with the rope's direction bit (0=swinging right to left, 1=swinging left to right)
937D XOR (IX+$00)
9380 RLCA
9381 RLCA Now A=1 if Willy is facing the same direction as the rope is swinging (he will move down the rope), or -1 otherwise (he will move up the rope)
9382 AND $02
9384 DEC A
9385 LD HL,$85D6 Increment or decrement the rope status indicator at 85D6
9388 ADD A,(HL)
9389 LD (HL),A
938A LD A,($80EB) Pick up the number of the room above from 80EB and copy it to C
938D LD C,A
938E LD A,($8420) Pick up the number of the current room from 8420
9391 CP C Is there a room above this one?
9392 JR NZ,$939B Jump if so
9394 LD A,(HL) Pick up the rope status indicator at 85D6
9395 CP $0C Is it 0x0C or greater?
9397 JR NC,$939B Jump if so
9399 LD (HL),$0C Set the rope status indicator at 85D6 to 0x0C (there is nowhere to go above this rope)
939B LD A,(HL) Pick up the rope status indicator at 85D6
939C CP (IX+$04) Compare it with the length of the rope
939F JR C,$93B3 If Willy is at or above the bottom of the rope, jump to consider the next entity
93A1 JR Z,$93B3
93A3 LD (HL),$F0 Set the rope status indicator at 85D6 to 0xF0 (Willy has just dropped off the bottom of the rope)
93A5 LD A,($85CF) Round down Willy's y-coordinate at 85CF to the nearest multiple of 8; this might move him upwards a little, but ensures that his actual pixel y-coordinate is a multiple of 4 before he starts falling
93A8 AND $F8
93AA LD ($85CF),A
93AD XOR A Initialise the airborne status indicator at 85D1
93AE LD ($85D1),A
93B1 JR $93B3 Make a redundant jump to the next instruction
The current entity has been dealt with. Time for the next one.
93B3 LD DE,$0008 Point IX at the first byte of the next entity's buffer
93B6 ADD IX,DE
93B8 JP $91C2 Jump back to deal with it
Prev: 90C0 Up: Map Next: 93BB