mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2025-02-27 21:30:11 +00:00
Fix dirty<->normal rendering transition
This commit is contained in:
parent
77b69cdc82
commit
9856bad091
@ -115,18 +115,18 @@ OKTOROK_SLOT_4 equ 4
|
|||||||
_GTEUpdateSprite
|
_GTEUpdateSprite
|
||||||
|
|
||||||
; Add 4 octoroks
|
; Add 4 octoroks
|
||||||
; pea OKTOROK_ID
|
pea OKTOROK_ID
|
||||||
; lda OktorokX
|
lda OktorokX
|
||||||
; pha
|
pha
|
||||||
; lda OktorokY
|
lda OktorokY
|
||||||
; pha
|
pha
|
||||||
; pea OKTOROK_SLOT_1
|
pea OKTOROK_SLOT_1
|
||||||
; _GTEAddSprite
|
_GTEAddSprite
|
||||||
|
|
||||||
; pea OKTOROK_SLOT_1
|
pea OKTOROK_SLOT_1
|
||||||
; pea $0000 ; with these flags (h/v flip)
|
pea $0000 ; with these flags (h/v flip)
|
||||||
; pea OKTOROK_VBUFF ; and use this stamp
|
pea OKTOROK_VBUFF ; and use this stamp
|
||||||
; _GTEUpdateSprite
|
_GTEUpdateSprite
|
||||||
|
|
||||||
; Draw the initial screen
|
; Draw the initial screen
|
||||||
|
|
||||||
@ -255,24 +255,23 @@ EvtLoop
|
|||||||
|
|
||||||
; Let's see what it looks like!
|
; Let's see what it looks like!
|
||||||
|
|
||||||
; lda vsync
|
lda vsync
|
||||||
; beq :no_vsync
|
beq :no_vsync
|
||||||
;:vsyncloop jsl GetVerticalCounter ; 8-bit value
|
:vsyncloop jsr _GetVBL ; 8-bit value
|
||||||
; cmp ScreenY0
|
cmp #12
|
||||||
; bcc :vsyncloop
|
bcc :vsyncloop
|
||||||
; sec
|
cmp #16
|
||||||
; sbc ScreenY0
|
bcs :vsyncloop ; Wait until we're within the top 4 scanlines
|
||||||
; cmp #4
|
lda #1
|
||||||
; bcs :vsyncloop ; Wait until we're within the top 8 scanlines
|
jsr _SetBorderColor
|
||||||
; lda #1
|
:no_vsync
|
||||||
; jsl SetBorderColor
|
|
||||||
;:no_vsync
|
|
||||||
_GTERenderDirty
|
_GTERenderDirty
|
||||||
|
|
||||||
; lda vsync
|
lda vsync
|
||||||
; beq :no_vsync2
|
beq :no_vsync2
|
||||||
; lda #0
|
lda #0
|
||||||
; jsl SetBorderColor
|
jsr _SetBorderColor
|
||||||
|
|
||||||
:no_vsync2
|
:no_vsync2
|
||||||
brl EvtLoop
|
brl EvtLoop
|
||||||
|
|
||||||
@ -300,9 +299,9 @@ TransitionRight
|
|||||||
bcs :out
|
bcs :out
|
||||||
clc
|
clc
|
||||||
adc #4
|
adc #4
|
||||||
|
sta StartX
|
||||||
pha
|
pha
|
||||||
lda StartY
|
pei StartY
|
||||||
pha
|
|
||||||
_GTESetBG0Origin
|
_GTESetBG0Origin
|
||||||
|
|
||||||
lda PlayerX
|
lda PlayerX
|
||||||
@ -323,8 +322,6 @@ TransitionRight
|
|||||||
bra :loop
|
bra :loop
|
||||||
:out
|
:out
|
||||||
|
|
||||||
lda #0 ; Move the player back to the left edge
|
|
||||||
sta PlayerX
|
|
||||||
inc MapScreenX ; Move the index to the next screen
|
inc MapScreenX ; Move the index to the next screen
|
||||||
:done
|
:done
|
||||||
rts
|
rts
|
||||||
@ -345,6 +342,7 @@ TransitionLeft
|
|||||||
beq :out
|
beq :out
|
||||||
sec
|
sec
|
||||||
sbc #4
|
sbc #4
|
||||||
|
sta StartX
|
||||||
pha
|
pha
|
||||||
pei StartY
|
pei StartY
|
||||||
_GTESetBG0Origin
|
_GTESetBG0Origin
|
||||||
@ -367,8 +365,6 @@ TransitionLeft
|
|||||||
_GTERender
|
_GTERender
|
||||||
bra :loop
|
bra :loop
|
||||||
:out
|
:out
|
||||||
; lda #128-8 ; Move the player back to the right edge
|
|
||||||
; sta PlayerX
|
|
||||||
dec MapScreenX ; Move the index to the next screen
|
dec MapScreenX ; Move the index to the next screen
|
||||||
:done
|
:done
|
||||||
rts
|
rts
|
||||||
@ -376,7 +372,6 @@ TransitionLeft
|
|||||||
ToolPath str '1/Tool160'
|
ToolPath str '1/Tool160'
|
||||||
MyUserId ds 2
|
MyUserId ds 2
|
||||||
; Color palette
|
; Color palette
|
||||||
;MyPalette dw $068F,$0EDA,$0000,$0000,$0BF1,$00A0,$0EEE,$0456,$0FA4,$0F59,$0E30,$01CE,$02E3,$0870,$0F93,$0FD7
|
|
||||||
MyPalette dw $0FDA,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$023E,$01CE,$02E3,$0870,$0F93,$0FD7
|
MyPalette dw $0FDA,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$023E,$01CE,$02E3,$0870,$0F93,$0FD7
|
||||||
|
|
||||||
MapScreenX ds 2
|
MapScreenX ds 2
|
||||||
@ -458,7 +453,26 @@ GTEStartUp
|
|||||||
|
|
||||||
:ok3
|
:ok3
|
||||||
rts
|
rts
|
||||||
|
|
||||||
PUT gen/App.TileMapBG0.s
|
|
||||||
|
|
||||||
ANGLEBNK ENT
|
BORDER_REG equ $E0C034 ; 0-3 = border, 4-7 Text color
|
||||||
|
VBL_VERT_REG equ $E0C02E
|
||||||
|
VBL_HORZ_REG equ $E0C02F
|
||||||
|
|
||||||
|
_GetVBL
|
||||||
|
sep #$20
|
||||||
|
ldal VBL_HORZ_REG
|
||||||
|
asl
|
||||||
|
ldal VBL_VERT_REG
|
||||||
|
rol ; put V5 into carry bit, if needed. See TN #39 for details.
|
||||||
|
rep #$20
|
||||||
|
and #$00FF
|
||||||
|
rts
|
||||||
|
|
||||||
|
_SetBorderColor sep #$20 ; ACC = $X_Y, REG = $W_Z
|
||||||
|
eorl BORDER_REG ; ACC = $(X^Y)_(Y^Z)
|
||||||
|
and #$0F ; ACC = $0_(Y^Z)
|
||||||
|
eorl BORDER_REG ; ACC = $W_(Y^Z^Z) = $W_Y
|
||||||
|
stal BORDER_REG
|
||||||
|
rep #$20
|
||||||
|
rts
|
||||||
|
PUT gen/App.TileMapBG0.s
|
||||||
|
@ -174,9 +174,6 @@ _ShadowOff
|
|||||||
rep #$20
|
rep #$20
|
||||||
rts
|
rts
|
||||||
|
|
||||||
GetVerticalCounter ENT
|
|
||||||
jsr _GetVBL
|
|
||||||
rtl
|
|
||||||
_GetVBL
|
_GetVBL
|
||||||
sep #$20
|
sep #$20
|
||||||
ldal VBL_HORZ_REG
|
ldal VBL_HORZ_REG
|
||||||
|
11
src/Render.s
11
src/Render.s
@ -20,8 +20,12 @@
|
|||||||
; It's important to do _ApplyBG0YPos first because it calculates the value of StartY % 208 which is
|
; It's important to do _ApplyBG0YPos first because it calculates the value of StartY % 208 which is
|
||||||
; used in all of the other loops
|
; used in all of the other loops
|
||||||
_Render
|
_Render
|
||||||
; lda LastRender ; Check to see what kind of rendering was done on the last frame. If
|
lda LastRender ; Check to see what kind of rendering was done on the last frame. If
|
||||||
; beq :no_change ; it was not this renderer,
|
beq :no_change ; it was not this renderer,
|
||||||
|
jsr _ResetToNormalTileProcs
|
||||||
|
jsr _Refresh
|
||||||
|
:no_change
|
||||||
|
|
||||||
jsr _DoTimers ; Run any pending timer tasks
|
jsr _DoTimers ; Run any pending timer tasks
|
||||||
|
|
||||||
stz SpriteRemovedFlag ; If we remove a sprite, then we need to flag a rebuild for the next frame
|
stz SpriteRemovedFlag ; If we remove a sprite, then we need to flag a rebuild for the next frame
|
||||||
@ -160,10 +164,9 @@ _RenderDirty
|
|||||||
lda LastRender ; If the full renderer was last called, we assume that
|
lda LastRender ; If the full renderer was last called, we assume that
|
||||||
bne :norecalc ; the scroll positions have likely changed, so recalculate
|
bne :norecalc ; the scroll positions have likely changed, so recalculate
|
||||||
jsr _RecalcTileScreenAddrs ; them to make sure sprites draw at the correct screen address
|
jsr _RecalcTileScreenAddrs ; them to make sure sprites draw at the correct screen address
|
||||||
jsr _ResetVisibleTiles ; Switch the tile procs to the dirty tile rendering functions
|
jsr _ResetToDirtyTileProcs ; Switch the tile procs to the dirty tile rendering functions
|
||||||
; jsr _ClearSpritesFromCodeField ; Restore the tiles to their non-sprite versions
|
; jsr _ClearSpritesFromCodeField ; Restore the tiles to their non-sprite versions
|
||||||
:norecalc
|
:norecalc
|
||||||
|
|
||||||
jsr _RenderSprites
|
jsr _RenderSprites
|
||||||
jsr _ApplyDirtyTiles
|
jsr _ApplyDirtyTiles
|
||||||
|
|
||||||
|
175
src/Tiles.s
175
src/Tiles.s
@ -166,52 +166,99 @@ InitTiles
|
|||||||
bpl :loop
|
bpl :loop
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
; Put everything on the dirty tile list
|
||||||
|
_Refresh
|
||||||
|
ldx #TILE_STORE_SIZE-2
|
||||||
|
:loop jsr _PushDirtyTileX
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
bpl :loop
|
||||||
|
rts
|
||||||
|
|
||||||
; Reset all of the tile proc values in the playfield.
|
; Reset all of the tile proc values in the playfield.
|
||||||
_ResetVisibleTiles
|
_ResetToDirtyTileProcs
|
||||||
:col equ tmp0
|
ldx #TILE_STORE_SIZE-2
|
||||||
:row equ tmp1
|
|
||||||
|
|
||||||
jsr _OriginToTileStore ; Get the (col,row) of the tile in the upper-left corner of the playfield
|
|
||||||
|
|
||||||
clc
|
|
||||||
txa
|
|
||||||
adc TileStoreLookupYTable,y ; Get the offset into the Tile Store lookup table
|
|
||||||
tay
|
|
||||||
pha ; Save for later
|
|
||||||
|
|
||||||
lda ScreenTileHeight
|
|
||||||
sta :row
|
|
||||||
lda ScreenTileWidth
|
|
||||||
sta :col
|
|
||||||
|
|
||||||
:loop
|
:loop
|
||||||
phy
|
|
||||||
ldx TileStoreLookup,y
|
|
||||||
lda TileStore+TS_TILE_ID,x
|
lda TileStore+TS_TILE_ID,x
|
||||||
|
jsr _SetDirtyTileProcs
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
bpl :loop
|
||||||
|
rts
|
||||||
|
|
||||||
|
_ResetToNormalTileProcs
|
||||||
|
ldx #TILE_STORE_SIZE-2
|
||||||
|
:loop
|
||||||
|
lda TileStore+TS_TILE_ID,x
|
||||||
|
jsr _SetNormalTileProcs
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
bpl :loop
|
||||||
|
rts
|
||||||
|
|
||||||
|
; A = tileID
|
||||||
|
; X = tile store index
|
||||||
|
_SetDirtyTileProcs
|
||||||
jsr _CalcTileProcIndex
|
jsr _CalcTileProcIndex
|
||||||
ldy #DirtyProcs
|
ldy #DirtyProcs
|
||||||
jsr _SetTileProcs
|
jmp _SetTileProcs
|
||||||
ply
|
|
||||||
|
|
||||||
iny
|
; A = tileID
|
||||||
iny
|
; X = tile store index
|
||||||
dec :col
|
_SetNormalTileProcs
|
||||||
bpl :loop
|
pha ; extra space
|
||||||
|
pha ; save the tile ID
|
||||||
|
jsr _CalcTileProcIndex
|
||||||
|
sta 3,s ; save for later
|
||||||
|
|
||||||
lda ScreenTileWidth
|
lda EngineMode
|
||||||
sta :col
|
bit #ENGINE_MODE_DYN_TILES+ENGINE_MODE_TWO_LAYER
|
||||||
|
beq :setTileFast
|
||||||
|
|
||||||
lda 1,s ; Move to the next row
|
bit #ENGINE_MODE_TWO_LAYER
|
||||||
clc
|
beq :setTileDyn
|
||||||
adc #2*TS_LOOKUP_SPAN
|
|
||||||
sta 1,s
|
|
||||||
tay
|
|
||||||
|
|
||||||
dec :row
|
pla ; restore newTileID
|
||||||
bpl :loop
|
bit #TILE_DYN_BIT
|
||||||
|
beq :pickTwoLyrProc
|
||||||
|
|
||||||
pla ; pop the saved value
|
ldy #TwoLyrDynProcs
|
||||||
rts
|
brl :pickDynProc
|
||||||
|
|
||||||
|
:pickTwoLyrProc ldy #TwoLyrProcs
|
||||||
|
pla ; pull of the proc index
|
||||||
|
jmp _SetTileProcs
|
||||||
|
|
||||||
|
; Specialized check for when the engine is in "Fast" mode. If is a simple decision tree based on whether
|
||||||
|
; the tile priority bit is set, and whether this is the special tile 0 or not.
|
||||||
|
:setTileFast
|
||||||
|
pla ; Throw away tile ID copy
|
||||||
|
ldy #FastProcs
|
||||||
|
pla
|
||||||
|
jmp _SetTileProcs
|
||||||
|
|
||||||
|
; Specialized check for when the engine has enabled dynamic tiles. In this case we are no longer
|
||||||
|
; guaranteed that the opcodes in a tile are PEA instructions.
|
||||||
|
:setTileDyn
|
||||||
|
pla ; get the cached tile ID
|
||||||
|
bit #TILE_DYN_BIT
|
||||||
|
beq :pickSlowProc ; If the Dynamic bit is not set, select a tile proc that sets opcodes
|
||||||
|
|
||||||
|
ldy #DynProcs ; use this table
|
||||||
|
:pickDynProc
|
||||||
|
and #TILE_PRIORITY_BIT
|
||||||
|
beq :pickZeroDynProc ; If the Priority bit is not set, pick the first entry
|
||||||
|
pla
|
||||||
|
lda #1 ; If the Priority bit is set, pick the other one
|
||||||
|
jmp _SetTileProcs
|
||||||
|
|
||||||
|
:pickZeroDynProc pla
|
||||||
|
lda #0
|
||||||
|
jmp _SetTileProcs
|
||||||
|
|
||||||
|
:pickSlowProc ldy #SlowProcs
|
||||||
|
pla
|
||||||
|
jmp _SetTileProcs
|
||||||
|
|
||||||
; Helper method to calculate the index into the tile proc table given a TileID
|
; Helper method to calculate the index into the tile proc table given a TileID
|
||||||
; Calculate the base tile proc selector from the tile Id
|
; Calculate the base tile proc selector from the tile Id
|
||||||
@ -302,62 +349,10 @@ _SetTile
|
|||||||
; functionality. Sometimes it is simple, but in cases of the sprites overlapping Dynamic Tiles and other cases
|
; functionality. Sometimes it is simple, but in cases of the sprites overlapping Dynamic Tiles and other cases
|
||||||
; it can be more involved.
|
; it can be more involved.
|
||||||
|
|
||||||
; Calculate the base tile proc selector from the tile Id
|
; Calculate the base tile proc selector from the tile Id (need X-register set to tile store index)
|
||||||
|
|
||||||
lda newTileId
|
lda newTileId
|
||||||
jsr _CalcTileProcIndex
|
jsr _SetNormalTileProcs
|
||||||
sta procIdx
|
|
||||||
|
|
||||||
; Now integrate with the engine mode indicator
|
|
||||||
|
|
||||||
lda EngineMode
|
|
||||||
bit #ENGINE_MODE_DYN_TILES+ENGINE_MODE_TWO_LAYER
|
|
||||||
beq :setTileFast
|
|
||||||
|
|
||||||
bit #ENGINE_MODE_TWO_LAYER
|
|
||||||
bne :not_dyn
|
|
||||||
brl :setTileDyn
|
|
||||||
|
|
||||||
:not_dyn
|
|
||||||
lda #TILE_DYN_BIT
|
|
||||||
bit newTileId
|
|
||||||
beq :pickTwoLyrProc
|
|
||||||
|
|
||||||
ldy #TwoLyrDynProcs
|
|
||||||
brl :pickDynProc
|
|
||||||
|
|
||||||
:pickTwoLyrProc ldy #TwoLyrProcs
|
|
||||||
lda procIdx
|
|
||||||
jsr _SetTileProcs
|
|
||||||
jmp _PushDirtyTileX
|
|
||||||
|
|
||||||
; Specialized check for when the engine is in "Fast" mode. If is a simple decision tree based on whether
|
|
||||||
; the tile priority bit is set, and whether this is the special tile 0 or not.
|
|
||||||
:setTileFast
|
|
||||||
ldy #FastProcs
|
|
||||||
lda procIdx
|
|
||||||
jsr _SetTileProcs
|
|
||||||
jmp _PushDirtyTileX
|
|
||||||
|
|
||||||
; Specialized check for when the engine has enabled dynamic tiles. In this case we are no longer
|
|
||||||
; guaranteed that the opcodes in a tile are PEA instructions.
|
|
||||||
:setTileDyn
|
|
||||||
lda #TILE_DYN_BIT
|
|
||||||
bit newTileId
|
|
||||||
beq :pickSlowProc ; If the Dynamic bit is not set, select a tile proc that sets opcodes
|
|
||||||
|
|
||||||
ldy #DynProcs ; use this table
|
|
||||||
:pickDynProc
|
|
||||||
lda newTileId ; Otherwise chose one of the two dynamic tuples
|
|
||||||
and #TILE_PRIORITY_BIT
|
|
||||||
beq *+5 ; If the Priority bit is not set, pick the first entry
|
|
||||||
lda #1 ; If the Priority bit is set, pick the other one
|
|
||||||
jsr _SetTileProcs
|
|
||||||
jmp _PushDirtyTileX
|
|
||||||
|
|
||||||
:pickSlowProc ldy #SlowProcs
|
|
||||||
lda procIdx
|
|
||||||
jsr _SetTileProcs
|
|
||||||
jmp _PushDirtyTileX
|
jmp _PushDirtyTileX
|
||||||
|
|
||||||
; X = Tile Store offset
|
; X = Tile Store offset
|
||||||
|
@ -705,13 +705,7 @@ _TSFillTileStore
|
|||||||
; _TSRefresh()
|
; _TSRefresh()
|
||||||
_TSRefresh
|
_TSRefresh
|
||||||
_TSEntry
|
_TSEntry
|
||||||
|
jsr _Refresh
|
||||||
ldx #TILE_STORE_SIZE-2
|
|
||||||
:loop jsr _PushDirtyTileX
|
|
||||||
dex
|
|
||||||
dex
|
|
||||||
bpl :loop
|
|
||||||
|
|
||||||
_TSExit #0;#0
|
_TSExit #0;#0
|
||||||
|
|
||||||
; Insert the GTE code
|
; Insert the GTE code
|
||||||
|
Loading…
x
Reference in New Issue
Block a user