Functional compiled sprites in demo-5

This commit is contained in:
Lucas Scharenbroich 2023-03-01 13:18:37 -06:00
parent e2e30dfcf4
commit c14f3c7283
11 changed files with 339 additions and 115 deletions

View File

@ -61,6 +61,7 @@ extern pascal Word GTEStatus(void) inline(0x06A0, tool_dispatcher);
/* GTE Sprite Routines */
extern pascal void GTECreateSpriteStamp(Word spriteDescriptor, Word vBuffAddr) inline(0x0FA0, tool_dispatcher);
extern pascal Word GTECompileSpriteStamp(Word spriteDescriptor, Word vBuffAddr) inline(0x2DA0, tool_dispatcher);
extern pascal void GTEAddSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr, Word x, Word y) inline(0x10A0, tool_dispatcher);
extern pascal void GTEMoveSprite(Word spriteSlot, Word x, Word y) inline(0x11A0, tool_dispatcher);
extern pascal void GTEUpdateSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr) inline(0x12A0, tool_dispatcher);

View File

@ -49,6 +49,10 @@ LastHFlip equ 44
SpriteFrame equ 46
SpriteToggle equ 48
SpriteCount equ 50
PlayerX1 equ 52
PlayerY1 equ 54
PlayerX2 equ 56
PlayerY2 equ 58
phk
plb
@ -111,12 +115,17 @@ SpriteCount equ 50
lda #16
sta PlayerGlobalX
sta PlayerX
sta PlayerX1
sta PlayerX2
lda MaxGlobalY
sec
sbc #48 ; 32 for tiles, 16 for sprite
lda #48 ; 32 for tiles, 16 for sprite
sta PlayerGlobalY
sta PlayerY
sta PlayerY1
sta PlayerY2
stz PlayerXVel
stz PlayerYVel
@ -142,6 +151,8 @@ HERO_FRAME_4 equ HERO_SIZE+151
HERO_VBUFF_4 equ VBUFF_SPRITE_START+3*VBUFF_SPRITE_STEP
HERO_SLOT equ 1
; Create stamps of each sprite
pea HERO_FRAME_1
pea HERO_VBUFF_1
_GTECreateSpriteStamp
@ -158,29 +169,37 @@ HERO_SLOT equ 1
pea HERO_VBUFF_4
_GTECreateSpriteStamp
; Compile the sprite stamps and hold the compilation token
pha ; Space for result
pea HERO_SIZE
pea HERO_VBUFF_1
_GTECompileSpriteStamp
pla
pea HERO_SLOT ; Put the player in slot 1
pea HERO_FLAGS
pea HERO_VBUFF_1 ; and use this stamp
pea HERO_FLAGS+SPRITE_COMPILED ; mark this as a compiled sprite (can only use in RENDER_WITH_SHADOWING mode)
pha ; pass in the token of the compiled stamp
pei PlayerX
pei PlayerY
_GTEAddSprite
; brl Exit
; Repeat for each stamp. _GTECompileSpriteStamp will return an error if it runs out of memory
pea HERO_SLOT+1 ; Put the player in slot 1
pea HERO_FLAGS
pea HERO_VBUFF_1 ; and use this stamp
lda PlayerX
adc #4
pha
pei PlayerY
pei PlayerX1
pei PlayerY1
_GTEAddSprite
pea HERO_SLOT+2 ; Put the player in slot 1
pea HERO_FLAGS
pea HERO_VBUFF_1 ; and use this stamp
lda PlayerX
adc #8
pha
pei PlayerY
pei PlayerX2
pei PlayerY2
_GTEAddSprite
pea #RENDER_WITH_SHADOWING
@ -230,31 +249,39 @@ EvtLoop
stz PlayerXVel
do_render
; jsr UpdatePlayerPos ; Apply forces
; jsr ApplyCollisions ; Check if we run into things
; jsr UpdateCameraPos ; Moves the screen
jsr UpdatePlayerPos ; Apply forces
jsr ApplyCollisions ; Check if we run into things
jsr UpdateCameraPos ; Moves the screen
; pea HERO_SLOT
; pei PlayerX
; pei PlayerY
; _GTEMoveSprite ; Move the sprite to this local position
pea HERO_SLOT
pei PlayerX
pei PlayerY
_GTEMoveSprite ; Move the sprite to this local position
; pea HERO_SLOT+1
; lda PlayerX
; adc #4
; pha
; pei PlayerY
; _GTEMoveSprite ; Move the sprite to this local position
pea HERO_SLOT+1
lda PlayerX1
sec
sbc StartX
pha
lda PlayerY1
sec
sbc StartY
pha
_GTEMoveSprite ; Move the sprite to this local position
; pea HERO_SLOT+2
; lda PlayerX
; adc #8
; pha
; pei PlayerY
; _GTEMoveSprite ; Move the sprite to this local position
pea HERO_SLOT+2
lda PlayerX2
sec
sbc StartX
pha
lda PlayerY2
sec
sbc StartY
pha
_GTEMoveSprite ; Move the sprite to this local position
; pea $0000
; _GTERender
pea #RENDER_WITH_SHADOWING
_GTERender
; Update the performance counters
@ -429,6 +456,17 @@ UpdatePlayerPos
ApplyCollisions
; Move coordinates down the list
lda PlayerX1
sta PlayerX2
lda PlayerY1
sta PlayerY2
lda PlayerGlobalX
sta PlayerX1
lda PlayerGlobalY
sta PlayerY1
; Convert global to local coordinates
lda PlayerGlobalX

View File

@ -129,6 +129,9 @@ _GTESetBG1Scale MAC
_GTEGetAddress MAC
UserTool $2C00+GTEToolNum
<<<
_GTECompileSpriteStamp MAC
UserTool $2D00+GTEToolNum
<<<
; EngineMode definitions
; Script definition
@ -181,6 +184,7 @@ TILE_CTRL_MASK equ $FE00
; Sprite constants
SPRITE_COMPILED equ $4000 ; This is a compiled sprite
SPRITE_HIDE equ $2000
SPRITE_16X16 equ $1800
SPRITE_16X8 equ $1000

View File

@ -220,6 +220,8 @@ EngineReset
stz BG1TileMapPtr
stz BG1TileMapPtr+2
stz CompileBankTop
stz SCBArrayPtr
stz SCBArrayPtr+2

View File

@ -40,12 +40,12 @@ EngineMode equ 20 ; Defined the mode/capabilities that ar
; bit 2: 0 = No static buffer, 1 = Allocation Bank 00 space for a static screen buffer
DirtyBits equ 22 ; Identify values that have changed between frames
BG1DataBank equ 24 ; Data bank that holds BG1 layer data
BG1AltBank equ 26 ; Alternate BG1 bank
CompileBank0 equ 24 ; Always zero to allow [CompileBank0],y addressing
CompileBank equ 26 ; Data bank that holds compiled sprite code
BlitterDP equ 28 ; Direct page address the holder blitter data
BlitterDP equ 28 ; Direct page address that holds blitter data
OldStartX equ 30
OldStartX equ 30 ; Used to track deltas between frames
OldStartY equ 32
LastPatchOffset equ 34 ; Offset into code field that was patched with BRA instructions
@ -61,7 +61,7 @@ BG1StartYMod208 equ 46
OldBG1StartX equ 48
OldBG1StartY equ 50
BG1OffsetIndex equ 52
BG1OffsetIndex equ 52 ; Utility index for scanline effect in BG1
BG0TileOriginX equ 54 ; Coordinate in the tile map that corresponds to the top-left corner
BG0TileOriginY equ 56
@ -73,22 +73,22 @@ BG1TileOriginY equ 64
OldBG1TileOriginX equ 66
OldBG1TileOriginY equ 68
TileMapWidth equ 70
TileMapWidth equ 70 ; Pointer to memory holding the tile map for the primary background
TileMapHeight equ 72
TileMapPtr equ 74
FringeMapPtr equ 78
BG1TileMapWidth equ 82
BG1TileMapHeight equ 84
BG1TileMapPtr equ 86
BG1TileMapPtr equ 86 ; Pointer to memory holding the tile map for the secondary background
SCBArrayPtr equ 90 ; Used for palette binding
SpriteBanks equ 94 ; Bank bytes for the sprite data and sprite mask
LastRender equ 96 ; Record which render function was last executed
; gap
CompileBankTop equ 98 ; First free byte i nthe compile bank. Grows upward in memeory.
SpriteMap equ 100 ; Bitmap of open sprite slots.
ActiveSpriteCount equ 102
BankLoad equ 104
BG1DataBank equ 104 ; Data bank that holds BG1 layer data
TileStoreBankAndBank01 equ 106
TileStoreBankAndTileDataBank equ 108
TileStoreBankDoubled equ 110

View File

@ -59,16 +59,20 @@ InitMemory lda EngineMode
_Deref
stx BlitterDP
; Allocate banks of memory for BG1
; Allocate banks of memory for BG1. If the user wants to swap between multiple BG1 banks, then they need to be allocated
; outside of GTE and selected using the GTESetBG1Bank() function. Passing a zero for that function's argument will
; always set the bank to the allocated bank number. Bank 00 and Bank 01 are illegal values.
lda EngineMode
bit #ENGINE_MODE_TWO_LAYER
beq :no_bg1
jsr AllocOneBank2
sta BG1DataBank
:no_bg1
jsr AllocOneBank2
sta BG1AltBank
:no_bg1
sta CompileBank
stz CompileBank0
; Allocate the 13 banks of memory we need and store in double-length array
]step equ 0

View File

@ -609,17 +609,11 @@ _DrawDirectSprites
bit #SPRITE_STATUS_HIDDEN
bne :next
lda _Sprites+SPRITE_ID,x ; If this is a compiled sprite, call the routine in the compilation bank
bit #SPRITE_COMPILED
bne :compiled
phx
jsr _DrawStampToScreen
plx
bra :next
:compiled
:next
lda _Sprites+SORTED_NEXT,x ; If there another sprite in the list?
tax
@ -647,8 +641,8 @@ _DrawComplementList
lda _DirectListTop,x
ldy _DirectListBottom,x
tax
lda #0
jsr DebugSCBs
; lda #0
; jsr DebugSCBs
jsr _BltRange
plx
@ -662,8 +656,8 @@ _DrawComplementList
phx
ldy _DirectListTop,x
tax
lda #1
jsr DebugSCBs
; lda #1
; jsr DebugSCBs
jsr _PEISlam
plx
bra :blt_range
@ -673,8 +667,8 @@ _DrawComplementList
bcs :out ; screen, then expose that range
tax
ldy ScreenHeight
lda #1
jsr DebugSCBs
; lda #1
; jsr DebugSCBs
jsr _PEISlam
:out
rts

View File

@ -331,7 +331,7 @@ phase1 dw :phase1_0
; the stamp every time. So this allows users to create stamps in advance and then
; assign them to the sprites as needed.
;
; Note that the user had full freedom to create a stamp at any VBUFF address, however,
; Note that the user has full freedom to create a stamp at any VBUFF address, however,
; without leaving a buffer around each stamp, graphical corruption will occur. It is
; recommended that the defines for VBUFF_SPRITE_START, VBUFF_TILE_ROW_BYTES and
; VBUFF_TILE_COL_BYTES to calculate tile-aligned corner locations to lay out the
@ -362,8 +362,8 @@ _CreateSpriteStamp
; 01 - 8x16 (1x2 tiles)
; 10 - 16x8 (2x1 tiles)
; 11 - 16x16 (2x2 tiles)
; Bit 13 : Show/Hid sprite
; Bit 14 : Reserved. Must be zero.
; Bit 13 : Show/Hide sprite during rendering
; Bit 14 : Mark sprite as a compile sprite. SPRITE_DISP is treated as a compilation token.
; Bit 15 : Reserved. Must be zero.
; TBD: Bit 15 : Low Sprite priority. Draws behind high priority tiles.
;
@ -371,7 +371,7 @@ _CreateSpriteStamp
; the vertical tiles are taken from tileId + 32. This is why tile sheets should be saved
; with a width of 256 pixels.
;
; A = vbuffAddress
; A = Sprite ID / Flags
; Y = High Byte = x-pos, Low Byte = y-pos
; X = Sprite Slot (0 - 15)
_AddSprite
@ -387,7 +387,8 @@ _AddSprite
lda #SPRITE_STATUS_ADDED ; Used to initialize the SPRITE_STATUS
sta _Sprites+SPRITE_STATUS,x
stz _Sprites+VBUFF_ADDR,x ; Clear the VBUFF address, just to initialize it
lda #$FFFF
sta _Sprites+VBUFF_ADDR,x ; Clear the VBUFF address, just to initialize it
phy
tya
@ -909,14 +910,123 @@ _CacheSpriteBanks
;
; X = sprite index
_PrecalcSpriteVBuff
lda _Sprites+SPRITE_ID,x
lda _Sprites+SPRITE_ID,x ; Compiled sprites use the SPRITE_DISP as a fixed address to compiled code
bit #SPRITE_COMPILED
bne :compiled
xba
and #$0006
tay
lda _Sprites+VBUFF_ADDR,x
clc
adc _stamp_step,y
sta _Sprites+SPRITE_DISP,x
sta _Sprites+SPRITE_DISP,x ; Interpreted as an address in the VBUFF bank
rts
:compiled
xba
and #$0006 ; Pick the address from the table of 4 values. Can use this value directly
clc ; as an index
adc _Sprites+VBUFF_ADDR,x
tay
lda [CompileBank0],y
sta _Sprites+SPRITE_DISP,x ; Interpreted as an address in the CompileBank
rts
; Compile the four stamps and keep a reference to the addresses. We take the current CompileBankTop address and allocate 8 bytes
; of memory. Then compile each stamp and save the compilation address in the header area. Finally, the DISP_ADDR is set
; to that value and the SPRITE_COMPILED bit is set in the SPRITE_ID word.
;
; A = sprite Id
; X = vbuff base address
_CompileStampSet
:height equ tmp8
:width equ tmp9
:base equ tmp10
:output equ tmp11
:addrs equ tmp12 ; 4 words (tmp12, tmp13, tmp14 and tmp15)
; Save the base address
stx :base
; Initialize the height and width based on the sprite flags
ldy #8
sty :height
ldx #4
stx :width
bit #$1000 ; wide flag
beq :skinny
ldx #8
stx :width
:skinny
bit #$0800 ; tall flag
beq :short
ldy #16
sty :height
:short
lda CompileBankTop
sta :output ; Save the current address as the return value
clc
adc #8
sta CompileBankTop ; Allocate space for the 4 addresses return by _CompileStamp
; ldy :height ; X and Y are already set for the first call
; ldx :width
lda :base
jsr _CompileStamp ; Compile into the bank
sta :addrs ; Save the address temporarily
ldy :height
ldx :width
clc
lda :base
adc _stamp_step+2
jsr _CompileStamp
sta :addrs+2
ldy :height
ldx :width
clc
lda :base
adc _stamp_step+4
jsr _CompileStamp
sta :addrs+4
ldy :height
ldx :width
clc
lda :base
adc _stamp_step+6
jsr _CompileStamp
sta :addrs+6
; Now the sprite stamps are all compiled. Set the bank to the compilation bank and fill in the header
phb
ldy :output
pei CompileBank
plb
lda :addrs
sta: 0,y
lda :addrs+2
sta: 2,y
lda :addrs+4
sta: 4,y
lda :addrs+6
sta: 6,y
plb
plb
tya ; Put the output value into the accumulator
clc ; No error
rts
_PrecalcSpriteSize
@ -1026,7 +1136,7 @@ _RemoveSprite
;
; A = Sprite slot
; X = New Sprite Flags
; Y = New Sprite Stamp Address
; Y = New Sprite Stamp Address | New Compiled Sprite Token
_UpdateSprite
cmp #MAX_SPRITES
bcc :ok

View File

@ -1,37 +1,48 @@
; Compile a stamp into a compilation cache
;
; A = vbuff address
; X = width (in bytes)
; Y = height (in scanlines)
_CompileStamp
_lines equ tmp0
_width0 equ tmp1
_width equ tmp2
baseAddr equ tmp3
destAddr equ tmp4
vbuffAddr equ tmp5
:lines equ tmp0
:sprwidth equ tmp1
:cntwidth equ tmp2
:baseAddr equ tmp3
:destAddr equ tmp4
:vbuffAddr equ tmp5
:rtnval equ tmp6
lda _Sprites+SPRITE_HEIGHT,x
sta _lines
LDA_IMM_OPCODE equ $A9
LDA_ABS_X_OPCODE equ $BD
AND_IMM_OPCODE equ $29
ORA_IMM_OPCODE equ $09
STA_ABS_X_OPCODE equ $9D
STZ_ABS_X_OPCODE equ $9E
RTL_OPCODE equ $6B
lda _Sprites+SPRITE_WIDTH,x ; Width in bytes (4 or 8)
sta :vbuffAddr
sty :lines
txa
lsr
sta
sta _width0
sta :sprwidth
lda _Sprites+SPRITE_DISP,x ; Get the address of the stamp
sta vbuffAddr
tax
; Get ready to build the sprite
ldy CompileBankTop ; First free byte in the compilation bank
sty :rtnval ; Save it as the return value
phb
pei CompileBank
plb
plb ; Set the bank to the compilation cache
stz baseAddr
stz destAddr
stz :baseAddr
stz :destAddr
:oloop
lda _width0
sta _width
lda :sprwidth
sta :cntwidth
ldx :vbuffAddr
:iloop
ldal spritemask,x
@ -42,9 +53,8 @@ vbuffAddr equ tmp5
; Mask with the screen data
lda #LDA_ABS_X_OPCODE
sta: 0,y
lda destAddr
lda :destAddr
sta: 1,y
sta: 10,y
lda #AND_IMM_OPCODE
sta: 3,y
ldal spritemask,x
@ -55,8 +65,11 @@ vbuffAddr equ tmp5
sta: 7,y
lda #STA_ABS_X_OPCODE
sta: 9,y
lda :destAddr
sta: 10,y
tya
clc
adc #12
tay
bra :next
@ -65,46 +78,63 @@ vbuffAddr equ tmp5
:no_mask lda #LDA_IMM_OPCODE
sta: 0,y
ldal spritedata,x
beq :zero
sta: 1,y
lda #STA_ABS_X_OPCODE
sta: 3,y
lda destAddr
lda :destAddr
sta: 4,y
tya
clc
adc #6
tay
bra :next
:zero lda #STZ_ABS_X_OPCODE
sta: 0,y
lda :destAddr
sta: 1,y
iny
iny
iny
:next
inx
inx
inc destAddr ; Move to the next word
inc destAddr
inc :destAddr ; Move to the next word
inc :destAddr
dec _width
dec :cntwidth
bne :iloop
lda vbuffAddr
lda :vbuffAddr
clc
adc #SPRITE_PLANE_SPAN
sta vbuffAddr
tax
sta :vbuffAddr
lda baseAddr ; Move to the next line
lda :baseAddr ; Move to the next line
clc
adc #160
sta baseAddr
sta destAddr
sta :baseAddr
sta :destAddr
dec lines
bne :oloop
dec :lines
beq :out
brl :oloop
:out
lda #RTL_OPCODE ; Finish up the subroutine
sta: 0,y
iny
sty CompileBankTop
plb
plb
lda :rtnval ; Address in the compile memory
rts
; Draw a sprite directly to the graphics screen. If sprite is clipped at all, do not draw.
@ -144,6 +174,11 @@ _DrawStampToScreen
adc _Sprites+SPRITE_X,x ; Move to the horizontal address
tay ; This is the on-screen address
lda _Sprites+SPRITE_ID,x ; If this is a compiled sprite, call the routine in the compilation bank
bit #SPRITE_COMPILED
beq *+5
brl :compiled
lda _Sprites+SPRITE_HEIGHT,x
sta tmp0
@ -222,6 +257,22 @@ _DrawStampToScreen
plb
rts
:compiled
lda CompileBank-1 ; Load the bank into the high byte
stal :patch+2 ; Put it into the 3rd address bytes (2nd byte is garbage)
lda _Sprites+SPRITE_DISP,x ; Address in the compile bank
stal :patch+1 ; Set 1st and 2nd address bytes
tyx ; Put on-screen address in X-register
phb ; Compiled sprites assume bank register is $01
pea $0101
plb
plb
:patch jsl $000000 ; Dispatch
plb
rts
; Alternate entry point that takes arguments in registers instead of using a _Sprite
; record
;

View File

@ -97,6 +97,9 @@ _CallTable
adrl _TSClearBG1Buffer-1
adrl _TSSetBG1Scale-1
adrl _TSGetAddress-1
adrl _TSCompileSpriteStamp-1
_CTEnd
_GTEAddSprite MAC
UserTool $1000+GTEToolNum
@ -232,14 +235,14 @@ _TSReserved
; SetScreenMode(width, height)
_TSSetScreenMode
height equ FirstParam
width equ FirstParam+2
:height equ FirstParam
:width equ FirstParam+2
_TSEntry
lda height,s
lda :height,s
tay
lda width,s
lda :width,s
tax
jsr _SetScreenMode
@ -350,7 +353,7 @@ _TSCreateSpriteStamp
_TSExit #0;#4
; AddSprite(spriteSlot, spriteFlags, vbuff, spriteX, spriteY)
; AddSprite(spriteSlot, spriteFlags, vbuff | cbuff, spriteX, spriteY)
_TSAddSprite
:spriteY equ FirstParam+0
:spriteX equ FirstParam+2
@ -499,10 +502,10 @@ _TSCopyPicToBG1
sta :src_stride
ldy BG1DataBank ; Pick the target data bank
lda :flags,s
bit #$0001
beq *+4
ldy BG1AltBank
; lda :flags,s
; bit #$0001
; beq *+4
; ldy BG1AltBank
lda :ptr+2,s
tax
@ -847,6 +850,22 @@ _TSGetAddress
:out
_TSExit #0;#2
; CompileSpriteStamp(spriteId, vbuffAddr)
_TSCompileSpriteStamp
:vbuff equ FirstParam
:spriteId equ FirstParam+2
:output equ FirstParam+4
_TSEntry
lda :vbuff,s
tax
lda :spriteId,s
jsr _CompileStampSet
sta :output,s
_TSExit #0;#4
; Insert the GTE code
put Math.s

View File

@ -59,16 +59,17 @@ _BltRange
beq :skip_bank
; TODO: Switch to loading the selected BG1 bank. No special "Alt" bank
lda RenderFlags
bit #RENDER_ALT_BG1
beq :primary
lda BG1AltBank
bra :alt
:primary lda BG1DataBank
:alt
;
; lda RenderFlags
; bit #RENDER_ALT_BG1
; beq :primary
;
; lda BG1AltBank
; bra :alt
;
;:primary lda BG1DataBank
;:alt
lda BG1DataBank
pha
plb