Prev: AD51 Up: Map Next: B045
ADA0: Draws hazards
This includes all cars, barriers, tumbleweeds, etc.
Used by the routines at main_loop, cpu_driver and escape_scene.
draw_hazards ADA0 XOR A n_hazards = 0
ADA1 LD ($A222),A
ADA4 LD IYh,$E3 IY = $E3xx
ADA7 LD IX,$A188 IX = &hazards[0]
ADAB LD DE,$0014 Stride of hazards entry in bytes
ADAE LD B,$06 6 iterations
dh_loop ADB0 RLC (IX+$00) Set carry if the hazard is active
ADB4 EXX Bank
ADB5 CALL C,dh_draw_one_hazard Call dh_draw_one_hazard if hazard active
ADB8 EXX Unbank
ADB9 ADD IX,DE Advance to next hazard
ADBB DJNZ dh_loop Loop while iterations remain -- B > 0
ADBD RET Return
dh_draw_one_hazard ADBE LD C,(IX+$0E) C = IX[14] -- top byte of horz position or accel?
Distance? If I disable this calculation and $A18C remains zero then the perp car cannot be caught up with. IX[4] here is e.g. $A18C IX[13] here is e.g. $A195 which seems to be the perp's acceleration or offset or ? (low byte)
ADC1 LD A,(IX+$04) IX[4] -= IX[13] -- bottom byte of accel/something?
ADC4 SUB (IX+$0D)
ADC7 LD (IX+$04),A
ADCA JR NC,dh_adcd If IX[4] was < IX[13] Then C++
ADCC INC C
dh_adcd ADCD LD A,(IX+$01) C += IX[1] -- distance related?
ADD0 ADD A,C
ADD1 LD C,A
ADD2 LD A,(IX+$0F) A = IX[15] + 1 -- counter?
ADD5 INC A
ADD6 JR NZ,dh_adf0 Jump to dh_adf0 if non-zero
ADD8 LD A,(IX+$11) A = IX[17] -- byte that indexes table_acdb
ADDB JR NC,draw_hazards_1 Jump if no carry (from earlier)
ADDD INC A Jump if ++A < 4
ADDE CP $04
ADE0 JR C,draw_hazards_0
ADE2 DEC A A--
ADE3 LD C,$FF C = $FF -- gets put in distance related field
draw_hazards_0 ADE5 LD (IX+$11),A IX[17] = A
draw_hazards_1 ADE8 AND A Set flags
ADE9 LD A,C A = C
ADEA JR Z,draw_hazards_2 Jump if zero
ADEC LD (IX+$01),A IX[1] = A -- update distance?
ADEF RET Return
dh_adf0 ADF0 LD A,C A = C
ADF1 CP $17 Jump if A < 23 -- still visible?
ADF3 JR C,draw_hazards_2
Wipe the hazard because it's gone?
ADF5 LD (IX+$00),$00 IX[0] = 0 -- hazard slot now spare
just_ret ADF9 RET Return
draw_hazards_2 ADFA LD (IX+$01),A IX[1] = A -- distance related
ADFD CP $14 Return if A >= 20
ADFF RET NC
AE00 DEC A A--
AE01 JR NZ,draw_hazards_5 Jump if non-zero
AE03 LD A,($A23F) A = ~(fast_counter & $E0)
AE06 AND $E0
AE08 CPL
AE09 CP (IX+$04) Jump if A >= IX[4]
AE0C JR NC,draw_hazards_4
AE0E LD B,(IX+$0F) B = IX[15] + 1
AE11 INC B
AE12 JR Z,draw_hazards_3 Jump if zero
Wipe the hazard because car overtaken?
AE14 LD (IX+$00),$00 IX[0] = 0 -- hazard slot now spare
AE18 RL B
AE1A RET NC Return if no carry
AE1B LD HL,$A22B Increment allow_overtake_bonus
AE1E INC (HL)
AE1F RET Return
draw_hazards_3 AE20 LD (IX+$04),A IX[4] = A
draw_hazards_4 AE23 XOR A A = 0
draw_hazards_5 AE24 ADD A,$4E A += $4E
$E300..$E316 is regularly accessed. $E300 is always $60, $E316 is always $A0
AE26 LD IYl,A IY.low = A -- i.e. $E300 | A
AE28 LD A,(IY+$01) A = IY[1]
AE2B LD C,A C = A
AE2C SUB (IY+$00) A -= IY[0] -- A is now the delta between adjacent elements
Multiplier. DE = multiplier. A = multiplicand. HL = result.
AE2F LD D,$00 DE = A; HL = 0
AE31 LD H,D
AE32 LD L,D
AE33 LD E,A
AE34 LD A,(IX+$04) A = IX[4]
AE37 LD B,$08 B = 8 -- iterations of multiply loop
draw_hazards_6 AE39 RLA Test top bit
AE3A JR NC,draw_hazards_7 If it carried out then add
AE3C ADD HL,DE
draw_hazards_7 AE3D ADD HL,HL Double
AE3E DJNZ draw_hazards_6 Loop
AE40 LD A,H A = H -- high part of result
AE41 RRA
AE42 LD (IX+$06),A IX[6] = A
AE45 NEG A = ~((C - A) << 1)
AE47 ADD A,C
AE48 ADD A,A
AE49 CPL
AE4A LD L,A HL = $E800 | A (road drawing left)
AE4B LD H,$E8
AE4D LD D,(HL) D = *HL
AE4E DEC L HL--
AE4F LD E,(HL) E = *HL
AE50 LD H,$EC H = $EC
AE52 LD A,(HL) A = *HL
AE53 INC L L++
AE54 LD H,(HL) H = *HL
AE55 LD L,A L = A
AE56 AND A Set flags
AE57 LD ($AE71),DE Self modify 'LD HL,xxxx' @ AE70
AE5B SBC HL,DE HL -= DE
AE5D EX DE,HL Swap
AE5E LD HL,$0000 HL = 0
AE61 LD A,(IX+$05) A = IX[5]
Another multiplier.
AE64 LD B,$08 B = 8
draw_hazards_8 AE66 RLA A <<= 1
AE67 JR NC,draw_hazards_9 If it carried out then add
AE69 ADD HL,DE
draw_hazards_9 AE6A ADD HL,HL Double
AE6B DJNZ draw_hazards_8 Loop
AE6D LD A,H A = H
AE6E RRA
AE6F LD C,A C = A
AE70 LD HL,$0000 HL = <self modified> + BC
AE73 ADD HL,BC
AE74 LD (IX+$02),L wordat(IX + 2) = HL
AE77 LD (IX+$03),H
AE7A CALL sub_ad51 Call sub_ad51
AE7D LD D,(IX+$01) D = IX[1]
AE80 LD E,(IX+$04) E = IX[4]
AE83 LD HL,$A222 HL = &n_hazards
AE86 LD A,(HL) A = *HL
AE87 INC (HL) (*HL)++
AE88 LD HL,$E900 HL -> table
AE8B AND A Set flags
AE8C JR Z,dh_no_hazards Jump to dh_no_hazards if zero
AE8E LD B,A Iterations
Loop starts (loop for all hazards)
draw_hazards_10 AE8F LD A,D A = D
AE90 CP (HL) Compare to *HL
AE91 INC L L++
AE92 JR C,draw_hazards_11 Jump if A < *HL
AE94 JR NZ,draw_hazards_12 Jump if A != *HL
AE96 LD A,E A = E
AE97 CP (HL) Compare to *HL
AE98 JR C,draw_hazards_12 Jump if A < *HL
draw_hazards_11 AE9A INC L L += 3
AE9B INC L
AE9C INC L
AE9D DJNZ draw_hazards_10 Loop
dh_no_hazards AE9F LD (HL),D wordat(HL) = DE; HL += 2
AEA0 INC L
AEA1 LD (HL),E
AEA2 INC L
AEA3 PUSH IX DE = IX
AEA5 POP DE
AEA6 LD (HL),E wordat(HL) = DE; HL++
AEA7 INC L
AEA8 LD (HL),D
AEA9 JR draw_hazards_13 Jump
draw_hazards_12 AEAB PUSH DE Preserve DE
AEAC LD A,B A = B * 4
AEAD ADD A,A
AEAE ADD A,A
AEAF LD C,A BC = A
AEB0 LD B,$00
AEB2 ADD A,$02 A += 2 + L
AEB4 ADD A,L
AEB5 LD E,A E = A
AEB6 SUB $04 A -= 4
AEB8 LD L,A L = A
AEB9 LD D,H D = H
AEBA LDDR Do *HL-- = *DE-- until BC == 0
AEBC EX DE,HL
AEBD PUSH IX DE = IX
AEBF POP DE
AEC0 LD (HL),D wordat(HL) = DE; HL -= 2
AEC1 DEC L
AEC2 LD (HL),E
AEC3 DEC L
AEC4 POP DE Restore DE
AEC5 LD (HL),E *HL = E
AEC6 DEC L L--
AEC7 LD (HL),D *HL = D
draw_hazards_13 AEC8 LD L,(IX+$0B) HL = wordat(IX + 11)
AECB LD H,(IX+$0C)
AECE JP (HL) Jump there
This entry point is used by the routine at draw_everything_else.
draw_hazards_14 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,draw_hazards_15
AEDA LD A,$0A A = 10
draw_hazards_15 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
draw_hazards_16 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' @ draw_object_right_7 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,draw_hazards_21 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,draw_hazards_17 Jump if negative
AF23 JP NZ,draw_hazards_20 Jump if non-zero
AF26 CP $80 Jump if A >= 128
AF28 JP NC,draw_hazards_19
AF2B ADD A,E A += E
AF2C JP draw_hazards_18 Jump
draw_hazards_17 AF2F ADD A,E A += E
AF30 JR NC,draw_hazards_20 Jump if no carry
draw_hazards_18 AF32 CALL draw_object_left_helicopter_entrypt Call draw_object_left_helicopter_entrypt
AF35 JP draw_hazards_20 Jump over next CALL
draw_hazards_19 AF38 CALL draw_object_right_helicopter_entrypt Call draw_object_right_helicopter_entrypt
draw_hazards_20 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 HL = &n_hazards
AF44 DEC (HL) (*HL)--
AF45 POP HL Restore HL
AF46 RET Z Return if zero
AF47 LD A,(HL) A = *HL
AF48 CP B Jump if A == B
AF49 JP Z,draw_hazards_16
AF4C LD ($AED0),HL Self modify 'LD HL' @ draw_hazards_14 to load HL
AF4F RET Return
draw_hazards_21 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,draw_hazards_22 Jump if negative
AF60 JP NZ,draw_hazards_20 Jump if non-zero
AF63 CP $80 Jump if A >= 128
AF65 JP NC,draw_hazards_24
AF68 ADD A,E A = E
AF69 JP draw_hazards_23 Jump
draw_hazards_22 AF6C ADD A,E A = E
AF6D JR NC,draw_hazards_20 -- checking result of test at AF56?
draw_hazards_23 AF6F CALL draw_object_left_helicopter_entrypt Call draw_object_left_helicopter_entrypt
AF72 JP draw_hazards_25 Jump
draw_hazards_24 AF75 CALL draw_object_right_helicopter_entrypt Call draw_object_right_helicopter_entrypt
draw_hazards_25 AF78 LD A,($933E) Read A from 'LD D,x' @ draw_object_right_7
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,dh_smash_level
AF85 LD A,($AFFC) A = x in 'LD A,x' @ AFFB
AF88 CP $04 Jump if A >= 4
AF8A JP NC,dh_smash_level
AF8D ADD A,A Double A
AF8E LD C,A BC = A
AF8F LD B,$00
AF91 LD HL,$CDEC HL = table_cdec + BC
AF94 ADD HL,BC
I see this getting hit only when in smash mode.
AF95 LD B,(HL) BC = wordat(HL)
AF96 INC HL
AF97 LD C,(HL)
AF98 LD HL,$E1D8 -> floating_arrow_big_defn (incl. "HERE!")
AF9B CALL dh_draw_hl_setup Call plotting func TBD
dh_smash_level AF9E LD A,($A232) Get smash_level
AFA1 CP $04 Jump if it's < 4
AFA3 JR C,dh_check_smash_level
AFA5 SUB $04 A = (A - 4) * 4 ?
AFA7 RLCA
AFA8 RLCA
AFA9 EX AF,AF' Bank
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 = table_ce00 + DE -- table?
AFB4 ADD HL,DE
AFB5 LD B,(HL) BC = wordat(HL); HL++
AFB6 INC HL
AFB7 LD C,(HL)
AFB8 EX AF,AF' Unbank
AFB9 LD E,A E = A this must be a distance value?
AFBA LD HL,$CDF4 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
AFCC CALL dh_draw Draw
dh_check_smash_level AFCF LD A,($A232) Get smash_level (should be 0..6)
AFD2 AND A Is smash_level 0?
AFD3 JP Z,draw_hazards_20 Jump if so (draw nothing, continue)
AFD6 DEC A Is smash_level 1?
AFD7 JR Z,draw_hazards_27 Jump if so (draw 1 lot)
AFD9 DEC A Is smash_level 2?
AFDA JR Z,draw_hazards_26 Jump if so (draw 2 lots)
Otherwise draw all 3 lots.
AFDC LD HL,$CE26 Smoke data
AFDF CALL dh_aff1 Call dh_aff1
draw_hazards_26 AFE2 LD HL,$CE0C Smoke data
AFE5 CALL dh_aff1 Call dh_aff1
draw_hazards_27 AFE8 LD HL,$CE19 Smoke data
AFEB CALL dh_aff1 Call dh_aff1
AFEE JP draw_hazards_20 Continue
Decrements a counter 5..1 then repeats this must be the car-on-fire animation index is it just the smoke?
dh_aff1 AFF1 LD A,(HL) Load counter and decrement it
AFF2 DEC A
AFF3 JP P,dh_aff8 Jump if +ve
AFF6 LD A,$05 It became zero, reset to 5
dh_aff8 AFF8 LD (HL),A *HL = A
AFF9 LD E,A Copy counter to E
AFFA INC HL HL++
some added value to animation index? perhaps a speed factor?
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.
dh_draw B01B ADD HL,DE HL += DE -- find graphic definition entry
HL -> graphic definition
dh_draw_hl_setup 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' @ draw_object_right_7 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,dh_exit_2 Jump to dh_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_helicopter_entrypt if A >= 128
B036 JP NC,draw_object_right_helicopter_entrypt
dh_exit_1 B039 ADD A,E Add pixel width
B03A JP draw_object_left_helicopter_entrypt Exit via draw_object_left_helicopter_entrypt
dh_exit_2 B03D ADD A,C A += C
B03E JR C,dh_exit_1 Jump if carry
B040 ADD A,E Add pixel width
B041 JP C,draw_object_left_helicopter_entrypt Exit via draw_object_left_helicopter_entrypt if carry
B044 RET Otherwise return
Prev: AD51 Up: Map Next: B045