Prev: AD51 Up: Map Next: AECF
ADA0: Draws all hazards
This includes all cars, barriers, tumbleweeds, etc.
n_hazards is zeroed, then all six slots are walked and the active ones passed to advance_hazard, which advances the hazard's distance, projects it into perspective, inserts it into the depth sorted draw list and fires its hit handler.
Used by the routines at main_loop, drive_attract_demo and escape_scene.
advance_hazards ADA0 XOR A n_hazards = 0
ADA1 LD ($A222),A
ADA4 LD IYh,$E3 IY = $E3xx
ADA7 LD IX,$A188 Point IX at hazards[0]
ADAB LD DE,$0014 Stride of hazards is 20 bytes
ADAE LD B,$06 6 iterations
ah_loop ADB0 RLC (IX+$00) Set carry if the hazard is active
ADB4 EXX Bank
ADB5 CALL C,advance_hazard Call advance_hazard if hazard active
ADB8 EXX Unbank
ADB9 ADD IX,DE Advance to next hazard
ADBB DJNZ ah_loop Loop while iterations remain -- B > 0
ADBD RET Return
advance_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 is the perp's speed
ADC1 LD A,(IX+$04) IX[4] -= IX[13] -- bottom byte of speed
ADC4 SUB (IX+$0D)
ADC7 LD (IX+$04),A
ADCA JR NC,ah_adcd If IX[4] was < IX[13] then C++
ADCC INC C
ah_adcd ADCD LD A,(IX+$01) C += IX[1] -- buffer offset/distance
ADD0 ADD A,C
ADD1 LD C,A
ADD2 LD A,(IX+$0F) A = IX[15] + 1 -- counter?
ADD5 INC A
ADD6 JR NZ,ah_adf0 Jump to ah_adf0 if non-zero
ADD8 LD A,(IX+$11) A = IX[17] -- byte that indexes table_acdb
ADDB JR NC,advance_hazards_1 Jump if no carry (carry not set by INC A, but ADD A,C)
ADDD INC A Jump if ++A < 4
ADDE CP $04
ADE0 JR C,advance_hazards_0
ADE2 DEC A A--
ADE3 LD C,$FF C = $FF -- gets put in distance related field
advance_hazards_0 ADE5 LD (IX+$11),A IX[17] = A -- set lane?
advance_hazards_1 ADE8 AND A Set flags
ADE9 LD A,C A = C
ADEA JR Z,ah_adfa Jump if zero
ADEC LD (IX+$01),A IX[1] = A -- buffer offset/distance
ADEF RET Return
ah_adf0 ADF0 LD A,C A = C
ADF1 CP $17 Jump if A < 23 -- still visible?
ADF3 JR C,ah_adfa
Wipe the hazard
ADF5 LD (IX+$00),$00 IX[0] = 0 -- hazard slot now spare
no_op ADF9 RET Return (used as just a RET elsewhere)
ah_adfa ADFA LD (IX+$01),A IX[1] = A -- buffer offset/distance
ADFD CP $14 Return if A >= 20
ADFF RET NC
AE00 DEC A A--
AE01 JR NZ,ah_ae24 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,ah_ae23
AE0E LD B,(IX+$0F) B = IX[15] + 1
AE11 INC B
AE12 JR Z,ah_ae20 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 overtake_bonus_counter
AE1E INC (HL)
AE1F RET Return
ah_ae20 AE20 LD (IX+$04),A IX[4] = A
ah_ae23 AE23 XOR A A = 0
ah_ae24 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
ah_ae39_loop AE39 RLA Test top bit
AE3A JR NC,ah_not_set If it carried out then add
AE3C ADD HL,DE
ah_not_set AE3D ADD HL,HL Double
AE3E DJNZ ah_ae39_loop 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 Clear carry
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
ah_ae66 AE66 RLA A <<= 1
AE67 JR NC,ah_ae6a If it carried out then add
AE69 ADD HL,DE
ah_ae6a AE6A ADD HL,HL Double
AE6B DJNZ ah_ae66 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 check_collision Call check_collision (result ignored)
AE7D LD D,(IX+$01) D = IX[1] -- buffer offset/distance
AE80 LD E,(IX+$04) E = IX[4] -- possibly a distance low byte?
AE83 LD HL,$A222 Load address of n_hazards
AE86 LD A,(HL) Load n_hazards
AE87 INC (HL) Increment n_hazards
AE88 LD HL,$E900 Load address of (road centre left?) table
AE8B AND A Jump to ah_no_hazards if n_hazards was zero
AE8C JR Z,ah_no_hazards
AE8E LD B,A Iterations
Loop starts (loop for all hazards)
ah_ae8f AE8F LD A,D A = D
AE90 CP (HL) Compare to *HL
AE91 INC L L++
AE92 JR C,ah_ae9a Jump if A < *HL
AE94 JR NZ,ah_aeab Jump if A != *HL
AE96 LD A,E A = E
AE97 CP (HL) Compare to *HL
AE98 JR C,ah_aeab Jump if A < *HL
ah_ae9a AE9A INC L L += 3
AE9B INC L
AE9C INC L
AE9D DJNZ ah_ae8f Loop
ah_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 ah_call_handler Jump
ah_aeab 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
ah_call_handler AEC8 LD L,(IX+$0B) HL = wordat(IX + 11)
AECB LD H,(IX+$0C)
AECE JP (HL) Jump there
Prev: AD51 Up: Map Next: AECF