Prev: E3C4 Up: Map Next: E4F7
E3E4: Redraw a rectangle of the screen from an image, its mask and the clean copy
Used by the routines at CLEAR_THING_BOX and REDRAW_OBJECT.
Krumlinde's RTN_Composite_To_Screen. The pixels the game draws on the screen once a room is drawn go through here (the colours are ATTRI's): a moving object's new picture (from REDRAW_OBJECT), the box on the panel for the thing in use (CLEAR_THING_BOX, SHOW_THING_IN_USE), and every character printed (PRINT, by way of the second entry, three instructions in).
The rectangle's top left corner is x, y at IY+$64 and IY+$65 (y counted up from the bottom of the screen, as everywhere in the game), its width in bytes at IY+$73 and its height in rows at IY+$67. A row is written as its width plus one screen bytes, since the image is shifted to x's pixel within its byte, and each byte is made from four buffer pages ($D8 to $DB: the 1 KB after the clean copy, from offset 364 of SOURCE_AFTER_TEMPLATES), indexed by one count that goes on through the rows: where page $D8 has a bit set, the screen keeps what it has; elsewhere, where page $D9 has it clear, the pixel comes from the image (IX); where $D9 has it set, it comes from page $DB if page $DA has it set too (when bit 1 of IY+$71 says pages $DA and $DB are in use), and otherwise from the clean copy of the room, the byte 32 KB above the screen byte (the copy RESTOR and room code $E2 make).
The callers fill the pages. For a moving object, REDRAW_OBJECT and the routines it calls (CULL_OBJECT, SORT_AND_DRAW_BEHIND, DRAW_SPRITE) fill them from the objects that overlap the rectangle: the object's own mask, what stands in front of it, and what moves behind it (see there). The printer clears pages $D8 and $D9, so a character is drawn as it is; CLEAR_THING_BOX sets every bit of page $D9, which puts the clean copy back over the box. The pixels to the left of x in each row's first byte are marked in page $D8 by this routine itself, so that they stay as they are.
The shift is made by jumping into a run of seven RRCAs: the start rewrites the operand of the JR before them. It also rewrites the JRs round the steps for pages $DA and $DB (to skip them unless they are in use) and the one before a row's last byte (to skip it when x is on a byte boundary, as nothing spills into it). Rows above the top of the screen (y above 191) are skipped, and it stops at the bottom of the screen.
At this entry the image's address is the word at IY+$68, and the routine starts three rows before it, as REDRAW_OBJECT's rectangle does; at the second, COMPOSITE_FROM_IX, three instructions in, HL is the address to start from.
COMPOSITE_TO_SCREEN E3E4 LD HL,(WORK_SPRITE) HL: the image less three rows (IY+$73 bytes each): REDRAW_OBJECT's rectangle starts three rows above the object's sprite.
E3E7 XOR A
E3E8 LD D,A
E3E9 LD B,$03
COMPOSITE_TO_SCREEN_0 E3EB ADD A,(IY+DRAW_WIDTH-V)
E3EE DJNZ COMPOSITE_TO_SCREEN_0
E3F0 LD E,A
E3F1 SBC HL,DE
This entry point is used by the routines at PRINT_FIND_GLYPH and SHOW_THING_IN_USE.
COMPOSITE_FROM_IX E3F3 PUSH HL IX: where the image's bytes are read from.
E3F4 POP IX
E3F6 EXX C': the index into the pages, from 0.
E3F7 LD C,$00
E3F9 EXX
E3FA LD BC,(POINT) B, C: the top left corner. Is the top on the screen (y 191 or less)? A: 191 less y, its row from the top.
E3FE LD A,$BF
E400 SUB B
E401 JR NC,COMPOSITE_TO_SCREEN_2
E403 EXX No: take the rows above the screen off the height; if none are left, there is nothing to draw.
E404 NEG
E406 LD B,A
E407 LD A,(SECOND_POINT_ROW)
E40A SUB B
E40B RET C
E40C RET Z
E40D LD (SECOND_POINT_ROW),A
E410 LD A,(SECOND_POINT) And skip them: IX on by the width for each, the page index by the width plus one.
E413 RRA
E414 RRA
E415 RRA
E416 LD E,A
E417 INC A
E418 LD C,A
E419 XOR A
E41A LD D,A
COMPOSITE_TO_SCREEN_1 E41B ADD IX,DE
E41D ADD A,C
E41E DJNZ COMPOSITE_TO_SCREEN_1
E420 LD C,A
E421 EXX Start at the top row.
E422 XOR A
COMPOSITE_TO_SCREEN_2 E423 CALL $22B0 HL: the screen address of the rectangle's first byte (the ROM's PIXEL-ADD, from its LD B,A on); A: x's pixel within its byte.
E426 PUSH HL Rewrite the JR into the RRCAs, to rotate the image right by x's pixel.
E427 CPL
E428 AND $07
E42A LD B,A
E42B LD ($E46C),A
E42E XOR A D: the bits of a rotated byte that stay in their own screen byte; E: those that spill into the next.
E42F INC B
COMPOSITE_TO_SCREEN_3 E430 SCF
E431 RLA
E432 DJNZ COMPOSITE_TO_SCREEN_3
E434 LD D,A
E435 CPL
E436 LD E,A
E437 LD HL,$002C Rewrite the JR before a row's last byte: skip it when x is on a byte boundary.
E43A AND A
E43B LD A,L
E43C JR Z,COMPOSITE_TO_SCREEN_4
E43E XOR A
COMPOSITE_TO_SCREEN_4 E43F LD ($E4AD),A
E442 EXX Rewrite the two JRs round the steps for pages $DA and $DB: skip them unless bit 1 of IY+$71 is set.
E443 LD HL,$000D
E446 LD DE,$000D
E449 LD A,E
E44A BIT 1,(IY+WORK_DIRECTION-V)
E44E JR Z,COMPOSITE_TO_SCREEN_5
E450 XOR A
E451 LD L,A
COMPOSITE_TO_SCREEN_5 E452 LD ($E487),A
E455 LD A,L
E456 LD ($E4BD),A
E459 POP HL HL': the screen address; B': page $D8.
E45A LD B,$D8
COMPOSITE_TO_SCREEN_6 E45C PUSH HL A row. The pixels left of x in its first byte are marked in page $D8, to be left as they are.
E45D LD A,(BC)
E45E EXX
E45F OR E
E460 EXX
E461 LD (BC),A
E462 EXX B: the image's bytes in a row; L: the bits spilt from the byte before, none yet.
E463 LD B,(IY+DRAW_WIDTH-V)
E466 LD L,$00
COMPOSITE_TO_SCREEN_7 E468 LD A,(IX+$00) Rotate the next image byte right by x's pixel (the JR lands on the right RRCA).
E46B JR COMPOSITE_TO_SCREEN_8
COMPOSITE_TO_SCREEN_8 E46D RRCA
E46E RRCA
E46F RRCA
E470 RRCA
E471 RRCA
E472 RRCA
E473 RRCA
E474 LD H,A A: this byte's image bits, and those spilt from the byte before.
E475 AND D
E476 OR L
E477 EXX Page $D9: the image where it is clear, the clean copy (the screen address with bit 7 set) where it is set.
E478 LD E,A
E479 INC B
E47A LD A,(BC)
E47B LD D,A
E47C CPL
E47D AND E
E47E LD E,A
E47F LD A,D
E480 SET 7,H
E482 AND (HL)
E483 RES 7,H
E485 OR E
E486 JR COMPOSITE_TO_SCREEN_9
COMPOSITE_TO_SCREEN_9 E488 LD E,A Where pages $D9 and $DA both have a bit set, page $DB's bit (skipped unless bit 1 of IY+$71 is set).
E489 INC B
E48A LD A,(BC)
E48B AND D
E48C CPL
E48D LD D,A
E48E CPL
E48F OR E
E490 LD E,A
E491 INC B
E492 LD A,(BC)
E493 OR D
E494 AND E
E495 LD E,A Page $D8: the screen's own bit where it is set, the new one elsewhere.
E496 LD B,$D8
E498 LD A,(BC)
E499 LD D,A
E49A CPL
E49B AND E
E49C LD E,A
E49D LD A,(HL)
E49E AND D
E49F OR E
E4A0 LD (HL),A
E4A1 INC L Next screen byte, next page index.
E4A2 INC C
E4A3 EXX Keep the bits that spill into the next byte; next image byte.
E4A4 LD A,H
E4A5 AND E
E4A6 LD L,A
E4A7 INC IX
E4A9 DJNZ COMPOSITE_TO_SCREEN_7
E4AB EXX The row's last screen byte, which only the spilt bits reach (skipped when x is on a byte boundary).
E4AC JR COMPOSITE_TO_SCREEN_10
COMPOSITE_TO_SCREEN_10 E4AE LD E,A Page $D9, as above.
E4AF INC B
E4B0 LD A,(BC)
E4B1 LD D,A
E4B2 CPL
E4B3 AND E
E4B4 LD E,A
E4B5 SET 7,H
E4B7 LD A,(HL)
E4B8 RES 7,H
E4BA AND D
E4BB OR E
E4BC JR COMPOSITE_TO_SCREEN_11
COMPOSITE_TO_SCREEN_11 E4BE LD E,A Pages $DA and $DB, as above.
E4BF INC B
E4C0 LD A,(BC)
E4C1 AND D
E4C2 CPL
E4C3 LD D,A
E4C4 CPL
E4C5 OR E
E4C6 LD E,A
E4C7 INC B
E4C8 LD A,(BC)
E4C9 OR D
E4CA AND E
E4CB LD E,A Page $D8, and the bits right of the image's end (D) left as they are too.
E4CC LD B,$D8
E4CE LD A,(BC)
E4CF EXX
E4D0 OR D
E4D1 EXX
E4D2 LD D,A
E4D3 CPL
E4D4 AND E
E4D5 LD E,A
E4D6 LD A,(HL)
E4D7 AND D
E4D8 OR E
E4D9 LD (HL),A
E4DA POP HL Next row: the page index past the row's last byte; one row fewer to do.
E4DB INC C
E4DC INC H
E4DD DEC (IY+SECOND_POINT_ROW-V)
E4E0 RET Z
E4E1 LD A,H The screen address of the row below; stop at the bottom of the screen.
E4E2 AND $07
E4E4 JP NZ,COMPOSITE_TO_SCREEN_6
E4E7 LD A,L
E4E8 ADD A,$20
E4EA LD L,A
E4EB LD A,H
E4EC JR C,COMPOSITE_TO_SCREEN_12
E4EE SUB $08
COMPOSITE_TO_SCREEN_12 E4F0 LD H,A
E4F1 CP $58
E4F3 RET NC
E4F4 JP COMPOSITE_TO_SCREEN_6
Prev: E3C4 Up: Map Next: E4F7