| Chase H.Q. | Routines |
| Prev: ADA0 | Up: Map | Next: B045 |
|
Called once per depth as draw_scene_objects walks the depth sorted draw list, and returns at once unless the first word of the draw table matches the current distance. For each hazard at that depth the bitmap comes from the level of detail table, the screen x position is worked out from the hazard's horizontal position and clip, and the sprite is drawn by the left or right hand object plotter.
A hazard whose flags are $FF is the perp car. Its position is also saved into the self modified fields dhs_draw_bitmap uses, and then the floating "HERE!" arrow is drawn while smash_level is under 5, the fire overlays once smash_level reaches 4, and trailing smoke for smash_level 1 to 3.
Used by the routine at draw_scene_objects.
|
||||||||||
| draw_hazard_sprites | AECF | LD HL,$0000 | HL = <self modified> | |||||||
| AED2 | LD A,B | A = B | ||||||||
| AED3 | CP (HL) | Return if A != *HL | ||||||||
| AED4 | RET NZ | |||||||||
| AED5 | DEC A | A-- | ||||||||
| AED6 | CP $0B | Jump if A < 11 | ||||||||
| AED8 | JR C,dhs_aedc | |||||||||
| AEDA | LD A,$0A | A = 10 | ||||||||
| dhs_aedc | AEDC | SRL A | A >>= 1 | |||||||
| AEDE | LD ($AFFC),A | Self modify 'LD A,x' @ AFFB -- possible speed factor | ||||||||
| AEE1 | LD E,A | E = A | ||||||||
| AEE2 | RLCA | A <<= 3 | ||||||||
| AEE3 | RLCA | |||||||||
| AEE4 | RLCA | |||||||||
| AEE5 | SUB E | A -= E | ||||||||
| AEE6 | LD E,A | DE = A | ||||||||
| AEE7 | LD D,$00 | |||||||||
| dhs_equal | AEE9 | INC L | L += 2 | |||||||
| AEEA | INC L | |||||||||
| AEEB | LD A,(HL) | IX = wordat(HL); HL += 2 | ||||||||
| AEEC | LD IXl,A | |||||||||
| AEEE | INC L | |||||||||
| AEEF | LD A,(HL) | |||||||||
| AEF0 | LD IXh,A | |||||||||
| AEF2 | INC L | |||||||||
| AEF3 | PUSH HL | Preserve HL, BC, DE | ||||||||
| AEF4 | PUSH BC | |||||||||
| AEF5 | PUSH DE | |||||||||
| AEF6 | LD H,(IX+$0A) | HL = wordat(IX + 9) | ||||||||
| AEF9 | LD L,(IX+$09) | |||||||||
| AEFC | ADD HL,DE | HL += DE | ||||||||
| AEFD | LD E,(HL) | E = *HL | ||||||||
| AEFE | RLC E | E <<= 3 ? | ||||||||
| AF00 | RLC E | |||||||||
| AF02 | RLC E | |||||||||
| AF04 | LD A,(IX+$06) | A = IX[6] - IX[16] | ||||||||
| AF07 | SUB (IX+$10) | |||||||||
| AF0A | LD ($933E),A | Self modify 'LD D,x' @ doc_loop to load A | ||||||||
| AF0D | LD A,(IX+$13) | A = IX[19] | ||||||||
| AF10 | LD ($93C1),A | Self modify 'LD A,x' @ 93C0 to load A | ||||||||
| AF13 | LD A,(IX+$0F) | A = IX[15] + 1 | ||||||||
| AF16 | INC A | |||||||||
| AF17 | JR Z,dhs_af50 | Jump if zero | ||||||||
| AF19 | LD A,(IX+$03) | A = IX[3] | ||||||||
| AF1C | AND A | Set flags | ||||||||
| AF1D | LD A,(IX+$02) | A = IX[2] | ||||||||
| AF20 | JP M,dhs_af2f | Jump if negative | ||||||||
| AF23 | JP NZ,dhs_draw_done_1 | Jump if non-zero | ||||||||
| AF26 | CP $80 | Jump if A >= 128 | ||||||||
| AF28 | JP NC,dhs_draw_right_1 | |||||||||
| AF2B | ADD A,E | A += E | ||||||||
| AF2C | JP dhs_draw_left_1 | Jump | ||||||||
| dhs_af2f | AF2F | ADD A,E | A += E | |||||||
| AF30 | JR NC,dhs_draw_done_1 | Jump if no carry | ||||||||
| dhs_draw_left_1 | AF32 | CALL draw_object_left_width_entrypt | Call draw_object_left_width_entrypt | |||||||
| AF35 | JP dhs_draw_done_1 | Jump over next CALL | ||||||||
| dhs_draw_right_1 | AF38 | CALL draw_object_right_width_entrypt | Call draw_object_right_width_entrypt | |||||||
| dhs_draw_done_1 | AF3B | POP DE | Restore DE, BC | |||||||
| AF3C | POP BC | |||||||||
| AF3D | XOR A | Self modify 'LD A,x' @ 93C0 to load 0 | ||||||||
| AF3E | LD ($93C1),A | |||||||||
| AF41 | LD HL,$A222 | Load address of n_hazards | ||||||||
| AF44 | DEC (HL) | Decrement n_hazards | ||||||||
| AF45 | POP HL | Restore HL (which?) | ||||||||
| AF46 | RET Z | Return if zero | ||||||||
| AF47 | LD A,(HL) | A = *HL | ||||||||
| AF48 | CP B | Jump if A == B | ||||||||
| AF49 | JP Z,dhs_equal | |||||||||
| AF4C | LD ($AED0),HL | Self modify 'LD HL' @ draw_hazard_sprites to load HL | ||||||||
| AF4F | RET | Return | ||||||||
| dhs_af50 | AF50 | LD A,(IX+$03) | A = IX[3] | |||||||
| AF53 | LD ($B02A),A | Self modify 'LD A,x' @ B029 to load A | ||||||||
| AF56 | AND A | Set flags | ||||||||
| AF57 | LD A,(IX+$02) | A = IX[2] | ||||||||
| AF5A | LD ($B02D),A | Self modify 'LD A,x' @ B02C to load A | ||||||||
| AF5D | JP M,dhs_af6c | Jump if negative | ||||||||
| AF60 | JP NZ,dhs_draw_done_1 | Jump if non-zero | ||||||||
| AF63 | CP $80 | Jump if A >= 128 | ||||||||
| AF65 | JP NC,dhs_draw_right_2 | |||||||||
| AF68 | ADD A,E | A = E | ||||||||
| AF69 | JP dhs_draw_left_2 | Jump | ||||||||
| dhs_af6c | AF6C | ADD A,E | A = E | |||||||
| AF6D | JR NC,dhs_draw_done_1 | -- checking result of test at AF56? | ||||||||
| dhs_draw_left_2 | AF6F | CALL draw_object_left_width_entrypt | Call draw_object_left_width_entrypt | |||||||
| AF72 | JP dhs_done_draw_object | Jump | ||||||||
| dhs_draw_right_2 | AF75 | CALL draw_object_right_width_entrypt | Call draw_object_right_width_entrypt | |||||||
| dhs_done_draw_object | AF78 | LD A,($933E) | Read A from 'LD D,x' @ doc_loop | |||||||
| AF7B | LD ($B024),A | Self modify 'LD A,x' @ B023 | ||||||||
| AF7E | LD A,($A232) | Get smash_level | ||||||||
| AF81 | CP $05 | Jump if A >= 5 | ||||||||
| AF83 | JR NC,dhs_smash_level | |||||||||
| AF85 | LD A,($AFFC) | A = x in 'LD A,x' @ AFFB | ||||||||
| AF88 | CP $04 | Jump if A >= 4 | ||||||||
| AF8A | JP NC,dhs_smash_level | |||||||||
| AF8D | ADD A,A | Double A to make it an index | ||||||||
| AF8E | LD C,A | BC = A | ||||||||
| AF8F | LD B,$00 | |||||||||
| AF91 | LD HL,$CDEC | HL = arrow_offsets + BC | ||||||||
| AF94 | ADD HL,BC | |||||||||
|
I see this getting hit only when in smash mode.
|
||||||||||
| AF95 | LD B,(HL) | Load x offset | ||||||||
| AF96 | INC HL | Advance | ||||||||
| AF97 | LD C,(HL) | Load y offset | ||||||||
| AF98 | LD HL,$E1D8 | Address of floating_arrow_here_defn (incl. "HERE!") | ||||||||
| AF9B | CALL dhs_draw_bitmap | Call dhs_draw_bitmap | ||||||||
| dhs_smash_level | AF9E | LD A,($A232) | Get smash_level | |||||||
| AFA1 | CP $04 | Jump if it's < 4 | ||||||||
| AFA3 | JR C,dhs_check_smash_level | |||||||||
| AFA5 | SUB $04 | Compute (smash_level - 4) * 4 | ||||||||
| AFA7 | RLCA | |||||||||
| AFA8 | RLCA | |||||||||
| AFA9 | EX AF,AF' | Bank scaled smash level | ||||||||
| AFAA | LD A,($AFFC) | A = x in 'LD A,x' @ AFFB | ||||||||
| AFAD | RLCA | *= 2 | ||||||||
| AFAE | LD E,A | DE = A | ||||||||
| AFAF | LD D,$00 | |||||||||
| AFB1 | LD HL,$CE00 | HL = smoke_offsets + DE -- index smoke_offsets | ||||||||
| AFB4 | ADD HL,DE | |||||||||
| AFB5 | LD B,(HL) | BC = wordat(HL); HL++ | ||||||||
| AFB6 | INC HL | |||||||||
| AFB7 | LD C,(HL) | |||||||||
| AFB8 | EX AF,AF' | Unbank scaled smash level | ||||||||
| AFB9 | LD E,A | E = A | ||||||||
| AFBA | LD HL,$CDF4 | Load address of table of car-on-fire LODs (six entries long) | ||||||||
| AFBD | LD A,($A236) | Take half-rate counter_C (counts 0/1/2/3) and make it 0/1/0/1 (this is the animation frame) | ||||||||
| AFC0 | AND $01 | |||||||||
| AFC2 | RLCA | Double it so it's a table offset | ||||||||
| AFC3 | ADD A,E | |||||||||
| AFC4 | LD E,A | |||||||||
| AFC5 | ADD HL,DE | Form table entry pointer | ||||||||
| AFC6 | LD A,(HL) | HL = wordat(HL) Load table entry (a pointer) into HL | ||||||||
| AFC7 | INC HL | |||||||||
| AFC8 | LD H,(HL) | |||||||||
| AFC9 | LD L,A | |||||||||
| AFCA | POP DE | Retrieve DE from stack | ||||||||
| AFCB | PUSH DE | |||||||||
|
DE is offset, HL is base of graphic defns, B/C is x/y
|
||||||||||
| AFCC | CALL dhs_draw | Draw | ||||||||
| dhs_check_smash_level | AFCF | LD A,($A232) | Get smash_level (should be 0..6) | |||||||
| AFD2 | AND A | Is smash_level 0? | ||||||||
| AFD3 | JP Z,dhs_draw_done_1 | Jump if so (draw nothing, continue) | ||||||||
| AFD6 | DEC A | Is smash_level 1? | ||||||||
| AFD7 | JR Z,dhs_draw_smoke_3 | Jump if so (draw 1 lot) | ||||||||
| AFD9 | DEC A | Is smash_level 2? | ||||||||
| AFDA | JR Z,dhs_draw_smoke_2 | Jump if so (draw 2 lots) | ||||||||
|
Otherwise draw all 3 lots.
|
||||||||||
| AFDC | LD HL,$CE26 | Smoke data | ||||||||
| AFDF | CALL dhs_smoke | Call dhs_smoke | ||||||||
| dhs_draw_smoke_2 | AFE2 | LD HL,$CE0C | Smoke data | |||||||
| AFE5 | CALL dhs_smoke | Call dhs_smoke | ||||||||
| dhs_draw_smoke_3 | AFE8 | LD HL,$CE19 | Smoke data | |||||||
| AFEB | CALL dhs_smoke | Call dhs_smoke | ||||||||
| AFEE | JP dhs_draw_done_1 | Continue | ||||||||
|
Decrements a counter 5..1 then repeats this must be the car-on-fire animation index is it just the smoke?
|
||||||||||
| dhs_smoke | AFF1 | LD A,(HL) | Load counter and decrement it | |||||||
| AFF2 | DEC A | |||||||||
| AFF3 | JP P,dhs_aff8 | Jump if +ve | ||||||||
| AFF6 | LD A,$05 | It became zero, reset to 5 | ||||||||
| dhs_aff8 | AFF8 | LD (HL),A | *HL = A | |||||||
| AFF9 | LD E,A | Copy counter to E | ||||||||
| AFFA | INC HL | HL++ | ||||||||
|
The self modified byte is the smoke burst's base frame, added to the counter to give the animation index. An index above 5 means this particle is not visible yet.
|
||||||||||
| AFFB | LD A,$00 | A = <self modified by AEDE> | ||||||||
| AFFD | LD C,A | C = A | ||||||||
| AFFE | LD D,A | D = A | ||||||||
| AFFF | ADD A,E | A += E -- add counter | ||||||||
| B000 | CP $06 | Return if A >= 6 | ||||||||
| B002 | RET NC | |||||||||
| B003 | LD E,A | E = A -- smoke animation index | ||||||||
| B004 | SUB D | D = A - D | ||||||||
| B005 | LD D,A | |||||||||
| B006 | SLA C | Double self mod value from earlier | ||||||||
| B008 | LD B,$00 | Widen to 16-bit | ||||||||
| B00A | ADD HL,BC | Add to HL | ||||||||
| B00B | LD A,(HL) | B = *HL - D | ||||||||
| B00C | SUB D | |||||||||
| B00D | LD B,A | |||||||||
| B00E | INC HL | HL++ | ||||||||
| B00F | LD C,(HL) | C = *HL | ||||||||
|
E = SMOKE animation index
Select the frame.
|
||||||||||
| B010 | LD A,E | DE = E * 7 | ||||||||
| B011 | ADD A,A | |||||||||
| B012 | ADD A,A | |||||||||
| B013 | ADD A,A | |||||||||
| B014 | SUB E | |||||||||
| B015 | LD E,A | |||||||||
| B016 | LD D,$00 | |||||||||
| B018 | LD HL,$E1AE | Point HL at smoke_defns | ||||||||
|
Similar code to $AA19 (in dust/stones code). Does plotting.
|
||||||||||
| dhs_draw | B01B | ADD HL,DE | HL += DE -- find graphic definition entry | |||||||
|
B,C = x,y offset/position? HL -> graphic definition
|
||||||||||
| dhs_draw_bitmap | B01C | LD E,(HL) | Fetch byte width | |||||||
| B01D | RLC E | Multiply it by 8 yielding the pixel width | ||||||||
| B01F | RLC E | |||||||||
| B021 | RLC E | |||||||||
| B023 | LD A,$00 | A = <self modified by AF7B> + B | ||||||||
| B025 | ADD A,B | |||||||||
| B026 | LD ($933E),A | Self modify 'LD D,x' @ doc_loop to load A | ||||||||
| B029 | LD A,$00 | A = <self modified> | ||||||||
| B02B | AND A | Set flags | ||||||||
| B02C | LD A,$00 | A = <self modified> | ||||||||
| B02E | JP M,dhs_exit_2 | Jump to dhs_exit_2 if negative | ||||||||
| B031 | RET NZ | Return if non-zero | ||||||||
| B032 | ADD A,C | A += C | ||||||||
| B033 | RET C | Return if carry | ||||||||
| B034 | CP $80 | Exit via draw_object_right_width_entrypt if A >= 128 | ||||||||
| B036 | JP NC,draw_object_right_width_entrypt | |||||||||
| dhs_exit_1 | B039 | ADD A,E | Add pixel width | |||||||
| B03A | JP draw_object_left_width_entrypt | Exit via draw_object_left_width_entrypt | ||||||||
| dhs_exit_2 | B03D | ADD A,C | A += C | |||||||
| B03E | JR C,dhs_exit_1 | Jump if carry | ||||||||
| B040 | ADD A,E | Add pixel width | ||||||||
| B041 | JP C,draw_object_left_width_entrypt | Exit via draw_object_left_width_entrypt if carry | ||||||||
| B044 | RET | Otherwise return | ||||||||
| Prev: ADA0 | Up: Map | Next: B045 |