mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-06-02 22:41:29 +00:00
Continued bug fixing
* Missed an XBA to swap tile command bits into a proper index range * Explicitly track the BASE_ADDR * Fix some register overwriting * Add an UpdateSprite method
This commit is contained in:
parent
160606bcc4
commit
3b8bf652e1
|
@ -46,6 +46,9 @@ EngineStartUp ENT
|
||||||
jsr EngineReset ; All of the resources are allocated, put the engine in a known state
|
jsr EngineReset ; All of the resources are allocated, put the engine in a known state
|
||||||
|
|
||||||
jsr InitGraphics ; Initialize all of the graphics-related data
|
jsr InitGraphics ; Initialize all of the graphics-related data
|
||||||
|
jsr InitSprites ; Initialize the sprite subsystem
|
||||||
|
jsr InitTiles ; Initialize the tile subsystem
|
||||||
|
|
||||||
jsr InitTimers ; Initialize the timer subsystem
|
jsr InitTimers ; Initialize the timer subsystem
|
||||||
|
|
||||||
plb
|
plb
|
||||||
|
@ -252,7 +255,6 @@ EngineReset
|
||||||
]step equ ]step+4
|
]step equ ]step+4
|
||||||
--^
|
--^
|
||||||
|
|
||||||
jsr _InitDirtyTiles
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Allow the user to dynamically select one of the pre-configured screen sizes, or pass
|
; Allow the user to dynamically select one of the pre-configured screen sizes, or pass
|
||||||
|
|
|
@ -38,6 +38,7 @@ StopScript EXT
|
||||||
|
|
||||||
; Sprite functions
|
; Sprite functions
|
||||||
AddSprite EXT
|
AddSprite EXT
|
||||||
|
UpdateSprite EXT
|
||||||
|
|
||||||
; Direct access to internals
|
; Direct access to internals
|
||||||
DoScriptSeq EXT
|
DoScriptSeq EXT
|
||||||
|
|
67
src/Sprite.s
67
src/Sprite.s
|
@ -6,20 +6,20 @@
|
||||||
; wider and taller than the physical graphics screen.
|
; wider and taller than the physical graphics screen.
|
||||||
;
|
;
|
||||||
; Initialize the sprite plane data and mask banks (all data = $0000, all masks = $FFFF)
|
; Initialize the sprite plane data and mask banks (all data = $0000, all masks = $FFFF)
|
||||||
_InitSprite
|
InitSprites
|
||||||
ldx #$FFFE
|
ldx #$FFFE
|
||||||
lda #0
|
lda #0
|
||||||
:loop stal spritedata,x
|
:loop1 stal spritedata,x
|
||||||
dex
|
dex
|
||||||
dex
|
dex
|
||||||
bpl :loop
|
bpl :loop1
|
||||||
|
|
||||||
ldx #$FFFE
|
ldx #$FFFE
|
||||||
lda #$FFFF
|
lda #$FFFF
|
||||||
:loop stal spritemask,x
|
:loop2 stal spritemask,x
|
||||||
dex
|
dex
|
||||||
dex
|
dex
|
||||||
bpl :loop
|
bpl :loop2
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ _RenderSprites
|
||||||
; This is the complicated part; we need to draw the sprite into the sprite place, but then
|
; This is the complicated part; we need to draw the sprite into the sprite place, but then
|
||||||
; calculate the code field tiles that this sprite potentially overlaps with and mark those
|
; calculate the code field tiles that this sprite potentially overlaps with and mark those
|
||||||
; tiles as dirty.
|
; tiles as dirty.
|
||||||
:render
|
:render
|
||||||
|
phx ; stash the X register
|
||||||
jsr _DrawTileSprite ; draw the sprite into the sprite plane
|
jsr _DrawTileSprite ; draw the sprite into the sprite plane
|
||||||
|
|
||||||
stz tmp0 ; flags to mark if the sprite is aligned to the code field grid or not
|
stz tmp0 ; flags to mark if the sprite is aligned to the code field grid or not
|
||||||
|
@ -59,7 +60,7 @@ _RenderSprites
|
||||||
sbc #164
|
sbc #164
|
||||||
lsr
|
lsr
|
||||||
lsr
|
lsr
|
||||||
pha ; Save the tile
|
pha ; Save the tile column
|
||||||
|
|
||||||
lda _Sprites+SPRITE_Y,x
|
lda _Sprites+SPRITE_Y,x
|
||||||
clc
|
clc
|
||||||
|
@ -81,10 +82,14 @@ _RenderSprites
|
||||||
tay
|
tay
|
||||||
plx
|
plx
|
||||||
jsr _GetTileStoreOffset ; Get the tile store value
|
jsr _GetTileStoreOffset ; Get the tile store value
|
||||||
jsr _PushDirtyTile ; Enqueue for processing
|
jsr _PushDirtyTile ; Enqueue for processing (Returns offset in Y-register)
|
||||||
|
|
||||||
|
lda #TILE_SPRITE_BIT ; Mark this tile as having a sprite, regardless of whether it was already enqueued
|
||||||
|
sta TileStore+TS_SPRITE_FLAG,y
|
||||||
|
|
||||||
; TODO: Mark adjacent tiles as dirty based on tmp0 and tmp1 values
|
; TODO: Mark adjacent tiles as dirty based on tmp0 and tmp1 values
|
||||||
|
|
||||||
|
plx ; Restore the X register
|
||||||
brl :next
|
brl :next
|
||||||
|
|
||||||
; _GetTileAt
|
; _GetTileAt
|
||||||
|
@ -258,7 +263,7 @@ AddSprite ENT
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
_AddSprite
|
_AddSprite
|
||||||
phx ; Save the parameters
|
phx ; Save the horizontal position and tile ID
|
||||||
pha
|
pha
|
||||||
|
|
||||||
ldx #0
|
ldx #0
|
||||||
|
@ -271,6 +276,7 @@ _AddSprite
|
||||||
|
|
||||||
pla ; Early out
|
pla ; Early out
|
||||||
pla
|
pla
|
||||||
|
sec ; Signal that no sprite slot was available
|
||||||
rts
|
rts
|
||||||
|
|
||||||
:open lda #SPRITE_STATUS_DIRTY
|
:open lda #SPRITE_STATUS_DIRTY
|
||||||
|
@ -284,10 +290,49 @@ _AddSprite
|
||||||
adc #NUM_BUFF_LINES ; The virtual buffer has 24 lines of off-screen space
|
adc #NUM_BUFF_LINES ; The virtual buffer has 24 lines of off-screen space
|
||||||
xba ; Each virtual scan line is 256 bytes wide for overdraw space
|
xba ; Each virtual scan line is 256 bytes wide for overdraw space
|
||||||
clc
|
clc
|
||||||
adc 1,s
|
adc 1,s ; Add the horizontal position
|
||||||
sta _Sprites+VBUFF_ADDR,x
|
sta _Sprites+VBUFF_ADDR,x
|
||||||
|
|
||||||
pla
|
pla ; Pop off the saved value
|
||||||
|
clc ; Mark that the sprite was successfully added
|
||||||
|
txa ; And return the sprite ID
|
||||||
|
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
|
||||||
|
UpdateSprite ENT
|
||||||
|
phb
|
||||||
|
phk
|
||||||
|
plb
|
||||||
|
jsr _UpdateSprite
|
||||||
|
plb
|
||||||
|
rtl
|
||||||
|
|
||||||
|
_UpdateSprite
|
||||||
|
cmp #MAX_SPRITES*2 ; Make sure we're in bounds
|
||||||
|
bcc :ok
|
||||||
|
rts
|
||||||
|
|
||||||
|
:ok
|
||||||
|
phx ; Save the horizontal position
|
||||||
|
tax ; Get the sprite index
|
||||||
|
|
||||||
|
lda #SPRITE_STATUS_DIRTY ; Position is changing, mark as dirty
|
||||||
|
sta _Sprites+SPRITE_STATUS,x ; Mark this sprite slot as occupied and that it needs to be drawn
|
||||||
|
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc #NUM_BUFF_LINES ; The virtual buffer has 24 lines of off-screen space
|
||||||
|
xba ; Each virtual scan line is 256 bytes wide for overdraw space
|
||||||
|
clc
|
||||||
|
adc 1,s ; Add the horizontal position
|
||||||
|
sta _Sprites+VBUFF_ADDR,x
|
||||||
|
|
||||||
|
pla ; Pop off the saved value
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Sprite data structures. We cache quite a few pieces of information about the sprite
|
; Sprite data structures. We cache quite a few pieces of information about the sprite
|
||||||
|
|
|
@ -112,6 +112,7 @@ _RenderTile2
|
||||||
lda TileStore+TS_TILE_ID,y ; build the finalized tile descriptor
|
lda TileStore+TS_TILE_ID,y ; build the finalized tile descriptor
|
||||||
ora TileStore+TS_SPRITE_FLAG,y
|
ora TileStore+TS_SPRITE_FLAG,y
|
||||||
and #TILE_CTRL_MASK
|
and #TILE_CTRL_MASK
|
||||||
|
xba
|
||||||
tax
|
tax
|
||||||
lda TileProcs,x ; load and patch in the appropriate subroutine
|
lda TileProcs,x ; load and patch in the appropriate subroutine
|
||||||
sta :tiledisp+1
|
sta :tiledisp+1
|
||||||
|
@ -123,10 +124,12 @@ _RenderTile2
|
||||||
pha
|
pha
|
||||||
rep #$20
|
rep #$20
|
||||||
lda TileStore+TS_CODE_ADDR_LOW,y ; load the address of the code field
|
lda TileStore+TS_CODE_ADDR_LOW,y ; load the address of the code field
|
||||||
|
pha
|
||||||
|
lda TileStore+TS_BASE_ADDR,y ; load the address of the code field
|
||||||
sta _BASE_ADDR
|
sta _BASE_ADDR
|
||||||
|
|
||||||
lda TileStore+TS_WORD_OFFSET,y
|
lda TileStore+TS_WORD_OFFSET,y
|
||||||
ldy _BASE_ADDR
|
ply
|
||||||
plb ; set the bank
|
plb ; set the bank
|
||||||
|
|
||||||
; B is set to the correct code field bank
|
; B is set to the correct code field bank
|
||||||
|
@ -495,11 +498,26 @@ DirtyTiles ds TILE_STORE_SIZE ; At most this many tiles can possibly
|
||||||
|
|
||||||
; Initialize the tile storage data structures. This takes care of populating the tile records with the
|
; Initialize the tile storage data structures. This takes care of populating the tile records with the
|
||||||
; appropriate constant values.
|
; appropriate constant values.
|
||||||
_InitDirtyTiles
|
InitTiles
|
||||||
:col equ tmp0
|
:col equ tmp0
|
||||||
:row equ tmp1
|
:row equ tmp1
|
||||||
|
|
||||||
ldx #TILE_STORE_SIZE-2 ; Initialize the tile backing store with zeros
|
; Fill in the TileStoreYTable. This is just a table of offsets into the Tile Store for each row. There
|
||||||
|
; are 26 rows with a stride of 41
|
||||||
|
ldy #0
|
||||||
|
lda #0
|
||||||
|
:yloop
|
||||||
|
sta TileStoreYTable,y
|
||||||
|
clc
|
||||||
|
adc #41*2
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
cpy #26*2
|
||||||
|
bcc :yloop
|
||||||
|
|
||||||
|
; Next, initialize the Tile Store itself
|
||||||
|
|
||||||
|
ldx #TILE_STORE_SIZE-2
|
||||||
lda #25
|
lda #25
|
||||||
sta :row
|
sta :row
|
||||||
lda #40
|
lda #40
|
||||||
|
@ -593,12 +611,13 @@ _SetTile
|
||||||
jsr _GetTileStoreOffset0
|
jsr _GetTileStoreOffset0
|
||||||
tay
|
tay
|
||||||
pla
|
pla
|
||||||
|
|
||||||
cmp TileStore+TS_TILE_ID,y
|
cmp TileStore+TS_TILE_ID,y
|
||||||
beq :nochange
|
beq :nochange
|
||||||
|
|
||||||
sta TileStore+TS_TILE_ID,y
|
sta TileStore+TS_TILE_ID,y
|
||||||
tya
|
; tya
|
||||||
jmp _PushDirtyTile
|
; jmp _PushDirtyTile
|
||||||
|
|
||||||
:nochange rts
|
:nochange rts
|
||||||
|
|
||||||
|
@ -606,10 +625,8 @@ _SetTile
|
||||||
; Append a new dirty tile record
|
; Append a new dirty tile record
|
||||||
;
|
;
|
||||||
; A = result of _GetTileStoreOffset for X, Y
|
; A = result of _GetTileStoreOffset for X, Y
|
||||||
; X = tile column [0, 40] (41 columns)
|
|
||||||
; Y = tile row [0, 25] (26 rows)
|
|
||||||
;
|
;
|
||||||
; The main purposed of this function is to
|
; The main purpose of this function is to
|
||||||
;
|
;
|
||||||
; 1. Avoid marking the same tile dirty multiple times, and
|
; 1. Avoid marking the same tile dirty multiple times, and
|
||||||
; 2. Pre-calculating all of the information necessary to render the tile
|
; 2. Pre-calculating all of the information necessary to render the tile
|
||||||
|
@ -623,7 +640,7 @@ _PushDirtyTile
|
||||||
; record fields.
|
; record fields.
|
||||||
|
|
||||||
ldx DirtyTileCount
|
ldx DirtyTileCount
|
||||||
|
|
||||||
txa
|
txa
|
||||||
sta TileStore+TS_DIRTY,y ; Store a back-link to this record
|
sta TileStore+TS_DIRTY,y ; Store a back-link to this record
|
||||||
|
|
||||||
|
@ -661,7 +678,7 @@ _ApplyTiles
|
||||||
bra :begin
|
bra :begin
|
||||||
|
|
||||||
:loop
|
:loop
|
||||||
; Retrieve the offset of the next dirty Tile Store items
|
; Retrieve the offset of the next dirty Tile Store items in the Y-register
|
||||||
|
|
||||||
jsr _PopDirtyTile2
|
jsr _PopDirtyTile2
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user