Prev: AB33 Up: Map Next: AC3C
AB9A: Spawn hazards
Spawns hittable hazards in the road, like barriers and tumbleweeds.
Nothing happens while allow_spawning is zero. The spawning distance is 20 minus allow_spawning, so 18 or 19, and if the road buffer's hazard byte at that offset is zero nothing is spawned.
That byte is the map command less 3, so it reads: 0 stop, 1/2/3 tumbleweeds left/right/both, 4/5/6 barriers left/right/both. Four or more therefore means a barrier: the heavier hittable variant is selected and 3 subtracted, folding the barrier codes onto the same three placements as the tumbleweeds.
What is left decides count and placement. 1 puts one obstacle at x=50, 2 puts one at x=220 and 3 puts a pair, at x=70 and 180 for tumbleweeds or x=80 and 160 for barriers. Barriers become a triple at x=32, 86 and 140 when inhibit_collision_detection is set. That flag is raised at 875C when the perp escapes, and it makes check_hazard_collisions return at once, so the triple only ever appears where nothing can be hit.
Used by the routines at main_loop, drive_attract_demo and escape_scene.
spawn_hazards AB9A LD A,($A254) Return if allow_spawning is zero
AB9D AND A
AB9E RET Z
Calculate a spawning distance.
AB9F CPL C = 20 - allow_spawning (can be 1 or 2 here)
ABA0 ADD A,$15
ABA2 LD C,A
Point HL at hazards data.
ABA3 LD A,($A240) Load road_buffer_offset.lo into A
ABA6 ADD A,$A0 Add 160 for the hazards data offset
ABA8 ADD A,C Add spawn distance
ABA9 LD L,A Point HL at road buffer hazards data
ABAA LD H,$EE
Do we have a hazard?
ABAC LD A,(HL) Load the hazard byte -- what's in this byte?
ABAD AND A Set flags
ABAE RET Z Return if zero - no hazard?
ABAF CP $04 Otherwise is it 4?
ABB1 LD DE,$0000 DE = 0 -- D used as hazard later?
ABB4 JR C,sh_select_hazard Jump if < 4 -- stop spawning barriers is the only case?
ABB6 LD E,$03 DE = 3 -- used as flag later?
ABB8 SUB E A -= 3
A is 1/2/3 here?
sh_select_hazard ABB9 LD B,$32 X coordinate = 50
ABBB DEC A If A was 1 exit via sh_add_hazards_done, adding one barrier? (left case?)
ABBC JR Z,sh_add_hazards_done
ABBE LD B,$DC X coordinate = 220
ABC0 DEC A If A was 2 exit via sh_add_hazards_done, adding one barrier? (right case?)
ABC1 JR Z,sh_add_hazards_done
ABC3 INC L L += 2 -- step to next hazards?
ABC4 INC L
ABC5 LD (HL),D *HL = 0 -- D is zero here
ABC6 INC L L += 2
ABC7 INC L
ABC8 LD (HL),D *HL = 0 -- D is zero here
ABC9 LD A,E A = E
ABCA CP $03 Is it 3?
ABCC JR NZ,sh_add_two_tumbleweeds Jump if non-zero
Three barriers rather than two whenever collision detection is switched off. $875C sets inhibit_collision_detection for the perp escape sequence, so the three-barrier arrangement is only ever placed when none of them can be driven into.
ABCE LD A,($A221) Load inhibit_collision_detection
ABD1 AND A Set flags
ABD2 JR Z,sh_add_two_barriers Jump to sh_add_two_barriers if zero, otherwise add three
Flag was set.
Populate hazards with three barriers (e.g. for perp escape screen).
sh_add_three_barriers ABD4 LD B,$20 X coordinate = 32
ABD6 CALL sh_find_free Add barrier
ABD9 LD B,$56 X coordinate = 86
ABDB CALL sh_find_free Add barrier
ABDE LD B,$8C X coordinate = 140
ABE0 JR sh_add_hazards_done Exit via sh_add_hazards_done
Populate hazards with two barriers (e.g. for dirt track).
sh_add_two_barriers ABE2 LD B,$50 X coordinate = 80
ABE4 CALL sh_find_free Add barrier
ABE7 LD B,$A0 X coordinate = 160
ABE9 JR sh_add_hazards_done Exit via sh_add_hazards_done
Populate hazards with two tumbleweeds (e.g. for dirt track).
sh_add_two_tumbleweeds ABEB LD B,$46 X coordinate = 70
ABED CALL sh_find_free Add barrier
ABF0 LD B,$B4 X coordinate = 180
sh_add_hazards_done ABF2 CALL sh_find_free Add barrier
ABF5 RET Return
Adds a barrier.
I:B Stored at entry+5 e.g. $20/$46/$56/$50/$B4
I:C Stored at entry+1 e.g. $13
sh_find_free ABF6 EXX Bank entry registers
ABF7 LD B,$06 6 iterations
ABF9 LD HL,$A188 Point HL at hazards table
ABFC LD DE,$0014 Stride of 20 bytes
sh_ff_loop ABFF RLC (HL) Check the flag byte to see if the entry is used (it's either $00 if empty, or $FF if used, so rotating it in place does not affect its value)
AC01 JR NC,sh_found_free Jump to sh_found_free if it didn't carry
AC03 ADD HL,DE Move to the next entry
AC04 DJNZ sh_ff_loop Loop while iterations remain
AC06 POP HL No iterations remain so discard the return address and exit spawn_hazards
AC07 RET
HL points to the unused entry.
sh_found_free AC08 PUSH HL IX = HL
AC09 POP IX
AC0B LD BC,$0013 Zero 20 bytes at HL
AC0E LD D,H
AC0F LD E,L
AC10 INC DE
AC11 LD (HL),$00
AC13 LDIR
AC15 EXX Restore entry registers
AC16 LD HL,$AC3C Load address of hazard_hit routine
AC19 LD (IX+$0C),H Store to IX+11
AC1C LD (IX+$0B),L
Gets hit when on the dirt track. sampled DE = $3 (tumbleweed), $0 (barrier)
AC1F LD HL,($5CF6) Point HL at the hazards data table entry (*$5CF6 -> hittable_objects_defs + 3)
AC22 ADD HL,DE
AC23 LD A,(HL) Copy the collision box width, IX[8], used by the bounding box overlap test in check_collision
AC24 LD (IX+$08),A
AC27 INC HL
AC28 LD A,(HL) Copy lod address (e.g. tumbleweed_lods)
AC29 LD (IX+$09),A
AC2C INC HL
AC2D LD A,(HL)
AC2E LD (IX+$0A),A
AC31 LD (IX+$05),B IX[5] = position across the road, 0 (left) to 255 (right) -- passed in, set up before sh_find_free calls
AC34 LD (IX+$01),C IX[1] = C -- buffer offset/distance
AC37 LD (IX+$00),$FF Mark the entry as used
AC3B RET Return
Prev: AB33 Up: Map Next: AC3C