From b60727508972da0925a73a9ad6960ca0c651232f Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroich Date: Sat, 20 Nov 2021 12:16:03 -0600 Subject: [PATCH] Separate updating a sprite's position with updating it's flags --- demos/sprites/App.Main.s | 20 +++++++++++++++++-- src/GTE.s | 3 ++- src/Sprite.s | 43 +++++++++++++++++++++++++++++++++++----- src/Sprite2.s | 2 +- 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/demos/sprites/App.Main.s b/demos/sprites/App.Main.s index 8331e92..3fb9747 100644 --- a/demos/sprites/App.Main.s +++ b/demos/sprites/App.Main.s @@ -108,9 +108,10 @@ DoLoadBG1 stz PlayerYVel ; Add a sprite to the engine and save it's sprite ID +SPRITE_ID equ {SPRITE_16X16+145} jsr UpdatePlayerLocal - lda #$1800+145 ; 16x16 sprite, tile ID = 64 + lda #SPRITE_ID ; 16x16 sprite, tile ID = 145 ldx PlayerX ldy PlayerY jsl AddSprite @@ -240,7 +241,7 @@ EvtLoop lda PlayerID ldx PlayerX ldy PlayerY - jsl UpdateSprite ; Move the sprite to this local position + jsl MoveSprite ; Move the sprite to this local position ; Update the timers jsl DoTimers @@ -408,6 +409,8 @@ UpdatePlayerLocal ; Simple updates with gravity and collisions. It's important that eveything in this ; subroutine be done against UpdatePlayerPos + stz tmp0 ; build up some flags + stz PlayerStanding lda PlayerYVel bmi :no_ground_check @@ -454,16 +457,20 @@ UpdatePlayerPos lda MaxGlobalX sta PlayerGlobalX + ldx #0 lda PlayerXVel beq :no_dxv bpl :pos_dxv + ldx #SPRITE_HFLIP inc bra :no_dxv :pos_dxv dec :no_dxv sta PlayerXVel + stx tmp0 + ldx #0 lda PlayerStanding bne :too_fast @@ -473,8 +480,17 @@ UpdatePlayerPos cmp #4 bcs :too_fast :is_neg + ldx #SPRITE_VFLIP sta PlayerYVel :too_fast + + txa + ora tmp0 + ora #SPRITE_ID + tax + lda PlayerID + jsl UpdateSprite ; Change the tile ID and / or flags + rts ; X = coordinate diff --git a/src/GTE.s b/src/GTE.s index d911db8..e223b7d 100644 --- a/src/GTE.s +++ b/src/GTE.s @@ -46,7 +46,8 @@ StopScript EXT ; Sprite functions AddSprite EXT -UpdateSprite EXT +MoveSprite EXT ; Set an existing sprite's position +UpdateSprite EXT ; Change an existing sprite's flags ; Direct access to internals DoScriptSeq EXT diff --git a/src/Sprite.s b/src/Sprite.s index 5354a32..cd5cf5e 100644 --- a/src/Sprite.s +++ b/src/Sprite.s @@ -884,12 +884,11 @@ _GetSpriteVBuffAddr pla rts -; Move a sprite to a new location. If the tile ID of the sprite needs to be changed, then -; a full remove/add cycle needs to happen +; Update the sprite's flags. We do not allow the size fo a sprite to be changed. That required +; the sprite to be removed and re-added. ; -; A = sprite ID -; X = x position -; Y = y position +; A = Sprite ID +; X = Sprite Tile ID and Flags UpdateSprite ENT phb phk @@ -898,11 +897,45 @@ UpdateSprite ENT plb rtl + _UpdateSprite cmp #MAX_SPRITES*2 ; Make sure we're in bounds bcc :ok rts +:ok + stx tmp0 ; Save the horizontal position + and #$FFFE ; Defensive + tax ; Get the sprite index + + lda #SPRITE_STATUS_DIRTY ; Content is changing, mark as dirty + sta _Sprites+SPRITE_STATUS,x + + lda tmp0 ; Update the Tile ID + sta _Sprites+SPRITE_ID,x ; Keep a copy of the full descriptor + jsr _GetTileAddr ; This applies the TILE_ID_MASK + sta _Sprites+TILE_DATA_OFFSET,x + rts + +; Move a sprite to a new location. If the tile ID of the sprite needs to be changed, then +; a full remove/add cycle needs to happen +; +; A = sprite ID +; X = x position +; Y = y position +MoveSprite ENT + phb + phk + plb + jsr _MoveSprite + plb + rtl + +_MoveSprite + cmp #MAX_SPRITES*2 ; Make sure we're in bounds + bcc :ok + rts + :ok stx tmp0 ; Save the horizontal position and #$FFFE ; Defensive diff --git a/src/Sprite2.s b/src/Sprite2.s index 549471e..63fc8bd 100644 --- a/src/Sprite2.s +++ b/src/Sprite2.s @@ -25,7 +25,7 @@ _MarkDirtySprite ; Clip the sprite's extent to the screen so we can assume (mostly) position values from here on out. Note that ; the sprite width and height are _only_ used in the clip and afterward all calculation use the clip rect ; -; OPTIMIZATION NODE: These values can be calculated in AddSprite/UpdateSprite once and stored in the sprite +; OPTIMIZATION NODE: These values can be calculated in AddSprite/MoveSprite once and stored in the sprite ; record since the screen size doesn't change. lda _Sprites+SPRITE_ID,x ; Get an index into the height/width tables based on the sprite bits