Prev: BD69 Up: Map Next: BE5B
BDAE: Draw Sprite
Used by the routine at DrawSpriteList.
Draws a sprite into the buffer, which is the picture of the play area, with twenty four bytes in each of one hundred and twelve rows. The sprite data is a byte for the number of columns, a byte for the number of rows, and for each row, from the bottom to the top, a mask byte and a pixel byte for each column. The mask clears the bits under the sprite and the pixels are then added.
Input
A The number of the sprite
IX The address of the object
Bit 1 of IX+07 is set to show that a sprite has been drawn. The sprite is shifted by the horizontal pixel position, which has to be even, and is flipped if bit 6 of the flags of the object is set. A shifted sprite is one byte wider, and the shifting is done by tables, which are built by BuildShiftTables. The row of pixels is drawn by code for the right number of columns: the code was unrolled so that it can be fast, and the address in the jump at SpriteJumpOpcode is set to the right place in it. The sprite data is taken off the stack. A sprite which is partly below the bottom or above the top of the play area has the rows which are outside it left out.
DrawSprite BDAE LD BC,$67F4 Point BC at SpritePointers.
Fetch the address of the sprite data.
BDB1 CALL GetTableEntry Call GetTableEntry.
BDB4 EX DE,HL Swap the address into DE.
BDB5 BIT 6,(IX+$07) Jump to DrawFlippedSprite to draw the flipped sprite if the object is flipped.
BDB9 JP NZ,DrawFlippedSprite
Fetch the horizontal pixel position.
BDBC LD A,($A220) Fetch SpriteHorizontalPosition.
BDBF AND %00000110 Keep the shift, which is zero, two, four or six pixels.
Draw the sprite unshifted.
BDC1 JP Z,DrawSprite_Aligned Jump to DrawSprite_Aligned if there is no shift.
BDC4 OR %11111000 Make the high byte of the address of the table for the shift.
BDC6 LD H,A Set H.
BDC7 LD A,(DE) Fetch the number of columns of the sprite.
BDC8 INC DE Move on to the next byte.
BDC9 AND %00000111 Keep the low three bits.
BDCB INC A Add one, as a shifted sprite is one byte wider.
BDCC LD B,A Keep the widened column count in B.
Store the number of bytes in a row of the sprite.
BDCD LD ($A222),A Set SpriteRowBytes.
BDD0 DEC A Take one off again.
BDD1 AND %00000111 Keep the low three bits.
BDD3 ADD A,A Double it.
BDD4 LD C,A Keep twice the column count in C.
BDD5 ADD A,A Multiply it by eight to make sixteen times the number of columns.
BDD6 ADD A,A
BDD7 ADD A,A
BDD8 ADD A,C Add the double to make eighteen times.
BDD9 NEG Make it negative.
BDDB ADD A,$5D Add 5D which gives the distance from DrawSprite_Jump to the code for the number of columns. Each column has eighteen bytes of code.
DrawSprite_SetJump BDDD PUSH BC Stash the number of columns on the stack.
BDDE PUSH HL Stash the high byte of the shift table on the stack.
BDDF LD H,$00 Clear H.
BDE1 AND A Test the sign of the distance.
BDE2 JP P,DrawSprite_SetJumpAddress Jump to DrawSprite_SetJumpAddress if it is positive.
BDE5 DEC H Make HL negative.
DrawSprite_SetJumpAddress BDE6 LD L,A Put the distance in L.
BDE7 LD BC,$BE87 Point BC at DrawSprite_Jump.
BDEA ADD HL,BC Add the distance to give the address to jump to.
Set the address of the jump at SpriteJumpOpcode.
BDEB LD ($A225),HL Set SpriteJumpAddress.
BDEE POP HL Restore the shift table from the stack.
BDEF POP BC Restore the number of bytes in a row from the stack.
BDF0 LD A,B Fetch the number of bytes in a row.
BDF1 CPL Invert it.
BDF2 ADD A,$1A Add 1A to give twenty five minus the number of bytes.
Store the distance from the end of a row to the start of the next.
BDF4 LD ($A227),A Set SpriteRowStep.
BDF7 EX DE,HL Swap the address of the sprite data into HL.
BDF8 LD C,$70 Set the number of rows in the buffer.
Fetch the vertical position.
BDFA LD A,($A221) Fetch SpriteVerticalPosition.
BDFD SUB $48 Subtract the position of the bottom row of the buffer.
BDFF JR C,DrawSprite_Below Jump to DrawSprite_Below if the sprite starts below it.
BE01 SUB C Subtract the number of rows in the buffer.
BE02 RET NC Return if the sprite starts above the top.
BE03 NEG Make it positive, which is the number of rows up to the top.
BE05 CP (HL) Compare it with the number of rows in the sprite.
BE06 JR C,DrawSprite_FirstByte Jump to DrawSprite_FirstByte if there is room for fewer rows.
BE08 LD A,(HL) Use the number of rows in the sprite.
DrawSprite_FirstByte BE09 INC HL Move on to the first byte of data.
Store the number of rows to draw.
BE0A LD ($A223),A Set SpriteRowsLeft.
DrawSprite_StartRows BE0D EX DE,HL Swap the address of the data into DE.
BE0E PUSH HL Stash the high byte of the shift table on the stack.
Fetch the pixel position.
BE0F LD HL,($A220) Fetch SpriteHorizontalPosition.
Find the address in the buffer.
BE12 CALL CalculateBufferAddress Call CalculateBufferAddress.
BE15 LD C,L Keep the buffer address in BC.
BE16 LD B,H
BE17 POP HL Restore the shift table from the stack.
Save the stack pointer.
BE18 LD ($A21D),SP Set SavedStackPointer.
BE1C EX DE,HL Point the stack pointer at the sprite data.
BE1D LD SP,HL
BE1E EX DE,HL
BE1F SET 1,(IX+$07) Set the flag which shows that a sprite has been drawn.
Fetch the number of rows to draw.
BE23 LD A,($A223) Fetch SpriteRowsLeft.
Draw the first row.
BE26 JR DrawSpriteRow Jump to DrawSpriteRow.
DrawSprite_Below BE28 NEG Make the number of rows below the bottom positive.
BE2A LD C,A Keep the rows below the bottom of the sprite in C.
BE2B LD A,(HL) Fetch the number of rows in the sprite.
BE2C SUB C Subtract the number below the bottom.
BE2D RET M Return if the sprite is all below the bottom.
BE2E RET Z Return if there is nothing left.
Store the number of rows to draw.
BE2F LD ($A223),A Set SpriteRowsLeft.
BE32 LD B,$00 Clear B.
BE34 DEC HL Move back to the first byte of the sprite data.
BE35 LD A,(HL) Fetch the number of columns.
BE36 AND %00111111 Keep the number of columns.
BE38 INC HL Move on to the data.
BE39 INC HL
BE3A SLA C Double the number of rows to skip.
BE3C RL B
DrawSprite_SkipRows BE3E ADD HL,BC Skip two bytes for each row below the bottom in each column.
BE3F DEC A
BE40 JR NZ,DrawSprite_SkipRows
Start drawing at the bottom of the buffer.
BE42 LD A,$48 Set SpriteVerticalPosition to the bottom of the buffer.
BE44 LD ($A221),A
Start the rows.
BE47 JR DrawSprite_StartRows Jump to DrawSprite_StartRows.
DrawSprite_Aligned BE49 LD A,(DE) Fetch the number of columns of the sprite.
BE4A INC DE Move on to the next byte.
BE4B AND %00001111 Keep the low four bits.
Store the number of bytes in a row of the sprite.
BE4D LD ($A222),A Set SpriteRowBytes.
BE50 LD B,A Keep the bytes in a row in B.
BE51 ADD A,A Multiply it by eight.
BE52 ADD A,A
BE53 ADD A,A
BE54 NEG Make it negative.
BE56 SUB $04 Subtract four, which gives the distance from DrawSprite_Jump to the code for the number of columns. Each column has eight bytes of code.
Set the address of the jump.
BE58 JP DrawSprite_SetJump Jump to DrawSprite_SetJump.
Prev: BD69 Up: Map Next: BE5B