diff --git a/src/Sprite.s b/src/Sprite.s index 9f4afaa..7a2b76c 100644 --- a/src/Sprite.s +++ b/src/Sprite.s @@ -64,29 +64,6 @@ NEXT_TO_LAST_COL equ {{TILE_STORE_WIDTH-2}*2} ldx #NEXT_TO_LAST_ROW+NEXT_TO_LAST_COL ; Next-to-Last row, Next-to-Last column jsr _SetVBuffValues -; Set the VBuff array addresses for each sprite, since they're static -; -; NOTE: Can remove later -; ldx #0 -; lda #VBuffArray -;:loop3 sta _Sprites+VBUFF_ARRAY_ADDR,x -; clc -; adc #4*2 ; skip ahead 4 tiles -; inx -; inx -; cpx #8*2 -; bcc :loop3 - -; Now do the second set of sprites -; lda #VBuffArray+{3*{TILE_STORE_WIDTH*2}} -;:loop4 sta _Sprites+VBUFF_ARRAY_ADDR,x -; clc -; adc #4*2 ; skip ahead 4 tiles -; inx -; inx -; cpx #16*2 -; bcc :loop4 - ; Initialize the Page 2 pointers ldx #$100 lda #^spritemask @@ -231,13 +208,9 @@ _RenderSprites ; Implement the logic for updating sprite and tile rendering information. Each iteration of the ; ActiveSpriteCount will call this routine with the Y-register set to the sprite index -tmpY equ tmp15 -tmpA equ tmp14 _DoPhase1 lda _Sprites+SPRITE_STATUS,y ora ForceSpriteFlag - sta tmpA - sty tmpY ; First step, if a sprite is being removed, then we just have to clear its old tile information ; and mark the tiles it overlapped as dirty. @@ -251,21 +224,15 @@ _DoPhase1 lda #SPRITE_STATUS_EMPTY ; Mark as empty so no error if we try to Add a sprite here again sta _Sprites+SPRITE_STATUS,y - lda _Sprites+TS_COVERAGE_SIZE,y ; Manually copy current value to old - sta _Sprites+OLD_TS_COVERAGE_SIZE,y - lda _Sprites+TS_LOOKUP_INDEX,y - sta _Sprites+OLD_TS_LOOKUP_INDEX,y - jmp _ClearSpriteFromTileStore ; Clear the tile flags, add to the dirty tile list and done ; Need to calculate new VBUFF information. The could be required for UPDATED, ADDED or MOVED -; sprites, so we do it unconditionally. +; sprites, so we do it unconditionally, but we do need to mark the current sprite for erasure if +; needed :no_clear - jsr _CalcDirtySprite ; If the sprite is marked as ADDED, then it does not need to have its old tile locations cleared - lda tmpA bit #SPRITE_STATUS_ADDED bne :no_move @@ -275,12 +242,15 @@ _DoPhase1 bit #SPRITE_STATUS_MOVED beq :no_move + phy jsr _ClearSpriteFromTileStore - ldy tmpY + ply ; Anything else (MOVED, UPDATED, ADDED) will need to have the VBUFF information updated and the ; current tiles marked for update :no_move + jsr _CalcDirtySprite ; This function preserves Y + lda #SPRITE_STATUS_OCCUPIED ; Clear the dirty bits (ADDED, UPDATED, MOVED) sta _Sprites+SPRITE_STATUS,y @@ -384,7 +354,7 @@ _CreateSpriteStamp ; the vertical tiles are taken from tileId + 32. This is why tile sheets should be saved ; with a width of 256 pixels. ; -; A = tileId + flags +; A = vbuffAddress ; Y = High Byte = x-pos, Low Byte = y-pos ; X = Sprite Slot (0 - 15) _AddSprite @@ -458,7 +428,7 @@ next _ClearSpriteFromTileStore lda _SpriteBitsNot,y ; Cache this value in a direct page location sta tmp0 - ldx _Sprites+OLD_TS_COVERAGE_SIZE,y + ldx _Sprites+TS_COVERAGE_SIZE,y jmp (csfts_tbl,x) csfts_tbl dw csfts_1x1,csfts_1x2,csfts_1x3,csfts_out dw csfts_2x1,csfts_2x2,csfts_2x3,csfts_out @@ -467,7 +437,7 @@ csfts_tbl dw csfts_1x1,csfts_1x2,csfts_1x3,csfts_out csfts_out rts -csfts_3x3 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_3x3 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 2 TSClearSprite 4 @@ -479,7 +449,7 @@ csfts_3x3 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y TSClearSprite 2*{TS_LOOKUP_SPAN*2}+4 rts -csfts_3x2 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_3x2 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 2 TSClearSprite 1*{TS_LOOKUP_SPAN*2}+0 @@ -488,13 +458,13 @@ csfts_3x2 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y TSClearSprite 2*{TS_LOOKUP_SPAN*2}+2 rts -csfts_3x1 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_3x1 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 1*{TS_LOOKUP_SPAN*2}+0 TSClearSprite 2*{TS_LOOKUP_SPAN*2}+0 rts -csfts_2x3 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_2x3 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 2 TSClearSprite 4 @@ -503,30 +473,30 @@ csfts_2x3 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y TSClearSprite 1*{TS_LOOKUP_SPAN*2}+4 rts -csfts_2x2 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_2x2 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 2 TSClearSprite 1*{TS_LOOKUP_SPAN*2}+0 TSClearSprite 1*{TS_LOOKUP_SPAN*2}+2 rts -csfts_2x1 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_2x1 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 1*{TS_LOOKUP_SPAN*2}+0 rts -csfts_1x3 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_1x3 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 2 TSClearSprite 4 rts -csfts_1x2 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_1x2 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 TSClearSprite 2 rts -csfts_1x1 ldx _Sprites+OLD_TS_LOOKUP_INDEX,y +csfts_1x1 ldx _Sprites+TS_LOOKUP_INDEX,y TSClearSprite 0 rts @@ -638,37 +608,6 @@ _CacheSpriteBanks rts -; A = x coordinate -; Y = y coordinate -;GetSpriteVBuffAddr ENT -; jsr _GetSpriteVBuffAddr -; rtl - -; A = x coordinate -; Y = y coordinate -;_GetSpriteVBuffAddr -; pha -; tya -; clc -; adc #NUM_BUFF_LINES ; The virtual buffer has 24 lines of off-screen space -; xba ; Each virtual scan line is 256 bytes wide for overdraw space -; clc -; adc 1,s -; sta 1,s -; pla -; rts - -; Version that uses temporary space (tmp15) -;_GetSpriteVBuffAddrTmp -; sta tmp15 -; tya -; clc -; adc #NUM_BUFF_LINES ; The virtual buffer has 24 lines of off-screen space -; xba ; Each virtual scan line is 256 bytes wide for overdraw space -; clc -; adc tmp15 -; rts - ; Precalculate some cached values for a sprite. These are *only* to make other part of code, ; specifically the draw/erase routines more efficient. ; diff --git a/src/Sprite2.s b/src/Sprite2.s index 0500bad..4d131e0 100644 --- a/src/Sprite2.s +++ b/src/Sprite2.s @@ -1,20 +1,9 @@ ; Scratch space to lay out idealized _MakeDirtySprite ; On input, X register = Sprite Array Index -;Left equ tmp1 -;Right equ tmp2 -;Top equ tmp3 -;Bottom equ tmp4 -;Origin equ tmp4 -;TileTop equ tmp5 RowTop equ tmp6 AreaIndex equ tmp7 - -;TileLeft equ tmp8 -;ColLeft equ tmp9 - -SpriteBit equ tmp10 ; set the bit of the value that if the current sprite index -; VBuffOrigin equ tmp11 +SpriteBit equ tmp8 ; set the bit of the value that if the current sprite index ; Table of pre-multiplied vbuff strides vbuff_mul @@ -48,7 +37,7 @@ vbuff_mul ; 8 10 2 8 ; ... ; -; For the Y-coordinate, we just use "mod 8" instead of "mod 4" +; For the Y-coordinate, we use "mod 8" instead of "mod 4" ; ; When this subroutine is completed, the following values will be calculated ; @@ -68,12 +57,14 @@ _CalcDirtySprite lda _Sprites+IS_OFF_SCREEN,y ; Check if the sprite is visible in the playfield bne mdsOut2 -; Copy the current values into the old value slots - - lda _Sprites+TS_COVERAGE_SIZE,y - sta _Sprites+OLD_TS_COVERAGE_SIZE,y - lda _Sprites+TS_LOOKUP_INDEX,y - sta _Sprites+OLD_TS_LOOKUP_INDEX,y +; Part 1: Calculate the visible tiles that the sprite covers. If the sprite is partially +; off-screen, then the visible tiles may be different than the set of tiles +; covered by the sprite. In particular, the upper-left corner tile which defines +; relative offset values will change. +; +; So, we do some calculations with the CLIPPED values and some with the actual +; sprite values. There is an optimization opportunity here to share calculations +; when the x or y position of the sprite is positive. ; Add the first visible row of the sprite to the Y-scroll offset to find the first line in the ; code field that needs to be drawn. The range of values is 0 to 199+207 = [0, 406]. This @@ -113,7 +104,6 @@ _CalcDirtySprite pha and #$FFFC lsr ; Even numbers from [0, 160] (81 elements) - sta tmp3 adc RowTop sta _Sprites+TS_LOOKUP_INDEX,y ; This is the index into the TileStoreLookup table @@ -131,15 +121,39 @@ _CalcDirtySprite sta _Sprites+TS_COVERAGE_SIZE,y ; Save this value as a key to the coverage size of the sprite -; Calculate the VBUFF offset based on the actual (signed) sprite position +; Part 2: Redo some calculation with the actual (signed) sprite positions that take into +; account negative coordinates to set the VBuff offset values. + + clc + lda _Sprites+SPRITE_Y,y + adc StartYMod208 + bpl :y_ok + clc + adc #208 ; Wrap the actual coordinat around +:y_ok and #$FFF8 ; mask first to ensure LSR will clear the carry + lsr + lsr + tax ; Tile store lookup index + + lda _Sprites+SPRITE_X,y + adc StartXMod164 + bpl :x_ok + clc + adc #164 +:x_ok and #$FFFC + lsr ; Even numbers from [0, 160] (81 elements) + sta tmp3 + adc TileStoreLookupYTable,x + pha ; will be PLX later clc ; Carry should still be clear here.... lda StartYMod208 - and #$0007 adc _Sprites+SPRITE_Y,y - bmi :neg_y + bpl :pos_y + clc + adc #208 +:pos_y and #$0007 -:neg_y asl ; Multiply by 48. Would be nice to use a asl ; table lookup, but the values can be negative asl ; so do the calculation @@ -158,11 +172,12 @@ _CalcDirtySprite clc lda StartXMod164 - and #$0003 adc _Sprites+SPRITE_X,y - bmi :neg_x + bpl :pos_x + clc + adc #164 +:pos_x and #$0003 -:neg_x clc adc tmp0 ; add to the vertical offset @@ -185,7 +200,8 @@ _CalcDirtySprite adc VBuffHorzTableSelect,x ; A bunch of 0, 4 or 8 values clc adc #VBuffArray - ldx _Sprites+TS_LOOKUP_INDEX,y + plx +; ldx _Sprites+TS_LOOKUP_INDEX,y sec sbc TileStoreLookup,x sta tmp1 ; Spill this value to direct page temp space @@ -193,6 +209,7 @@ _CalcDirtySprite ; Last task. Since we don't need to use the X-register to cache values; load the direct page 2 ; offset for the SPRITE_VBUFF_PTR and save it +tmp_out tya ora #$100 tax @@ -254,35 +271,17 @@ ROW equ TILE_STORE_WIDTH*2 ; This many bytes to the nex COL equ 2 ; This many bytes for each element :mark1x1 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y ; get the address of this sprite's vbuff values -; lda _Sprites+TS_VBUFF_BASE,y ; get the starting vbuff address -; sta: {0*ROW}+{0*COL},x ; Put in the vbuff address - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2} rts :mark1x2 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{1*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+2 rts :mark1x3 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{1*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{2*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+2 @@ -290,28 +289,12 @@ COL equ 2 ; This many bytes for each e rts :mark2x1 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_ROW_BYTES -; sta: {1*ROW}+{0*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 1*{TS_LOOKUP_SPAN*2}+0 rts :mark2x2 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{1*COL},x -; adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{1*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+2 @@ -320,20 +303,6 @@ COL equ 2 ; This many bytes for each e rts :mark2x3 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{1*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{2*COL},x -; adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES} -; sta: {1*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{1*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{2*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+2 @@ -344,14 +313,6 @@ COL equ 2 ; This many bytes for each e rts :mark3x1 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_ROW_BYTES -; sta: {1*ROW}+{0*COL},x -; adc #VBUFF_TILE_ROW_BYTES -; sta: {2*ROW}+{0*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 1*{TS_LOOKUP_SPAN*2}+0 @@ -359,20 +320,6 @@ COL equ 2 ; This many bytes for each e rts :mark3x2 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{1*COL},x -; adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{1*COL},x -; adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES -; sta: {2*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {2*ROW}+{1*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+2 @@ -383,26 +330,6 @@ COL equ 2 ; This many bytes for each e rts :mark3x3 -; ldx _Sprites+VBUFF_ARRAY_ADDR,y -; lda _Sprites+TS_VBUFF_BASE,y -; sta: {0*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{1*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {0*ROW}+{2*COL},x -; adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES} -; sta: {1*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{1*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {1*ROW}+{2*COL},x -; adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES} -; sta: {2*ROW}+{0*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {2*ROW}+{1*COL},x -; adc #VBUFF_TILE_COL_BYTES -; sta: {2*ROW}+{2*COL},x - ldx _Sprites+TS_LOOKUP_INDEX,y TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+2 diff --git a/src/static/TileStoreDefs.s b/src/static/TileStoreDefs.s index a4ec69f..1e5ada2 100644 --- a/src/static/TileStoreDefs.s +++ b/src/static/TileStoreDefs.s @@ -50,32 +50,18 @@ VBUFF_ADDR equ {MAX_SPRITES*8} ; Base address of the sprite's ; These values are cached / calculated during the rendering process TS_LOOKUP_INDEX equ {MAX_SPRITES*10} ; The index from the TileStoreLookup table that corresponds to the top-left corner of the sprite TS_COVERAGE_SIZE equ {MAX_SPRITES*12} ; Representation of how many TileStore tiles (NxM) are covered by this sprite -OLD_TS_LOOKUP_INDEX equ {MAX_SPRITES*14} ; Copy of the values to support diffing -OLD_TS_COVERAGE_SIZE equ {MAX_SPRITES*16} -SPRITE_DISP equ {MAX_SPRITES*18} ; Cached address of the specific stamp based on sprite flags -SPRITE_CLIP_LEFT equ {MAX_SPRITES*20} -SPRITE_CLIP_RIGHT equ {MAX_SPRITES*22} -SPRITE_CLIP_TOP equ {MAX_SPRITES*24} -SPRITE_CLIP_BOTTOM equ {MAX_SPRITES*26} -IS_OFF_SCREEN equ {MAX_SPRITES*28} -SPRITE_WIDTH equ {MAX_SPRITES*30} -SPRITE_HEIGHT equ {MAX_SPRITES*32} -SPRITE_CLIP_WIDTH equ {MAX_SPRITES*34} -SPRITE_CLIP_HEIGHT equ {MAX_SPRITES*36} -TS_VBUFF_BASE equ {MAX_SPRITES*38} ; Finalized VBUFF address based on the sprite position and tile offsets -VBUFF_ARRAY_ADDR equ {MAX_SPRITES*40} ; Fixed address where this sprite's VBUFF addresses are stores. The array is the same shape as TileStore, but much smaller -;TILE_DATA_OFFSET equ {MAX_SPRITES*2} -;TILE_STORE_ADDR_1 equ {MAX_SPRITES*12} -;TILE_STORE_ADDR_2 equ {MAX_SPRITES*14} -;TILE_STORE_ADDR_3 equ {MAX_SPRITES*16} -;TS_VBUFF_BASE_ADDR equ {MAX_SPRITES*16} ; Fixed address of the TS_VBUFF_X memory locations -;TILE_STORE_ADDR_4 equ {MAX_SPRITES*18} -;TILE_STORE_ADDR_5 equ {MAX_SPRITES*20} -;TILE_STORE_ADDR_6 equ {MAX_SPRITES*22} -;TILE_STORE_ADDR_7 equ {MAX_SPRITES*24} -;TILE_STORE_ADDR_8 equ {MAX_SPRITES*26} -;TILE_STORE_ADDR_9 equ {MAX_SPRITES*28} -;TILE_STORE_ADDR_10 equ {MAX_SPRITES*30} +SPRITE_DISP equ {MAX_SPRITES*14} ; Cached address of the specific stamp based on sprite flags +SPRITE_CLIP_LEFT equ {MAX_SPRITES*16} +SPRITE_CLIP_RIGHT equ {MAX_SPRITES*18} +SPRITE_CLIP_TOP equ {MAX_SPRITES*20} +SPRITE_CLIP_BOTTOM equ {MAX_SPRITES*22} +IS_OFF_SCREEN equ {MAX_SPRITES*24} +SPRITE_WIDTH equ {MAX_SPRITES*26} +SPRITE_HEIGHT equ {MAX_SPRITES*28} +SPRITE_CLIP_WIDTH equ {MAX_SPRITES*30} +SPRITE_CLIP_HEIGHT equ {MAX_SPRITES*32} +TS_VBUFF_BASE equ {MAX_SPRITES*34} ; Finalized VBUFF address based on the sprite position and tile offsets +VBUFF_ARRAY_ADDR equ {MAX_SPRITES*36} ; Fixed address where this sprite's VBUFF addresses are stores. The array is the same shape as TileStore, but much smaller ; 52 rows by 82 columns + 2 extra rows and columns for sprite sizes ; diff --git a/src/tiles/FastRenderer.s b/src/tiles/FastRenderer.s index aed1eae..00b46af 100644 --- a/src/tiles/FastRenderer.s +++ b/src/tiles/FastRenderer.s @@ -38,7 +38,7 @@ FastTileProcs dw _TBCopyDataFast,_TBCopyDataFast,_TBCopyDataFast,_TBCopyDataFa SpriteDispatch txy - SpriteBitsToVBuffAddrs OneSpriteFast;TwoSpritesFast;ThreeSpritesFast;ThreeSpritesFast + SpriteBitsToVBuffAddrs OneSpriteFast;TwoSpritesFast;ThreeSpritesFast;FourSpritesFast ; Where there are sprites involved, the first step is to call a routine to copy the ; tile data into a temporary buffer. Then the sprite data is merged and placed into @@ -177,37 +177,58 @@ ThreeSpritesFast plb ; Reset to the bank in the top byte of CODE_ADDR_HIGH rts - +FourSpriteLine mac +; and [sprite_ptr3],y + db $37,sprite_ptr3 + ora (sprite_ptr3),y +; and [sprite_ptr2],y + db $37,sprite_ptr2 + ora (sprite_ptr2),y +; and [sprite_ptr1],y + db $37,sprite_ptr1 + ora (sprite_ptr1),y +; and [sprite_ptr0],y + db $37,sprite_ptr0 + ora (sprite_ptr0),y + <<< FourSpritesFast -; tyx -; lda TileStore+TS_TILE_ADDR,y -; per :-1 -; jmp (TileStore+TS_BASE_TILE_COPY,x) ; Copy the tile data to the temporary buffer -;: -; lda TileStore+TS_VBUFF_ADDR_0,y ; address of the sprite data -; sta spritedata_0 -; sta spritemask_0 -; lda TileStore+TS_VBUFF_ADDR_1,y -; sta spritedata_1 -; sta spritemask_1 -; lda TileStore+TS_VBUFF_ADDR_2,y -; sta spritedata_2 -; sta spritemask_2 - + ldx TileStore+TS_TILE_ADDR,y lda TileStore+TS_CODE_ADDR_HIGH,y ; load the bank of the target code field line - pha ; and put on the stack for later. - lda TileStore+TS_CODE_ADDR_LOW,y - tay - plb ; set the code field bank + pha ; and put on the stack for later. Has TileStore bank in high byte. + lda TileStore+TS_CODE_ADDR_LOW,y ; load the address of the code field + pha ; Need to pop it later.... -; ThreeSpritesToCodeField 0 -; ThreeSpritesToCodeField 1 -; ThreeSpritesToCodeField 2 -; ThreeSpritesToCodeField 3 -; ThreeSpritesToCodeField 4 -; ThreeSpritesToCodeField 5 -; ThreeSpritesToCodeField 6 -; ThreeSpritesToCodeField 7 + sep #$20 ; set the sprite data bank + lda #^spritedata + pha + plb + rep #$20 +]line equ 0 + lup 8 + ldy #{]line*SPRITE_PLANE_SPAN} + ldal tiledata+{]line*4},x + FourSpriteLine + sta tmp_tile_data+{]line*4} + + ldy #{]line*SPRITE_PLANE_SPAN}+2 + ldal tiledata+{]line*4}+2,x + FourSpriteLine + sta tmp_tile_data+{]line*4}+2 +]line equ ]line+1 + --^ + + ply ; Pop off CODE_ADDR_LOW + plb ; Set the CODE_ADDR_HIGH bank + +]line equ 0 + lup 8 + lda tmp_tile_data+{]line*4} + sta: $0004+{]line*$1000},y + lda tmp_tile_data+{]line*4}+2 + sta: $0001+{]line*$1000},y +]line equ ]line+1 + --^ + plb ; Reset to the bank in the top byte of CODE_ADDR_HIGH rts \ No newline at end of file