Prev: A27A Up: Map Next: A579
A399: Checks for collisions
Used by the routines at main_loop and cpu_driver.
check_collisions A399 LD HL,$0048 HL = $0048
A39C LD DE,$01D8 DE = $01D8
A39F EXX
A3A0 LD A,($A265) A = split_road -- fairly sure this is a split road flag
A3A3 AND A Set flags
A3A4 JR Z,cc_at_split Jump to cc_at_split if zero
A3A6 LD A,($A266) A = split_road_countdown
A3A9 AND A Set flags
A3AA JP Z,cc_not_split Jump to cc_not_split if zero
A3AD DEC A A--
A3AE RET Z Return if zero [can't collide immediately before split?]
Check left hand side of car.
cc_at_split A3AF LD HL,($EAFE) HL = *$EAFE
A3B2 LD A,H A = H (0 or 255)
A3B3 AND A Set flags
A3B4 JR NZ,check_collisions_0
A3B6 PUSH HL Jump to check_collisions_0 if HL < $40
A3B7 LD BC,$0040
A3BA SBC HL,BC
A3BC POP HL
A3BD JR C,check_collisions_0
A3BF PUSH HL Jump to check_collisions_1 if HL < $6A
A3C0 LD C,$6A
A3C2 SBC HL,BC
A3C4 POP HL
A3C5 JR C,check_collisions_1
A3C7 LD C,$85 HL -= $85
A3C9 SBC HL,BC
A3CB INC A A++ -- A == 1 => partially off-road
A3CC JR C,cc_split_set Jump to cc_split_set if A was 255
A3CE INC A A++ -- A == 2 => fully off-road
A3CF JR cc_split_set Jump to cc_split_set
check_collisions_0 A3D1 XOR A var_a23d = 0
A3D2 LD ($A23D),A
Check right hand side of car.
check_collisions_1 A3D5 LD HL,($EAFC) HL = *$EAFC
A3D8 LD A,H A = H
A3D9 AND A Set flags
A3DA LD A,$00 A = 0
A3DC JR NZ,check_collisions_2
A3DE PUSH HL Jump to check_collisions_2 if HL >= $BE
A3DF LD BC,$00BE
A3E2 SBC HL,BC
A3E4 POP HL
A3E5 JR NC,check_collisions_2
A3E7 PUSH HL Jump to cc_split_set if HL >= $8E
A3E8 LD BC,$008E
A3EB SBC HL,BC
A3ED POP HL
A3EE JR NC,cc_split_set
A3F0 LD C,$7C HL -= $7C
A3F2 SBC HL,BC
A3F4 INC A A++ -- A == 1 => partially off-road
A3F5 JR NC,cc_split_set Jump to cc_split_set if no carry
A3F7 INC A A++ -- A == 2 => fully off-road
A3F8 JR cc_split_set Jump to cc_split_set
check_collisions_2 A3FA LD ($A23C),A var_a23c = A
cc_split_set A3FD LD ($A23E),A off_road = A -- 0/1/2 => on-road/one wheel off-road/both wheels off-road
A400 AND A Set flags
A401 LD C,$00 C = $00
A403 JR Z,check_collisions_4 not off road?
A405 LD A,($A240) Load road_buffer_offset into A
A408 ADD A,$40 Add 64 so it's the lanes data offset
A40A LD L,A HL = $EE00 | L
A40B LD H,$EE
A40D LD A,(HL) A = *HL
A40E BIT 6,A Test bit 6 -- tunnel bits perhaps?
A410 JR Z,check_collisions_4 Jump if clear
A412 RLA Test bit 7
A413 JR C,check_collisions_4 Jump if set
A415 BIT 3,A Test bit 3 (was bit 2 before RLA)
A417 LD A,($A26D) A = road_pos.hi
A41A JR Z,check_collisions_3 Jump if clear
A41C LD C,A C = A
A41D LD A,$14 A = 20
A41F EX AF,AF'
A420 LD A,C A = C & 1
A421 AND $01
A423 JP check_collisions_8
check_collisions_3 A426 LD HL,$00D1 HL = $00D1
A429 LD DE,$0195 DE = $0195
A42C EXX
A42D AND A Set flags
A42E LD C,$01 C = 1
A430 JR Z,cc_hit_tunnel_wall
A432 INC C C++
cc_hit_tunnel_wall A433 PUSH BC
A434 LD BC,$0604 BC = $0604
A437 CALL start_sfx Call start_sfx
A43A POP BC
check_collisions_4 A43B LD A,C A = C
A43C LD ($B3DC),A ($B3DC) = A
A43F EXX
A440 LD ($B396),HL ($B396) = HL
A443 LD ($B3A4),DE ($B3A4) = DE
A447 AND A Set flags
A448 RET NZ Return if non-zero
A449 LD A,($A240) Load road_buffer_offset into A
A44C ADD A,$60 Add 96 so it's the right side objects data offset
A44E LD L,A L = A
A44F EX AF,AF'
A450 LD H,$EE H = $EE
A452 LD A,($A240) Load road_buffer_offset into A
A455 RLA Doubling?
A456 LD A,(HL) A = *HL
A457 JR NC,check_collisions_5
A459 INC L L++
check_collisions_5 A45A OR (HL) A |= *HL
A45B JR Z,check_collisions_6
A45D LD C,A HL = addrof_graphic_defs[A * 7]
A45E ADD A,A
A45F ADD A,A
A460 ADD A,A
A461 SUB C
A462 LD C,A
A463 LD B,$00
A465 LD HL,($5CFA)
A468 ADD HL,BC
A469 LD C,(HL) C = *HL++
A46A INC HL
A46B LD E,(HL) E = *HL++
A46C INC HL
A46D LD A,(HL) A = *HL
A46E LD D,B D = B
A46F LD HL,($EAFC) HL = *$EAFC
A472 PUSH HL
A473 SBC HL,BC HL -= BC
A475 POP HL
A476 JR NC,check_collisions_6
A478 SBC HL,DE HL -= DE
A47A JR C,check_collisions_6
A47C EX AF,AF'
A47D XOR A A = 0
A47E JR cc_hit_scenery Jump to cc_hit_scenery
check_collisions_6 A480 EX AF,AF'
A481 ADD A,$20 A += 32
A483 LD L,A HL = $EE00 | A
A484 LD H,$EE
A486 LD A,($A240) Load road_buffer_offset into A
A489 RLA Doubling?
A48A LD A,(HL) A = *HL
A48B JR NC,check_collisions_7
A48D INC L L++
check_collisions_7 A48E OR (HL) A |= *HL
A48F RET Z Return if zero
A490 LD C,A HL = (*$5D00)[A * 7]
A491 ADD A,A
A492 ADD A,A
A493 ADD A,A
A494 SUB C
A495 LD C,A
A496 LD B,$00
A498 LD HL,($5D00)
A49B ADD HL,BC
A49C LD C,(HL) C = *HL++
A49D INC HL
A49E LD E,(HL) E = *HL++
A49F INC HL
A4A0 LD A,(HL) A = *HL
A4A1 LD D,B D = B must be zero?
A4A2 LD HL,($EAFE) HL = *$EAFE
A4A5 PUSH HL
A4A6 SBC HL,BC HL -= BC
A4A8 POP HL
A4A9 RET C Return if carry
A4AA SBC HL,DE HL -= DE
A4AC RET NC Return if no carry
A4AD EX AF,AF'
A4AE LD A,$01 A = $01
cc_hit_scenery A4B0 PUSH AF
A4B1 LD BC,$0403 BC = $0403 -- arrive here if drive into scenery, e.g. a tree
A4B4 CALL start_sfx Call start_sfx
A4B7 POP AF
This entry point is used by the routines at smash_handler and hazard_handler_a8cd.
check_collisions_8 A4B8 LD HL,$B326 HL = &<crashed flag>
A4BB INC (HL) Set flags
A4BC DEC (HL)
A4BD RET NZ Return if already crashed?
A4BE LD (HL),$01 Set crashed flag
A4C0 LD ($B36F),A *$B36F = A++
A4C3 INC A
A4C4 LD ($B38E),A *$B38E = A
A4C7 LD A,$05
A4C9 LD ($B385),A *$B385 = 5
A4CC LD HL,($A24A) HL = speed
A4CF PUSH HL Preserve HL
A4D0 SRL H H >>= 1
A4D2 LD A,L A = L
A4D3 RR A
A4D5 SRL A A = (A << 3) + 16
A4D7 SRL A
A4D9 SRL A
A4DB ADD A,$10
A4DD LD L,$18 L = 24
A4DF CP L
A4E0 JR C,check_collisions_9
A4E2 LD L,A L = A
check_collisions_9 A4E3 LD ($B357),HL *$B357 = HL
A4E6 EX AF,AF'
A4E7 LD L,A HL = A
A4E8 LD H,$00
A4EA POP DE
A4EB PUSH HL
A4EC SBC HL,DE HL -= DE
A4EE POP HL
A4EF JR C,check_collisions_10
A4F1 EX DE,HL
check_collisions_10 A4F2 LD ($B32F),HL Self modify 'LD BC' @ B32E to load HL
A4F5 RET Return
cc_not_split A4F6 LD HL,($E8FE) HL = *$E8FE [mystery var]
A4F9 LD A,H A = H (0 or 255)
A4FA AND A Set flags
A4FB JR NZ,check_collisions_11 A isn't zero
A4FD PUSH HL Jump to check_collisions_11 if HL < $6A
A4FE LD BC,$006A
A501 SBC HL,BC
A503 POP HL
A504 JR C,check_collisions_11
A506 LD C,$85
A508 SBC HL,BC HL -= $85
A50A INC A A++ -- A == 1 => partially off-road
A50B JR C,cc_not_split_set Jump to cc_not_split_set if HL < $85
A50D INC A A++ -- A == 2 => fully off-road
A50E JR cc_not_split_set Jump to cc_not_split_set
check_collisions_11 A510 LD HL,($EDFC) HL = *$EDFC
A513 LD A,H A = H
A514 AND A Set flags
A515 LD A,$00 A = 0
A517 JR NZ,cc_not_split_set JR NZ,cc_not_split_set
A519 PUSH HL Jump to cc_not_split_set if HL >= $8E
A51A LD BC,$008E
A51D SBC HL,BC
A51F POP HL
A520 JR NC,cc_not_split_set
A522 LD C,$7C HL -= $7C
A524 SBC HL,BC
A526 INC A A++ -- A == 1 => partially off-road
A527 JR NC,cc_not_split_set Jump to cc_not_split_set if HL >= $7C
A529 INC A A++ -- A == 2 => fully off-road
cc_not_split_set A52A LD ($A23E),A off_road = A
A52D XOR A A = 0
A52E LD ($B3DC),A *$B3DC = A
A531 EXX
A532 LD ($B396),HL *$B396 = HL
A535 LD ($B3A4),DE *$B3A4 = DE
A539 LD A,($A249) Jump to check_collisions_12 if fork_taken was 1 (right fork taken)
A53C AND A
A53D JR NZ,check_collisions_12
A53F LD HL,($5CFC) HL = *$5CFC
A542 LD C,(HL) C = *HL++
A543 INC HL
A544 LD E,(HL) E = *HL++
A545 INC HL
A546 LD A,(HL) A = *HL
A547 LD B,$00 B = 0
A549 LD D,B D = B
A54A LD HL,($EAFE) HL = *$EAFE
A54D PUSH HL Return if HL >= BC
A54E SBC HL,BC
A550 POP HL
A551 RET NC
A552 SBC HL,DE Return if HL < DE
A554 RET C
A555 LD A,$8C A = $8C
A557 EX AF,AF'
A558 XOR A A = 0
A559 JP cc_hit_scenery Jump to cc_hit_scenery
check_collisions_12 A55C LD HL,($5D02) HL = *$5D02
A55F LD C,(HL) C = *HL++
A560 INC HL
A561 LD E,(HL) E = *HL++
A562 INC HL
A563 LD B,$00 B = 0
A565 LD D,B D = B
A566 LD HL,($EAFC) HL = *$EAFC
A569 PUSH HL Return if HL < BC
A56A SBC HL,BC
A56C POP HL
A56D RET C
A56E SBC HL,DE Return if HL >= DE
A570 RET NC
A571 LD A,$8C A = $8C
A573 EX AF,AF'
A574 LD A,$01 A = 1
A576 JP cc_hit_scenery Jump to cc_hit_scenery
Prev: A27A Up: Map Next: A579