Prev: E3D9 Up: Map Next: E49F
E3FF: Draw Sprite
Used by the routine at UpdateLogoPiece.
Draws the sprite of an object in the screen buffer, with its mask. The sprite is clipped at the top and bottom of the window by its position. A sprite is drawn by popping its bytes off the stack, so the code that does the drawing changes itself to fit the sprite.
Only the rows of a player sprite that the timer at MaterialiseTimer allows are drawn, so the player appears from the bottom to the top while materialising.
The bottom of the buffer is the top of the window, and the rows of a sprite are stored from the bottom upwards, so a sprite starts at its Y position and is drawn towards the top of the screen.
Input
IX Object
DrawSprite E3FF CALL FlipSprite Turn the sprite round or upside down, if it needs it.
E402 LD A,(IX+$0E) Work out the position of the sprite in a character, in pixels (00, 02, 04 or 06).
E405 AND $06
E407 JP Z,DrawSprite_Aligned Jump to DrawSprite_Aligned if the sprite is on a character boundary.
E40A OR $F8 Make the high byte of the address of the table for shifting the sprite.
E40C LD H,A
E40D LD A,(DE) Fetch the width of the sprite, and add one for the part that is shifted into the next character.
E40E INC DE
E40F AND $07
E411 INC A
E412 LD B,A
E413 LD ($BBC2),A Keep the number of characters to draw.
E416 DEC A Double the width of the sprite in characters.
E417 AND $07
E419 ADD A,A
E41A LD C,A
E41B ADD A,A Multiply it by nine, to make eighteen bytes of code for each character.
E41C ADD A,A
E41D ADD A,A
E41E ADD A,C
E41F NEG Subtract the length of the code from the end of the shifted row.
E421 ADD A,$5A
Change the code to jump into the row.
DrawSprite_Patch E423 LD ($E4CC),A Set the offset of the jump in the code.
E426 LD A,B Work out the number of bytes to move on to the next row, and set it in the code.
E427 CPL
E428 ADD A,$1A
E42A LD ($E52A),A
E42D EX DE,HL Start with the sprite.
E42E LD A,(IX+$00) Check whether the object is one of the legs or the body of the player.
E431 SUB $10
E433 CP $20
E435 LD A,$70 Use a height of 70 (the whole window).
E437 JR NC,DrawSprite_Clip Jump to DrawSprite_Clip unless it is the player.
E439 LD A,($BC02) Use the height of the player while materialising.
Clip the sprite at the top and bottom of the window.
DrawSprite_Clip E43C LD C,A Keep the height.
E43D LD A,(IX+$0F) Work out the position of the sprite in the window, and jump to DrawSprite_Below if it starts below the window.
E440 SUB $48
E442 JR C,DrawSprite_Below
E444 SUB C Return if it starts above the height of the window.
E445 RET NC
E446 NEG Work out the number of rows that fit between the sprite and the top of the window.
E448 CP (HL) Jump to DrawSprite_Rows if fewer rows fit than there are in the sprite.
E449 JR C,DrawSprite_Rows
E44B LD A,(HL) Otherwise use the number of rows of the sprite.
DrawSprite_Rows E44C INC HL Point at the first row of the sprite, and keep the number of rows to draw.
E44D LD ($BBC3),A
Set up the registers, and draw the rows of the sprite.
DrawSprite_Draw E450 EX DE,HL Keep the address of the sprite.
E451 PUSH HL
E452 LD L,(IX+$0E) Fetch the position of the sprite.
E455 LD H,(IX+$0F)
E458 CALL CalculateBufferAddress Find the address of the position in the screen buffer.
E45B LD C,L Move it into BC.
E45C LD B,H
E45D POP HL Get the address of the sprite back.
E45E LD ($BBAE),SP Keep the stack pointer.
E462 EX DE,HL Point the stack pointer at the sprite.
E463 LD SP,HL
E464 EX DE,HL
E465 SET 1,(IX+$07) Flag that the object has been drawn.
E469 LD A,($BBC3) Fetch the number of rows to draw.
E46C JR DrawSpriteRow Jump to DrawSpriteRow to draw them.
The sprite starts below the window, so skip the rows that are not visible.
DrawSprite_Below E46E NEG Work out the number of rows to skip.
E470 LD C,A
E471 LD A,(HL) Work out the number of rows that are left.
E472 SUB C
E473 RET M Return if no rows are left.
E474 RET Z
E475 LD ($BBC3),A Keep the number of rows to draw, and clear B.
E478 LD B,$00
E47A DEC HL Fetch the width of the sprite.
E47B LD A,(HL)
E47C AND $3F
E47E INC HL Point at the first row.
E47F INC HL
E480 SLA C Work out the number of bytes that make up a row, and double it.
E482 RL B
DrawSprite_Skip E484 ADD HL,BC Skip the rows, one at a time.
E485 DEC A
E486 JR NZ,DrawSprite_Skip
E488 LD (IX+$0F),$48 Start the sprite at the bottom of the window.
E48C JR DrawSprite_Draw Jump to DrawSprite_Draw to draw the sprite.
The sprite is on a character boundary.
DrawSprite_Aligned E48E LD A,(DE) Fetch the width of the sprite.
E48F INC DE
E490 AND $0F
E492 LD ($BBC2),A Keep the number of characters to draw.
E495 LD B,A Make it the count of characters.
E496 ADD A,A Multiply it by eight.
E497 ADD A,A
E498 ADD A,A
E499 NEG Negate it.
E49B SUB $06 Take off the length of the code that is left after the characters.
E49D JR DrawSprite_Patch Jump to DrawSprite_Patch to change the code.
Prev: E3D9 Up: Map Next: E49F