Prev: B063 Up: Map Next: B457
B318: Animates the hero car
Called every frame after move_hero_car. It runs the crash spin: while the crashed flag is set the speed decays by a quarter each frame, the flag is cleared once the speed falls below the crash speed threshold, and the spin position advances by the crash spin speed. The road position is then clamped to its minimum and maximum, and the perp caught animation phase is driven.
The drawing is delegated: draw_debris for the debris, ahc_check_hand_flag for the "stop" hand, draw_hero_car for the car itself and, when cornering or boosting, draw_smoke for the smoke.
Used by the routines at main_loop and drive_attract_demo.
animate_hero_car B318 LD HL,($A24A) Jump to ahc_check_crashed if speed != 0
B31B LD A,H
B31C OR L
B31D JR NZ,ahc_check_crashed
Speed is zero.
B31F LD ($B3DC),A Self modify 'LD A' @ ahc_load_flip_flag (below) to load zero
B322 LD ($A23E),A off_road = 0
ahc_check_crashed B325 LD A,$00 A = <self modified> -- crashed flag set by sch_new_crash
B327 AND A Jump if not crashed
B328 JR Z,ahc_not_crashed
Crashed.
ahc_crashed B32A LD ($A24D),A cornering = A (which is non-zero here)
B32D PUSH HL Preserve speed
B32E LD BC,$0000 BC = <self modified> -- set when crashed by sch_exit
B331 SBC HL,BC Compare speed against the crash exit threshold
B333 POP HL Restore speed
B334 JR C,ahc_speed_less_or_eq Jump to ahc_speed_less_or_eq if speed is below the threshold
ahc_speed_greater B336 LD D,H Divide speed by four (D becomes zero since game max speed is 511)
B337 LD A,L
B338 SRL D
B33A RR A
B33C SRL A
B33E OR $03 A |= 3 -- the decay is never less than 3, so it cannot stall at low speed
B340 LD E,A E = A
B341 SBC HL,DE HL -= DE -- overall expr is new_speed = (speed - ((speed / 4) | 3))
B343 JR Z,ahc_speed_less_or_eq Jump to ahc_speed_less_or_eq if equal
B345 LD A,$02 Turn speed = 2 (fast turning)
B347 JR NC,ahc_assign_speed Jump to ahc_assign_speed if HL > DE
Otherwise HL < DE.
ahc_speed_less_or_eq B349 XOR A Clear crashed flag
B34A LD ($B326),A
B34D INC A Turn speed = 1 (normal turning)
B34E JR ahc_assign_turn_speed Jump to set turn speed
ahc_assign_speed B350 LD ($A24A),HL Set speed to HL
ahc_assign_turn_speed B353 LD ($A250),A Set turn_speed to A -- could be 0?, 1 or 2
This value is set by sch_a4e3, then decremented by 1/16 each time we pass here.
B356 LD HL,$0000 HL = <self modified below>
Divide HL by 16.
B359 LD D,H DE = HL
B35A LD E,L
B35B SRL D DE / 2 -- after this it all fits into E
B35D RR E
B35F SRL E Divide E by 8
B361 SRL E
B363 SRL E
B365 SBC HL,DE HL -= DE -- i.e. original HL minus HL/16
B367 LD ($B357),HL Self modify 'LD HL,$xxxx' @ B356 above
B36A EX DE,HL
B36B LD HL,($A26C) Load road_pos
B36E LD C,$00 Load flip_flag, self modified by A4C0 in check_scenery_collisions
B370 LD A,C flip_car = (flip_flag & 1)
B371 AND $01
B373 LD ($A251),A
B376 DEC C Jump if flip_flag is 1
B377 JR Z,ahc_reduce_road_pos
B379 DEC C Jump if flip_flag is 2 -- is this ever taken?
B37A JR Z,ahc_assign_road_pos
Flip flag was zero?
ahc_increase_road_pos B37C ADD HL,DE Increment road position by DE
B37D JR ahc_assign_road_pos Jump to set road_pos
ahc_reduce_road_pos B37F SBC HL,DE Decrement road position by DE
ahc_assign_road_pos B381 LD ($A26C),HL Set road_pos to HL
Decrement this counter.
B384 LD A,$00 Set to 5 on collisions (by A4C7, and decremented below)
B386 AND A Jump if zero
B387 JR Z,ahc_b38f
B389 DEC A Decrement
B38A LD ($B385),A Self modify 'LD A,x' @ B384 (above) to x = A
B38D LD A,$00 A = <self modified> -- gets set to (flip flag + 1)
ahc_b38f B38F LD ($B3DC),A *$B3DC = A (below)
Arrive here if not crashed.
ahc_not_crashed B392 LD HL,($A26C) Load road_pos
B395 LD DE,$0048 DE = <self modified>
B398 LD A,H A = H
B399 AND A Set flags
B39A JP M,ahc_b3b0 Jump if top bit is set?
B39D JR NZ,ahc_b3a3 Jump if non-zero
Otherwise it was zero.
B39F LD A,L A = L
B3A0 SUB E A -= E
B3A1 JR C,ahc_b3b0 Jump if E > L
ahc_b3a3 B3A3 LD DE,$01D8 DE = <self modified>
B3A6 LD A,H A = H
B3A7 CP D
B3A8 JR C,ahc_assign_road_pos_2 Jump if
B3AA JR NZ,ahc_b3b0
B3AC LD A,L A = L
B3AD SUB E A -= E
B3AE JR C,ahc_assign_road_pos_2 Jump if E > L
ahc_b3b0 B3B0 EX DE,HL
ahc_assign_road_pos_2 B3B1 LD ($A26C),HL Set road_pos to HL
B3B4 LD A,($A24D) A = cornering | smoke
B3B7 LD HL,$A24F
B3BA OR (HL)
B3BB LD BC,$0105 Effect 1 (cornering squeal), Priority 5
B3BE CALL NZ,start_sfx Call start_sfx if cornering or smoke
B3C1 LD A,($A230) Jump if perp_caught_phase == 0
B3C4 AND A
B3C5 JR Z,ahc_debris
B3C7 DEC A Jump if perp_caught_phase is 1 (starts the pull over sequence)
B3C8 JR Z,ahc_debris
New turn speed = MIN(A,2)
B3CA CP $02 Jump if A < 2
B3CC JR C,ahc_b3d0
B3CE LD A,$02 Else A = 2
ahc_b3d0 B3D0 LD ($A250),A turn_speed = A
B3D3 LD A,$01 flip_car = 1
B3D5 LD ($A251),A
ahc_debris B3D8 CALL draw_debris Draw debris
ahc_load_flip_flag B3DB LD A,$00 A = <self modified> -- flip flag + 1
B3DD AND A Jump if not flipped
B3DE JR Z,ahc_b407
Otherwise it's flipped.
B3E0 LD C,A C = A
B3E1 RLCA A *= 2
B3E2 ADD A,C A += C + 24
B3E3 ADD A,$18
B3E5 LD C,A C = A
B3E6 LD A,($A250) Load turn_speed
B3E9 CP $02 Jump if < 2
B3EB JR C,ahc_b3f5
turn_speed is 2.
B3ED LD A,($A251) Load flip_car
B3F0 AND A Jump if zero
B3F1 JR Z,ahc_b3f4
B3F3 INC C 2 -> 3
ahc_b3f4 B3F4 INC C 2/3 -> 3/4
ahc_b3f5 B3F5 EXX Bank
B3F6 LD A,($A234) B' = counter_A & 1 -- animation counter
B3F9 AND $01
B3FB LD B,A
B3FC RLCA C' = A << 1
B3FD LD C,A
B3FE EXX Unbank
B3FF LD A,C A = C
B400 CALL draw_crash Draw crash
B403 XOR A off_road = 0
B404 LD ($A23E),A
ahc_b407 B407 CALL ahc_check_hand_flag Call ahc_check_hand_flag
Make the car bounce up and down when it goes off-road.
B40A LD B,$00 Default bounce of zero to pass to draw_hero_car. It should be either 0 or 3.
B40C LD A,($A23E) Add the bounce only when one wheel is off-road (if off_road == 1)
B40F DEC A
B410 JR NZ,ahc_draw_car
B412 LD A,($A236) New bounce = (counter_C & 1) * 3 -- half rate counter 0/1/2/3
B415 AND $01
B417 LD B,A
B418 ADD A,A
B419 ADD A,B
B41A LD B,A
ahc_draw_car B41B LD A,($A250) Load turn_speed
B41E CALL draw_hero_car Call draw_hero_car
B421 LD A,($A228) Jump if cherry_light is zero
B424 AND A
B425 JR Z,ahc_need_smoke
Draw the cherry light.
B427 XOR A Base frame index 0
B428 LD BC,$0102 Turn the light from a turn_speed of 1, shifting the frame by 2 per turn step
B42B CALL draw_cherry_light Call draw_cherry_light
Check to see if smoke needs drawing.
ahc_need_smoke B42E LD A,($A234) Load counter_A (0/1/2/3 full rate) into B -- animate smoke fast if cornering
B431 LD B,A
B432 LD HL,$A24D Read cornering flag
B435 LD A,(HL) Jump to ahc_do_draw_smoke if it's non-zero
B436 AND A
B437 JR NZ,ahc_do_draw_smoke
Not cornering.
B439 LD A,($A236) Load counter_C (0/1/2/3 half rate) into B
B43C LD B,A
B43D INC HL Advance to boost var
B43E LD A,(HL) Read boost var
B43F INC HL Advance to smoke var
B440 OR (HL) Merge together
B441 JR NZ,ahc_do_draw_smoke Jump to ahc_do_draw_smoke if either is set
No boost nor smoke.
B443 LD A,($A23E) Load off_road
B446 CP $02 Return if not fully off-road
B448 RET NZ
Otherwise we're off-road.
Draw the smoke.
ahc_do_draw_smoke B449 XOR A A' = 0 -- no flip?
B44A EX AF,AF'
B44B LD A,B A = B -- smoke anim index
B44C PUSH AF Preserve smoke anim index
B44D CALL draw_smoke Call draw_smoke - for the right hand side
B450 LD A,$01 A' = 1 -- flip?
B452 EX AF,AF'
B453 POP AF Restore smoke anim index
B454 JP draw_smoke Exit via draw_smoke - for the left hand side
Prev: B063 Up: Map Next: B457