Routines |
Prev: D4B2 | Up: Map | Next: D5D4 |
Follows previous section at D4B2
|
||||
This routine handles the room's foreground objects - originally set up at C501, and stored in data sets at 7F01.
|
||||
D4FC | LD A,($EAB7) | Get room number | ||
D4FF | CP $E0 | Is it a vertical tunnel room ( >= room 224)? | ||
D501 | JP NC,$D6D2 | If so, no foreground objects - skip this routine | ||
D504 | LD HL,($EB70) | Get pointer to foreground scenery room object data (7F01) | ||
Copy item set data bytes into various working buffer addresses:
|
||||
D507 | LD ($EABE),HL | Store pointer to object data in address pointer buffer | ||
D50A | LD A,(HL) | First byte of data set | ||
D50B | INC HL | |||
D50C | CP $FF | Is it end-of-data? | ||
D50E | JP Z,$D5D4 | If so, skip out of this routine | ||
D511 | LD B,A | Store first byte in B register (used as a counter and checked later at D581) | ||
D512 | LD A,(HL) | Second byte of data set | ||
D513 | INC HL | |||
D514 | LD ($EB47),A | Store second byte of set | ||
D517 | LD A,(HL) | Get third byte of set - item's horizontal position in room (in character/8-pixel steps) | ||
D518 | INC HL | |||
D519 | LD ($EB48),A | Store horizontal position for item | ||
D51C | LD A,(HL) | Get fourth byte of set | ||
D51D | INC HL | |||
D51E | LD ($EB49),A | Store byte 4 of set | ||
D521 | LD A,(HL) | Get fifth byte of set - item's vertical position from top of playing area (in pixels) | ||
D522 | INC HL | |||
D523 | LD ($EB4A),A | Store vertical position for item | ||
D526 | LD ($EAD2),A | Store in second buffer | ||
D529 | LD E,(HL) | Get address pointer to item graphics | ||
D52A | INC HL | |||
D52B | LD D,(HL) | |||
D52C | INC HL | |||
D52D | LD ($EACD),DE | ...and store in graphic address pointer buffer | ||
Convert horizontal position from characters to pixels:
|
||||
D531 | LD HL,($EB47) | Get horizontal co-ordinate in 8-pixel/character steps (high byte = H register the important bit) | ||
D534 | LD D,H | Copy to DE register pair | ||
D535 | LD E,L | |||
D536 | ADD HL,HL | x 2 | ||
D537 | SBC A,A | Use the carry flag to identify whether it's a negative or positive offset (left/right) | ||
D538 | ADD HL,HL | x 4 | ||
D539 | RLA | The RLA rotates increase (or decrease if negative) the accumulator, and this gives us an idea of which screen (i.e. left/right of the current viewport) the scenery object is in | ||
D53A | ADD HL,HL | x 8 | ||
D53B | RLA | |||
D53C | LD ($EAD4),A | ...Store the rotated byte indicating horizontal screen/viewport number in current room | ||
D53F | LD A,H | The high byte of HL contains the rest of the horizontal position of the object | ||
D540 | LD C,A | |||
D541 | LD ($EAD3),A | Store it | ||
Check Maroc's horizontal movement speed/direction and move the foreground scenery objects accordingly:
|
||||
D544 | LD A,($EB04) | Maroc's horizontal movement speed
|
||
D547 | LD L,A | |||
D548 | RLA | |||
D549 | SBC A,A | Using an RLA followed by a SBC means the carry flag indicates left/right direction using the H register (e.g. 255 = Maroc moving right, 0 = Maroc moving left) | ||
D54A | LD H,A | Store this value in the high byte (H), which will cause an addition/subtraction in the next instructions, depending on left/right direction. | ||
D54B | ADD HL,HL | x 2 | ||
D54C | ADD HL,HL | x 4 | ||
D54D | ADD HL,HL | x 8 | ||
D54E | ADD HL,HL | x 16 (this is the extra that moves the foreground scenery 2x faster than other room elements) | ||
D54F | ADD HL,DE | Add speed offset to horizontal screen position | ||
D550 | LD ($EB47),HL | ...and store | ||
The high byte (H) of the calculation calculated byte is a character square co-ordinate, the low byte (L) containing a fractions/remainder value. Multiply by 8 to convert to pixel values.
|
||||
D553 | ADD HL,HL | x 2 | ||
D554 | SBC A,A | Use the carry bit to determine whether the offset value is negative or positive (depending on direction) | ||
D555 | ADD HL,HL | x 4 | ||
D556 | RLA | |||
D557 | ADD HL,HL | x 8 | ||
D558 | RLA | |||
D559 | LD ($EACC),A | Store the high byte - indicating negative (255) or positive (0) | ||
D55C | LD A,H | And the low byte, containing the horizontal pixel co-ordinate | ||
D55D | LD ($EACB),A | |||
D560 | CP C | Has the scenery item's horizontal position changed at all? | ||
D561 | JR Z,$D565 | |||
D563 | INC B | If so, increment a flag in B register | ||
D564 | INC B | |||
Check vertical movement speed/direction and move the foreground scenery objects accordingly:
|
||||
D565 | LD HL,($EB49) | Get vertical screen pixel co-ordinate | ||
D568 | EX DE,HL | Copy into DE register | ||
D569 | LD A,($EB05) | Get vertical movement speed/direction (negative = Maroc moving down, positive = Maroc moving up) | ||
D56C | LD L,$00 | Clear L register | ||
D56E | SRA A | Divide speed offset by 2... | ||
D570 | RR L | Rotate carry remainder offset into L register | ||
D572 | SRA A | Divide speed offset by 4... | ||
D574 | RR L | Rotate carry remainder offset into L register | ||
D576 | LD H,A | |||
D577 | ADD HL,DE | Add the offset to the vertical pixel position | ||
D578 | LD ($EB49),HL | ...and store new position. | ||
D57B | LD A,H | Has the scenery item's vertical position changed at all? | ||
D57C | CP D | |||
D57D | JR Z,$D581 | |||
D57F | INC B | If so, increment a flag in B register | ||
D580 | INC B | |||
Check if either horizontal or vertical position has changed - the B register has been updated if so:
|
||||
D581 | LD A,B | |||
D582 | CP $02 | |||
D584 | JR C,$D5A2 | Carry here means neither position has changed - no need to erase anything so skip the next few instructions | ||
The item has moved, so it'll need erasing at its pre-move position:
|
||||
D586 | LD A,$00 | Set draw/erase flag to 0 (ERASE) | ||
D588 | LD ($EACF),A | |||
D58B | CALL $DDA1 | Erase the foreground scenery item | ||
D58E | LD A,($EACB) | |||
D591 | LD ($EAD3),A | Copy the item's calculated horizontal (pixel) screen position into working graphic buffer | ||
D594 | LD A,($EB4A) | |||
D597 | LD ($EAD2),A | Copy the item's calculated vertical (pixel) screen position into working graphic buffer | ||
D59A | LD A,($EACC) | |||
D59D | LD ($EAD4),A | Also copy the horizontal co-ordinate high byte | ||
D5A0 | JR $D5AB | |||
Check for item movement again:
|
||||
D5A2 | CP $00 | |||
D5A4 | JR NZ,$D5AB | |||
D5A6 | LD ($EAD5),A | Flag indicating whether (any part of) graphic needs drawing on screen - nothing's changed movement-wise since last check, so set to zero | ||
D5A9 | JR $D5B3 | ...and skip draw routine | ||
Item needs drawing on screen:
|
||||
D5AB | LD A,$01 | Set draw/erase flag to 1 (DRAW) | ||
D5AD | LD ($EACF),A | |||
D5B0 | CALL $DDA1 | Draw the foreground scenery item | ||
Copy scenery item data into data sets at 7F01
|
||||
D5B3 | LD HL,($EABE) | (Copy of) pointer to scenery item data at 7F01 | ||
D5B6 | LD A,($EAD5) | Flag indicating whether (any part of) graphic is visible on screen | ||
D5B9 | LD (HL),A | Store in (first byte of) scenery data item | ||
D5BA | INC HL | |||
D5BB | LD A,($EB47) | |||
D5BE | LD (HL),A | Put horizontal object position overflow/precision offset into byte 2 of set | ||
D5BF | INC HL | |||
D5C0 | LD A,($EB48) | |||
D5C3 | LD (HL),A | Put horizontal object position into byte 3 of set | ||
D5C4 | INC HL | |||
D5C5 | LD A,($EB49) | |||
D5C8 | LD (HL),A | Put vertical object position overflow/precision offset into byte 4 of set | ||
D5C9 | INC HL | |||
D5CA | LD A,($EB4A) | |||
D5CD | LD (HL),A | Put vertical object position into byte 5 of set | ||
D5CE | INC HL | Move pointer along to next data set item at 7F01 | ||
D5CF | INC HL | |||
D5D0 | INC HL | |||
D5D1 | JP $D507 | Continue to deal with (move, erase and draw) foreground scenery items | ||
Next routine is at D5D4 (after all foreground scenery items dealt with)
|
Prev: D4B2 | Up: Map | Next: D5D4 |