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 = fork_visible
A3A3 AND A Set flags
A3A4 JR Z,cc_at_fork Jump to cc_at_fork if zero
A3A6 LD A,($A266) A = fork_countdown
A3A9 AND A Set flags
A3AA JP Z,cc_not_fork Jump to cc_not_fork if zero
A3AD DEC A A--
A3AE RET Z Return if zero [can't collide immediately before fork?]
Check left hand side of car.
cc_at_fork A3AF LD HL,($EAFE) HL = *$EAFE
A3B2 LD A,H A = H (0 or 255)
A3B3 AND A Set flags
A3B4 JR NZ,cc_a3d1 Jump to cc_a3d1 if non-zero
A3B6 PUSH HL Jump to cc_a3d1 if HL < $40
A3B7 LD BC,$0040
A3BA SBC HL,BC
A3BC POP HL
A3BD JR C,cc_a3d1
A3BF PUSH HL Jump to cc_a3d5 if HL < $6A
A3C0 LD C,$6A
A3C2 SBC HL,BC
A3C4 POP HL
A3C5 JR C,cc_a3d5
A3C7 LD C,$85 HL -= $85
A3C9 SBC HL,BC
A3CB INC A A++ -- A == 1 => partially off-road
A3CC JR C,cc_fork_set Jump to cc_fork_set if A was 255
A3CE INC A A++ -- A == 2 => fully off-road
A3CF JR cc_fork_set Jump to cc_fork_set
cc_a3d1 A3D1 XOR A var_a23d = 0
A3D2 LD ($A23D),A
Check right hand side of car.
cc_a3d5 A3D5 LD HL,($EAFC) HL = *$EAFC
A3D8 LD A,H A = H
A3D9 AND A Set flags
A3DA LD A,$00 A = 0 (not self modified)
A3DC JR NZ,cc_a3fa Jump to cc_a3fa if non-zero
A3DE PUSH HL Jump to cc_a3fa if HL >= $BE
A3DF LD BC,$00BE
A3E2 SBC HL,BC
A3E4 POP HL
A3E5 JR NC,cc_a3fa
A3E7 PUSH HL Jump to cc_fork_set if HL >= $8E
A3E8 LD BC,$008E
A3EB SBC HL,BC
A3ED POP HL
A3EE JR NC,cc_fork_set
A3F0 LD C,$7C HL -= $7C
A3F2 SBC HL,BC
A3F4 INC A A++ -- A == 1 => partially off-road
A3F5 JR NC,cc_fork_set Jump to cc_fork_set if no carry
A3F7 INC A A++ -- A == 2 => fully off-road
A3F8 JR cc_fork_set Jump to cc_fork_set
cc_a3fa A3FA LD ($A23C),A var_a23c = A
cc_fork_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 = 0 (not self modified)
A403 JR Z,cc_a43b 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 Point HL at road buffer lanes data
A40B LD H,$EE
A40D LD A,(HL) A = *HL
A40E BIT 6,A Test bit 6 -- tunnel bits perhaps?
A410 JR Z,cc_a43b Jump if clear
A412 RLA Test bit 7
A413 JR C,cc_a43b 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,cc_a426 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 cc_hit_scenery2 Jump to cc_hit_scenery2
cc_a426 A426 LD HL,$00D1 HL = $00D1
A429 LD DE,$0195 DE = $0195
A42C EXX
A42D AND A Set flags [A is ?]
A42E LD C,$01 C = 1
A430 JR Z,cc_hit_tunnel_wall
A432 INC C C = 2
cc_hit_tunnel_wall A433 PUSH BC Preserve BC
A434 LD BC,$0604 Effect 6 (tunnel wall hit), Priority 4
A437 CALL start_sfx Call start_sfx
A43A POP BC Restore BC
cc_a43b 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
-- RIGHT SIDE OBJECT HIT CHECKING --
A44C ADD A,$60 Add 96 so it's the right side objects data offset
A44E LD L,A Point HL at road buffer right side objects data
A44F EX AF,AF' Bank road buffer offset
A450 LD H,$EE (cont.)
A452 LD A,($A240) Load road_buffer_offset into A
A455 RLA Top bit -> carry
A456 LD A,(HL) Read a right side object data byte
A457 JR NC,cc_a45a Jump if top bit was clear
A459 INC L L++ -- so if the top bit of the road buffer offset is set we take next byte?
cc_a45a A45A OR (HL) OR in the (next) byte
A45B JR Z,cc_a480 Jump if it's zero -- no object
Build a graphics_defs address.
A45D LD C,A HL = (*addrof_right_hand_objects)[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
Read collision values.
A469 LD C,(HL) C = *HL++ -- e.g. $5E5B. a higher value
A46A INC HL
A46B LD E,(HL) E = *HL++ -- e.g. $5E5C. a lower value
A46C INC HL
A46D LD A,(HL) A = *HL -- e.g. $5E5D. TBD
A46E LD D,B D = B -- B is zero here, so BC = C and DE = E
Check for collisions with scenery (right hand side).
A46F LD HL,($EAFC) HL = *$EAFC -- near end of road drawing words (centre)... must be position of car
A472 PUSH HL Jump to cc_a480 if HL >= BC
A473 SBC HL,BC
A475 POP HL
A476 JR NC,cc_a480
A478 SBC HL,DE Jump to cc_a480 if HL < DE
A47A JR C,cc_a480
A47C EX AF,AF' Unbank road buffer offset
A47D XOR A A = 0 -- perhaps a right hand flag
A47E JR cc_hit_scenery Jump to cc_hit_scenery
cc_a480 A480 EX AF,AF' Unbank road buffer offset
-- LEFT SIDE OBJECT HIT CHECKING --
A481 ADD A,$20 Add 32 so it's the left side objects data offset
A483 LD L,A Point HL at road buffer left side objects data
A484 LD H,$EE
A486 LD A,($A240) Load road_buffer_offset into A
A489 RLA Top bit -> carry
A48A LD A,(HL) Read a left side object data byte
A48B JR NC,cc_a48e Jump if top bit was clear
A48D INC L L++
cc_a48e A48E OR (HL) OR in the (next) byte
A48F RET Z Return if zero -- no object
A490 LD C,A HL = (*addrof_left_hand_objects)[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
Read collision values.
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?
Check for collisions with scenery (left hand side).
A4A2 LD HL,($EAFE) HL = *$EAFE -- suspected position of car
A4A5 PUSH HL Return if HL < BC
A4A6 SBC HL,BC
A4A8 POP HL
A4A9 RET C
A4AA SBC HL,DE Return if HL >= DE
A4AC RET NC
A4AD EX AF,AF' Unbank road buffer offset
A4AE LD A,$01 A = 1 -- perhaps a left hand flag
Arrive here if hit scenery, e.g. drove a tree or a lamp post.
cc_hit_scenery A4B0 PUSH AF Preserve AF -- suspected left hand flag
A4B1 LD BC,$0403 Effect 4 (scenery crash), Priority 3
A4B4 CALL start_sfx Call start_sfx
A4B7 POP AF Restore AF
This entry point is used by the routines at smash_handler and hazard_handler_a8cd.
cc_hit_scenery2 A4B8 LD HL,$B326 HL = &<crashed flag>
A4BB INC (HL) Set flags
A4BC DEC (HL)
A4BD RET NZ Return if already crashed
cc_new_crash A4BE LD (HL),$01 Set crashed flag
A4C0 LD ($B36F),A *$B36F = A++ -- set flip flag (0/1 = right/left)
A4C3 INC A
A4C4 LD ($B38E),A *$B38E = A
A4C7 LD A,$05 *$B385 = 5
A4C9 LD ($B385),A
A4CC LD HL,($A24A) Load speed into HL
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,cc_a4e3
A4E2 LD L,A L = A
cc_a4e3 A4E3 LD ($B357),HL Self modify 'LD HL,$xxxx' @ B356
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,cc_a4f2
A4F1 EX DE,HL
cc_a4f2 A4F2 LD ($B32F),HL Self modify 'LD BC' @ B32E to load HL
A4F5 RET Return
cc_not_fork A4F6 LD HL,($E8FE) HL = *$E8FE -- checking the final word of the road drawing (left) table
A4F9 LD A,H A = H (0 or 255)
A4FA AND A Set flags
A4FB JR NZ,cc_a510 Jump to cc_a510 if A isn't zero
A4FD PUSH HL Jump to cc_a510 if HL < $6A
A4FE LD BC,$006A
A501 SBC HL,BC
A503 POP HL
A504 JR C,cc_a510
A506 LD C,$85 HL -= $85
A508 SBC HL,BC
A50A INC A A++ -- A == 1 => partially off-road
A50B JR C,cc_not_fork_set Jump to cc_not_fork_set if HL < $85
A50D INC A A++ -- A == 2 => fully off-road
A50E JR cc_not_fork_set Jump to cc_not_fork_set
cc_a510 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_fork_set JR NZ,cc_not_fork_set
A519 PUSH HL Jump to cc_not_fork_set if HL >= $8E
A51A LD BC,$008E
A51D SBC HL,BC
A51F POP HL
A520 JR NC,cc_not_fork_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_fork_set Jump to cc_not_fork_set if HL >= $7C
A529 INC A A++ -- A == 2 => fully off-road
Set the off-road flag etc.
cc_not_fork_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 cc_a55c if fork_taken was 1 (right fork taken)
A53C AND A
A53D JR NZ,cc_a55c
A53F LD HL,($5CFC) HL = *$5CFC
A542 LD C,(HL) C = *HL++ -- max object boundary
A543 INC HL
A544 LD E,(HL) E = *HL++ -- min object boundary
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 -- perhaps a right hand flag
A559 JP cc_hit_scenery Exit via cc_hit_scenery
cc_a55c 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' Bank
A574 LD A,$01 A = 1 -- perhaps a left hand flag
A576 JP cc_hit_scenery Exit via cc_hit_scenery
Prev: A27A Up: Map Next: A579