← A15F Apply-queued-heading flags, one cell per pool slot Map A299 → Test for a collision ahead of the ball
A167: Update the balls for this frame
Drives the one or two balls in play, once per frame.
update_balls A167 LD A,(death_pause_timer) Does the death pause run? The bat freezes on the same flag.
A16A OR A
A16B RET NZ
A16C LD A,(capture_active) While ball A is captured, skip its move and deflect; jump to ball B.
A16F OR A
A170 JR NZ,update_balls_ball_b
A172 LD A,(ball_a_move_gate) Ball A re-hit gate. Left idle, the move pass runs this frame. When armed, it adds the speed and runs the pass only once the sum crosses the gate. The heading store arms it on each reflection. The position step is not gated.
A175 OR A
A176 JR Z,update_balls_move_a
A178 LD C,A
A179 LD A,(ball_a_speed)
A17C ADD A,C
A17D LD (ball_a_move_gate),A
A180 CP $09
A182 JR C,update_balls_deflect_a
A184 XOR A
A185 LD (ball_a_move_gate),A
update_balls_move_a A188 XOR A Take ball A as the active ball and run its move pass.
A189 LD (active_ball),A
A18C CALL move_ball
update_balls_deflect_a A18F LD A,(ball_a_deflect_cooldown) Ball A inhabitant-deflect cooldown: left idle, the deflect test runs. When armed, it adds the speed each frame and skips the deflect until the sum crosses the threshold. It then clears it.
A192 OR A
A193 JR Z,update_balls_a_post
A195 LD C,A
A196 LD A,(ball_a_speed)
A199 ADD A,C
A19A LD (ball_a_deflect_cooldown),A
A19D CP $0D
A19F JR C,update_balls_ball_b
A1A1 XOR A
A1A2 LD (ball_a_deflect_cooldown),A
update_balls_a_post A1A5 LD (ball_a_skip_catch),A Clear ball A's bat-catch bypass for the frame.
A1A8 LD A,(ball_a_on_bat) Run ball A's inhabitant-overlap deflection unless it is on the bat or its move gate suppressed the probe.
A1AB OR A
A1AC JR NZ,update_balls_ball_b
A1AE LD A,(ball_a_move_gate)
A1B1 OR A
A1B2 JR NZ,update_balls_ball_b
A1B4 LD A,$01 Take ball A as the overlap subject and deflect it off the first solid pool object it overlaps.
A1B6 LD (overlap_slot_1),A
A1B9 CALL ball_object_deflect
update_balls_ball_b A1BC LD A,(ball_b_in_play) Ball B runs only while it is in play; otherwise jump to the queued-heading pass.
A1BF OR A
A1C0 JR Z,update_balls_queued_a
A1C2 LD A,(ball_b_move_gate) Ball B re-hit gate, same as ball A's but with ball B's speed as the addend
A1C5 OR A
A1C6 JR Z,update_balls_move_b
A1C8 LD C,A
A1C9 LD A,(ball_b_speed)
A1CC ADD A,C
A1CD LD (ball_b_move_gate),A
A1D0 CP $09
A1D2 JR C,update_balls_deflect_b
A1D4 XOR A
A1D5 LD (ball_b_move_gate),A
update_balls_move_b A1D8 LD A,$01 Take ball B as the active ball and run its move pass.
A1DA LD (active_ball),A
A1DD CALL move_ball
update_balls_deflect_b A1E0 LD A,(missile_shot) The missile shot skips its deflect cooldown and the deflect test.
A1E3 OR A
A1E4 JR NZ,update_balls_queued_a
A1E6 LD A,(ball_b_deflect_cooldown) Ball B inhabitant-deflect cooldown. While it is non-zero, ball B skips its deflect test. Each frame it adds a ball speed, and it clears once the sum crosses the threshold. BUG: it adds ball A's speed, where ball B's move gate uses ball B's. Ball B's deflect-suppression window therefore drains at ball A's speed.
A1E9 OR A
A1EA JR Z,update_balls_b_post
A1EC LD C,A
A1ED LD A,(ball_a_speed)
A1F0 ADD A,C
A1F1 LD (ball_b_deflect_cooldown),A
A1F4 CP $0D
A1F6 JR C,update_balls_queued_a
A1F8 XOR A
A1F9 LD (ball_b_deflect_cooldown),A
update_balls_b_post A1FC XOR A Clear ball B's bypass the same way.
A1FD LD (ball_b_skip_catch),A
A200 LD A,(ball_b_on_bat) Deflect ball B unless it is parked on the bat or its move gate suppressed the probe.
A203 OR A
A204 JR NZ,update_balls_queued_a
A206 LD A,(ball_b_move_gate)
A209 OR A
A20A JR NZ,update_balls_queued_a
A20C LD A,$02 Take ball B as the overlap subject and deflect it off the first solid pool object it overlaps.
A20E LD (overlap_slot_1),A
A211 CALL ball_object_deflect
update_balls_queued_a A214 LD A,(capture_active) Apply any heading queued for ball A by an earlier deflection, unless ball A is captured.
A217 OR A
A218 JR NZ,update_balls_queued_b
A21A LD A,(apply_heading_a) If ball A has no queued heading, skip to ball B's.
A21D OR A
A21E JR Z,update_balls_queued_b
A220 XOR A Consume the queued-heading flag.
A221 LD (apply_heading_a),A
A224 LD A,(ball_b_on_bat) If ball B is on the bat, set ball A's bypass so its next bat hit is a plain bounce.
A227 OR A
A228 JR Z,update_balls_arm_cool_a
A22A LD A,$01
A22C LD (ball_a_skip_catch),A
update_balls_arm_cool_a A22F LD A,(ball_a_deflect_cooldown) Arm the deflect cooldown if it does not already run.
A232 OR A
A233 JR NZ,update_balls_apply_dir_a
A235 LD A,$01
A237 LD (ball_a_deflect_cooldown),A
update_balls_apply_dir_a A23A LD A,(pending_heading_a) Apply the queued heading: copy ball A's pending deflection heading into its heading code.
A23D LD (ball_a_heading),A
A240 XOR A Select ball A and re-derive its velocity.
A241 LD (active_ball),A
A244 CALL set_ball_velocity
update_balls_queued_b A247 LD A,(ball_b_in_play) Apply ball B's queued heading only while it is in play.
A24A OR A
A24B JR Z,update_balls_finish
A24D LD A,(apply_heading_b) If ball B's apply-heading flag is clear, finish.
A250 OR A
A251 JR Z,update_balls_finish
A253 XOR A Consume ball B's queued-heading flag.
A254 LD (apply_heading_b),A
A257 LD A,(ball_a_on_bat) If ball A is on the bat, set ball B's bypass.
A25A OR A
A25B JR Z,update_balls_arm_cool_b
A25D LD A,$01
A25F LD (ball_b_skip_catch),A
update_balls_arm_cool_b A262 LD A,(ball_b_deflect_cooldown) Arm ball B's deflect cooldown if idle.
A265 OR A
A266 JR NZ,update_balls_apply_dir_b
A268 LD A,$01
A26A LD (ball_b_deflect_cooldown),A
update_balls_apply_dir_b A26D LD A,(pending_heading_b) Apply ball B's pending heading into its heading code.
A270 LD (ball_b_heading),A
A273 LD A,$01 Select ball B and re-derive its velocity.
A275 LD (active_ball),A
A278 CALL set_ball_velocity
update_balls_finish A27B CALL resolve_ball_bounces Resolve each ball's bounce off the bat.
A27E LD A,(capture_active) Advance ball A's on-screen position unless ball A is captured.
A281 OR A
A282 JR NZ,update_balls_0
A284 XOR A
A285 LD (active_ball),A
A288 CALL step_ball
update_balls_0 A28B LD A,(ball_b_in_play) Advance ball B's position too when it is in play.
A28E OR A
A28F RET Z
A290 LD A,$01
A292 LD (active_ball),A
A295 CALL step_ball
A298 RET
← A15F Apply-queued-heading flags, one cell per pool slot Map A299 → Test for a collision ahead of the ball
Fork me on GitHub