Prev: A9DE Up: Map Next: AAC6
AA38: Draw the helicopter
AB89 (in drive_helicopter) self modifies 8FA4 to call this.
It returns unless the counter is 3, the only distance at which the helicopter is drawn. The rotor position comes from multiplying the top three bits of fast_counter by the difference between two adjacent object_positions entries, halving the high byte of the product. The body's y offset is the vertical base less the lower of those two entries. Five body parts are then drawn in a loop and the rotor is drawn separately, using the self modified rotor position.
Note that IY addresses the height table, but the two bytes read as IY+$4E and IY+$4F land well past the end of it, past the clamped heights, past the horizon values and one spare byte, in the object_positions buffer at $E34F that layout_objects fills.
Input
B Counter
IY Somewhere in the object_positions buffer ($E34F onwards)
draw_helicopter AA38 LD A,B Return if counter isn't 3
AA39 CP $03
AA3B RET NZ
AA3C LD A,(IY+$4F) A = IY[$4F] - IY[$4E] -- a delta between two adjacent object_positions entries ($E34F onwards)
AA3F SUB (IY+$4E)
AA42 LD D,$00 D = 0
AA44 LD H,D HL = 0
AA45 LD L,D
AA46 LD E,A E = A => DE = A -- DE is now the delta from above, widened
AA47 LD A,($A23F) Load fast_counter
AA4A LD B,$08 B = 8
AA4C AND $E0 fast_counter & $E0
Multiplier
dhl_loop1 AA4E RLA Shift top bit out
AA4F JR NC,dhl_aa52 If it was set then HL += DE
AA51 ADD HL,DE
dhl_aa52 AA52 ADD HL,HL HL <<= 1
AA53 DJNZ dhl_loop1 Loop dhl_loop1 while B > 0
AA55 LD A,H A = H / 2 -- is this undoing overshoot?
AA56 RRA
AA57 LD ($AA8D),A Self modify 'LD A' @ AA8C (below)
AA5A LD A,$00 A = <self modified> -- Self modified by AAEE (in move_helicopter)
AA5C SUB (IY+$4E) A -= IY[$4E]
AA5F LD ($AA77),A Self modify 'ADD A' @ AA76 (below)
AA62 LD B,$05 5 iterations
AA64 LD A,($A234) A = counter_A & 1 -- counter used for turbo smoke and helicopter blades
AA67 AND $01
AA69 LD HL,($5D08) Load addrof_helicopter_stuff_1
AA6C JR Z,dhl_aa71 Jump if A was zero
AA6E LD HL,($5D0A) Kiad addrof_helicopter_stuff_2
dhl_aa71 AA71 LD E,(HL) DE = wordat(HL); HL += 2
AA72 INC HL
AA73 LD D,(HL)
AA74 INC HL
AA75 LD A,(DE) A = *DE
AA76 ADD A,$00 A += <self modified> -- Self modified by AA5F (above)
AA78 INC DE DE++
AA79 PUSH IY Preserve IY, HL, BC
AA7B PUSH HL
AA7C PUSH BC
AA7D CALL draw_helicoper_part Call draw_helicoper_part
AA80 POP BC Restore IY, HL, BC
AA81 POP HL
AA82 POP IY
AA84 DJNZ dhl_aa71 Loop loop_aa71 while B > 0
AA86 LD E,(HL) DE = wordat(HL); HL++
AA87 INC HL
AA88 LD D,(HL)
AA89 XOR A A = 0 [can't see a reason for this]
AA8A PUSH IY Preserve IY
AA8C LD A,$00 A = <self modified> -- Self modified by AA57 (above)
AA8E CALL draw_helicoper_part Call draw_helicoper_part
AA91 POP IY Restore IY
AA93 RET Return
draw_helicoper_part AA94 LD BC,$0000 BC = <self modified> -- Self modified by AB00, move_helicopter_4 + others
AA97 NEG A = -A
AA99 LD ($933E),A Self modify 'LD D,x' @ doc_loop to load A
AA9C LD A,(DE) HL = *DE++
AA9D INC DE
AA9E LD L,A
AA9F LD H,$00
AAA1 AND A Make widened value negative
AAA2 JP P,dhl_widened
AAA5 DEC H
dhl_widened AAA6 ADD HL,BC HL += BC
AAA7 EX DE,HL
AAA8 LD B,(HL) B = *HL
AAA9 RLC B B <<= 3
AAAB RLC B
AAAD RLC B
AAAF LD A,D A = D
AAB0 AND A Set flags
AAB1 LD A,E A = E
AAB2 LD C,$00 C = 0
AAB4 JP M,dhl_aac1
AAB7 RET NZ Return if non-zero
AAB8 CP $80 Jump to draw_object_right_width_entrypt if A >= 128
AABA JP NC,draw_object_right_width_entrypt
AABD ADD A,B A += B
AABE JP draw_object_left_width_entrypt Exit via draw_object_left_width_entrypt
dhl_aac1 AAC1 ADD A,B A += B
AAC2 RET NC Return if no carry
AAC3 JP draw_object_left_width_entrypt Exit via draw_object_left_width_entrypt
Prev: A9DE Up: Map Next: AAC6