Prev: B828 Up: Map Next: B8D2
B848: Scroll the horizon
Returns immediately when the speed is zero. Otherwise two independent sections run.
Horizontal (sh_curved_road): when current_curvature is non-zero, picks a pair of bytes out of horizon_table using an index built from the curvature and the top bits of the speed, counts horizon_x_scroll down, and on reaching zero reloads it and steps the horizon's horizontal shift (C7E7) by the table's signed step, wrapping to stay in 0..19.
Vertical (sh_straight_road): with a non-zero incline, works out how many ticks have passed since the last vertical step, converts that to a movement using the per-incline rate from horizon_table, applies it to horizon_level and carries the remainders in horizon_y_accum and horizon_y_step.
Used by the routines at main_loop, drive_attract_demo and escape_scene.
Input
A' The scroll amount move_hero_car banked at B296, consumed by B857; only meaningful when current_curvature is non-zero
Output
A' Zeroed at sh_straight_road then used as the routine's own accumulator
scroll_horizon B848 LD HL,($A24A) Load speed into HL
B84B LD A,H Return if speed is zero
B84C OR L
B84D RET Z
B84E LD A,($A25C) Load current_curvature into A
B851 AND A Jump if current_curvature is zero
B852 JR Z,sh_straight_road
current_curvature is non-zero here.
sh_curved_road B854 EX AF,AF' Bank current_curvature into A', unbanking the scroll amount move_hero_car left there at B296. The banked current_curvature is never read back: B873 overwrites A. Only the flags come back, at B872
B855 RR H Bottom bit of H (speed.hi) moves to carry (H now unused)
A here is move_hero_car's scroll amount, unbanked by the EX above.
B857 RLA A = ((A << 3) + (carry << 2)) & 6
B858 RLA
B859 RLA
B85A AND $06
B85C LD C,A BC = horizon_curve_index + A
B85D LD A,($A25D)
B860 ADD A,C
B861 LD C,A
B862 LD B,$00
B864 LD HL,$B828 32 byte horizon scroll rate table at horizon_table
B867 ADD HL,BC HL += BC
B868 LD B,(HL) Two separate bytes, not a word: B is the reload value for horizon_x_scroll (B871) and C the signed step applied to the shift (B873)
B869 INC HL
B86A LD C,(HL)
Decrement horizon_x_scroll.
B86B LD HL,$A25E HL = &horizon_x_scroll
B86E DEC (HL) *HL--
B86F JR NZ,sh_straight_road Jump if non-zero
It became zero.
B871 LD (HL),B *HL = B [reload value from the table]
B872 EX AF,AF' Restores the AF banked at sh_curved_road, which brings back the flags set by the AND A at B851 as well as A
B873 LD A,C A = C [the table's signed step; this does not touch the flags]
B874 JP P,sh_update_hz_shift Jump if positive. The flags are still B851's, so this tests the sign of current_curvature, not of C
B877 NEG A = -A
sh_update_hz_shift B879 LD HL,$C7E8 Load address of operand in 'LD A,x' @ C7E7 (horizon's horizontal shift value 0..19)
B87C ADD A,(HL) A += *HL
B87D JP P,sh_reduce Jump if positive
Otherwise negative (or zero?).
B880 ADD A,$14 A += 20 -- wrap around?
sh_reduce B882 CP $14 If A >= 20 then A -= 20
B884 JR C,sh_set_hz_shift
B886 SUB $14
sh_set_hz_shift B888 LD (HL),A Store new horizontal shift value
sh_straight_road B889 XOR A Zero A, B, E
B88A LD B,A
B88B LD E,A
B88C EX AF,AF' Bank zeroed A, unbank other one
B88D LD A,($A258) Return if incline is zero (flat road)
B890 OR A
B891 RET Z
B892 JP P,sh_not_flat_road Jump if positive
Otherwise negative.
B895 INC E E++
B896 NEG A = -A
sh_not_flat_road B898 LD HL,$B827 horizon_table - 1: the incline magnitude added next is 1-based, so incline 1 selects the first byte
B89B LD C,A BC = A (B is zeroed earlier)
B89C ADD HL,BC HL += BC
B89D LD A,($A25B) A = fast_counter - horizon_y_step
B8A0 LD C,A
B8A1 LD A,($A23F)
B8A4 SUB C
B8A5 AND A Set flags
B8A6 RET Z Return if zero
B8A7 LD C,(HL) C = *HL -- loading from horizon table
sh_b8a8_loop B8A8 SUB C A -= C
B8A9 JR C,sh_b8b1_exit Jump if carry
B8AB INC B B++
B8AC EX AF,AF' Add the rate to the accumulator kept in A', which was zeroed at sh_straight_road. B8CB reads the total back
B8AD ADD A,C
B8AE EX AF,AF'
B8AF JR sh_b8a8_loop Loop
sh_b8b1_exit B8B1 LD A,B Return if B is zero
B8B2 AND A
B8B3 RET Z
B8B4 LD HL,$A25A horizon_y_accum += A
B8B7 ADD A,(HL)
B8B8 LD (HL),A
Sign extend the step count using the downhill flag B895 put in E.
B8B9 LD A,B A = B [the number of steps counted above]
B8BA RR E Move the downhill flag into carry
B8BC LD B,$00 B = 0 -- just widen to (B,A)
B8BE JR NC,sh_set_horizon Jump if no carry
Otherwise negative.
B8C0 DEC B B = $FF
B8C1 NEG A = -A
Adjust horizon_level by (B,A).
sh_set_horizon B8C3 LD HL,($A171) Change horizon_level by (B,A)
B8C6 LD C,A
B8C7 ADD HL,BC
B8C8 LD ($A171),HL
B8CB EX AF,AF' Retrieve the accumulator built at B8AD. A is that total from here on, not the step count B8C1 left
B8CC LD HL,$A25B horizon_y_step += A
B8CF ADD A,(HL)
B8D0 LD (HL),A
B8D1 RET Return
Prev: B828 Up: Map Next: B8D2