![]() |
Routines |
| Prev: E3C4 | Up: Map | Next: E4F7 |
|
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 |