Prev: D710 Up: Map Next: D73C
D718: Draw an object's sprite into the buffer, through its mask
A sprite is a header -- width in bytes in bits 0 to 3, the flip state in bits 6 and 7, then the height in rows -- and then a pair of bytes for every byte of every row: a mask and an image. Rows are drawn from the bottom up. Each background byte is cleared where the mask is set and then has the image put in, so a sprite punches its own shape out of whatever was drawn before it and objects can overlap in depth.
The row loop at sprite_row is unrolled for the widest sprite, five bytes, and this routine patches it for the one in hand: the offset of the JR at sprite_row_jump decides how far into the unrolled code a row starts, and the operand of the ADD at sprite_next_row how far BC must then move to reach the next row up. There are two unrolled runs. A sprite whose pixel x is a multiple of 8 uses the plain one; any other uses the shifted one, which reads its bytes through the tables from shift_tbls up and so touches one byte more per row.
The stack pointer is borrowed to read the sprite: SP is pointed at the data and each POP DE fetches a mask byte into E and its image byte into D. The real SP is kept in $5BA9 meanwhile. The listing has no EI anywhere, so the game runs with interrupts off and nothing can push onto the sprite while SP is borrowed.
Bytes $18 and $19 come out as the width and height actually drawn, which wipe_next_object uses next frame to wipe the picture away. Only the top of the screen is clipped; nothing is clipped at the sides.
Input
IX the object: its graphic in byte 0, its pixel position in bytes $1A
and $1B, its flip bits in byte 7
print_sprite D718 CALL flip_sprite DE = the sprite, turned the way byte 7 asks
D71B LD A,(IX+$1A) x within its byte; 0 goes to the aligned case at sprite_aligned
D71E AND $07
D720 JR Z,sprite_aligned
D722 RLCA H = $F0 + 2 * the shift, the page pair build_lookup_tbls built for it
D723 AND $0E
D725 OR $F0
D727 LD H,A
D728 LD A,(DE) the width from the header, plus one: the bytes a shifted row touches, into byte $18
D729 INC DE
D72A AND $07
D72C INC A
D72D LD B,A
D72E LD (IX+$18),A
D731 DEC A the JR offset for sprite_row_jump: 16 bytes of code per byte of width, counted back from the end of the shifted run
D732 AND $07
D734 ADD A,A
D735 ADD A,A
D736 ADD A,A
D737 ADD A,A
D738 NEG
D73A ADD A,$50
Prev: D710 Up: Map Next: D73C