Prev: 41720 Up: Map Next: 42366
41731: Draw Sprites
Used by the routines at DrawObject and UpdateStarLayer.
Erases one sprite and draws another without flicker. It works out the rectangle that holds both sprites (which is at most seven bytes wide), copies that part of the screen to a buffer at 63488, erases the first sprite from the buffer, draws the second sprite into the buffer and then copies the buffer back to the screen. The sprites are set up by SelectEraseSprite, SelectDrawSprite and ClipSecondSprite or ClipFirstSprite. A sprite with no rows is not drawn.
Input
B High byte of the shift table for the second sprite
B' High byte of the shift table for the first sprite
DE Address of the data of the second sprite
DE' Address of the data of the first sprite
IX Routine that draws the second sprite
IY Routine that erases the first sprite
DrawSprites 41731 PUSH DE Save the address of the data of the second sprite.
41732 PUSH BC Stash BC on the stack.
41733 LD HL,(23592) Fetch the widths of the two sprites in bytes.
41736 LD (41720),HL Keep a copy of the widths.
41739 ADD HL,HL Multiply the widths by eight to get them in pixels.
41740 ADD HL,HL
41741 ADD HL,HL
41742 LD (23592),HL Store the widths in pixels.
41745 LD A,(41431) Fetch the number of rows of the first sprite.
41748 AND A Test it.
41749 JR NZ,DrawSprites_SecondPosition Jump to DrawSprites_SecondPosition if the sprite has rows.
41751 LD HL,(41429) Copy the position of the second sprite...
41754 LD (41427),HL ...to the first sprite.
DrawSprites_SecondPosition 41757 LD A,(41432) Fetch the number of rows of the second sprite.
41760 AND A Test it.
41761 JR NZ,DrawSprites_Wrapped Jump to DrawSprites_Wrapped if the sprite has rows.
41763 LD HL,(41427) Copy the position of the first sprite...
41766 LD (41429),HL ...to the second sprite.
DrawSprites_Wrapped 41769 LD A,(41722) Fetch the flag for sprites beyond the right of the playfield.
41772 AND A Test it.
41773 JR Z,DrawSprites_Top Jump to DrawSprites_Top if it is not set.
41775 LD A,(41427) Fetch the horizontal position of the first sprite.
41778 SUB 96 Take off 96.
41780 LD (41427),A Store it.
41783 LD A,(41429) Fetch the horizontal position of the second sprite.
41786 SUB 96 Take off 96.
41788 LD (41429),A Store it.
Find the bottom of the rectangle, which is the larger of the vertical positions of the two sprites (the rows of a sprite go up from its position).
DrawSprites_Top 41791 LD A,(41428) Fetch the vertical position of the first sprite.
41794 LD E,A Store it in E.
41795 LD A,(41430) Fetch the vertical position of the second sprite.
41798 LD D,A Store it in D.
41799 CP E Is the second sprite higher than the first?
41800 JR NC,DrawSprites_TopFound Jump to DrawSprites_TopFound if so.
41802 LD A,E Use the position of the first sprite.
DrawSprites_TopFound 41803 LD (23597),A Store the bottom of the rectangle.
41806 LD H,A Keep it in H.
Find the top of the rectangle, which gives the number of rows.
41807 LD BC,(41431) Fetch the number of rows of each sprite.
41811 LD A,E Take the number of rows from the position of the first sprite...
41812 SUB C
41813 LD E,A
41814 LD A,D ...and from the position of the second sprite.
41815 SUB B
41816 CP E Is the top of the second sprite higher than that of the first?
41817 JR NC,DrawSprites_BottomFound Jump to DrawSprites_BottomFound if not.
41819 LD E,A Use the top of the second sprite.
DrawSprites_BottomFound 41820 LD A,H Take the top from the bottom...
41821 SUB E
41822 INC A ...and add one to get the number of rows of the rectangle.
41823 LD (52791),A Store it.
Find the left of the rectangle, which is the lowest of the horizontal positions of the two sprites, rounded down to a whole byte.
41826 LD A,(41427) Fetch the horizontal position of the first sprite.
41829 LD E,A Store it in E.
41830 LD A,(41429) Fetch the horizontal position of the second sprite.
41833 LD D,A Store it in D.
41834 CP E Is the second sprite further to the left?
41835 JR C,DrawSprites_Left Jump to DrawSprites_Left if so.
41837 LD A,E Use the position of the first sprite.
DrawSprites_Left 41838 AND %11111000 Round down to a whole byte.
41840 LD (23596),A Store the left of the rectangle.
41843 LD L,A Keep it in L.
Find the right of the rectangle, which gives the number of bytes in each row.
41844 LD BC,(23592) Fetch the widths of the sprites in pixels.
41848 LD A,E Work out the right of the first sprite relative to the left.
41849 SUB L
41850 ADD A,C
41851 LD E,A
41852 LD A,D Work out the right of the second sprite relative to the left.
41853 SUB L
41854 ADD A,B
41855 CP E Is the second sprite further to the right?
41856 JR NC,DrawSprites_Right Jump to DrawSprites_Right if so.
41858 LD A,E Use the right of the first sprite.
DrawSprites_Right 41859 ADD A,6 Add six to allow for shifting.
41861 LD C,A Store it in C.
41862 SRL A Divide it by eight to get the number of bytes in a row.
41864 SRL A
41866 SRL A
41868 LD (52789),A Store it.
41871 LD A,(41722) Fetch the flag for sprites beyond the right of the playfield.
41874 AND A Test it.
41875 JP Z,DrawSprites_Copy Jump to DrawSprites_Copy if it is not set.
The sprites reach beyond the right of the playfield. Work out how many bytes of each row are beyond 168, then copy that many from the left of the playfield at the end of each row of the buffer.
41878 LD A,L Fetch the left of the rectangle.
41879 ADD A,C Add the width in pixels.
41880 SUB 168 Take off 168.
41882 SRL A Divide it by eight.
41884 SRL A
41886 SRL A
41888 LD B,A Store the number of bytes beyond in B.
41889 LD A,(52789) Fetch the number of bytes in a row.
41892 SUB B Subtract the bytes beyond.
41893 LD (42289),A Store it as the amount to skip at 42288.
41896 LD (41948),A Store it as the amount to skip at 41947.
41899 LD E,A Start the copy that far along each row of the buffer.
41900 LD A,B Fetch the number of bytes beyond.
41901 XOR %00000111 Flip the bottom three bits.
41903 DEC A Turn it into a distance to jump into a run of copies...
41904 ADD A,A
41905 ADD A,3
41907 LD (42272),A ...and store it for the copy back to the screen at DrawSprites_ClipJump.
41910 LD (41931),A Store it for the copy to the buffer at DrawSprites_WrapJump.
41913 LD C,255 Set the counter that is used by LDI.
41915 LD D,248 Use the buffer.
41917 LD L,8 Use the left of the playfield.
41919 CALL GetScreenAddress Find the screen address.
41922 LD (52803),HL Keep the screen address of the left of the playfield.
41925 LD A,(52791) Fetch the number of rows.
41928 LD B,A Store it in B.
DrawSprites_WrapRow 41929 PUSH HL Save the screen address of the row.
DrawSprites_WrapJump 41930 DJNZ DrawSprites_WrapJump Jump into the run of copies.
41932 JP DrawSprites_Erase Jump to DrawSprites_Erase when the rows are done.
DrawSprites_WrapCopy 41935 LDI Copy a byte of the row to the buffer.
41937 LDI Copy a byte of the row to the buffer.
41939 LDI Copy a byte of the row to the buffer.
41941 LDI Copy a byte of the row to the buffer.
41943 LDI Copy a byte of the row to the buffer.
41945 LDI Copy a byte of the row to the buffer.
41947 LD A,0 Move to the start of the next row of the buffer.
41949 ADD A,E Add the amount to skip.
41950 LD E,A Store it in E.
41951 POP HL Restore the screen address of the row.
41952 DEC H Move up a pixel row.
41953 LD A,H Fetch the high byte.
41954 INC A Add one.
41955 AND %00000111 Keep the bits that give the pixel row.
41957 JP NZ,DrawSprites_WrapRow Jump to DrawSprites_WrapRow if the row is still in the same cell.
41960 LD A,L Fetch the low byte.
41961 SUB 32 Move up a row of cells.
41963 LD L,A Store it.
41964 JP C,DrawSprites_WrapRow Jump to DrawSprites_WrapRow if that crossed a third of the screen.
41967 LD A,H Fetch the high byte.
41968 ADD A,8 Add eight to correct it.
41970 LD H,A Store it.
41971 JP DrawSprites_WrapRow Jump to DrawSprites_WrapRow.
Copy the rectangle from the screen to the buffer.
DrawSprites_Copy 41974 LD DE,63488 Use the buffer.
41977 LD A,(52789) Fetch the number of bytes in a row.
41980 XOR %00000111 Flip the bottom three bits.
41982 ADD A,A Turn it into a distance to jump into a run of copies...
41983 ADD A,3
41985 LD (42323),A ...and store it for the copy back to the screen at DrawSprites_CopyAllJump.
41988 LD (42005),A Store it for the copy to the buffer at DrawSprites_CopyJump.
41991 CALL GetScreenAddress Find the screen address of the bottom left of the rectangle.
41994 LD (52803),HL Keep it.
41997 LD C,255 Set the counter that is used by LDI.
41999 LD A,(52791) Fetch the number of rows.
42002 LD B,A Store it in B.
DrawSprites_CopyRow 42003 PUSH HL Save the screen address of the row.
DrawSprites_CopyJump 42004 DJNZ DrawSprites_CopyRow Jump into the run of copies.
42006 JP DrawSprites_Erase Jump to DrawSprites_Erase when the rows are done.
DrawSprites_CopyBytes 42009 LDI Copy a byte of the row to the buffer.
42011 LDI Copy a byte of the row to the buffer.
42013 LDI Copy a byte of the row to the buffer.
42015 LDI Copy a byte of the row to the buffer.
42017 LDI Copy a byte of the row to the buffer.
42019 LDI Copy a byte of the row to the buffer.
42021 LDI Copy a byte of the row to the buffer.
42023 POP HL Restore the screen address of the row.
42024 DEC H Move up a pixel row.
42025 LD A,H Fetch the high byte.
42026 INC A Add one.
42027 AND %00000111 Keep the bits that give the pixel row.
42029 JP NZ,DrawSprites_CopyRow Jump to DrawSprites_CopyRow if the row is still in the same cell.
42032 LD A,L Fetch the low byte.
42033 SUB 32 Move up a row of cells.
42035 LD L,A Store it.
42036 JP C,DrawSprites_CopyRow Jump to DrawSprites_CopyRow if that crossed a third of the screen.
42039 LD A,H Fetch the high byte.
42040 ADD A,8 Add eight to correct it.
42042 LD H,A Store it.
42043 JP DrawSprites_CopyRow Jump to DrawSprites_CopyRow.
Erase the first sprite from the buffer.
DrawSprites_Erase 42046 POP HL Discard the extra screen address.
42047 POP BC Bring BC back off the stack.
42048 POP DE Restore the address of the data of the second sprite.
42049 EXX Switch to the registers of the first sprite.
42050 LD A,(41431) Fetch the number of rows of the first sprite.
42053 AND A Test it.
42054 JP Z,DrawSprites_Draw Jump to DrawSprites_Draw if there is nothing to erase.
42057 LD HL,(41427) Fetch the position of the first sprite.
42060 CALL FindBufferAddress Find its address in the buffer.
42063 LD A,(41720) Fetch the width of the first sprite.
42066 LD C,A Store it in C.
42067 LD A,B Fetch the high byte of the shift table.
42068 CP 248 Jump to DrawSprites_EraseSkip if the sprite is not aligned to a byte.
42070 JR NZ,DrawSprites_EraseSkip
42072 DEC C An aligned sprite is one byte narrower.
DrawSprites_EraseSkip 42073 LD A,(52789) Fetch the number of bytes in a row.
42076 SUB C Take off the width to get the amount to skip to the next row.
42077 LD (42710),A Store it at 42709 for aligned sprites...
42080 LD (42792),A ...and at 42791 for shifted sprites.
42083 LD A,(41431) Fetch the number of rows of the first sprite.
42086 EX AF,AF' Store it.
42087 JP (IY) Erase the sprite.
This entry point is used by the routines at EraseAlignedRowInBuffer and EraseShiftedRowInBuffer.
Draw the second sprite into the buffer.
DrawSprites_Draw 42089 EXX Switch to the registers of the second sprite (the main set).
42090 LD A,(41432) Fetch the number of rows of the second sprite.
42093 AND A Test it.
42094 JP Z,DrawSprites_CopyBack Jump to DrawSprites_CopyBack if there is nothing to draw.
42097 LD HL,(41429) Fetch the position of the second sprite.
42100 CALL FindBufferAddress Find its address in the buffer.
42103 LD A,(41721) Fetch the width of the second sprite.
42106 LD C,A Store it in C.
42107 LD A,B Fetch the high byte of the shift table.
42108 CP 248 Jump to DrawSprites_DrawSkip if the sprite is not aligned to a byte.
42110 JR NZ,DrawSprites_DrawSkip
42112 DEC C An aligned sprite is one byte narrower.
DrawSprites_DrawSkip 42113 LD A,(52789) Fetch the number of bytes in a row.
42116 SUB C Take off the width to get the amount to skip to the next row.
42117 LD (42833),A Store it at 42832 for aligned sprites...
42120 LD (42905),A ...and at 42904 for shifted sprites.
42123 DEC A Take one off.
42124 LD (42181),A Store it at 42180.
42127 LD (47757),HL Keep the address of the sprite in the buffer.
42130 LD A,(41432) Fetch the number of rows of the second sprite.
42133 EX AF,AF' Store it.
42134 JP (IX) Draw the sprite.
This entry point is used by the routines at DrawAlignedRowInBuffer and DrawShiftedRowInBuffer.
When the value at 41730 is not zero, dissolve the second sprite in the buffer by clearing some of its pixels using one of the masks at 41723.
DrawSprites_Dissolve 42136 LD A,(41730) Fetch the dissolve value.
42139 AND A Test it.
42140 JP Z,DrawSprites_CopyBack Jump to DrawSprites_CopyBack if the sprite is not dissolving.
42143 AND %00001111 Keep the bottom four bits.
42145 LD HL,41722 Use the masks.
42148 CALL AddAToHL Add the dissolve value.
42151 LD D,(HL) Fetch the mask.
42152 LD HL,(47757) Fetch the address of the sprite in the buffer.
42155 LD A,(41721) Fetch the width of the second sprite.
42158 LD E,A Store it in E.
42159 LD A,(41432) Fetch the number of rows of the second sprite.
42162 LD C,A Store it in C.
42163 LD A,(41429) Fetch the horizontal position of the second sprite.
42166 AND %00000111 Keep the bottom three bits.
42168 JR Z,DrawSprites_DissolveRow Jump to DrawSprites_DissolveRow if the sprite is aligned to a byte.
42170 INC E A shifted sprite is one byte wider.
DrawSprites_DissolveRow 42171 LD B,E Set the number of bytes in a row.
DrawSprites_DissolveByte 42172 LD A,D Fetch the mask.
42173 AND (HL) Apply it to the byte.
42174 LD (HL),A Store the byte.
42175 RRC D Rotate the mask.
42177 INC L Move on to the next byte.
42178 DJNZ DrawSprites_DissolveByte Loop back to DrawSprites_DissolveByte for each byte of the row.
42180 LD A,0 Move on to the start of the next row of the buffer.
42182 ADD A,L Add the amount to skip.
42183 LD L,A Store it in L.
42184 DEC C Count the rows.
42185 JR NZ,DrawSprites_DissolveRow Loop back to DrawSprites_DissolveRow for each row.
Copy the buffer back to the screen, without going past the left or right edge of the playfield.
DrawSprites_CopyBack 42187 LD DE,(52803) Fetch the screen address of the bottom left of the rectangle.
42191 LD HL,63488 Use the buffer.
42194 LD A,(41722) Fetch the flag for sprites beyond the right of the playfield.
42197 AND A Test it.
42198 JR Z,DrawSprites_Clip Jump to DrawSprites_Clip if it is not set.
42200 LD A,(42289) Fetch the amount to skip.
42203 LD L,A Start the copy that far along each row of the buffer.
42204 JP DrawSprites_ClipRows Jump to DrawSprites_ClipRows.
DrawSprites_Clip 42207 LD A,(52789) Fetch the number of bytes in a row.
42210 ADD A,A Multiply it by eight to get the width in pixels.
42211 ADD A,A
42212 ADD A,A
42213 LD B,A Store it in B.
42214 LD A,(23596) Fetch the left of the rectangle.
42217 AND A Test it.
42218 JR Z,DrawSprites_ClipLeft Jump to DrawSprites_ClipLeft if it is zero.
42220 LD C,A Store the left in C.
42221 ADD A,23 Add 23.
42223 ADD A,B Add the width in pixels.
42224 JP NC,DrawSprites_CopyAll Jump to DrawSprites_CopyAll if the rectangle ends within the screen.
42227 JR DrawSprites_ClipRight Jump to DrawSprites_ClipRight.
DrawSprites_ClipLeft 42229 INC E Skip the first byte of the buffer...
42230 INC L ...and the first byte of the screen.
42231 LD A,(52789) Fetch the number of bytes in a row.
42234 DEC A Take one off.
42235 JR DrawSprites_ClipSkip Jump to DrawSprites_ClipSkip.
DrawSprites_ClipRight 42237 LD A,238 Subtract the left from 238...
42239 SUB C ...to get the width that fits.
42240 SRL A Divide it by eight to get the number of bytes.
42242 SRL A
42244 SRL A
DrawSprites_ClipSkip 42246 LD B,A Store the number of bytes to copy in B.
42247 LD A,(52789) Fetch the number of bytes in a row.
42250 SUB B Subtract the number of bytes to copy.
42251 LD (42289),A Store it as the amount to skip at 42288.
42254 LD A,B Fetch the number of bytes to copy.
42255 XOR %00000111 Flip the bottom three bits.
42257 DEC A Work out the distance to jump into the run of copies...
42258 ADD A,A
42259 ADD A,3
42261 LD (42272),A ...and store it at DrawSprites_ClipJump.
DrawSprites_ClipRows 42264 LD C,255 Set the counter that is used by LDI.
42266 LD A,(52791) Fetch the number of rows.
42269 LD B,A Store it in B.
DrawSprites_ClipRow 42270 PUSH DE Save the screen address of the row.
DrawSprites_ClipJump 42271 DJNZ DrawSprites_ClipRow Jump into the run of copies.
42273 JP DrawSprites_Done Jump to DrawSprites_Done when the rows are done.
DrawSprites_ClipBytes 42276 LDI Copy a byte of the row to the screen.
42278 LDI Copy a byte of the row to the screen.
42280 LDI Copy a byte of the row to the screen.
42282 LDI Copy a byte of the row to the screen.
42284 LDI Copy a byte of the row to the screen.
42286 LDI Copy a byte of the row to the screen.
42288 LD A,0 Move to the start of the next row of the buffer.
42290 ADD A,L Add the amount to skip.
42291 LD L,A Store it in L.
42292 POP DE Restore the screen address of the row.
42293 DEC D Move up a pixel row.
42294 LD A,D Fetch the high byte.
42295 INC A Add one.
42296 AND %00000111 Keep the bits that give the pixel row.
42298 JP NZ,DrawSprites_ClipRow Jump to DrawSprites_ClipRow if the row is still in the same cell.
42301 LD A,E Fetch the low byte.
42302 SUB 32 Move up a row of cells.
42304 LD E,A Store it.
42305 JP C,DrawSprites_ClipRow Jump to DrawSprites_ClipRow if that crossed a third of the screen.
42308 LD A,D Fetch the high byte.
42309 ADD A,8 Add eight to correct it.
42311 LD D,A Store it.
42312 JP DrawSprites_ClipRow Jump to DrawSprites_ClipRow.
DrawSprites_CopyAll 42315 LD A,(52791) Fetch the number of rows.
42318 LD B,A Store it in B.
42319 LD C,255 Set the counter that is used by LDI.
DrawSprites_CopyAllRow 42321 PUSH DE Save the screen address of the row.
DrawSprites_CopyAllJump 42322 DJNZ DrawSprites_CopyAllJump Jump into the run of copies.
42324 JP DrawSprites_Done Jump to DrawSprites_Done when the rows are done.
DrawSprites_CopyAllBytes 42327 LDI Copy a byte of the row to the screen.
42329 LDI Copy a byte of the row to the screen.
42331 LDI Copy a byte of the row to the screen.
42333 LDI Copy a byte of the row to the screen.
42335 LDI Copy a byte of the row to the screen.
42337 LDI Copy a byte of the row to the screen.
42339 LDI Copy a byte of the row to the screen.
42341 POP DE Restore the screen address of the row.
42342 DEC D Move up a pixel row.
42343 LD A,D Fetch the high byte.
42344 INC A Add one.
42345 AND %00000111 Keep the bits that give the pixel row.
42347 JP NZ,DrawSprites_CopyAllRow Jump to DrawSprites_CopyAllRow if the row is still in the same cell.
42350 LD A,E Fetch the low byte.
42351 SUB 32 Move up a row of cells.
42353 LD E,A Store it.
42354 JP C,DrawSprites_CopyAllRow Jump to DrawSprites_CopyAllRow if that crossed a third of the screen.
42357 LD A,D Fetch the high byte.
42358 ADD A,8 Add eight to correct it.
42360 LD D,A Store it.
42361 JP DrawSprites_CopyAllRow Jump to DrawSprites_CopyAllRow.
DrawSprites_Done 42364 POP DE Discard the extra screen address.
42365 RET Return.
Prev: 41720 Up: Map Next: 42366