Lite render mode bugfixes

This commit is contained in:
Lucas Scharenbroich 2023-06-26 11:21:05 -05:00
parent 94dafd2093
commit 2013771524
10 changed files with 345 additions and 28 deletions

View File

@ -212,8 +212,8 @@ lite_base EXT
ldy #lite_base
:loop2
lda BTableHigh ; This is the same value for the lite blitter
sta BRowTableHigh+2,x
sta BRowTableHigh+{26*2}+2,x
sta BRowTableHigh,x
sta BRowTableHigh+{26*2},x
tya
sta BRowTableLow,x

View File

@ -631,12 +631,8 @@ _RenderLite
sta RenderFlags
jsr _DoTimers ; Run any pending timer tasks
; brk $65
jsr _ApplyBG0YPosLite ; Set stack addresses for the virtual lines to the physical screen
; brk $66
jsr _ApplyBG0XPosPre ; Lock in certain rendering variables (not lite/non-lite specific)
; brk $67
jsr _UpdateBG0TileMap ; and the tile maps. These subroutines build up a list of tiles
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
@ -652,7 +648,7 @@ _RenderLite
; jsr _DrawObjShadow ; Draw the background
; jsr _DrawDirectSprites ; Draw the sprites directly to the Bank $01 graphics buffer (skipping the render-to-tile step)
;
; jsr _ShadowOn ; Turn shadowing back on
jsr _ShadowOn ; Turn shadowing back on
;
; jsr _DrawFinalPass

View File

@ -125,7 +125,8 @@ InitTiles
bra :out
:fast
lda #0 ; Initialize with Tile 0
ldy #FastProcs
; ldy #FastProcs
ldy #LiteProcs
jsr _SetTileProcs
bra :out
@ -275,7 +276,8 @@ _SetNormalTileProcs
; the tile priority bit is set, and whether this is the special tile 0 or not.
:setTileFast
pla ; Throw away tile ID copy
ldy #FastProcs
; ldy #FastProcs
ldy #LiteProcs
pla
jmp _SetTileProcs
@ -465,6 +467,22 @@ FastCopyTmpDataA
plb
rts
LiteCopyTmpDataA
pei USER_TILE_CODE_PTR+2
ldy USER_TILE_CODE_PTR
plb
]line equ 0
lup 8
lda tmp_tile_data+{]line*4}
sta: $0004+{]line*_LINE_SIZE},y
lda tmp_tile_data+{]line*4}+2
sta: $0001+{]line*_LINE_SIZE},y
]line equ ]line+1
--^
plb
rts
; X = Tile Store offset
; Y = Engine Mode Base Table address
; A = Table proc index
@ -544,6 +562,18 @@ FastUnderZV dw ConstTile0Fast,SpriteUnder0Fast,SpriteUnder0Fast
FastUnderNA dw CopyTileAFast,SpriteUnderAFast,OneSpriteFastUnderA
FastUnderNV dw CopyTileVFast,SpriteUnderVFast,OneSpriteFastUnderV
; "Lite" procs. For when the engine is in GTE Lite mode. Different
; stride than the "Fast" procs.
LiteProcs
LiteOverZA dw ConstTile0Lite,SpriteOver0Lite,OneSpriteLiteOver0
LiteOverZV dw ConstTile0Lite,SpriteOver0Lite,OneSpriteLiteOver0
LiteOverNA dw CopyTileALite,SpriteOverALite,OneSpriteLiteOverA
LiteOverNV dw CopyTileVLite,SpriteOverVLite,OneSpriteLiteOverV
LiteUnderZA dw ConstTile0Lite,SpriteUnder0Lite,SpriteUnder0Lite
LiteUnderZV dw ConstTile0Lite,SpriteUnder0Lite,SpriteUnder0Lite
LiteUnderNA dw CopyTileALite,SpriteUnderALite,OneSpriteLiteUnderA
LiteUnderNV dw CopyTileVLite,SpriteUnderVLite,OneSpriteLiteUnderV
; "Slow" procs. These are duplicates of the "Fast" functions, but also
; set the PEA opcode in all cases.
SlowProcs

View File

@ -1120,6 +1120,7 @@ _TSEnableBackground
put SpriteRender.s
put Render.s
put render/Render.s
put render/Lite.s
put render/Fast.s
put render/Slow.s
put render/Dynamic.s

View File

@ -17,6 +17,8 @@ _BltRangeLite
:exit_ptr equ tmp0
:jmp_low_save equ tmp2
phb
clc
dey
tya ; Get the address of the line that we want to return from
@ -52,7 +54,11 @@ _BltRangeLite
php ; save the current processor flags
sep #$20 ; run the lite blitter in 8-bit accumulator mode
brk $99
lda :exit_ptr+2 ; set the bank to the code field
pha
plb
sei ; disable interrupts
_R0W1
tsx ; save the stack pointer in Y
@ -72,4 +78,6 @@ blt_return_lite ENT
ldy #_EXIT_EVEN+1
lda :jmp_low_save
sta [:exit_ptr],y
plb
rts

View File

@ -81,7 +81,7 @@ _RestoreBG0OpcodesAltLite
sta :exit_address
sec
CopyXToYPrep :do_restore
CopyXToYPrep :do_restore;:draw_count_x6
ldx :low_save_addr
ldy :exit_address
@ -300,7 +300,7 @@ _ApplyBG0XPosAltLite
ldal BTableLow,x ; Get the address of the code field line
sta :base_address ; Will use this address a few times
adc #_ENTRY_JMP ; Add the offsets in order to get absolaute addresses
adc #_ENTRY_JMP ; Add the offsets in order to get absolute addresses
sta :entry_jmp_addr
adc #{_LOW_SAVE-_ENTRY_JMP}
sta :low_save_addr
@ -314,8 +314,8 @@ _ApplyBG0XPosAltLite
; then overwrite it with the branch instruction.
sec ; These macros preform subtractions that do not underflow
CopyXToYPrep :do_save_entry_e
LiteSetConstPrep :do_set_bra_e
CopyXToYPrep :do_save_entry_e;:draw_count_x6
LiteSetConstPrep :do_set_bra_e;:draw_count_x3
stal :do_setopcode_e+1
stal :do_set_rel_e+1
@ -358,6 +358,7 @@ _ApplyBG0XPosAltLite
txa ; StartXMod164 - 1
clc
adc ScreenWidth
cmp #164 ; Keep the value in range
bcc *+5
sbc #164
@ -429,9 +430,9 @@ _ApplyBG0XPosAltLite
; Setup the jumps into the unrolled loops
sec
CopyXToYPrep :do_save_entry_o
CopyXToYPrep :do_save_entry_o;:draw_count_x6
stal :do_save_high_byte+1
LiteSetConstPrep :do_set_bra_o
LiteSetConstPrep :do_set_bra_o;:draw_count_x3
stal :do_setopcode_o+1
stal :do_set_rel_o+1
stal :do_odd_code_entry+1
@ -453,7 +454,7 @@ _ApplyBG0XPosAltLite
ldy :low_save_addr
:do_save_entry_o jsr $0000 ; Save the low word of the exit into a save location for restore later
ldx :exit_address
ldy :exit_address
lda :exit_bra
:do_set_bra_o jsr $0000 ; Insert a BRA instruction over the saved word
@ -623,7 +624,7 @@ _ApplyScanlineBG0XPosLite
; X = value
CopyXToYPrep mac
lda #x2y_bottom
sbc blttmp+10 ; Copy from above, :draw_count_x6 equ blttmp+10
sbc ]2 ; count_x6
stal ]1+1 ; A jmp/jsr instruction
<<<
]line equ 199
@ -639,7 +640,7 @@ x2y_bottom rts
; Y = code field offset
LiteSetConstPrep mac
lda #lsc_bottom
sbc blttmp+8 ; Copy from above, :draw_count_x3 equ blttmp+8
sbc ]2 ; count_x3
stal ]1+1 ; A jmp/jsr instruction
<<<

View File

@ -36,7 +36,7 @@ lite_entry_jmp brl $0000 ; If the screen is odd-align
; relative offset of the instruction field in the register
; and falls through to the next instruction.
lda: $0001,x ; Get the low byte and push onto the stack
lda: *+1,x ; Get the low byte and push onto the stack
pha
lite_odd_entry brl $0000 ; unconditionally jump into the "next" instruction in the
; code field. This is OK, even if the entry point was the
@ -74,7 +74,7 @@ lite_loop_exit_3 jmp lite_even_exit ; +255
mx %10
lite_odd_exit lda #0 ; get the high byte of the saved PEA operand (odd-case is already in 8-bit mode)
pha
lite_even_exit jmp $0000 ; Jump to the next line.
lite_even_exit jmp *+5 ; Jump to the next line.
dfb $F4,$00 ; low-word of the saved PEA instruction
; Now repeat the code above 207 more times. Loop 206 times and then manually do the last one
@ -83,7 +83,7 @@ lite_even_exit jmp $0000 ; Jump to the next line.
ldx #0000
txs
dfb $82,$00,$00
lda: 1,x
lda: *+1,x
pha
dfb $82,$00,$00
@ -198,7 +198,7 @@ lite_even_exit jmp $0000 ; Jump to the next line.
mx %10
lda #0
pha
jmp $0000
jmp *+5
dfb $F4,$00
]line equ ]line+1
--^
@ -206,7 +206,7 @@ lite_even_exit jmp $0000 ; Jump to the next line.
:entry_207 ldx #0000
txs
dfb $82,$00,$00 ; brl $0000 starts at the next instruction
lda: 1,x
lda: *+1,x
sep #$20
pha
dfb $82,$00,$00

View File

@ -284,7 +284,6 @@ CopyTileAFast
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated)
plb
tax
_CopyTileAFast
]line equ 0

282
src/render/Lite.s Normal file
View File

@ -0,0 +1,282 @@
; Collection of render function used when the engine is in "GTE Lite" mode. In this mode
; there are no dynamic tile or two layer tiles enabled, so all of the tiles are comprised
; of PEA opcodes. These functions take advantage of this and the fact that masks are
; not needed to improve rendering speed.
;
; The GTE Lite mode uses a compact code field that fits in a single bank of memory, so
; all of the rendering routines are basically the same as those in Fast.s, but use a
; different stride.
SpriteUnder0Lite
ConstTile0Lite
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
plb
lda #0
]line equ 0
lup 8
sta: {_LINE_SIZE*]line}+$0001,y
sta: {_LINE_SIZE*]line}+$0004,y
]line equ ]line+1
--^
plb
rts
SpriteOverALite
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
lda TileStore+TS_TILE_ADDR,x
tax
plb
_SpriteOverALite
]line equ 0
lup 8
ldal tiledata+{]line*4},x
and tmp_sprite_mask+{]line*4}
ora tmp_sprite_data+{]line*4}
sta: $0004+{]line*_LINE_SIZE},y
ldal tiledata+{]line*4}+2,x
and tmp_sprite_mask+{]line*4}+2
ora tmp_sprite_data+{]line*4}+2
sta: $0001+{]line*_LINE_SIZE},y
]line equ ]line+1
--^
plb
rts
SpriteOverVLite
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
lda TileStore+TS_TILE_ADDR,x
tax
plb
_SpriteOverVLite
]src equ 7
]dest equ 0
lup 8
ldal tiledata+{]src*4},x
and tmp_sprite_mask+{]dest*4}
ora tmp_sprite_data+{]dest*4}
sta: $0004+{]dest*_LINE_SIZE},y
ldal tiledata+{]src*4}+2,x
and tmp_sprite_mask+{]dest*4}+2
ora tmp_sprite_data+{]dest*4}+2
sta: $0001+{]dest*_LINE_SIZE},y
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts
SpriteOver0Lite
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
plb
_SpriteOver0Lite
]line equ 0
lup 8
lda tmp_sprite_data+{]line*4}
sta: $0004+{]line*_LINE_SIZE},y
lda tmp_sprite_data+{]line*4}+2
sta: $0001+{]line*_LINE_SIZE},y
]line equ ]line+1
--^
plb
rts
SpriteUnderALite
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
lda TileStore+TS_TILE_ADDR,x
tax
plb
_SpriteUnderALite
]line equ 0
lup 8
lda tmp_sprite_data+{]line*4}
andl tiledata+{]line*4}+32,x
oral tiledata+{]line*4},x
sta: $0004+{]line*_LINE_SIZE},y
lda tmp_sprite_data+{]line*4}+2
andl tiledata+{]line*4}+32+2,x
oral tiledata+{]line*4}+2,x
sta: $0001+{]line*_LINE_SIZE},y
]line equ ]line+1
--^
plb
rts
SpriteUnderVLite
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
lda TileStore+TS_TILE_ADDR,x
tax
plb
_SpriteUnderVLite
]src equ 7
]dest equ 0
lup 8
lda tmp_sprite_data+{]dest*4}
andl tiledata+{]src*4}+32,x
oral tiledata+{]src*4},x
sta: $0004+{]dest*_LINE_SIZE},y
lda tmp_sprite_data+{]dest*4}+2
andl tiledata+{]src*4}+32+2,x
oral tiledata+{]src*4}+2,x
sta: $0001+{]dest*_LINE_SIZE},y
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts
CopyTileALite
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
lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated)
plb
tax
; brk $ac
_CopyTileALite
]line equ 0
lup 8
ldal tiledata+{]line*4},x
sta: $0004+{]line*_LINE_SIZE},y
ldal tiledata+{]line*4}+2,x
sta: $0001+{]line*_LINE_SIZE},y
]line equ ]line+1
--^
plb
rts
CopyTileVLite
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
lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated)
plb
tax
_CopyTileVLite
]src equ 7
]dest equ 0
lup 8
ldal tiledata+{]src*4},x
sta: $0004+{]dest*_LINE_SIZE},y
ldal tiledata+{]src*4}+2,x
sta: $0001+{]dest*_LINE_SIZE},y
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts
OneSpriteLiteOver0
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
_OneSpriteLiteOver0
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
sta: $0004+{]line*_LINE_SIZE},y
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
sta: $0001+{]line*_LINE_SIZE},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
OneSpriteLiteOverV
jsr FastCopyTileDataV
bra _OneSpriteLiteOver
OneSpriteLiteOverA
jsr FastCopyTileDataA
_OneSpriteLiteOver
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
_OneSpriteLiteOverA
_OneSpriteLiteOverV
]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*_LINE_SIZE},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*_LINE_SIZE},y
]line equ ]line+1
--^
plb
rts
OneSpriteLiteUnderA
jsr FastCopyTileDataAndMaskA
bra _OneSpriteLiteUnder
OneSpriteLiteUnderV
jsr FastCopyTileDataAndMaskV
_OneSpriteLiteUnder
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
_OneSpriteLiteUnderA
_OneSpriteLiteUnderV
]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*_LINE_SIZE},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*_LINE_SIZE},y
]line equ ]line+1
--^
plb
rts

View File

@ -1,8 +1,8 @@
This folder contains the rendering tuples for the different type of tile rendering modes
that are defined by both the engine mode and the specific tile attributes. There are
a *lot* or variants, so they are cataloged here.
a *lot* of variants, so they are cataloged here.
The top-level TileRender function in the main entry point that defined the overal tile render
The top-level TileRender function in the main entry point that defines the overal tile render
flow as well as the register parameters and calling conventions for each of the modular
components.
@ -50,7 +50,7 @@ There are 5 pluggable functions that make up a rendering mode
4. K_TS_COPY_TILE_DATA & K_TS_APPLY_TILE_DATA
A pair of function that copye tile data (and possible mask information) into a temporary
A pair of function that copy tile data (and possible mask information) into a temporary
direct page space and then render that workspace into the code field.
These functions are used as building blocks by the generic Over/Under multi-sprite