← CBFE Spawn and death reaction state machine Map CCD2 → Ball kill, the shared overlap helpers, then the per-type handlers
CC56: Update the objects' behaviors
The table of word pointers to the per-type behavior handlers in the inhabitant-behavior block, indexed by object type, comes first.
The per-frame inhabitant processor. It walks the five inhabitant records. Each non-empty slot goes to the behavior handler its type selects in the handler table. On entry it also ages the move-freeze timer and ends the freeze once the timer reaches 512 frames.
handler_table CC56 DEFW $0000 No handler
CC58 DEFW $0000 No handler, the ball gem's type
CC5A DEFW update_face_monster
CC5C DEFW update_ufo
CC5E DEFW update_diamond
CC60 DEFW update_bowling_ball
CC62 DEFW update_hive
CC64 DEFW update_bee
CC66 DEFW update_capsule
CC68 DEFW update_orb
CC6A DEFW update_h_rotor
CC6C DEFW $0000 No handler
CC6E DEFW $0000 No handler
CC70 DEFW update_wheel
CC72 DEFW update_visor
CC74 DEFW update_starburst
CC76 DEFW hockey_mask
CC78 DEFW update_comet
CC7A DEFW update_warp_gate
CC7C DEFW update_dart
update_inhabitants CC7E LD A,(move_freeze) While the move-freeze flag is set, age its 16-bit freeze timer. Clear the flag and both timer bytes 512 frames after the freeze began.
CC81 OR A
CC82 JR Z,scan_inhabitants
CC84 LD HL,freeze_timer_lo
CC87 INC (HL)
CC88 JR NZ,scan_inhabitants
CC8A LD HL,freeze_timer_hi
CC8D INC (HL)
CC8E LD A,(HL)
CC8F CP $02
CC91 JR NZ,scan_inhabitants
CC93 XOR A
CC94 LD (move_freeze),A
CC97 LD (freeze_timer_lo),A
CC9A LD (freeze_timer_hi),A
scan_inhabitants CC9D LD C,$03 Start at the first inhabitant slot: its index in C, its logic record in IY and its sprite record in IX.
CC9F LD IY,inhabitant_records
CCA3 LD IX,inhabitant_objects
inhabitant_slot_loop CCA7 LD A,(IY+$08) Read the slot's type. Skip an empty slot, or else double the type into a table offset.
CCAA OR A
CCAB JR Z,inhabitant_next_slot
CCAD ADD A,A
CCAE LD E,A
CCAF LD D,$00
CCB1 LD HL,handler_table Point HL at this type's entry in the handler table.
CCB4 ADD HL,DE
CCB5 LD A,(HL)
CCB6 LD (inhabitant_slot_loop+$18),A Copy the entry's two bytes into the operand of the CALL below – a dispatch that modifies its own code.
CCB9 INC HL
CCBA LD A,(HL)
CCBB LD (inhabitant_slot_loop+$19),A
A handler scores only when a ball reaches the inhabitant, and it banks the points into the pending score. Most inhabitants take that through the ball kill. The orb and the dart take it through the plain overlap instead. The starburst scores through the plain overlap on the touch, and through the ball kill during its knock-back slide. The sweep kills an inhabitant and scores nothing. Every handler is entered the same way:
Register What it carries
IX The inhabitant's 9-byte sprite record in the object pool
IY Its 16-byte logic record, laid out as the secondary object's logic record
C Its pool-slot index
CCBE CALL $0000 Run this inhabitant's behavior handler.
inhabitant_next_slot CCC1 LD DE,$0010 Step to the next slot, a record and a sprite entry on, and loop through the last inhabitant slot.
CCC4 ADD IY,DE
CCC6 LD DE,$0009
CCC9 ADD IX,DE
CCCB INC C
CCCC LD A,C
CCCD CP $08
CCCF JR NZ,inhabitant_slot_loop
CCD1 RET
← CBFE Spawn and death reaction state machine Map CCD2 → Ball kill, the shared overlap helpers, then the per-type handlers
Fork me on GitHub