Expose the ability to select which rendering order to use for sprites

This commit is contained in:
Lucas Scharenbroich 2023-03-09 00:23:12 -06:00
parent c533d846d7
commit 39163ea786
5 changed files with 2269 additions and 2187 deletions

View File

@ -26,17 +26,36 @@ DTile equ 14
Tmp2 equ 16
ScreenWidth equ 18
ScreenHeight equ 20
SpriteFlags equ 22
frameCount equ 24
OldOneSecondCounter equ 26
SpriteAddr equ 28
RenderMode equ 30
; Control modes
DefaultMode equ RENDER_WITH_SHADOWING
SlowSprites equ 0
; Typical init
phk
plb
sta MyUserId ; GS/OS passes the memory manager user ID for the application into the program
tdc
sta MyDirectPage ; Keep a copy for the overlay callback
_MTStartUp ; GTE requires the miscellaneous toolset to be running
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER
lda #ENGINE_MODE_USER_TOOL ; +ENGINE_MODE_TWO_LAYER
jsr GTEStartUp ; Load and install the GTE User Tool
; Init local variables
stz frameCount
lda #DefaultMode
sta RenderMode
; Initialize the graphics screen to a 256x160 playfield
pea #160
@ -46,7 +65,7 @@ ScreenHeight equ 20
; Load a tileset
pea 0
pea 120
pea 360
pea #^TSZelda
pea #TSZelda
_GTELoadTileSet
@ -59,6 +78,14 @@ ScreenHeight equ 20
jsr SetLimits
lda #193 ; Tile ID of '0'
jsr InitOverlay ; Initialize the status bar
pha
_GTEGetSeconds
pla
sta OldOneSecondCounter
jsr UdtOverlay
; Create stamps for the sprites we are going to use
HERO_SPRITE equ SPRITE_16X16+1
@ -66,6 +93,23 @@ HERO_SPRITE equ SPRITE_16X16+1
pea VBUFF_SPRITE_START ; vbuff address
_GTECreateSpriteStamp
DO SlowSprites
lda #SPRITE_16X16
sta SpriteFlags
lda #VBUFF_SPRITE_START
sta SpriteAddr
ELSE
lda #SPRITE_16X16+SPRITE_COMPILED
sta SpriteFlags
pha ; Space for result
pea SPRITE_16X16
pea VBUFF_SPRITE_START
_GTECompileSpriteStamp
pla
sta SpriteAddr
FIN
; Create sprites
stz Tmp0
stz Tmp1 ; Slot number
@ -73,8 +117,8 @@ HERO_SPRITE equ SPRITE_16X16+1
ldx Tmp0
:sloop
pei Tmp1 ; Put the sprite in this slot
pea SPRITE_16X16 ; with these flags (h/v flip)
pea VBUFF_SPRITE_START
pei SpriteFlags ; with these flags (h/v flip)
pei SpriteAddr
lda PlayerX,x
pha
lda PlayerY,x
@ -93,10 +137,6 @@ HERO_SPRITE equ SPRITE_16X16+1
jsr _fillTileStore
; Initialize the frame counter
stz FrameCount
; Set the screen coordinates
lda #0
@ -118,49 +158,60 @@ HERO_SPRITE equ SPRITE_16X16+1
brl :do_render
:do_more
and #$007F
cmp #'a'
cmp #'a' ; Put in single-step advance mode
bne :skip_a
:a_loop
jsr :next_frame
:a_spin
pha ; space for result, with pattern
_GTEReadControl
pla
bit #PAD_KEY_DOWN
bne :a_spin
and #$007F
cmp #'r' ; resume?
beq :do_render
cmp #'s'
beq :toggle_sort
cmp #'a'
beq :a_loop
bra :a_spin
:toggle_sort lda RenderMode
eor #RENDER_SPRITES_SORTED
sta RenderMode
pei RenderMode
_GTERender
bra :a_spin
:skip_a
:do_render jsr :next_frame
brl :evt_loop
:next_frame
jsr _moveSprites
inc ScreenX
inc ScreenY
pei ScreenX
pei ScreenY
_GTESetBG0Origin
brl :do_render
:skip_a
cmp #'z'
bne :skip_z
inc PlayerX
pea 0
lda PlayerX
pha
lda PlayerY
pha
_GTEMoveSprite
:skip_z
:do_render
jsr _moveSprites
pea #RENDER_WITH_SHADOWING
pei RenderMode
_GTERender
; Update the performance counters
inc FrameCount
inc frameCount
pha
_GTEGetSeconds
pla
cmp LastSecond
beq :no_fps
sta LastSecond
; lda FrameCount
; ldx #0
; ldy #$FFFF
; jsr DrawWord
stz FrameCount
:no_fps
brl :evt_loop
cmp OldOneSecondCounter
beq :noudt
sta OldOneSecondCounter
jsr UdtOverlay
stz frameCount
:noudt
rts
; Shut down everything
Exit
@ -170,11 +221,17 @@ qtRec adrl $0000
da $00
; Array of sprite positions and velocities
DO 1
PlayerX dw 8,14,29,34,45,67,81,83,92,101,39,22,7,74,111,9
PlayerY dw 72,24,13,56,35,72,23,8,93,123,134,87,143,14,46,65
PlayerU dw 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4
PlayerV dw 1,1,1,1,2,2,2,4,3,3,3,3,4,4,4,4
ELSE
PlayerX dw 2,12,22,32,42,52,62,72,2,12,22,32,42,52,62,72,
PlayerY dw 24,24,24,24,24,24,24,24,44,44,44,44,44,44,44,44
PlayerU dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
PlayerV dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
FIN
_moveSprites
stz Tmp0
:loop
@ -280,15 +337,15 @@ _fillTileStore
jsr _drawTree
lda Tmp1
inc
inc
clc
adc #2
sta Tmp1
cmp #40
bcc :iloop
lda Tmp0
inc
inc
clc
adc #2
sta Tmp0
cmp #25
bcc :oloop
@ -427,11 +484,12 @@ _drawTreeHV
_GTESetTile
rts
MyDirectPage ds 2
MyUserId ds 2
FrameCount ds 2
LastSecond dw 0
palette dw $0000,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$023E,$0,$0,$0,$0,$0
palette dw $0000,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$0FD7,$0F59,$0000,$01CE,$0EDA,$0EEE
PUT ../kfest-2022/StartUp.s
PUT App.Msg.s
PUT font.s
PUT ../shell/Overlay.s
; PUT App.Msg.s
; PUT font.s

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,7 @@ RENDER_BG1_VERT_OFFSET equ $0004
RENDER_BG1_ROTATION equ $0008
RENDER_PER_SCANLINE equ $0010
RENDER_WITH_SHADOWING equ $0020
RENDER_SPRITES_SORTED equ $0040
; Overlay flags
OVERLAY_MASKED equ $0000 ; Overlay has a mask, so the background must be draw first

View File

@ -175,6 +175,7 @@ RENDER_BG1_VERT_OFFSET equ $0004
RENDER_BG1_ROTATION equ $0008
RENDER_PER_SCANLINE equ $0010
RENDER_WITH_SHADOWING equ $0020
RENDER_SPRITES_SORTED equ $0040 ; Draw the sprites in y-sorted order. Otherwise, use the index.
; Overlay flags
OVERLAY_MASKED equ $0000 ; Overlay has a mask, so the background must be draw first

View File

@ -156,7 +156,6 @@ _DoOverlay
; Use the per-scanline tables to set the screen. This is really meant to be used without the built-in tilemap
; support and is more of a low-level way to control the background rendering
_RenderScanlines
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
jsr _ApplyBG1YPos ; Set the y-register values of the blitter
@ -343,9 +342,6 @@ _RenderWithShadowing
; to create priority lists of scanline ranges.
jsr _BuildShadowList ; Create the rages based on the sorted sprite y-values
; 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
@ -604,30 +600,55 @@ _DrawShadowList
; Run through the list of sprites that are not IS_OFFSCREEN and not OVERLAYS and draw them directly to the graphics screen. We can use
; compiled sprites here, with limitations.
_DrawDirectSprites
lda RenderFlags
bit #RENDER_SPRITES_SORTED
bne :sorted
; Shift through the sprites
lda SpriteMap
beq :empty
sta tmp15
ldx #0
:iloop
lsr tmp15
bcc :next
jsr :render
:next inx
inx
lda tmp15
bne :iloop
rts
:sorted
ldx _SortedHead
bmi :empty
:loop
lda _Sprites+SPRITE_ID,x
bit #SPRITE_OVERLAY
bne :next
lda _Sprites+SPRITE_STATUS,x
bit #SPRITE_STATUS_HIDDEN
bne :next
phx
jsr _DrawStampToScreen
plx
bra :next
:next
jsr :render
lda _Sprites+SORTED_NEXT,x ; If there another sprite in the list?
tax
bpl :loop
:empty
rts
:render
lda _Sprites+SPRITE_ID,x
bit #SPRITE_OVERLAY
beq *+3
rts
lda _Sprites+SPRITE_STATUS,x
bit #SPRITE_STATUS_HIDDEN
beq *+3
rts
phx
jsr _DrawStampToScreen
plx
rts
; Run through the sorted list and perform a final render the jumps between calling _PEISlam for shadowed lines,
; _BltRange for clean backgrounds and Overlays as needed.
;
@ -653,7 +674,7 @@ _DrawFinalPass
bmi :empty
lda _Sprites+SPRITE_CLIP_TOP,x ; Load the first object's top edge
sta :curr_top
; sta :curr_top
beq :loop ; If it's at the top edge of the screen, proceed. Othrewise _BltRange the top range
ldx #0
@ -669,7 +690,7 @@ _DrawFinalPass
lda _Sprites+SPRITE_CLIP_TOP,x
sta :curr_top
lda _Sprites+SPRITE_CLIP_BOTTOM,x ; Optimistically set the end of the segment to the bottom of this object
inc ; Clip values are on the scanline, so add one to make it a proper interval
inc ; Clip values are on the scanline, so add one to make it a proper interval
:update
sta :curr_bottom
@ -762,6 +783,8 @@ _DrawFinalPass
lda ScreenAddr,x
clc
adc ScreenX0
ldx :curr_top
ldy :curr_bottom
:disp jsl $000000
rts