mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2025-02-16 10:32:20 +00:00
Checkpoint for initial framing for compiled sprite support
This commit is contained in:
parent
981182592e
commit
e2e30dfcf4
@ -228,13 +228,14 @@ TILE_CTRL_MASK equ $FE00
|
|||||||
; TILE_PROC_MASK equ $F800 ; Select tile proc for rendering
|
; TILE_PROC_MASK equ $F800 ; Select tile proc for rendering
|
||||||
|
|
||||||
; Sprite constants
|
; Sprite constants
|
||||||
SPRITE_HIDE equ $2000
|
SPRITE_COMPILED equ $4000 ; This is a compiled sprite (SPRITE_DISP points to a routine in the compiled cache bank)
|
||||||
|
SPRITE_HIDE equ $2000 ; Do not render the sprite
|
||||||
SPRITE_16X16 equ $1800 ; 16 pixels wide x 16 pixels tall
|
SPRITE_16X16 equ $1800 ; 16 pixels wide x 16 pixels tall
|
||||||
SPRITE_16X8 equ $1000 ; 16 pixels wide x 8 pixels tall
|
SPRITE_16X8 equ $1000 ; 16 pixels wide x 8 pixels tall
|
||||||
SPRITE_8X16 equ $0800 ; 8 pixels wide x 16 pixels tall
|
SPRITE_8X16 equ $0800 ; 8 pixels wide x 16 pixels tall
|
||||||
SPRITE_8X8 equ $0000 ; 8 pixels wide x 8 pixels tall
|
SPRITE_8X8 equ $0000 ; 8 pixels wide x 8 pixels tall
|
||||||
SPRITE_VFLIP equ $0400
|
SPRITE_VFLIP equ $0400 ; Flip the sprite vertically
|
||||||
SPRITE_HFLIP equ $0200
|
SPRITE_HFLIP equ $0200 ; Flip the sprite horizontally
|
||||||
|
|
||||||
; Stamp storage parameters
|
; Stamp storage parameters
|
||||||
VBUFF_STRIDE_BYTES equ {12*4} ; Each line has 4 slots of 16 pixels + 8 buffer pixels
|
VBUFF_STRIDE_BYTES equ {12*4} ; Each line has 4 slots of 16 pixels + 8 buffer pixels
|
||||||
|
71
src/Render.s
71
src/Render.s
@ -341,7 +341,9 @@ _RenderWithShadowing
|
|||||||
; to create priority lists of scanline ranges.
|
; to create priority lists of scanline ranges.
|
||||||
|
|
||||||
jsr _BuildShadowList ; Create the rages based on the sorted sprite y-values
|
jsr _BuildShadowList ; Create the rages based on the sorted sprite y-values
|
||||||
jsr _ComplementList ; Create the complement to identify non-sprite scanlines
|
; jsr _MergeOverlay ; Add the overlay range into the shadow list (treat it as a sprite)
|
||||||
|
|
||||||
|
jsr _ComplementList ; Create the complement to identify non-sprite / non-overlay scanlines
|
||||||
|
|
||||||
jsr _ShadowOff ; Turn off shadowing and draw all the scanlines with sprites on them
|
jsr _ShadowOff ; Turn off shadowing and draw all the scanlines with sprites on them
|
||||||
jsr _DrawShadowList
|
jsr _DrawShadowList
|
||||||
@ -484,7 +486,7 @@ _BuildShadowList
|
|||||||
|
|
||||||
ldx _SortedHead
|
ldx _SortedHead
|
||||||
bmi :empty
|
bmi :empty
|
||||||
bra :insert
|
bra :insert
|
||||||
|
|
||||||
; Start of loop
|
; Start of loop
|
||||||
:advance
|
:advance
|
||||||
@ -496,7 +498,7 @@ _BuildShadowList
|
|||||||
sta _ShadowListTop,y ; Set the top entry of the list to the sprite top
|
sta _ShadowListTop,y ; Set the top entry of the list to the sprite top
|
||||||
|
|
||||||
lda _Sprites+SPRITE_CLIP_BOTTOM,x ; Optimistically set the end of the segment to the bottom of this sprite
|
lda _Sprites+SPRITE_CLIP_BOTTOM,x ; Optimistically set the end of the segment to the bottom of this sprite
|
||||||
inc
|
inc ; Clip values are on the scanline, so add one to make it a proper interval
|
||||||
|
|
||||||
:replace
|
:replace
|
||||||
sta _ShadowListBottom,y
|
sta _ShadowListBottom,y
|
||||||
@ -603,13 +605,25 @@ _DrawDirectSprites
|
|||||||
bmi :empty
|
bmi :empty
|
||||||
|
|
||||||
:loop
|
:loop
|
||||||
phx
|
lda _Sprites+SPRITE_STATUS,x
|
||||||
jsr _DrawStampToScreen
|
bit #SPRITE_STATUS_HIDDEN
|
||||||
plx
|
bne :next
|
||||||
|
|
||||||
lda _Sprites+SORTED_NEXT,x ; If there another sprite in the list?
|
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
|
tax
|
||||||
bpl :loop
|
bpl :loop
|
||||||
|
|
||||||
:empty
|
:empty
|
||||||
rts
|
rts
|
||||||
@ -633,6 +647,8 @@ _DrawComplementList
|
|||||||
lda _DirectListTop,x
|
lda _DirectListTop,x
|
||||||
ldy _DirectListBottom,x
|
ldy _DirectListBottom,x
|
||||||
tax
|
tax
|
||||||
|
lda #0
|
||||||
|
jsr DebugSCBs
|
||||||
jsr _BltRange
|
jsr _BltRange
|
||||||
plx
|
plx
|
||||||
|
|
||||||
@ -646,6 +662,8 @@ _DrawComplementList
|
|||||||
phx
|
phx
|
||||||
ldy _DirectListTop,x
|
ldy _DirectListTop,x
|
||||||
tax
|
tax
|
||||||
|
lda #1
|
||||||
|
jsr DebugSCBs
|
||||||
jsr _PEISlam
|
jsr _PEISlam
|
||||||
plx
|
plx
|
||||||
bra :blt_range
|
bra :blt_range
|
||||||
@ -655,6 +673,41 @@ _DrawComplementList
|
|||||||
bcs :out ; screen, then expose that range
|
bcs :out ; screen, then expose that range
|
||||||
tax
|
tax
|
||||||
ldy ScreenHeight
|
ldy ScreenHeight
|
||||||
|
lda #1
|
||||||
|
jsr DebugSCBs
|
||||||
jsr _PEISlam
|
jsr _PEISlam
|
||||||
:out
|
:out
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
; Helper to set a palette index on a range of SCBs to help show whicih actions are applied to which lines
|
||||||
|
DebugSCBs
|
||||||
|
phx
|
||||||
|
phy
|
||||||
|
sep #$30 ; short m/x
|
||||||
|
|
||||||
|
pha ; save the SCB value
|
||||||
|
|
||||||
|
phx
|
||||||
|
tya
|
||||||
|
sec
|
||||||
|
sbc 1,s
|
||||||
|
tay ; number of scanlines
|
||||||
|
|
||||||
|
pla
|
||||||
|
clc
|
||||||
|
adc ScreenY0
|
||||||
|
tax ; physical line index
|
||||||
|
|
||||||
|
pla
|
||||||
|
:loop
|
||||||
|
stal SHR_SCB,x
|
||||||
|
inx
|
||||||
|
dey
|
||||||
|
bne :loop
|
||||||
|
|
||||||
|
rep #$30
|
||||||
|
ply
|
||||||
|
plx
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,129 @@
|
|||||||
; Draw a sprite directly to the graphics screen. No clipping / bounds checking is performed
|
; Compile a stamp into a compilation cache
|
||||||
|
_CompileStamp
|
||||||
|
_lines equ tmp0
|
||||||
|
_width0 equ tmp1
|
||||||
|
_width equ tmp2
|
||||||
|
baseAddr equ tmp3
|
||||||
|
destAddr equ tmp4
|
||||||
|
vbuffAddr equ tmp5
|
||||||
|
|
||||||
|
lda _Sprites+SPRITE_HEIGHT,x
|
||||||
|
sta _lines
|
||||||
|
|
||||||
|
lda _Sprites+SPRITE_WIDTH,x ; Width in bytes (4 or 8)
|
||||||
|
lsr
|
||||||
|
sta
|
||||||
|
sta _width0
|
||||||
|
|
||||||
|
lda _Sprites+SPRITE_DISP,x ; Get the address of the stamp
|
||||||
|
sta vbuffAddr
|
||||||
|
tax
|
||||||
|
|
||||||
|
ldy CompileBankTop ; First free byte in the compilation bank
|
||||||
|
|
||||||
|
phb
|
||||||
|
pei CompileBank
|
||||||
|
plb
|
||||||
|
plb ; Set the bank to the compilation cache
|
||||||
|
|
||||||
|
stz baseAddr
|
||||||
|
stz destAddr
|
||||||
|
|
||||||
|
:oloop
|
||||||
|
lda _width0
|
||||||
|
sta _width
|
||||||
|
|
||||||
|
:iloop
|
||||||
|
ldal spritemask,x
|
||||||
|
beq :no_mask ; If Mask == $0000, then it's a solid word
|
||||||
|
cmp #$FFFF
|
||||||
|
beq :next ; If Mask == $FFFF, then it's transparent
|
||||||
|
|
||||||
|
; Mask with the screen data
|
||||||
|
lda #LDA_ABS_X_OPCODE
|
||||||
|
sta: 0,y
|
||||||
|
lda destAddr
|
||||||
|
sta: 1,y
|
||||||
|
sta: 10,y
|
||||||
|
lda #AND_IMM_OPCODE
|
||||||
|
sta: 3,y
|
||||||
|
ldal spritemask,x
|
||||||
|
sta: 4,y
|
||||||
|
lda #ORA_IMM_OPCODE
|
||||||
|
sta: 6,y
|
||||||
|
ldal spritedata,x
|
||||||
|
sta: 7,y
|
||||||
|
lda #STA_ABS_X_OPCODE
|
||||||
|
sta: 9,y
|
||||||
|
|
||||||
|
tya
|
||||||
|
adc #12
|
||||||
|
tay
|
||||||
|
bra :next
|
||||||
|
|
||||||
|
; Just store the data
|
||||||
|
:no_mask lda #LDA_IMM_OPCODE
|
||||||
|
sta: 0,y
|
||||||
|
ldal spritedata,x
|
||||||
|
sta: 1,y
|
||||||
|
|
||||||
|
lda #STA_ABS_X_OPCODE
|
||||||
|
sta: 3,y
|
||||||
|
lda destAddr
|
||||||
|
sta: 4,y
|
||||||
|
|
||||||
|
tya
|
||||||
|
adc #6
|
||||||
|
tay
|
||||||
|
|
||||||
|
:next
|
||||||
|
inx
|
||||||
|
inx
|
||||||
|
|
||||||
|
inc destAddr ; Move to the next word
|
||||||
|
inc destAddr
|
||||||
|
|
||||||
|
dec _width
|
||||||
|
bne :iloop
|
||||||
|
|
||||||
|
lda vbuffAddr
|
||||||
|
adc #SPRITE_PLANE_SPAN
|
||||||
|
sta vbuffAddr
|
||||||
|
tax
|
||||||
|
|
||||||
|
lda baseAddr ; Move to the next line
|
||||||
|
adc #160
|
||||||
|
sta baseAddr
|
||||||
|
sta destAddr
|
||||||
|
|
||||||
|
dec lines
|
||||||
|
bne :oloop
|
||||||
|
|
||||||
|
lda #RTL_OPCODE ; Finish up the subroutine
|
||||||
|
sta: 0,y
|
||||||
|
iny
|
||||||
|
sty CompileBankTop
|
||||||
|
|
||||||
|
plb
|
||||||
|
rts
|
||||||
|
|
||||||
|
; Draw a sprite directly to the graphics screen. If sprite is clipped at all, do not draw.
|
||||||
;
|
;
|
||||||
; X = sprite record index
|
; X = sprite record index
|
||||||
|
_DSTSOut
|
||||||
|
rts
|
||||||
|
|
||||||
_DrawStampToScreen
|
_DrawStampToScreen
|
||||||
|
lda _Sprites+IS_OFF_SCREEN,x ; If the sprite is off-screen, don't draw it
|
||||||
|
bne _DSTSOut
|
||||||
|
|
||||||
|
lda _Sprites+SPRITE_CLIP_WIDTH,x ; If the sprite is clipped to the playfield, don't draw it
|
||||||
|
cmp _Sprites+SPRITE_WIDTH,x
|
||||||
|
bne _DSTSOut
|
||||||
|
lda _Sprites+SPRITE_CLIP_HEIGHT,x
|
||||||
|
cmp _Sprites+SPRITE_HEIGHT,x
|
||||||
|
bne _DSTSOut
|
||||||
|
|
||||||
clc
|
clc
|
||||||
lda _Sprites+SPRITE_Y,x
|
lda _Sprites+SPRITE_Y,x
|
||||||
adc ScreenY0
|
adc ScreenY0
|
||||||
|
@ -61,7 +61,7 @@ SPRITE_HEIGHT equ {MAX_SPRITES*28}
|
|||||||
SPRITE_CLIP_WIDTH equ {MAX_SPRITES*30}
|
SPRITE_CLIP_WIDTH equ {MAX_SPRITES*30}
|
||||||
SPRITE_CLIP_HEIGHT equ {MAX_SPRITES*32}
|
SPRITE_CLIP_HEIGHT equ {MAX_SPRITES*32}
|
||||||
TS_VBUFF_BASE equ {MAX_SPRITES*34} ; Finalized VBUFF address based on the sprite position and tile offsets
|
TS_VBUFF_BASE equ {MAX_SPRITES*34} ; Finalized VBUFF address based on the sprite position and tile offsets
|
||||||
SORTED_PREV equ {MAX_SPRITES*36}
|
SORTED_PREV equ {MAX_SPRITES*36} ; Doubly-Linked List that maintains the sprites in sorted order based on SPRITE_Y
|
||||||
SORTED_NEXT equ {MAX_SPRITES*38}
|
SORTED_NEXT equ {MAX_SPRITES*38}
|
||||||
|
|
||||||
; 52 rows by 82 columns + 2 extra rows and columns for sprite sizes
|
; 52 rows by 82 columns + 2 extra rows and columns for sprite sizes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user