Prev: ADA0 Up: Map Next: B045
AECF: Draws the hazard sprites at one depth
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.
Input
B Current draw depth; must match the draw table entry
IY Pointer into the height table
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