Prev: DF34 Up: Map Next: DFFA
DF97: Cut a step in -U short at the boxes of the cells ahead
The last of the four routines of MOVE_TABLE, for an object facing -U (bits 6-7 of +6 = 3). The object's footprint is its U and V plus or minus its half-sizes (+8, +9); its leading edge is at U less the half-size in U. The cells to test are the ones that edge's two corners stand in now, and, if this turn's step in U (+A, negative) takes the edge into the next column, the ones its corners reach there -- at most four, each tested once. For each, CUT_STEP_MINUS_U checks the object's box, moved by the step, against the cell's boxes and cuts the step short at the first it runs into; the first cut ends the search, with carry set.
The corners only choose which cells to look in: the box test itself works from the object's own position and step (PLACE_IN_CELL), so a cell tested twice or one the object is nowhere near costs time but cannot give a wrong answer.
Input
IX The object
Output
F Carry set if the step was cut (and bit 0 of +7 set)
CLIP_MINUS_U DF97 LD L,(IX+$01) DE = U less the half-size in U: the leading edge
DF9A LD H,(IX+$02)
DF9D LD C,(IX+$08)
DFA0 LD B,$00
DFA2 AND A
DFA3 SBC HL,BC
DFA5 EX DE,HL
DFA6 LD L,(IX+$03) HL = V less the half-size in V: the edge's low corner
DFA9 LD H,(IX+$04)
DFAC LD C,(IX+$09)
DFAF AND A
DFB0 SBC HL,BC
DFB2 PUSH DE Test the cell under that corner; stop if the step was cut
DFB3 PUSH HL
DFB4 CALL CUT_STEP_MINUS_U
DFB7 POP HL
DFB8 POP DE
DFB9 RET C
DFBA PUSH DE HL = V plus the half-size: the other corner; if it is in the same row, its cell has just been tested
DFBB PUSH HL
DFBC LD C,(IX+$09)
DFBF SLA C
DFC1 LD B,$00
DFC3 LD A,H
DFC4 ADD HL,BC
DFC5 CP H
DFC6 JR Z,CLIP_MINUS_U_0
DFC8 CALL CUT_STEP_MINUS_U Test the cell under the other corner. DE and HL come back swapped: HL the edge's U, DE the low V
DFCB POP DE
DFCC POP HL
DFCD RET C
DFCE LD C,(IX+$0A) Add the step in U, negative, B = $FF sign-extending it; if the edge stays in its column there is no new cell. A step of 0 reads as -256 here, so a still object tests the column behind as well, to no effect
DFD1 LD B,$FF
DFD3 LD A,H
DFD4 ADD HL,BC
DFD5 CP H
DFD6 RET Z
DFD7 EX DE,HL Test the cell the moved edge reaches, at the low V corner...
DFD8 PUSH DE
DFD9 PUSH HL
DFDA CALL CUT_STEP_MINUS_U
DFDD POP HL
DFDE POP DE
DFDF RET C
DFE0 LD C,(IX+$09) ...and at the high one
DFE3 SLA C
DFE5 LD B,$00
DFE7 ADD HL,BC
DFE8 JP CUT_STEP_MINUS_U
CLIP_MINUS_U_0 DFEB POP DE Both corners in one row: only the cell the moved edge reaches, if it is in a new column
DFEC POP HL
DFED LD C,(IX+$0A)
DFF0 LD B,$FF
DFF2 LD A,H
DFF3 ADD HL,BC
DFF4 CP H
DFF5 RET Z
DFF6 EX DE,HL
DFF7 JP CUT_STEP_MINUS_U
Prev: DF34 Up: Map Next: DFFA