mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-11-25 15:32:59 +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
|
||||
|
||||
; 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_16X8 equ $1000 ; 16 pixels wide x 8 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_VFLIP equ $0400
|
||||
SPRITE_HFLIP equ $0200
|
||||
SPRITE_VFLIP equ $0400 ; Flip the sprite vertically
|
||||
SPRITE_HFLIP equ $0200 ; Flip the sprite horizontally
|
||||
|
||||
; Stamp storage parameters
|
||||
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.
|
||||
|
||||
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 _DrawShadowList
|
||||
@ -484,7 +486,7 @@ _BuildShadowList
|
||||
|
||||
ldx _SortedHead
|
||||
bmi :empty
|
||||
bra :insert
|
||||
bra :insert
|
||||
|
||||
; Start of loop
|
||||
:advance
|
||||
@ -496,7 +498,7 @@ _BuildShadowList
|
||||
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
|
||||
inc
|
||||
inc ; Clip values are on the scanline, so add one to make it a proper interval
|
||||
|
||||
:replace
|
||||
sta _ShadowListBottom,y
|
||||
@ -603,13 +605,25 @@ _DrawDirectSprites
|
||||
bmi :empty
|
||||
|
||||
:loop
|
||||
phx
|
||||
jsr _DrawStampToScreen
|
||||
plx
|
||||
lda _Sprites+SPRITE_STATUS,x
|
||||
bit #SPRITE_STATUS_HIDDEN
|
||||
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
|
||||
bpl :loop
|
||||
bpl :loop
|
||||
|
||||
:empty
|
||||
rts
|
||||
@ -633,6 +647,8 @@ _DrawComplementList
|
||||
lda _DirectListTop,x
|
||||
ldy _DirectListBottom,x
|
||||
tax
|
||||
lda #0
|
||||
jsr DebugSCBs
|
||||
jsr _BltRange
|
||||
plx
|
||||
|
||||
@ -646,6 +662,8 @@ _DrawComplementList
|
||||
phx
|
||||
ldy _DirectListTop,x
|
||||
tax
|
||||
lda #1
|
||||
jsr DebugSCBs
|
||||
jsr _PEISlam
|
||||
plx
|
||||
bra :blt_range
|
||||
@ -655,6 +673,41 @@ _DrawComplementList
|
||||
bcs :out ; screen, then expose that range
|
||||
tax
|
||||
ldy ScreenHeight
|
||||
lda #1
|
||||
jsr DebugSCBs
|
||||
jsr _PEISlam
|
||||
: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
|
||||
_DSTSOut
|
||||
rts
|
||||
|
||||
_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
|
||||
lda _Sprites+SPRITE_Y,x
|
||||
adc ScreenY0
|
||||
|
@ -61,7 +61,7 @@ SPRITE_HEIGHT equ {MAX_SPRITES*28}
|
||||
SPRITE_CLIP_WIDTH equ {MAX_SPRITES*30}
|
||||
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
|
||||
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}
|
||||
|
||||
; 52 rows by 82 columns + 2 extra rows and columns for sprite sizes
|
||||
|
Loading…
Reference in New Issue
Block a user