Prev: 9F79 Up: Map Next: A0BE
9F99: Sort Draw List
Used by the routines at RunFrame and RunGame.
Sorts the draw list at DrawList into the order in which the items must be drawn, and builds the sorted list at SortedDrawList. This is a painter's algorithm: an item can only be drawn after every item which is behind it. Each item in the lists has three bytes: flags, and the address of its record. Bit 0 of the flags is set if the record is an entity, and reset if it is a compact record with the three coordinates at offsets 02 04 and 06 which is given the size 06 06 01. Bit 7 is set once the item has been moved to the sorted list. . The routine takes the first item which has not been moved, and compares it with each of the other items which have not been moved. The result for each pair is a number in the range 00-1A made from the relation along the first, second and third coordinates (00 for 'the other item is before this one', 01 for 'they overlap' and 02 for 'the other item is after this one'). The number selects a routine from the table at DrawOrderTable. If the other item has to be drawn first then it becomes the item under consideration (unless it has been tried already, which would be a loop). When an item has no other item that has to be drawn before it, it is moved to the sorted list and the whole process starts again.
SortDrawList 9F99 LD HL,$AF8F Point HL at the sorted list.
9F9C LD ($A17A),HL Store it as the address of the next free place in the sorted list.
This entry point is used by the routine at MoveItemToSortedList.
SortDrawList_Next 9F9F LD DE,$AFFB Point DE at the start of the draw list.
SortDrawList_FirstLoop 9FA2 LD A,(DE) Fetch the flags of the next item.
9FA3 INC DE Move onto the address of the record.
9FA4 AND A Test the flags.
9FA5 JP Z,EndSortedList Jump to EndSortedList if this is the end of the list.
9FA8 BIT 7,A Test whether the item has been moved already.
9FAA LD L,A Keep the flags in L.
9FAB LD A,(DE) Fetch the first byte of the address of the record.
9FAC LD C,A Keep it in C.
9FAD INC DE Move onto the second byte of the address.
9FAE LD A,(DE) Fetch it.
9FAF LD B,A Keep it in B.
9FB0 INC DE Move onto the next item.
9FB1 JR NZ,SortDrawList_FirstLoop Jump back to look at the next item if this one has been moved already.
9FB3 LD ($A1AE),DE Store the address of the next item as that of the item under consideration.
9FB7 PUSH BC Copy the address of the record into IX (using the stack).
9FB8 POP IX
9FBA RR L Rotate bit 0 of the flags into the carry flag.
9FBC JR C,SortDrawList_SecondLoop Jump to SortDrawList_SecondLoop if the record is an entity.
9FBE LD L,(IX+$02) Fetch the first byte of the first coordinate of the record.
9FC1 LD H,(IX+$03) Fetch the second byte of the first coordinate of the record.
9FC4 LD ($9F7B),HL Store the first coordinate in the first scratch item.
9FC7 LD L,(IX+$04) Fetch the first byte of the second coordinate of the record.
9FCA LD H,(IX+$05) Fetch the second byte of the second coordinate of the record.
9FCD LD ($9F7E),HL Store the second coordinate in the first scratch item.
9FD0 LD L,(IX+$06) Fetch the first byte of the third coordinate of the record.
9FD3 LD H,(IX+$07) Fetch the second byte of the third coordinate of the record.
9FD6 LD ($9F81),HL Store the third coordinate in the first scratch item.
9FD9 LD IX,$9F79 Point IX at ScratchItems.
This entry point is used by the routines at IgnoreItem, IgnoreOverlap, DrawOtherItemFirst and ResolveFullOverlap.
SortDrawList_SecondLoop 9FDD LD A,(DE) Fetch the flags of the next item to compare.
9FDE INC DE Move onto the address of the record.
9FDF AND A Test the flags.
9FE0 JP Z,MoveItemToSortedList Jump to MoveItemToSortedList if the end of the list has been reached, as no other item has to go first.
9FE3 BIT 7,A Test whether the item has been moved already.
9FE5 LD L,A Keep the flags in L.
9FE6 LD A,(DE) Fetch the first byte of the address of the record.
9FE7 LD C,A Keep it in C.
9FE8 INC DE Move onto the second byte of the address.
9FE9 LD A,(DE) Fetch it.
9FEA LD B,A Keep it in B.
9FEB INC DE Move onto the next item.
9FEC JR NZ,SortDrawList_SecondLoop Jump back to look at the next item if this one has been moved already.
9FEE LD ($A1B0),DE Store the address of the next item as that of the other item.
9FF2 PUSH BC Copy the address of the record into IY (using the stack).
9FF3 POP IY
9FF5 RR L Rotate bit 0 of the flags into the carry flag.
9FF7 JR C,SortDrawList_Compare Jump to SortDrawList_Compare if the record is an entity.
9FF9 LD L,(IY+$02) Fetch the first byte of the first coordinate of the record.
9FFC LD H,(IY+$03) Fetch the second byte of the first coordinate of the record.
9FFF LD ($9F8B),HL Store the first coordinate in the second scratch item.
A002 LD L,(IY+$04) Fetch the first byte of the second coordinate of the record.
A005 LD H,(IY+$05) Fetch the second byte of the second coordinate of the record.
A008 LD ($9F8E),HL Store the second coordinate in the second scratch item.
A00B LD L,(IY+$06) Fetch the first byte of the third coordinate of the record.
A00E LD H,(IY+$07) Fetch the second byte of the third coordinate of the record.
A011 LD ($9F91),HL Store the third coordinate in the second scratch item.
A014 LD IY,$9F89 Point IY at ScratchItems_Second.
A018 LD BC,$9F89 Use it as the address to compare against.
Skip the pair if both are the same item.
SortDrawList_Compare A01B PUSH IX Copy the address of the item under consideration into HL (using the stack).
A01D POP HL
A01E AND A Compare it with the address of the other item.
A01F SBC HL,BC
A021 JR Z,SortDrawList_SecondLoop Jump to SortDrawList_SecondLoop if they are the same item.
Compare the third coordinate of the two items, and put the result in C: 00 if the other item is entirely before this one, 01 if they overlap, and 02 if the other item is entirely after this one.
A023 EXX Switch to the alternate registers.
A024 LD C,$00 Clear the result.
A026 LD H,(IY+$08) Fetch the first byte of the third coordinate of the other item.
A029 LD L,(IY+$09) Fetch the second byte of the third coordinate of the other item.
A02C LD D,$00 Clear D.
A02E LD E,(IY+$0D) Fetch the third size of the other item.
A031 DEC E Subtract one to make the last position it covers.
A032 ADD HL,DE Find the last position that the other item covers.
A033 LD D,(IX+$08) Fetch the first byte of the third coordinate of this item.
A036 LD E,(IX+$09) Fetch the second byte of the third coordinate of this item.
A039 SBC HL,DE Subtract the position of this item.
A03B JR C,SortDrawList_Second Jump to SortDrawList_Second if the other item ends before this one begins.
A03D LD L,(IX+$0D) Fetch the third size of this item.
A040 LD H,$00 Clear H.
A042 ADD HL,DE Find the position just beyond this item.
A043 EX DE,HL Keep it in DE.
A044 LD H,(IY+$08) Fetch the first byte of the third coordinate of the other item.
A047 LD L,(IY+$09) Fetch the second byte of the third coordinate of the other item.
A04A AND A Subtract the position beyond this item.
A04B SBC HL,DE
A04D JR C,SortDrawList_ThirdAdd Jump to SortDrawList_ThirdAdd if the other item starts before the end of this one.
A04F INC C Add one to the result.
SortDrawList_ThirdAdd A050 INC C Add one to the result.
Do the same for the second coordinate, adding 03 to the result for an overlap and 06 for the other item being entirely after this one.
SortDrawList_Second A051 LD H,(IY+$05) Fetch the first byte of the second coordinate of the other item.
A054 LD L,(IY+$06) Fetch the second byte of the second coordinate of the other item.
A057 LD D,$00 Clear D.
A059 LD E,(IY+$0C) Fetch the second size of the other item.
A05C DEC E Subtract one to make the last position it covers.
A05D ADD HL,DE Find the last position that the other item covers.
A05E LD D,(IX+$05) Fetch the first byte of the second coordinate of this item.
A061 LD E,(IX+$06) Fetch the second byte of the second coordinate of this item.
A064 SBC HL,DE Subtract the position of this item.
A066 JR C,SortDrawList_First Jump to SortDrawList_First if the other item ends before this one begins.
A068 LD L,(IX+$0C) Fetch the second size of this item.
A06B LD H,$00 Clear H.
A06D ADD HL,DE Find the position just beyond this item.
A06E EX DE,HL Keep it in DE.
A06F LD H,(IY+$05) Fetch the first byte of the second coordinate of the other item.
A072 LD L,(IY+$06) Fetch the second byte of the second coordinate of the other item.
A075 AND A Subtract the position beyond this item.
A076 SBC HL,DE
A078 LD A,C Fetch the result so far.
A079 JR C,SortDrawList_SecondAdd Jump to SortDrawList_SecondAdd if the other item starts before the end of this one.
A07B ADD A,$03 Add 03 to the result.
SortDrawList_SecondAdd A07D ADD A,$03 Add 03 to the result.
A07F LD C,A Store the result.
Do the same for the first coordinate, adding 09 to the result for an overlap and 12 for the other item being entirely after this one.
SortDrawList_First A080 LD H,(IY+$02) Fetch the first byte of the first coordinate of the other item.
A083 LD L,(IY+$03) Fetch the second byte of the first coordinate of the other item.
A086 LD D,$00 Clear D.
A088 LD E,(IY+$0B) Fetch the first size of the other item.
A08B DEC E Subtract one to make the last position it covers.
A08C ADD HL,DE Find the last position that the other item covers.
A08D LD D,(IX+$02) Fetch the first byte of the first coordinate of this item.
A090 LD E,(IX+$03) Fetch the second byte of the first coordinate of this item.
A093 SBC HL,DE Subtract the position of this item.
A095 JR C,SortDrawList_Dispatch Jump to SortDrawList_Dispatch if the other item ends before this one begins.
A097 LD L,(IX+$0B) Fetch the first size of this item.
A09A LD H,$00 Clear H.
A09C ADD HL,DE Find the position just beyond this item.
A09D EX DE,HL Keep it in DE.
A09E LD H,(IY+$02) Fetch the first byte of the first coordinate of the other item.
A0A1 LD L,(IY+$03) Fetch the second byte of the first coordinate of the other item.
A0A4 AND A Subtract the position beyond this item.
A0A5 SBC HL,DE
A0A7 LD A,C Fetch the result so far.
A0A8 JR C,SortDrawList_FirstAdd Jump to SortDrawList_FirstAdd if the other item starts before the end of this one.
A0AA ADD A,$09 Add 09 to the result.
SortDrawList_FirstAdd A0AC ADD A,$09 Add 09 to the result.
A0AE LD C,A Store the result.
Use the result to jump to the routine in the table at DrawOrderTable.
SortDrawList_Dispatch A0AF LD A,C Fetch the result.
A0B0 ADD A,A Double it to make the offset into the table.
A0B1 EXX Switch back to the normal registers.
A0B2 LD HL,$A0BE Point HL at DrawOrderTable.
A0B5 LD C,A Copy the offset into C.
A0B6 LD B,$00 Clear B.
A0B8 ADD HL,BC Add the offset to find the entry.
A0B9 LD A,(HL) Fetch the first byte of the address.
A0BA INC HL Move onto the second byte.
A0BB LD H,(HL) Fetch it.
A0BC LD L,A Combine them into HL.
A0BD JP (HL) Jump to the routine.
Prev: 9F79 Up: Map Next: A0BE