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