![]() |
Routines |
| Prev: EE73 | Up: Map | Next: EF4E |
|
The one routine that draws objects, and it never touches the screen: it draws the object at IX into a buffer the shape of the region being rebuilt -- a row one byte wider than the region's width in bytes (IY+$73), as many rows as the region is high, wrapping within its 256-byte page -- clipped to the region and shifted to the pixel. The compositor (COMPOSITE_TO_SCREEN) then makes the screen's bytes from the buffers. Krumlinde's name for it is RTN_Draw_Sprite.
The mode in A says what is drawn where. Mode $80, for the object being redrawn (REDRAW_OBJECT): its mask, into page $D9, with three rows of $FF (nothing covered) above and below it. Mode 0, for an object in front of it (CULL_OBJECT): its cover -- the mask inverted, a bit set where the object shows -- ORed into page $D8. Modes 4 and 8, for the objects behind (SORT_AND_DRAW_BEHIND): the cover ORed into page $DA and cleared out of page $DB, and then the image ORed into page $DB. A sprite is its image and then its mask, each width/8 bytes by height rows (+2 and +3), so every mode but 8 starts one plane in.
The setting up works out, in turn: which rows to draw -- skipping the sprite's rows above the region, or the buffer's rows above the sprite -- into IY+$75; the shift, x mod 8, written into the JR in DRAW_SPRITE_ROWS that jumps into its run of RRCAs, and the masks for the two parts of a shifted byte written into the three ANDs there; and which columns: a sprite starting left of the region is handled by DRAW_SPRITE_CLIP_LEFT, one starting inside it by moving the buffer pointer along (DRAW_SPRITE_SKIP_COLUMNS). Then DRAW_SPRITE_ROWS draws.
The bits of C, besides the mode's: bit 4, the sprite starts left of the region; bit 5, the first column only primes the spill and is not written; bit 6, no spill column after the last, because the sprite is on a byte boundary or is cut by the region's right edge.
|
||||||||||
| DRAW_SPRITE | EE8D | PUSH BC | The sprite's width in bytes, kept at IY+$78 | |||||||
| EE8E | PUSH DE | |||||||||
| EE8F | LD C,A | |||||||||
| EE90 | LD A,(IX+OBJ_WIDTH) | |||||||||
| EE93 | SRL A | |||||||||
| EE95 | SRL A | |||||||||
| EE97 | SRL A | |||||||||
| EE99 | LD B,A | |||||||||
| EE9A | LD (FOUND_RECORD),A | |||||||||
| EE9D | XOR A | One plane's size: width times height | ||||||||
| DRAW_SPRITE_0 | EE9E | ADD A,(IX+OBJ_ROWS) | ||||||||
| EEA1 | DJNZ DRAW_SPRITE_0 | |||||||||
| EEA3 | LD H,(IX+OBJ_SPRITE+$01) | The sprite; every mode but 8 draws the second plane, the mask | ||||||||
| EEA6 | LD L,(IX+OBJ_SPRITE) | |||||||||
| EEA9 | BIT 3,C | |||||||||
| EEAB | JR NZ,DRAW_SPRITE_1 | |||||||||
| EEAD | LD E,A | |||||||||
| EEAE | LD D,$00 | |||||||||
| EEB0 | ADD HL,DE | |||||||||
| DRAW_SPRITE_1 | EEB1 | EX DE,HL | DE: where to read from | |||||||
| EEB2 | LD A,(POINT_ROW) | Does the sprite start above the region's top row? | ||||||||
| EEB5 | SUB (IX+OBJ_SCREEN_Y) | |||||||||
| EEB8 | JR C,DRAW_SPRITE_3 | |||||||||
| EEBA | LD B,A | No: skip the buffer's rows above it (a count of 0 goes round 256 times and comes back to no rows) | ||||||||
| EEBB | XOR A | |||||||||
| DRAW_SPRITE_2 | EEBC | ADD A,(IY+DRAW_WIDTH-V) | ||||||||
| EEBF | INC A | |||||||||
| EEC0 | DJNZ DRAW_SPRITE_2 | |||||||||
| EEC2 | LD L,A | |||||||||
| EEC3 | LD H,$D9 | |||||||||
| EEC5 | LD A,(POINT_ROW) | And draw down to the region's bottom, or the sprite's height if that is less | ||||||||
| EEC8 | SUB (IY+SECOND_POINT_ROW-V) | |||||||||
| EECB | LD B,A | |||||||||
| EECC | LD A,(IX+OBJ_SCREEN_Y) | |||||||||
| EECF | SUB B | |||||||||
| EED0 | CP (IX+OBJ_ROWS) | |||||||||
| EED3 | JR C,DRAW_SPRITE_5 | |||||||||
| EED5 | LD A,(IX+OBJ_ROWS) | |||||||||
| EED8 | JR DRAW_SPRITE_5 | |||||||||
| DRAW_SPRITE_3 | EEDA | CPL | Yes: skip the sprite's rows above the region | |||||||
| EEDB | LD H,A | |||||||||
| EEDC | LD B,(IY+FOUND_RECORD-V) | |||||||||
| EEDF | INC H | |||||||||
| EEE0 | XOR A | |||||||||
| DRAW_SPRITE_4 | EEE1 | ADD A,H | ||||||||
| EEE2 | DJNZ DRAW_SPRITE_4 | |||||||||
| EEE4 | LD H,$00 | |||||||||
| EEE6 | LD L,A | |||||||||
| EEE7 | ADD HL,DE | |||||||||
| EEE8 | EX DE,HL | |||||||||
| EEE9 | LD HL,BUFFER_D900 | And draw from the buffer's top down to the sprite's bottom | ||||||||
| EEEC | LD A,(IX+OBJ_SCREEN_Y) | |||||||||
| EEEF | SUB (IX+OBJ_ROWS) | |||||||||
| EEF2 | LD B,A | |||||||||
| EEF3 | LD A,(POINT_ROW) | |||||||||
| EEF6 | SUB B | |||||||||
| DRAW_SPRITE_5 | EEF7 | LD (IY+WORK_ANIMATION-V),A | The rows to draw | |||||||
| EEFA | LD A,(IX+OBJ_SCREEN_X) | 7 minus (x mod 8) into the JR's displacement: that many of the seven RRCAs are jumped over | ||||||||
| EEFD | CPL | |||||||||
| EEFE | AND $07 | |||||||||
| EF00 | LD ($EFD1),A | |||||||||
| EF03 | CP $07 | On a byte boundary: nothing spills into a next column | ||||||||
| EF05 | JR NZ,DRAW_SPRITE_6 | |||||||||
| EF07 | SET 6,C | |||||||||
| DRAW_SPRITE_6 | EF09 | LD B,A | A mask of the low 8 minus (x mod 8) bits: the part of a shifted byte that stays in its column | |||||||
| EF0A | XOR A | |||||||||
| EF0B | INC B | |||||||||
| DRAW_SPRITE_7 | EF0C | SCF | ||||||||
| EF0D | RLA | |||||||||
| EF0E | DJNZ DRAW_SPRITE_7 | |||||||||
| EF10 | LD ($EFF4),A | Into the two ANDs that keep it, and its complement into the one that keeps the spill | ||||||||
| EF13 | LD ($EFE3),A | |||||||||
| EF16 | CPL | |||||||||
| EF17 | LD ($F008),A | |||||||||
| EF1A | LD A,(POINT) | Columns from the region's left byte to the sprite's; bit 4 if the sprite starts left of it | ||||||||
| EF1D | AND $F8 | |||||||||
| EF1F | LD B,A | |||||||||
| EF20 | LD A,(IX+OBJ_SCREEN_X) | |||||||||
| EF23 | AND $F8 | |||||||||
| EF25 | SUB B | |||||||||
| EF26 | JR NC,DRAW_SPRITE_8 | |||||||||
| EF28 | SET 4,C | |||||||||
| EF2A | NEG | |||||||||
| DRAW_SPRITE_8 | EF2C | SRL A | In bytes; starting left: DRAW_SPRITE_CLIP_LEFT | |||||||
| EF2E | SRL A | |||||||||
| EF30 | SRL A | |||||||||
| EF32 | LD B,A | |||||||||
| EF33 | BIT 4,C | |||||||||
| EF35 | JR NZ,DRAW_SPRITE_CLIP_LEFT | |||||||||
| EF37 | INC B | Starting inside: draw what fits before the region's right edge and its spare column, the spill cut off... | ||||||||
| EF38 | SET 6,C | |||||||||
| EF3A | SUB (IY+DRAW_WIDTH-V) | |||||||||
| EF3D | NEG | |||||||||
| EF3F | INC A | |||||||||
| EF40 | CP (IY+FOUND_RECORD-V) | |||||||||
| EF43 | JR C,DRAW_SPRITE_SKIP_COLUMNS_0 | |||||||||
| EF45 | JR Z,DRAW_SPRITE_SKIP_COLUMNS_0 | |||||||||
| EF47 | LD A,(FOUND_RECORD) | ...or the whole width and the spill column after it | ||||||||
| EF4A | RES 6,C | |||||||||
| EF4C | JR DRAW_SPRITE_SKIP_COLUMNS_0 | |||||||||
| Prev: EE73 | Up: Map | Next: EF4E |