Prev: CBCE Up: Map Next: CDD6
CD3A: Build the per-row height tables at $E300 and $E336
Called once a frame from the main loop. It reads the road buffer's height channel and the perspective Y scale table, and produces three things.
The loop at CD64 walks 21 rows of the height channel, accumulating the incline seen so far in C. Each row's perspective scale is multiplied by the magnitude of that accumulator using the shift-and-add routine at bht_multiplier, negating the multiplier when the accumulator is negative, and added to the row's base scale entry. The results are written to $E300 onwards, with $A0 left as a sentinel after the twenty-first.
The loop at bht_loop2 copies those 21 entries to $E336, tracking a running minimum that starts at 96, so the copy never rises above the closest road point seen so far.
Finally the accumulator is rounded down to a multiple of 8 and stored at $E34B, and the difference from the previous frame's value at $E34C. The latter is written by walking the pointer off the end of the height table rather than by a direct store, so it is invisible to a search for $E34C. update_screen scrolls the sky and ground colour boundary from $E34D, which lags that delta by a frame.
Used by the routines at main_loop, drive_attract_demo and escape_scene.
Point IY at the road buffer's height data.
build_height_table CD3A LD IYh,$EE Set the high byte of IY to road buffer memory region ($EExx)
CD3D LD A,($A240) Load road_buffer_offset into A
CD40 ADD A,$20 Add 32 so it's the height data offset (wrapping around)
CD42 LD IYl,A IY is now the road buffer height data pointer
CD44 LD C,(IY+$00) Read the current height byte into C
The height byte is the byte B from the map data but converted like so: ((B & 15) - 8). Heights are therefore 0 for level road, 7 for max downslope, -8 for max upslope.
build A - an index into the road drawing tables.
See similar code at 917A.
CD47 LD A,($A23F) A = fast_counter & $E0 -- top three bits
CD4A AND $E0
Scale 0..223 (in steps of 16) to 0..153, reducing A by 31.25%, mapping the incoming value to the 7x22 byte tables. So fast_counter indexes the rows of the table.
CD4C LD L,A Copy for reducing
CD4D LD B,A Copy to be a multiplier later
CD4E RRC L Divide A by 4 and subtract -- nothing will rotate out due to AND $E0
CD50 RRC L
CD52 SUB L
CD53 RRC L Divide A by 16 and subtract
CD55 RRC L
CD57 SUB L
Look up that value in the vertical table.
CD58 LD L,A Point HL into road drawing tables at ($E600 | (A + 1))
CD59 INC L
CD5A LD H,$E6
CD5C LD A,B Multiplier = (fast_counter & $E0) from above
Multiplicand is the height byte from the map (7 max downslope, 0 level, -8 max upslope).
CD5D CALL scale_curvature_or_height Call multiply (A = multiplier, C = multiplicand) result in A
CD60 NEG Negate result and copy to C
CD62 LD C,A
CD63 EXX Bank
This builds the look-up table at $E301. Assuming it's a height table.
CD64 LD B,$15 21 iterations
CD66 LD DE,$E301 DE = $E301
bht_loop CD69 EXX Unbank
CD6A LD E,(HL) E = *HL * 2 -- HL points at $E6xx (road drawing tables)
CD6B SLA E
CD6D PUSH HL Preserve HL
CD6E LD D,$00 DE is now the value from table, widened
CD70 LD L,D Initialise result to zero
CD71 LD H,L
CD72 LD A,C A = negated multiply result from above
CD73 ADD A,(IY+$00) A += *IY -- a height byte
CD76 LD C,A C = A
CD77 JR Z,bht_continue Jump to bht_continue if zero (since multiply by zero is a no-op)
CD79 JP P,bht_multiplier Jump if positive
Otherwise handle negative case.
CD7C LD A,E E = -E; D = $FF -- negate multiplier
CD7D DEC D
CD7E NEG
CD80 LD E,A
CD81 LD A,C A = -C -- negate multiplicand
CD82 NEG
Multiplier.
bht_multiplier CD84 ADD A,A Throw sign bit away?
bht_bit6 CD85 ADD A,A Shift out a high bit of multiplicand
CD86 JR NC,bht_bit5 Copy multiplier (from DE) if a bit shifted out
CD88 LD L,E
CD89 LD H,D
CD8A ADD HL,HL Shift result up to prepare for next bit
bht_bit5 CD8B ADD A,A Shift out a high bit of multiplicand
CD8C JR NC,bht_bit4 Add multiplier (from DE) if a bit shifted out
CD8E ADD HL,DE
bht_bit4 CD8F ADD HL,HL Shift result up to prepare for next bit
CD90 ADD A,A Repeat
CD91 JR NC,bht_bit3
CD93 ADD HL,DE
bht_bit3 CD94 ADD HL,HL
CD95 ADD A,A Repeat
CD96 JR NC,bht_bit2
CD98 ADD HL,DE
bht_bit2 CD99 ADD HL,HL
CD9A ADD A,A Repeat
CD9B JR NC,bht_bit1
CD9D ADD HL,DE
bht_bit1 CD9E ADD HL,HL
CD9F ADD A,A Repeat
CDA0 JR NC,bht_bit0
CDA2 ADD HL,DE
bht_bit0 CDA3 ADD HL,HL
CDA4 ADD A,A Repeat
CDA5 JR NC,bht_cda8
CDA7 ADD HL,DE
bht_cda8 CDA8 ADD HL,HL
CDA9 LD A,H A = H -- top byte of result
bht_continue CDAA POP HL Restore HL
CDAB ADD A,(HL) A += *HL -- HL points at $E6xx (road drawing data)
CDAC INC L Advance to next byte of HL while wrapping around
CDAD EXX Bank
CDAE LD (DE),A Write A to the table at $E3xx
CDAF INC E Increment address of entry in table (wrapping around)
CDB0 INC IYl IYl++ (wrapping around)
CDB2 DJNZ bht_loop Loop to bht_loop while B
CDB4 LD A,$A0 Final byte is always $A0
CDB6 LD (DE),A
Copy the table to $E336 while setting negative values to 96[?]
CDB7 LD HL,$E336 Load address of destination
CDBA LD DE,$E301 Load address of source (height table?)
CDBD LD BC,$1560 B = 21 iterations, C = 96 limit/minimum?
bht_loop2 CDC0 LD A,(DE) Read from table just built
CDC1 CP C Jump to bht_write_it if (A - C) is positive
CDC2 JP P,bht_write_it
CDC5 LD C,A Otherwise it's negative, so use A
bht_write_it CDC6 LD (HL),C Write it
CDC7 INC L HL++ (wrapping around)
CDC8 INC E DE++ (wrapping around)
CDC9 DJNZ bht_loop2 Loop to bht_loop2 while B
Final bytes.
CDCB LD A,C C = A = (C + 3) & $F8
CDCC ADD A,$03
CDCE AND $F8
CDD0 LD C,A
CDD1 SUB (HL) A -= *HL
CDD2 LD (HL),C *HL = C
CDD3 INC L HL++ (wrapping around)
CDD4 LD (HL),A *HL = A
CDD5 RET Return
Prev: CBCE Up: Map Next: CDD6