Prev: 54450 Up: Map Next: 54740
54524: Move and draw the room's foreground scenery items
Follows previous section at 54450
This routine handles the room's foreground objects - originally set up at 50433, and stored in data sets at 32513.
  • Foreground object horizontal position and movement speed is calculated at 2x the values of the rest of the on-screen scenery. This produces a parallax scrolling effect.
  • At Maroc's full speed (32 or -32 depending on left/right direction) foreground scenery objects move 16 pixels, other scenery objects move 8 pixels
  • Unlike the other room elements, foreground scenery items move in whole character or 2 character steps
  • Foreground scenery horizontal position is stored in 1 character/8-pixel steps, rather than 4-pixel/half-character steps like other items
foreground scenery movement
54524 LD A,(60087) Get room number
54527 CP 224 Is it a vertical tunnel room ( >= room 224)?
54529 JP NC,54994 If so, no foreground objects - skip this routine
54532 LD HL,(60272) Get pointer to foreground scenery room object data (32513)
Copy item set data bytes into various working buffer addresses:
54535 LD (60094),HL Store pointer to object data in address pointer buffer
54538 LD A,(HL) First byte of data set
54539 INC HL
54540 CP 255 Is it end-of-data?
54542 JP Z,54740 If so, skip out of this routine
54545 LD B,A Store first byte in B register (used as a counter and checked later at 54657)
54546 LD A,(HL) Second byte of data set
54547 INC HL
54548 LD (60231),A Store second byte of set
54551 LD A,(HL) Get third byte of set - item's horizontal position in room (in character/8-pixel steps)
54552 INC HL
54553 LD (60232),A Store horizontal position for item
54556 LD A,(HL) Get fourth byte of set
54557 INC HL
54558 LD (60233),A Store byte 4 of set
54561 LD A,(HL) Get fifth byte of set - item's vertical position from top of playing area (in pixels)
54562 INC HL
54563 LD (60234),A Store vertical position for item
54566 LD (60114),A Store in second buffer
54569 LD E,(HL) Get address pointer to item graphics
54570 INC HL
54571 LD D,(HL)
54572 INC HL
54573 LD (60109),DE ...and store in graphic address pointer buffer
Convert horizontal position from characters to pixels:
54577 LD HL,(60231) Get horizontal co-ordinate in 8-pixel/character steps (high byte = H register the important bit)
54580 LD D,H Copy to DE register pair
54581 LD E,L
54582 ADD HL,HL x 2
54583 SBC A,A Use the carry flag to identify whether it's a negative or positive offset (left/right)
54584 ADD HL,HL x 4
54585 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
54586 ADD HL,HL x 8
54587 RLA
54588 LD (60116),A ...Store the rotated byte indicating horizontal screen/viewport number in current room
54591 LD A,H The high byte of HL contains the rest of the horizontal position of the object
54592 LD C,A
54593 LD (60115),A Store it
Check Maroc's horizontal movement speed/direction and move the foreground scenery objects accordingly:
54596 LD A,(60164) Maroc's horizontal movement speed
  • Negative values = Maroc is moving right (so scenery is moving left)
  • Positive values = Maroc is moving left (so scenery is moving right)
54599 LD L,A
54600 RLA
54601 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)
54602 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.
54603 ADD HL,HL x 2
54604 ADD HL,HL x 4
54605 ADD HL,HL x 8
54606 ADD HL,HL x 16 (this is the extra that moves the foreground scenery 2x faster than other room elements)
54607 ADD HL,DE Add speed offset to horizontal screen position
54608 LD (60231),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.
54611 ADD HL,HL x 2
54612 SBC A,A Use the carry bit to determine whether the offset value is negative or positive (depending on direction)
54613 ADD HL,HL x 4
54614 RLA
54615 ADD HL,HL x 8
54616 RLA
54617 LD (60108),A Store the high byte - indicating negative (255) or positive (0)
54620 LD A,H And the low byte, containing the horizontal pixel co-ordinate
54621 LD (60107),A
54624 CP C Has the scenery item's horizontal position changed at all?
54625 JR Z,54629
54627 INC B If so, increment a flag in B register
54628 INC B
Check vertical movement speed/direction and move the foreground scenery objects accordingly:
54629 LD HL,(60233) Get vertical screen pixel co-ordinate
54632 EX DE,HL Copy into DE register
54633 LD A,(60165) Get vertical movement speed/direction (negative = Maroc moving down, positive = Maroc moving up)
54636 LD L,0 Clear L register
54638 SRA A Divide speed offset by 2...
54640 RR L Rotate carry remainder offset into L register
54642 SRA A Divide speed offset by 4...
54644 RR L Rotate carry remainder offset into L register
54646 LD H,A
54647 ADD HL,DE Add the offset to the vertical pixel position
54648 LD (60233),HL ...and store new position.
54651 LD A,H Has the scenery item's vertical position changed at all?
54652 CP D
54653 JR Z,54657
54655 INC B If so, increment a flag in B register
54656 INC B
Check if either horizontal or vertical position has changed - the B register has been updated if so:
  • 0 = neither horizontal or vertical position changed
  • 2 = either horizontal or vertical position changed
  • 4 = both horizontal and vertical position changed
54657 LD A,B
54658 CP 2
54660 JR C,54690 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:
54662 LD A,0 Set draw/erase flag to 0 (ERASE)
54664 LD (60111),A
54667 CALL 56737 Erase the foreground scenery item
54670 LD A,(60107)
54673 LD (60115),A Copy the item's calculated horizontal (pixel) screen position into working graphic buffer
54676 LD A,(60234)
54679 LD (60114),A Copy the item's calculated vertical (pixel) screen position into working graphic buffer
54682 LD A,(60108)
54685 LD (60116),A Also copy the horizontal co-ordinate high byte
54688 JR 54699
Check for item movement again:
54690 CP 0
54692 JR NZ,54699
54694 LD (60117),A Flag indicating whether (any part of) graphic needs drawing on screen - nothing's changed movement-wise since last check, so set to zero
54697 JR 54707 ...and skip draw routine
Item needs drawing on screen:
54699 LD A,1 Set draw/erase flag to 1 (DRAW)
54701 LD (60111),A
54704 CALL 56737 Draw the foreground scenery item
Copy scenery item data into data sets at 32513
54707 LD HL,(60094) (Copy of) pointer to scenery item data at 32513
54710 LD A,(60117) Flag indicating whether (any part of) graphic is visible on screen
54713 LD (HL),A Store in (first byte of) scenery data item
54714 INC HL
54715 LD A,(60231)
54718 LD (HL),A Put horizontal object position overflow/precision offset into byte 2 of set
54719 INC HL
54720 LD A,(60232)
54723 LD (HL),A Put horizontal object position into byte 3 of set
54724 INC HL
54725 LD A,(60233)
54728 LD (HL),A Put vertical object position overflow/precision offset into byte 4 of set
54729 INC HL
54730 LD A,(60234)
54733 LD (HL),A Put vertical object position into byte 5 of set
54734 INC HL Move pointer along to next data set item at 32513
54735 INC HL
54736 INC HL
54737 JP 54535 Continue to deal with (move, erase and draw) foreground scenery items
Next routine is at 54740 (after all foreground scenery items dealt with)
Prev: 54450 Up: Map Next: 54740