This commit is contained in:
Lucas Scharenbroich 2023-05-02 15:59:35 -05:00
commit 89a56d479e
8 changed files with 35 additions and 115 deletions

View File

@ -117,6 +117,7 @@ extern pascal Word GTEStartScript(Word numTicks, Pointer scriptAddr) inline(0x21
/* GTE Overlay Functions */
extern pascal Word GTESetOverlay(Word top, Word bottom, Pointer procPtr) inline(0x22A0, tool_dispatcher);
extern pascal Word GTEClearOverlay() inline(0x23A0, tool_dispatcher);
extern pascal void GTEUpdateOverlay(Word top, Word bottom, Pointer procPtr) inline(0x2FA0, tool_dispatcher);
/* ReadControl return value bits */
@ -164,7 +165,7 @@ extern pascal Word GTEClearOverlay() inline(0x23A0, tool_dispatcher);
#define TILE_CTRL_MASK 0xFE00
/* GTE Sprite Constants */
#define GTE_SPRITE_COMPILES 0x4000
#define GTE_SPRITE_COMPILED 0x4000
#define GTE_SPRITE_HIDE 0x2000
#define GTE_SPRITE_16X16 0x1800
#define GTE_SPRITE_16X8 0x1000

View File

@ -468,9 +468,10 @@ _RenderWithShadowing
; At this point, everything in the background has been rendered into the code field. Next, we need
; to create priority lists of scanline ranges.
jsr _FilterObjectList ; Walk the sorted list and create an array of objects that need to be rendered
jsr _ShadowOff ; Turn off shadowing and draw all the scanlines with sprites on them
jsr _DrawShadowList
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
@ -500,27 +501,6 @@ _RenderWithShadowing
:no_removal
rts
; Iterate through the shadow list and call _BltRange on each
_DrawShadowList
ldx #0
bra :start
:loop
phx ; Save the index
lda _ShadowListTop,x
ldy _ShadowListBottom,x
tax
jsr _BltRange
plx
inx
inx
:start
cpx _ShadowListCount
bcc :loop
rts
; Run through the list of sprites that are not OFFSCREEN and not OVERLAYS and draw them directly to the graphics screen. We can use
; compiled sprites here, with limitations.
_DrawDirectSprites
@ -724,61 +704,8 @@ _DrawObjShadow
;:empty
; rts
; Split
;
; Y = current item
; X = next item
;
; Compares the bottom values of X and Y. If the current item extends past the next item, then this splits off the
; bottom ortion of Y and inserts it into the appropriate position in the linked list
split
:prev equ tmp15
lda ObjectList+OL_SPRITE_BOTTOM,x ; If the next item is fully within the current one, split
cmp ObjectList+OL_SPRITE_BOTTOM,y
bcc :do_split
rts
:do_split
sta ObjectList+OL_SPRITE_TOP,y ; Set the top of the current item past the bottom of the next item
:split_lp
lda ObjectList+OL_NEXT,x ; search to find the spot in the linked list that we should
bmi :insert_after ; move the fragment forward to
stx :prev
tax
lda ObjectList+OL_SPRITE_TOP,y
cmp ObjectList+OL_SPRITE_TOP,x
bcc :insert_before ; If the modified node's top value is <= the node we are inspecting,
beq :insert_before ; then it can be inserted here
bra :split_lp
:insert_before
ldx :prev
lda ObjectList+OL_NEXT,x
; Insert Y node after X node. A = OL_NEXT,x
:insert_after
sta ObjectList+OL_NEXT,y
tya
sta ObjectList+OL_NEXT,x
tyx
rts
; X = top
; A = bottom
; Preserve X, Y
:_BltRange3
phx
phy
tay
jsr _BltRange
ply
plx
rts
; Helper function to only return object from the sorted list if they are relevant for
; display.
_GetNextItem
cpx #EOL ; early out if we're at the end of the list
bne *+3

View File

@ -428,22 +428,22 @@ UserHook1 rtl
; A = Table proc index
;
; see TileProcTables in static/TileStore.s
tblPtr equ blttmp
_SetTileProcs
:tblPtr equ blttmp
; Multiple the proc index by 6 to get the correct table entry offset
asl
sta tblPtr
sta :tblPtr
asl
adc tblPtr
sta tblPtr
adc :tblPtr
sta :tblPtr
; Add this offset to the base table address
tya
adc tblPtr
sta tblPtr
adc :tblPtr
sta :tblPtr
; Set the pointer to this bank
@ -451,20 +451,20 @@ _SetTileProcs
phk
pla
and #$00FF
sta tblPtr+2
sta :tblPtr+2
; Lookup the tile procedures
ldy #0
lda [tblPtr],y
lda [:tblPtr],y
stal K_TS_BASE_TILE_DISP,x
ldy #2
lda [tblPtr],y
lda [:tblPtr],y
stal K_TS_SPRITE_TILE_DISP,x
ldy #4
lda [tblPtr],y
lda [:tblPtr],y
stal K_TS_ONE_SPRITE,x
rts

View File

@ -746,6 +746,7 @@ _TSSetOverlay
_TSExit #0;#8
; UpdateOverlay(top, bottom, proc)
_TSUpdateOverlay
:proc equ FirstParam+0
:bottom equ FirstParam+4

View File

@ -150,17 +150,17 @@ jmp_rtn_1 jmp l_jmp_rtn-base ; Could inline the code and
; 8 or 16 lines in order to give the system time to handle interrupts.
enable_int ldal stk_save+1 ; restore the stack
tcs
sep #$20 ; 8-bit mode
ldal STATE_REG ; Read Bank 0 / Write Bank 0
and #$CF
sep #$30 ; 8-bit mode
ldal STATE_REG
tax ; Save the value
and #$CF ; Read Bank 0 / Write Bank 0
stal STATE_REG
cli
nop ; Give a couple of cycles
sei
ldal STATE_REG
ora #$10 ; Read Bank 0 / Write Bank 1
txa ; Restore the state
stal STATE_REG
rep #$20
rep #$30
bra entry_1
; This is the spot that needs to be page-aligned. In addition to simplifying the entry address
@ -240,14 +240,14 @@ epilogue_1 tsc
; its passed state, because having the carry bit clear prevents evaluation of
; the V bit.
;
; Version 2: In order to improve performance, especially for two-layer tiles + sprites, the
; snippet code was revised to have a fixed structure so that the constant DATA and
; MASK values always exist in the same location, regarless of the tile type. The
; tradeoff is that there is a different entry point into the snippet based on the
; tile type, but that is significantly cheaper to lookup and patch into the code
; field JMP instruction than it is to rebuild 20+ bytes of code each time.
; In order to improve performance, especially for two-layer tiles + sprites, the
; snippet code has a fixed structure so that the constant DATA and MASK values
; always exist in the same location, regarless of the tile type. The
; tradeoff is that there is a different entry point into the snippet based on the
; tile type, but that is significantly cheaper to lookup and patch into the code
; field JMP instruction than it is to rebuild 20+ bytes of code each time.
;
; There are different snippet templates + offset tables based on the EngineMode
; There are different snippet templates + offset tables based on the EngineMode
;
; EngineMode
;

View File

@ -286,7 +286,7 @@ DynamicOverTwoLyr
; tile blitter in the TwoLayer function set sees that a tile is marked as DAMAGED, it must
; restore the original code structure before proceeding.
;
; The damages area is not too bad -- just the 10 bytes from [2, 10] are overwritten and must be
; The damaged area is not too bad -- just the 10 bytes from [2, 10] are overwritten and must be
; restored. This is actually less work than a lot of the snippet macros were doing before
; applying the fixed snippet optimization.
DynamicUnderTwoLyr

View File

@ -550,7 +550,7 @@ ObjectListCount ENT
ObjectListHead ENT
ds 2
ObjectList ENT
ds {10*{MAX_ELEMENTS+2}} ; Extra space at the end for a sentinel marker
ds {2*{MAX_ELEMENTS+2}} ; Extra space at the end for a sentinel marker
; Steps to the different sprite stamps

View File

@ -15,12 +15,7 @@ TS_WORD_OFFSET equ {TILE_STORE_SIZE*6} ; const value, word offset v
TS_JMP_ADDR equ {TILE_STORE_SIZE*7} ; const value, address of the 32-byte snippet space for this tile
TS_SCREEN_ADDR equ {TILE_STORE_SIZE*8} ; cached value of on-screen location of tile. Used for DirtyRender.
; TODO: Move these arrays into the K bank to support direct dispatch via jmp (abs,x)
; TS_BASE_TILE_COPY equ {TILE_STORE_SIZE*9} ; derived from TS_TILE_ID to optimize tile copy to support sprite rendering
; TS_BASE_TILE_DISP equ {TILE_STORE_SIZE*10} ; derived from TS_TILE_ID to optimize base (non-sprite) tile dispatch in the Render function
; TS_DIRTY_TILE_DISP equ {TILE_STORE_SIZE*11} ; derived from TS_TILE_ID to optimize dirty tile dispatch in the Render function
TILE_STORE_NUM equ 12 ; Need this many parallel arrays
TILE_STORE_NUM equ 9 ; Need this many parallel arrays
; Sprite data structures. We cache quite a few pieces of information about the sprite
; to make calculations faster, so this is hidden from the caller.
@ -28,15 +23,11 @@ TILE_STORE_NUM equ 12 ; Need this many parallel arra
MAX_SPRITES equ 16
SPRITE_REC_SIZE equ 42
MAX_OVERLAYS equ 2
MAX_OVERLAYS equ 3
MAX_ELEMENTS equ {MAX_SPRITES+MAX_OVERLAYS}
; Object list used in renderer
OL_SPRITE_ID equ 0 ; Usual parallel arrays
OL_SPRITE_TOP equ {2*{MAX_ELEMENTS+1}}
OL_SPRITE_BOTTOM equ {4*{MAX_ELEMENTS+1}}
OL_NEXT equ {6*{MAX_ELEMENTS+1}}
OL_INDEX equ {8*{MAX_ELEMENTS+1}} ; Reference to the index in the _Sprites array
OL_INDEX equ {0*{MAX_ELEMENTS+1}} ; Reference to the index in the _Sprites array
; Mark each sprite as ADDED, UPDATED, MOVED, REMOVED depending on the actions applied to it
; on this frame. Quick note, the same Sprite ID cannot be removed and added in the same frame.