diff --git a/ORCACDefs/gte.h b/ORCACDefs/gte.h index a46f743..a83704c 100644 --- a/ORCACDefs/gte.h +++ b/ORCACDefs/gte.h @@ -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 diff --git a/src/Render.s b/src/Render.s index 869bf4b..cd2b052 100644 --- a/src/Render.s +++ b/src/Render.s @@ -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 diff --git a/src/Tiles.s b/src/Tiles.s index d109938..040465d 100644 --- a/src/Tiles.s +++ b/src/Tiles.s @@ -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 diff --git a/src/Tool.s b/src/Tool.s index cbdd55b..8559852 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -746,6 +746,7 @@ _TSSetOverlay _TSExit #0;#8 +; UpdateOverlay(top, bottom, proc) _TSUpdateOverlay :proc equ FirstParam+0 :bottom equ FirstParam+4 diff --git a/src/blitter/Template.s b/src/blitter/Template.s index 4bf4d14..efd33be 100644 --- a/src/blitter/Template.s +++ b/src/blitter/Template.s @@ -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 ; diff --git a/src/render/Dynamic.s b/src/render/Dynamic.s index 3c9cdf2..228a534 100644 --- a/src/render/Dynamic.s +++ b/src/render/Dynamic.s @@ -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 diff --git a/src/static/TileStore.s b/src/static/TileStore.s index 350482c..c4690ed 100644 --- a/src/static/TileStore.s +++ b/src/static/TileStore.s @@ -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 diff --git a/src/static/TileStoreDefs.s b/src/static/TileStoreDefs.s index e80c541..488f47d 100644 --- a/src/static/TileStoreDefs.s +++ b/src/static/TileStoreDefs.s @@ -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.