iigs-game-engine/src/render/Sprite1.s

266 lines
9.1 KiB
ArmAsm

; Specialized routines that can be assigned to K_TS_ONE_SPRITE for rendering a single sprite into
; a tile. There are more variants of this function because having a single sprite in a tile is a very
; common scenario, so we put additional effort into optimizing this case.
;------------------------------
; Section: Above Tile Renderers
; The simplest implementation. When drawing a sprite over Tile 0 in FAST mode, we can just copy the
; sprite data into the coe field directly.
OneSpriteFastOver0
ldy TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
phy ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
tax ; VBuff address from SpriteBitsToVBuffAddrs macro
plb ; set to the code field bank
_OneSpriteFastOver0
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
sta: $0004+{]line*$1000},y
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
plb ; Restore the TileStore bank
rts
; Next implementation; drawing a sprite onto a regular tile. The 1-sprite dispatch preserves the
; X-register, so it already points to the TileStore
OneSpriteFastOverV
jsr FastCopyTileDataV
bra _OneSpriteFastOver
OneSpriteFastOverA
jsr FastCopyTileDataA
_OneSpriteFastOver
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
ldx sprite_ptr0
plb
_OneSpriteFastOverA
_OneSpriteFastOverV
]line equ 0
lup 8
lda tmp_tile_data+{]line*4}
andl spritemask+{]line*SPRITE_PLANE_SPAN},x
oral spritedata+{]line*SPRITE_PLANE_SPAN},x
sta: $0004+{]line*$1000},y
lda tmp_tile_data+{]line*4}+2
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
plb
rts
; This is the "SLOW" variant that fills in the PEA opcode specialized for Tile 0.
OneSpriteSlowOver0
ldy TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
phy ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
tax ; VBuff address from SpriteBitsToVBuffAddrs macro
plb ; set to the code field bank
jsr FillPEAOpcode
jmp _OneSpriteFastOver0
; Slow variant for regular tile.
OneSpriteSlowOverV
jsr FastCopyTileDataV
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
ldx sprite_ptr0
plb
jsr FillPEAOpcode
jmp _OneSpriteFastOverV
OneSpriteSlowOverA
jsr FastCopyTileDataA
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
ldx sprite_ptr0
plb
jsr FillPEAOpcode
jmp _OneSpriteFastOverA
;------------------------------
; Section: Below Tile Renderers
; Drawing under the zero tile is the same as not drawing a sprite fo both the fast and slow cases
OneSpriteFastUnderA
jsr FastCopyTileDataAndMaskA
bra _OneSpriteFastUnder
OneSpriteFastUnderV
jsr FastCopyTileDataAndMaskV
_OneSpriteFastUnder
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
ldx sprite_ptr0
plb
_OneSpriteFastUnderA
_OneSpriteFastUnderV
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
and tmp_tile_mask+{]line*4}
ora tmp_tile_data+{]line*4}
sta: $0004+{]line*$1000},y
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
and tmp_tile_mask+{]line*4}+2
ora tmp_tile_data+{]line*4}+2
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
plb
rts
OneSpriteSlowUnderA
jsr FastCopyTileDataAndMaskA
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
ldx sprite_ptr0
plb
jsr FillPEAOpcode
jmp _OneSpriteFastUnderA
OneSpriteSlowUnderV
jsr FastCopyTileDataAndMaskV
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
ldx sprite_ptr0
plb
jsr FillPEAOpcode
jmp _OneSpriteFastUnderV
;-------------------------------
; Dynamic tiles with one sprite.
OneSpriteDynamicUnder
txy
tax
jsr _CopySpriteDataToDP
tyx
jmp DynamicUnder
OneSpriteDynamicOver
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp DynamicOver
;-------------------------------
; Two Layer tiles with one sprite. Just copy the data and go through the generic sprite path
OneSpriteOver0TwoLyr
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteOver0TwoLyr
OneSpriteTwoLyrOverA
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteOverATwoLyr
OneSpriteTwoLyrOverV
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteOverVTwoLyr
OneSpriteTwoLyrUnderA
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteUnderATwoLyr
OneSpriteTwoLyrUnderV
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteUnderVTwoLyr
;-----------------------------------------
; Dynamic two-layer tiles with one sprite.
OneSpriteDynamicOverTwoLyr
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp DynamicOverTwoLyr
OneSpriteDynamicUnderTwoLyr
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp DynamicUnderTwoLyr
;-------------------------------------
; Generic helpers
_CopySpriteDataToDP
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
sta tmp_sprite_data+{]line*4}
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
sta tmp_sprite_data+{]line*4}+2
]line equ ]line+1
--^
rts
_CopySpriteMaskToDP
]line equ 0
lup 8
ldal spritemask+{]line*SPRITE_PLANE_SPAN},x
sta tmp_sprite_mask+{]line*4}
ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
sta tmp_sprite_mask+{]line*4}+2
]line equ ]line+1
--^
rts
_CopySpriteDataAndMaskToDP
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
sta tmp_sprite_data+{]line*4}
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
sta tmp_sprite_data+{]line*4}+2
ldal spritemask+{]line*SPRITE_PLANE_SPAN},x
sta tmp_sprite_mask+{]line*4}
ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
sta tmp_sprite_mask+{]line*4}+2
]line equ ]line+1
--^
rts