| Chase H.Q. | Routines |
| Prev: B063 | Up: Map | Next: B457 |
|
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 |