Prev: D7B3 Up: Map Next: D8E4
D7E4: Test Entity Cells
Used by the routine at MoveEntity.
Tests each cell of the level that the entity's box covers, by calling TestGroupObjects, and retests a cell when a collision moves the entity. When bit 6 of the flags is set, a z within one page of FF is stored in field 1F after a zero top byte has been snapped up by one unit. A hit planted by HandleOverlap then turns the heading away from it. Purpose of bit 6 is not yet known.
Input
IX The entity
The cell is the high byte of x and the high byte of y. A collision can move those bytes, and the extent can make the entity cover the next cell.
TestEntityCells D7E4 LD L,(IX+$02) Take the cell from the high bytes of x and y.
D7E7 LD H,(IX+$05)
D7EA PUSH HL Test that cell.
D7EB CALL TestGroupObjects
D7EE POP HL Restore the cell.
D7EF LD A,(IX+$02) Retest the previous column when the high byte of x moved.
D7F2 CP L
D7F3 JR Z,TestEntityCells_SpanX
D7F5 DEC A Use the column below the new x.
D7F6 LD L,A
D7F7 JR TestEntityCells_Second
TestEntityCells_SpanX D7F9 LD A,(IX+$03) The entity covers the next column when the x extent carries.
D7FC ADD A,(IX+$0B)
D7FF JR NC,TestEntityCells_Moved
TestEntityCells_Second D801 PUSH HL Test the next column.
D802 INC L
D803 CALL TestGroupObjects
D806 POP HL Restore the cell.
D807 LD A,(IX+$05) Retest this row when the high byte of y moved.
D80A CP H
D80B JR Z,TestEntityCells_SpanY
D80D LD H,A Test the entity's row, then the row above.
D80E PUSH HL
D80F CALL TestGroupObjects
D812 POP HL
D813 INC H
D814 JR TestEntityCells_Next
TestEntityCells_SpanY D816 LD A,(IX+$06) The entity covers the next row when the y extent carries.
D819 ADD A,(IX+$0C)
D81C JR NC,TestEntityCells_Snap
D81E INC H Test the next row.
D81F PUSH HL
D820 CALL TestGroupObjects
D823 POP HL
TestEntityCells_Next D824 INC L Test the diagonal cell too.
D825 JR TestEntityCells_Cell
TestEntityCells_Moved D827 LD A,(IX+$05) Use the entity's row when y has moved.
D82A CP H
D82B JR Z,TestEntityCells_SpanRow
D82D LD H,A Use that row.
D82E JR TestEntityCells_Cell
TestEntityCells_SpanRow D830 LD A,(IX+$06) Cover the next row when the y extent carries.
D833 ADD A,(IX+$0C)
D836 JR NC,TestEntityCells_Snap
D838 INC H Use the next row.
TestEntityCells_Cell D839 CALL TestGroupObjects Test this cell.
Bit 6 of the flags stores a z that is within one page of FF into field 1F. A zero top byte is snapped up by one unit first. A pickup stores zero instead.
TestEntityCells_Snap D83C LD C,$00 Start with no hit. HandleOverlap plants one in this byte.
D83E BIT 6,(IX+$1E) Snap z when bit 6 of the flags is set.
D842 JR Z,TestEntityCells_Hit
D844 LD L,(IX+$09) A zero top byte of z is snapped up by one unit.
D847 LD A,(IX+$08)
D84A AND A
D84B JR NZ,TestEntityCells_Distance
D84D LD L,A Write that snap back into z.
D84E LD (IX+$09),A
D851 INC A
D852 LD (IX+$08),A
D855 LD A,(IX+$00) A pickup stores zero in field 1F.
D858 CP $0F
D85A JR Z,TestEntityCells_Store
D85C LD A,L Otherwise measure from one.
D85D INC A
TestEntityCells_Distance D85E LD H,A Store the distance when z is within one page of FF.
D85F XOR A
D860 LD DE,$00FF
D863 SBC HL,DE
D865 OR H
D866 JR NZ,TestEntityCells_Hit
TestEntityCells_Store D868 LD (IX+$1F),L Remember that distance in field 1F.
A hit turns the heading. Fields 18 and 19 supply the two components, and the low bits of the hit choose which axis is turned.
TestEntityCells_Hit D86B LD A,C Return when nothing was hit.
D86C AND A
D86D RET Z
D86E LD B,A Remember the hit and clear it.
D86F XOR A
D870 LD ($D83D),A
D873 BIT 5,(IX+$01) Return when bit 5 of the frame is set.
D877 RET NZ
D878 LD A,(IX+$18) Return when fields 18 and 19 are both zero.
D87B OR (IX+$19)
D87E RET Z
D87F LD A,B Return when the hit was FF.
D880 CP $FF
D882 RET Z
D883 LD A,(IX+$18) Use field 18 as one component.
D886 AND A
D887 JR NZ,TestEntityCells_Component
D889 LD A,(IX+$11) Read the heading.
D88C ADD A,$10 Add 10 to the heading.
D88E AND %00111111 Use the low six bits of the heading.
D890 CP $20 Use FE when those bits are 20 or more.
D892 JR C,TestEntityCells_Component
D894 LD A,$FE Use FE for that component.
TestEntityCells_Component D896 LD L,A Keep the first component.
D897 LD A,(IX+$19) Use field 19 as the other component.
D89A AND A
D89B JR NZ,TestEntityCells_Other
D89D LD A,(IX+$11) Read the heading.
D8A0 AND %00111111 Use the low six bits of the heading.
D8A2 CP $20 Use FE when those bits are 20 or more.
D8A4 JR C,TestEntityCells_Other
D8A6 LD A,$FE Use FE for that component.
TestEntityCells_Other D8A8 LD H,A Keep the second component.
D8A9 LD A,B Use the low two bits of the hit.
D8AA AND $03
D8AC JR Z,TestEntityCells_Swap Swap the components when the hit was on x.
D8AE LD B,H
D8AF LD C,L
D8B0 JR TestEntityCells_Heading
TestEntityCells_Swap D8B2 LD A,H Turn the second component to face the other way.
D8B3 NEG
D8B5 LD C,A
D8B6 LD A,B
D8B7 RRA
D8B8 RRA
D8B9 RRA
D8BA LD B,L Keep the first component.
TestEntityCells_Heading D8BB RRCA Face the patched step away from the first component.
D8BC LD E,A
D8BD XOR B
D8BE RLA
D8BF LD B,$FE
D8C1 JR C,TestEntityCells_Signs
D8C3 LD A,B Face the other way when the signs differ.
D8C4 NEG
D8C6 LD B,A
TestEntityCells_Signs D8C7 LD A,E Compare the signs of the two components.
D8C8 XOR C
D8C9 RLA
D8CA JR NC,TestEntityCells_Apply Keep the turn when the signs agree.
D8CC BIT 7,B A positive turn is 01.
D8CE LD B,$01
D8D0 JR Z,TestEntityCells_Apply
D8D2 LD B,$FF A negative turn is FF.
TestEntityCells_Apply D8D4 LD A,(IX+$11) Read the heading.
D8D7 LD C,A Keep the old heading aside.
D8D8 ADD A,B Add the turn to the heading.
D8D9 AND %00111111 Use the low six bits of the new heading.
D8DB LD B,A Keep the new heading aside.
D8DC LD A,C Use bits 6-7 of the old heading.
D8DD AND $C0
D8DF OR B Combine them with the new heading.
D8E0 LD (IX+$11),A
D8E3 RET Return.
Prev: D7B3 Up: Map Next: D8E4