Prev: A4F6 Up: Map Next: A60E
A579: Lays out roadside objects
Two passes over up to 21 road slots. The first walks object_positions and turns the run of per-slot sizes into running totals, so each entry ends up holding where that slot's strip of objects starts.
The second reads the lanes byte for each slot from the road buffer and pushes a left and right pair of 16-bit x positions onto a stack growing down from $EB00. Bits 1 and 0 of the lane offset choose the table the left boundary comes from and bits 7 to 2 choose the one for the right; fork slots use the centre and centre right tables directly.
Used by the routines at main_loop, drive_attract_demo and escape_scene.
layout_objects A579 LD HL,$E34F Load address of object_positions
A57C LD B,$15 21 iterations [max no of objects on-screen? max no of stripes?]
object_positions is individual sizes. Turn them into positions.
A57E XOR A Initialise total to zero
lo_loop1 A57F ADD A,(HL) Increment total by (HL)
A580 LD (HL),A Write total back in place
A581 INC L
A582 DJNZ lo_loop1 Loop lo_loop1 while B > 0
Setup addresses.
A584 LD ($A60B),SP Save SP to restore on exit (self modify)
A588 LD SP,$EB00 Load SP with $EB00 - where results will be stored (end of - stack is descending)
A58B LD D,$EE Point DE at road buffer
A58D LD A,($A240) Load road_buffer_offset.lo into A
A590 ADD A,$40 Add 64 so it's the lanes data offset
A592 LD E,A Finalised DE now points into lanes data
A593 LD IY,$E34F Load address of object_positions
A597 LD B,$15 21 iterations
A599 LD A,($A265) Load fork_visible
A59C AND A Set flags
A59D JP Z,lo_positions_loop Jump to lo_positions_loop if zero (passing iterations in B)
Otherwise the road fork is visible.
lo_fork_visible A5A0 LD A,($A266) Load fork_countdown
A5A3 AND A Set flags
A5A4 JR Z,lo_forking Jump to lo_forking if forking
Fork is visible but not forking as yet.
A5A6 LD B,A Set iterations to fork_countdown
lo_positions_loop A5A7 LD A,(DE) Read a lanes byte
A5A8 EXX Bank
A5A9 LD E,A Copy lanes byte to E
L = ~(IY[0] * 2). The doubling is the 16-bit stride of the x-position tables and the complement reverses the direction of travel through them: for a slot depth of N the pair of bytes read is the word at index 127 - N, counting back from the far end of the 128-entry table. ~(2N) is always odd, which is why the reads below take the high byte first and step down to the low one.
A5AA LD A,(IY+$00) Read from current index in object_positions array
A5AD ADD A,A Double it for the 16-bit table stride
A5AE CPL Complement to index back from the end of the table
A5AF LD L,A Move result to L
Read left hand offset bits (0+1).
A5B0 LD A,E Copy lanes byte to A
A5B1 AND $03 Isolate left hand offset bits
A5B3 JR NZ,lo_a5bf Jump if there's a left hand offset
Otherwise no left hand offset is set.
A5B5 LD H,$E8 Set HL to left hand table address: $E8xx
A5B7 LD B,(HL) Load BC from the table
A5B8 DEC L
A5B9 LD C,(HL)
A5BA PUSH BC Store left hand value - then fallthrough
lo_set_right_hand A5BB LD H,$EC Set HL to right hand table - $ECxx
A5BD JR lo_load_and_store_right Jump to lo_load_and_store_right
The left hand position of the road in A is 1/2/3 here. Use that to select table $E8xx/$E9xx/$EAxx.
lo_a5bf A5BF ADD A,$E7 Set table high byte to $E7 + A
A5C1 LD H,A
Sampled HL = $E869 $E865 $E863 $E861 (road drawing left)
A5C2 LD B,(HL) Load BC from the table
A5C3 DEC L
A5C4 LD C,(HL)
A5C5 PUSH BC Store left hand value
A5C6 RL E Shift bit 7 of lanes byte into carry (checked later)
A5C8 BIT 7,E Test former bit 6; set if tunnel, dirt track or fork (carry preserved)
A5CA JP Z,lo_normal_road Jump to lo_normal_road if clear
A5CD JR C,lo_set_right_hand Jump to lo_set_right_hand if carry (dirt track or fork)
Otherwise it's a tunnel piece.
A5CF LD A,$03 Set lane shift amount for 3 lanes
A5D1 JR lo_set_table_right Jump to lo_set_table_right
lo_normal_road A5D3 LD A,$03 Set lane shift amount for 3 lanes
A5D5 JR C,lo_set_table_right Jump to lo_set_table_right if 3 lane or 3/4 lane widening/narrowing
Otherwise it's 2 lane or 2/3 lane widening/narrowing.
A5D7 DEC A Set lane shift amount for 2 lanes
lo_set_table_right A5D8 ADD A,H Add A to table high byte
A5D9 LD H,A
lo_load_and_store_right A5DA LD C,(HL) Load BC from the table
A5DB INC L
A5DC LD B,(HL)
A5DD PUSH BC Store right hand value
A5DE EXX Unbank
A5DF INC IY Advance object_positions pointer
A5E1 INC E Advance lanes pointer
A5E2 DJNZ lo_positions_loop Loop to lo_positions_loop while B > 0
$EB00 now contains pairs of 16-bit left,right object positions.
A5E4 LD A,($A266) Load fork_countdown
A5E7 AND A Set flags
A5E8 JP Z,lo_return Jump to lo_return if zero (no fork)
Otherwise we're about to fork.
lo_forking A5EB LD A,($A266) Calculate (21 - fork_countdown)
A5EE CPL
A5EF ADD A,$16
A5F1 JR Z,lo_return Jump to lo_return if zero [no fork, or not about to fork?]
A5F3 LD B,A Set iterations to above
A5F4 LD H,$EB Set up to read from $EBxx
lo_fork_loop A5F6 LD A,(IY+$00) L = ~(IY[0] * 2), the same reversed word index as lo_positions_loop forms
A5F9 ADD A,A
A5FA CPL
A5FB LD L,A
A5FC DEC H Step back by 256 to read from $EAxx (centre table)
A5FD LD D,(HL) Load DE from table (reading high byte first)
A5FE DEC L
A5FF LD E,(HL)
A600 PUSH DE Store left hand value
A601 INC H Restore pointer to read from $EBxx (centre right)
A602 LD E,(HL) Load DE from table (reading low byte first)
A603 INC L
A604 LD D,(HL)
A605 PUSH DE Store right hand value
A606 INC IY Advance object_positions pointer
A608 DJNZ lo_fork_loop Loop lo_fork_loop while B > 0
lo_return A60A LD SP,$0000 Restore original stack pointer (self modified above)
A60D RET Return
Prev: A4F6 Up: Map Next: A60E