Prev: CFAF Up: Map Next: D0A0
CFF2: Draw the listed things, furthest back first
Used by the routine at DRAW_CELLS.
The second half: the things LIST_THINGS_IN_CELL listed are drawn one at a time, each chosen by a pass along the list. The first entry not yet drawn is the candidate (IX). Every later entry not yet drawn (IY) is compared with it, and the outcome goes through DEPTH_TABLE: either the candidate stays, or IY is further back and becomes the candidate, and the pass carries on from IY. At the end of the list the candidate is drawn (DRAW_SPRITE) and its entry marked drawn by clearing bit 7 of its high byte -- every record's address has it set -- and the next pass starts; DRAW_LIST_AT keeps the place just past the candidate's entry, DRAW_LIST_NEXT just past IY's. The list is empty of undrawn things when a pass finds none, and the routine returns.
The comparison is two-dimensional: a record is a box in U and V (its position at +1 and +3, its half-sizes at +8 and +9) and nothing in the town has a height. On each axis each side of the box is worked out as (the low byte of the position plus or minus the half-size) / 2 + 64 -- only the low bytes, since the things listed share a cell, and RRA shifting the carry of the 9-bit sum back in, so a side from 128 below the cell to 128 past it becomes a byte from 0 to 255. Then 0 if the candidate is wholly beyond IY on that axis (its low side at or above IY's high side), 2 if IY is wholly beyond the candidate, 1 if they overlap: U counts once, V three times, and the town turned round adds 9, which reverses what "further back" means. Further back is smaller U and larger V, as in Knight Lore and Alien 8: higher up the screen (PROJECT_CELL).
A new candidate is not compared with the entries the pass has already gone by, so an order among three things can come out wrong; but a pass never goes back to the top, so it cannot go round in a circle, and Filmation's chain of candidates is not needed.
SORT_AND_DRAW_THINGS CFF2 LD HL,DRAW_LIST From the top of the list
SORT_AND_DRAW_THINGS_0 CFF5 LD E,(HL) The next entry; the zero at the end: everything is drawn
CFF6 INC HL
CFF7 LD D,(HL)
CFF8 INC HL
CFF9 LD A,D
CFFA OR E
CFFB RET Z
CFFC BIT 7,D Bit 7 of the high byte clear: drawn already
CFFE JR Z,SORT_AND_DRAW_THINGS_0
D000 LD (DRAW_LIST_AT),HL The first thing not yet drawn is the candidate, in IX
D003 PUSH DE
D004 POP IX
SORT_AND_DRAW_THINGS_1 D006 LD E,(HL) The next entry; at the end of the list, draw the candidate
D007 INC HL
D008 LD D,(HL)
D009 INC HL
D00A LD A,D
D00B OR E
D00C JP Z,SORT_AND_DRAW_THINGS_7
D00F BIT 7,D Drawn already: pass it by
D011 JR Z,SORT_AND_DRAW_THINGS_1
D013 LD (DRAW_LIST_NEXT),HL IY the thing to compare with the candidate
D016 PUSH DE
D017 POP IY
D019 LD C,$00 U: 0 if the candidate's low side is at or above IY's high side
D01B LD A,(IY+$01)
D01E ADD A,(IY+$08)
D021 RRA
D022 ADD A,$40
D024 LD B,A
D025 LD A,(IX+$01)
D028 SUB (IX+$08)
D02B RRA
D02C ADD A,$40
D02E SUB B
D02F JR NC,SORT_AND_DRAW_THINGS_3
D031 LD A,(IX+$01) Otherwise 2 if IY's low side is at or above the candidate's high side, and 1 if they overlap
D034 ADD A,(IX+$08)
D037 RRA
D038 ADD A,$40
D03A LD B,A
D03B LD A,(IY+$01)
D03E SUB (IY+$08)
D041 RRA
D042 ADD A,$40
D044 SUB B
D045 JR C,SORT_AND_DRAW_THINGS_2
D047 INC C
SORT_AND_DRAW_THINGS_2 D048 INC C
SORT_AND_DRAW_THINGS_3 D049 LD A,(IY+$03) V the same, adding 0...
D04C ADD A,(IY+$09)
D04F RRA
D050 ADD A,$40
D052 LD B,A
D053 LD A,(IX+$03)
D056 SUB (IX+$09)
D059 RRA
D05A ADD A,$40
D05C SUB B
D05D LD A,C
D05E JR NC,SORT_AND_DRAW_THINGS_5
D060 LD A,(IX+$03) ...3 if they overlap, or 6 if IY is wholly beyond
D063 ADD A,(IX+$09)
D066 RRA
D067 ADD A,$40
D069 LD B,A
D06A LD A,(IY+$03)
D06D SUB (IY+$09)
D070 RRA
D071 ADD A,$40
D073 SUB B
D074 LD A,C
D075 JR C,SORT_AND_DRAW_THINGS_4
D077 ADD A,$03
SORT_AND_DRAW_THINGS_4 D079 ADD A,$03
SORT_AND_DRAW_THINGS_5 D07B LD C,A Plus 9 with the town turned round
D07C LD A,(VIEW)
D07F AND $01
D081 JR Z,SORT_AND_DRAW_THINGS_6
D083 LD A,C
D084 ADD A,$09
D086 LD C,A
SORT_AND_DRAW_THINGS_6 D087 LD A,C The outcome, through DEPTH_TABLE: the candidate stays, or IY takes its place
D088 LD BC,DEPTH_TABLE
D08B CALL DISPATCH
D08E LD HL,(DRAW_LIST_NEXT) On along the list from IY
D091 JP SORT_AND_DRAW_THINGS_1
SORT_AND_DRAW_THINGS_7 D094 LD HL,(DRAW_LIST_AT) The end of the list: the candidate's entry marked drawn
D097 DEC HL
D098 RES 7,(HL)
D09A CALL DRAW_SPRITE Draw it, and the next pass
D09D JP SORT_AND_DRAW_THINGS
Prev: CFAF Up: Map Next: D0A0