← C76D Fill the free inhabitant slots with wheels Map C872 → Saved probe-tile pointer
C7E8: Steer an object around solid playfield tiles
Steers an object around solid playfield tiles each frame. When a cell ahead of it is solid, it takes a new heading from the steer table.
Input
IX the object's object_table sprite record, with its pixel X and Y
IY the object's logic record (obj2_record), read for its heading
Each heading owns an entry in the steer table that names up to two cells to test, as offsets from the saved probe-tile pointer. An entry can skip either test. The two results form a blocked code in the wall-probe result: first cell only, second cell only, or both. With neither cell solid, the routine keeps the heading. Otherwise it reads the new heading from the entry by that code. The wheel bias then adjusts the result for the wheel.
object_avoid_walls C7E8 LD A,(IY+$00) Read the heading. The down, down-left, left and up-left headings put the probe to the right of the object.
C7EB CP $04
C7ED JR C,avoid_probe_x_low
C7EF LD A,(IX+$00)
C7F2 ADD A,$02
C7F4 JR avoid_probe_x_col
avoid_probe_x_low C7F6 LD A,(IX+$00) The other four headings put it to the left of the object.
C7F9 SUB $02
avoid_probe_x_col C7FB RRCA Take the probe's tile column, 0–31.
C7FC RRCA
C7FD RRCA
C7FE AND $1F
C800 LD D,A
C801 LD A,(IY+$00) The up, up-right, right and up-left headings put the probe below the object. The other four put it above.
C804 CP $03
C806 JR C,avoid_probe_y_high
C808 CP $07
C80A JR C,avoid_probe_y_low
avoid_probe_y_high C80C LD A,(IX+$01) Put the probe below the object.
C80F ADD A,$02
C811 JR avoid_probe_y_row
avoid_probe_y_low C813 LD A,(IX+$01) Put the probe above the object.
C816 SUB $02
avoid_probe_y_row C818 AND $F8 Take the probe's tile row, and save the probe cell's tile-map address for the tile test to index.
C81A LD L,A
C81B LD H,$00
C81D ADD HL,HL
C81E ADD HL,HL
C81F LD A,L
C820 OR D
C821 LD L,A
C822 LD DE,tilemap
C825 ADD HL,DE
C826 LD (probe_tile_ptr),HL
C829 LD A,(IY+$00) Point at this heading's entry in the steer table.
C82C ADD A,A
C82D ADD A,A
C82E ADD A,A
C82F LD E,A
C830 XOR A Clear the blocked-probe accumulator.
C831 LD (probe_block_code),A
C834 LD D,$00 Read the entry's first cell offset. A heading with no first cell to probe skips the test below.
C836 LD HL,wall_avoid_steer
C839 ADD HL,DE
C83A LD A,(HL)
C83B CP $FF
C83D JR Z,avoid_probe_second
C83F CALL object_tile_check Test that cell, and store 1 into the accumulator if it is solid.
C842 LD (probe_block_code),A
avoid_probe_second C845 INC HL Read the entry's second cell offset. A heading with no second cell to probe skips the test below.
C846 LD A,(HL)
C847 CP $FF
C849 JR Z,avoid_apply
C84B CALL object_tile_check Test that cell; if it is passable, leave the accumulator unchanged.
C84E OR A
C84F JR Z,avoid_apply
C851 LD A,(probe_block_code) Second cell solid: add its weight to the accumulator.
C854 ADD A,$02
C856 LD (probe_block_code),A
avoid_apply C859 LD A,(probe_block_code) Accumulator 0 (both cells passable): keep the current heading.
C85C OR A
C85D RET Z
C85E INC E Otherwise take the new heading from the entry byte one past the accumulator. That is byte 2 if only the first cell is blocked, byte 3 if only the second, and byte 4 if both.
C85F LD A,(probe_block_code)
C862 ADD A,E
C863 LD E,A
C864 LD D,$00
C866 LD HL,wall_avoid_steer
C869 ADD HL,DE
C86A LD E,(HL)
C86B CALL object_steer
C86E LD (IY+$00),E Store the new heading.
C871 RET
← C76D Fill the free inhabitant slots with wheels Map C872 → Saved probe-tile pointer
Fork me on GitHub