Prev: CE85 Up: Map Next: CF85
CEAB: Redraw what changed and copy it to the screen
Used by the routine at OBJECT_DONE.
Called at the end of every turn (OBJECT_DONE). The draw list (DRAW_LIST) holds the number of every record to be drawn this turn, up to an $FF, and SEQUENCE_AT steps through it. First, for each one that moved -- bit 5 of its flags, cleared here -- the area covering both where it was drawn last turn (+1C to +1F) and where it is now (+18 to +1B) is cleared in the buffer and remembered on the stack, WIPE_COUNT counting them. Then every listed object is drawn into the buffer in depth order (SORT_AND_DRAW), and the carried things on the panel if they changed (SHOW_CARRIED); and last the remembered areas -- and only those -- are copied to the screen.
Nothing is ever rubbed out on the screen itself, so nothing flickers: the scenery is made of objects too, so what stood behind a moving thing is simply drawn again. On the first turn in a room (NEW_ROOM set) nothing is wiped: the buffer is freshly built and the main loop shows all of it. The areas count towards the turn's drawing work (DRAW_WORK), which sets how long the main loop waits. Pentagram's routine, instruction for instruction; Knight Lore's does the same in more pieces.
RENDER_DYNAMIC_OBJECTS CEAB XOR A No areas yet
CEAC LD (WIPE_COUNT),A
CEAF PUSH IX Kept for the caller
CEB1 LD A,(NEW_ROOM) The first turn in a room: nothing to wipe
CEB4 AND A
CEB5 JP NZ,RENDER_DYNAMIC_OBJECTS_8
CEB8 LD HL,DRAW_LIST From the start of the draw list
CEBB LD (SEQUENCE_AT),HL
RENDER_DYNAMIC_OBJECTS_0 CEBE LD HL,(SEQUENCE_AT) The next record's number; $FF ends the list
CEC1 LD A,(HL)
CEC2 INC HL
CEC3 LD (SEQUENCE_AT),HL
CEC6 CP $FF
CEC8 JP Z,RENDER_DYNAMIC_OBJECTS_8
CECB CALL GET_PTR_OBJECT IX = the record
CECE PUSH HL
CECF POP IX
CED1 BIT 5,(IX+$07) Bit 5 of the flags: it moved; the others in the list are only being drawn again
CED5 JR Z,RENDER_DYNAMIC_OBJECTS_0
CED7 RES 5,(IX+$07) Only once
CEDB LD A,(IX+$1A) C = the further left of the new pixel x (+1A) and the old (+1E)
CEDE SUB (IX+$1E)
CEE1 JP C,RENDER_DYNAMIC_OBJECTS_6
CEE4 LD C,(IX+$1E)
RENDER_DYNAMIC_OBJECTS_1 CEE7 LD A,(IX+$1E) The old right edge in bytes: old x / 8 + old width (+1C)
CEEA RRCA
CEEB RRCA
CEEC RRCA
CEED AND $1F
CEEF ADD A,(IX+$1C)
CEF2 LD E,A
CEF3 LD A,(IX+$1A) The new one: new x / 8 + new width (+18); E = the further right
CEF6 RRCA
CEF7 RRCA
CEF8 RRCA
CEF9 AND $1F
CEFB ADD A,(IX+$18)
CEFE CP E
CEFF JR C,RENDER_DYNAMIC_OBJECTS_2
CF01 LD E,A
RENDER_DYNAMIC_OBJECTS_2 CF02 LD A,C H = the width in bytes, from the left edge's byte to the right edge
CF03 RRCA
CF04 RRCA
CF05 RRCA
CF06 AND $1F
CF08 LD B,A
CF09 LD A,E
CF0A SUB B
CF0B LD H,A
CF0C LD A,(IX+$1B) B = the lower of the new pixel y (+1B) and the old (+1F)
CF0F SUB (IX+$1F)
CF12 JR C,RENDER_DYNAMIC_OBJECTS_7
CF14 LD B,(IX+$1F)
RENDER_DYNAMIC_OBJECTS_3 CF17 LD A,(IX+$1F) The old top: old y + old height (+1D)
CF1A ADD A,(IX+$1D)
CF1D LD E,A
CF1E LD A,(IX+$1B) The new top: new y + new height (+19); A = the higher
CF21 ADD A,(IX+$19)
CF24 CP E
CF25 JR NC,RENDER_DYNAMIC_OBJECTS_4
CF27 LD A,E
RENDER_DYNAMIC_OBJECTS_4 CF28 SUB B L = the height in rows
CF29 LD L,A
CF2A LD A,B An area that starts above the top of the screen has nothing to wipe
CF2B CP $C0
CF2D JR NC,RENDER_DYNAMIC_OBJECTS_0
CF2F ADD A,L If it runs past line 192, keep only the part below
CF30 SUB $C0
CF32 JR C,RENDER_DYNAMIC_OBJECTS_5
CF34 NEG
CF36 ADD A,L
CF37 LD L,A
RENDER_DYNAMIC_OBJECTS_5 CF38 CALL CALC_VRAM_ADDR DE = its display address, BC = its buffer address
CF3B CALL CALC_VIDBUF_ADDR
CF3E LD A,L Rearranged: HL = the buffer address, B = the width, C = the height
CF3F LD L,C
CF40 LD C,A
CF41 LD A,H
CF42 LD H,B
CF43 LD B,A
CF44 LD A,(WIPE_COUNT) One more area
CF47 INC A
CF48 LD (WIPE_COUNT),A
CF4B PUSH BC On the stack until the objects have been drawn
CF4C PUSH DE
CF4D PUSH HL
CF4E XOR A Cleared in the buffer: FILL_BOX fills B bytes by C rows with A
CF4F CALL FILL_BOX
CF52 JP RENDER_DYNAMIC_OBJECTS_0 The next record
RENDER_DYNAMIC_OBJECTS_6 CF55 LD C,(IX+$1A) The new x is the further left
CF58 JR RENDER_DYNAMIC_OBJECTS_1
RENDER_DYNAMIC_OBJECTS_7 CF5A LD B,(IX+$1B) The new y is the lower
CF5D JR RENDER_DYNAMIC_OBJECTS_3
RENDER_DYNAMIC_OBJECTS_8 CF5F CALL SORT_AND_DRAW Every listed object into the buffer, in depth order
CF62 CALL SHOW_CARRIED The carried things on the panel, if they changed
CF65 LD HL,WIPE_COUNT The areas count towards the turn's drawing work
CF68 LD A,(DRAW_WORK)
CF6B ADD A,(HL)
CF6C LD (DRAW_WORK),A
RENDER_DYNAMIC_OBJECTS_9 CF6F LD HL,WIPE_COUNT None left to copy
CF72 LD A,(HL)
CF73 AND A
CF74 JR Z,RENDER_DYNAMIC_OBJECTS_10
CF76 DEC (HL) Take one off the stack, with the width and height swapped into the order BLIT_TO_SCREEN takes them
CF77 POP HL
CF78 POP DE
CF79 POP BC
CF7A LD A,B
CF7B LD B,C
CF7C LD C,A
CF7D CALL BLIT_TO_SCREEN Copy it to the screen; the next
CF80 JR RENDER_DYNAMIC_OBJECTS_9
RENDER_DYNAMIC_OBJECTS_10 CF82 POP IX Done
CF84 RET
Prev: CE85 Up: Map Next: CF85