Restore BG1 rotation code

This commit is contained in:
Lucas Scharenbroich 2022-07-12 21:03:30 -05:00
parent d7c0577167
commit 4506f808c9
12 changed files with 124 additions and 116 deletions

View File

@ -114,6 +114,9 @@ _GTERefresh MAC
_GTERenderDirty MAC
UserTool $2700+GTEToolNum
<<<
_GTESetBG1Rotation MAC
UserTool $2800+GTEToolNum
<<<
; EngineMode definitions
; Script definition

View File

@ -257,6 +257,7 @@ _stamp_step EXT
VBuffVertTableSelect EXT
VBuffHorzTableSelect EXT
Overlays EXT
BG1YCache EXT
; Tool error codes
NO_TIMERS_AVAILABLE equ 10

View File

@ -36,3 +36,10 @@
KND #$1001 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
ALI BANK
SNA TSTORE
; 64KB Rotation Data Tables
ASM RotData.s
KND #$1001 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
ALI BANK
SNA ROTDATA

View File

@ -31,7 +31,7 @@ _Render
stz SpriteRemovedFlag ; If we remove a sprite, then we need to flag a rebuild for the next frame
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
jsr _ApplyBG1YPos
; jsr _ApplyBG1YPos
; _ApplyBG0Xpos need to be split because we have to set the offsets, then draw in any updated tiles, and
; finally patch out the code field. Right now, the BRA operand is getting overwritten by tile data.
@ -46,7 +46,7 @@ _Render
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode
jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position
; jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position
; The code fields are locked in now and ready to be rendered. See if there is an overlay or any
; other reason to render with shadowing off. Otherwise, just do things quickly.

View File

@ -91,6 +91,8 @@ _CallTable
adrl _TSFillTileStore-1
adrl _TSRefresh-1
adrl _TSRenderDirty-1
adrl _TSSetBG1Rotation-1
_CTEnd
_GTEAddSprite MAC
UserTool $1000+GTEToolNum
@ -708,6 +710,31 @@ _TSRefresh
jsr _Refresh
_TSExit #0;#0
; SetBG1Rotation(rotIndex)
_TSSetBG1Rotation
:rotIndex equ FirstParam+0
x_angles EXT
y_angles EXT
_TSEntry
lda :rotIndex,s
and #$003F ; only 64 angles to choose from
asl
tax
ldal x_angles,x ; load the address of addresses for this angle
tay
phx
jsr _ApplyBG1XPosAngle
plx
ldal y_angles,x ; load the address of addresses for this angle
tay
jsr _ApplyBG1YPosAngle
_TSExit #0;#2
; Insert the GTE code
put Math.s
@ -736,9 +763,7 @@ _TSRefresh
put blitter/Vert.s
put blitter/BG0.s
put blitter/BG1.s
put blitter/Rotation.s
put blitter/Template.s
put blitter/TemplateUtils.s
put blitter/Blitter.s
put blitter/TileProcs.s
put blitter/Tiles00000.s
; put blitter/Tiles.s

View File

@ -492,5 +492,3 @@ ApplyBG1OffsetValues
:do01 ldal BG1YCache+00
sta: BG1_ADDR+$0000,y
:none rts
BG1YCache ds 32

View File

@ -2,38 +2,15 @@
; into an addition of two function parametertized by the angle of rotation: pixel = *(f(x, a) + f(y, a))
;
; The pre-build a number of rotation tables and then populate the direct page values and Y-register values
; for each line of the blitter, such that a single lda (00),y instruction fetched the appropriate data
; for each line of the blitter, such that a single lda (00),y instruction fetches the appropriate data
;
; This is about as fast of a rotation as we can do.
;
; When possible, off-screen locations are calculate to produce an address of $FFFE, so that the last two bytes
; of the BG1 data buffer provides the "fill value".
ANGLEBNK ext
ANGLEBNK EXT
_ApplyBG1XPosAngle
; phy
; lda BG1StartX
; jsr Mod164
; sta BG1StartXMod164
; lda #162
; sec
; sbc StartXMod164
; bpl *+6
; clc
; adc #164
; clc
; adc BG1StartXMod164
; cmp #164
; bcc *+5
; sbc #164
; clc
; adc 1,s
; tay ; cache the value
; pla ; pop the value
phd ; save the direct page because we are going to switch to the
lda BlitterDP ; blitter direct page space and fill in the addresses
tcd
@ -63,9 +40,7 @@ _ApplyBG1YPosAngle
sty :angle_tbl
lda BG1StartY
jsr Mod208
sta BG1StartYMod208
lda BG1StartYMod208
sta :ytbl_idx ; Start copying from the first entry in the table
lda StartYMod208 ; This is the base line of the virtual screen
@ -136,14 +111,12 @@ _ApplyBG1YPosAngle
; Y = starting line * $1000
; X = number of lines (x2)
CopyAngleYTableToBG1Addr
; tax
; ldal ANGLEBNK+XX,x
; sta BG1_ADDR+$F000,y
phx
phb
jsr _SetDataBank ; restore access to this bank
jsr SaveBG1AngleValues
plb
plx ; x is used directly in this routine
jmp ApplyBG1OffsetValues
@ -172,37 +145,37 @@ SaveBG1AngleValues
bra :x08
:do16 tax
ldal ANGLEBNK+06,x
sta BG1YCache+30
stal BG1YCache+30
:x15 ldal ANGLEBNK+06,x
sta BG1YCache+28
stal BG1YCache+28
:x14 ldal ANGLEBNK+06,x
sta BG1YCache+26
stal BG1YCache+26
:x13 ldal ANGLEBNK+06,x
sta BG1YCache+24
stal BG1YCache+24
:x12 ldal ANGLEBNK+04,x
sta BG1YCache+22
stal BG1YCache+22
:x11 ldal ANGLEBNK+04,x
sta BG1YCache+20
stal BG1YCache+20
:x10 ldal ANGLEBNK+04,x
sta BG1YCache+18
stal BG1YCache+18
:x09 ldal ANGLEBNK+04,x
sta BG1YCache+16
stal BG1YCache+16
:x08 ldal ANGLEBNK+02,x
sta BG1YCache+14
stal BG1YCache+14
:x07 ldal ANGLEBNK+02,x
sta BG1YCache+12
stal BG1YCache+12
:x06 ldal ANGLEBNK+02,x
sta BG1YCache+10
stal BG1YCache+10
:x05 ldal ANGLEBNK+02,x
sta BG1YCache+08
stal BG1YCache+08
:x04 ldal ANGLEBNK+00,x
sta BG1YCache+06
stal BG1YCache+06
:x03 ldal ANGLEBNK+00,x
sta BG1YCache+04
stal BG1YCache+04
:x02 ldal ANGLEBNK+00,x
sta BG1YCache+02
stal BG1YCache+02
:x01 ldal ANGLEBNK+00,x
sta BG1YCache+00
stal BG1YCache+00
:none rts
:do07 tax
bra :x07

View File

@ -25,63 +25,6 @@ _TBSolidTile_VH
jsr _TBCopyDataV
jmp _TBFillPEAOpcode
; The workhorse blitter. This blitter copies tile data into the code field without masking. This is the
; most common blitter function. It is slightly optimized to fall through to the code that sets the PEA
; opcodes in order to be slightly more efficient given it's frequent usage.
;
; There is a small variation of this blitter that just copies the data without setting the PEA opcodes. This
; is used by the engine when the capabilitiy bits have turned off the second background layer. In fact, most
; of the tile rendering routines have an optimized version for this important use case. Skipping the opcode
; step results in a 37% speed boost in tile rendering.
;
; This does not increase the FPS by 37% because only a small number of tiles are drawn each frame, but it
; has an impact and can significantly help out when sprites trigger more dirty tile updates than normal.
; This is called via a JMP (abs,x) with an extra byte on the stack that holds the bank
; register value. This must be restored prior to returning
CopyTileAFast
tax
_CopyTileAFast
]line equ 0
lup 8
ldal tiledata+{]line*4},x
sta: $0004+{]line*$1000},y
ldal tiledata+{]line*4}+2,x
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
plb
rts
CopyTileASlow
tax
jsr FillPEAOpcode
jmp _CopyTileAFast
CopyTileVFast
tax
_CopyTileVFast
]src equ 7
]dest equ 0
lup 8
ldal tiledata+{]src*4},x
sta: $0004+{]dest*$1000},y
ldal tiledata+{]src*4}+2,x
sta: $0001+{]dest*$1000},y
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts
CopyTileVSlow
tax
jsr FillPEAOpcode
jmp _CopyTileVFast
; Old routines
_TBCopyData
]line equ 0

View File

@ -256,3 +256,49 @@ FastCopyTileDataAndMaskV
plb
rts
; The workhorse blitter. This blitter copies tile data into the code field without masking. This is the
; most common blitter function. It is slightly optimized to fall through to the code that sets the PEA
; opcodes in order to be slightly more efficient given it's frequent usage.
;
; There is a small variation of this blitter that just copies the data without setting the PEA opcodes. This
; is used by the engine when the capabilitiy bits have turned off the second background layer. In fact, most
; of the tile rendering routines have an optimized version for this important use case. Skipping the opcode
; step results in a 37% speed boost in tile rendering.
;
; This does not increase the FPS by 37% because only a small number of tiles are drawn each frame, but it
; has an impact and can significantly help out when sprites trigger more dirty tile updates than normal.
; This is called via a JMP (abs,x) with an extra byte on the stack that holds the bank
; register value. This must be restored prior to returning
CopyTileAFast
tax
_CopyTileAFast
]line equ 0
lup 8
ldal tiledata+{]line*4},x
sta: $0004+{]line*$1000},y
ldal tiledata+{]line*4}+2,x
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
plb
rts
CopyTileVFast
tax
_CopyTileVFast
]src equ 7
]dest equ 0
lup 8
ldal tiledata+{]src*4},x
sta: $0004+{]dest*$1000},y
ldal tiledata+{]src*4}+2,x
sta: $0001+{]dest*$1000},y
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts

View File

@ -83,4 +83,15 @@ FillPEAOpcode
_FillPEAOpcode
jsr FillPEAOpcode
plb ; Restore the TileStore bank
rts
rts
CopyTileASlow
tax
jsr FillPEAOpcode
jmp _CopyTileAFast
CopyTileVSlow
tax
jsr FillPEAOpcode
jmp _CopyTileVFast

View File

@ -506,5 +506,7 @@ _SpriteBitsNot ENT
_stamp_step ENT
dw 0,12,24,36
BG1YCache ENT
ds 32
blt_return
stk_save

View File

@ -35,7 +35,6 @@ SPRITE_REC_SIZE equ 42
; available to the AddSprite function until the next frame.
SPRITE_STATUS_EMPTY equ $0000 ; If the status value is zero, this sprite slot is available
SPRITE_STATUS_OCCUPIED equ $8000 ; Set the MSB to flag it as occupied
SPRITE_STATUS_ADDED equ $0001 ; Sprite was just added (new sprite)
SPRITE_STATUS_MOVED equ $0002 ; Sprite's position was changed
SPRITE_STATUS_UPDATED equ $0004 ; Sprite's non-position attributes were changed