Prev: D704 Up: Map Next: D780
D718: Print Sprite
Draws the sprite of an object into ScreenBuffer, at the pixel position of the object. A sprite has a width byte (the vertical flip in bit 7, the horizontal flip in bit 6 and the width in columns in the low bits), a height byte, and then the data for each line from the top. Each column of a line is a pair of bytes: a mask byte, then a data byte. The mask clears the bits of the background and the data sets bits. A sprite that does not start on a byte boundary has each pair shifted across two bytes of the buffer, with the tables built by BuildLookupTables. The routine copies the sprite with unrolled code, which it enters part of the way along, so that it does as many columns as the sprite has. To do this it changes the code, and it uses the stack pointer to read the data of the sprite.
Input
IX The address of the object
Find the sprite and choose the draw path.
PrintSprite D718 CALL GetSpriteAddress Find the sprite.
D71B LD A,(IX+$1A) Fetch the pixel x position.
D71E AND %00000111 Keep the bits of the position in the byte.
D720 JR Z,PrintSprite_Aligned Jump to PrintSprite_Aligned if the sprite is on a byte boundary.
Choose the page of the shift table.
D722 RLCA Double it.
D723 AND %00001110 Keep bits 1 to 3.
D725 OR %11110000 Make it the page of the table of shifted bytes.
D727 LD H,A Copy it to H.
Fetch the width of the sprite, and move on to the height.
D728 LD A,(DE) Fetch the width byte of the sprite.
D729 INC DE Increment DE.
D72A AND %00000111 Keep the width.
D72C INC A Add one for the byte that the shifted sprite spills into.
D72D LD B,A Copy it to B.
D72E LD (IX+$18),A Set the width in bytes of the object.
D731 DEC A Take one off it to work out the number of pairs, less one.
D732 AND %00000111 Keep bits 0 to 2.
D734 ADD A,A Multiply it by sixteen, which is the size of the code for a pair.
D735 ADD A,A
D736 ADD A,A
D737 ADD A,A
D738 NEG Negate it.
D73A ADD A,$50 Add 50.
Change the jump and the step.
PrintSprite_Patch D73C LD ($D7AD),A Change the offset of the jump into the unrolled code.
D73F LD A,B Fetch the width in bytes.
D740 CPL Invert it.
D741 ADD A,$22 Add 22.
D743 LD ($D801),A Write it to D801.
Clip the sprite to the top of the screen.
D746 LD A,(DE) Fetch the height of the sprite.
D747 INC DE Increment DE.
D748 LD (IX+$19),A Set the height in lines of the object.
D74B ADD A,(IX+$1B) Add the pixel y position.
D74E SUB $C0 Take the number of lines on the screen off it.
D750 JR C,PrintSprite_Draw Jump to PrintSprite_Draw if the sprite does not go off the top of the screen.
D752 NEG Make the number of lines that are off the screen positive.
D754 ADD A,(IX+$19) Take it off the height.
D757 LD (IX+$19),A Set the height in lines of the object.
Draw the rows that are on the screen.
PrintSprite_Draw D75A LD C,(IX+$1A) Fetch the pixel x position.
D75D LD B,(IX+$1B) Fetch the pixel y position.
D760 CALL CalculateBufferAddress Find the address in the screen buffer.
D763 LD ($5BA9),SP Set SavedStackPointer.
D767 EX DE,HL Point the stack pointer at the data of the sprite.
D768 LD SP,HL
D769 EX DE,HL
D76A LD A,(IX+$19) Fetch the number of lines.
D76D JR DrawLines Jump to DrawLines.
The sprite is aligned, so the bytes do not need to be shifted.
PrintSprite_Aligned D76F LD A,(DE) Fetch the width byte of the sprite.
D770 INC DE Increment DE.
D771 AND %00001111 Keep the width.
D773 LD (IX+$18),A Set the width in bytes of the object.
D776 LD B,A Copy it to B.
D777 ADD A,A Multiply it by eight, which is the size of the code for a column.
D778 ADD A,A
D779 ADD A,A
D77A NEG Negate it.
D77C SUB $06 Take 06 off it to get the offset from the end of the unrolled code.
D77E JR PrintSprite_Patch Jump to PrintSprite_Patch.
View the equivalent code in;
Prev: D704 Up: Map Next: D780