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 Tmp2 equ 16
ScreenWidth equ 18 ScreenWidth equ 18
ScreenHeight equ 20 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 ; Typical init
phk phk
plb plb
sta MyUserId ; GS/OS passes the memory manager user ID for the application into the program 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 _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 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 ; Initialize the graphics screen to a 256x160 playfield
pea #160 pea #160
@ -46,7 +65,7 @@ ScreenHeight equ 20
; Load a tileset ; Load a tileset
pea 0 pea 0
pea 120 pea 360
pea #^TSZelda pea #^TSZelda
pea #TSZelda pea #TSZelda
_GTELoadTileSet _GTELoadTileSet
@ -59,6 +78,14 @@ ScreenHeight equ 20
jsr SetLimits 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 ; Create stamps for the sprites we are going to use
HERO_SPRITE equ SPRITE_16X16+1 HERO_SPRITE equ SPRITE_16X16+1
@ -66,6 +93,23 @@ HERO_SPRITE equ SPRITE_16X16+1
pea VBUFF_SPRITE_START ; vbuff address pea VBUFF_SPRITE_START ; vbuff address
_GTECreateSpriteStamp _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 ; Create sprites
stz Tmp0 stz Tmp0
stz Tmp1 ; Slot number stz Tmp1 ; Slot number
@ -73,8 +117,8 @@ HERO_SPRITE equ SPRITE_16X16+1
ldx Tmp0 ldx Tmp0
:sloop :sloop
pei Tmp1 ; Put the sprite in this slot pei Tmp1 ; Put the sprite in this slot
pea SPRITE_16X16 ; with these flags (h/v flip) pei SpriteFlags ; with these flags (h/v flip)
pea VBUFF_SPRITE_START pei SpriteAddr
lda PlayerX,x lda PlayerX,x
pha pha
lda PlayerY,x lda PlayerY,x
@ -93,10 +137,6 @@ HERO_SPRITE equ SPRITE_16X16+1
jsr _fillTileStore jsr _fillTileStore
; Initialize the frame counter
stz FrameCount
; Set the screen coordinates ; Set the screen coordinates
lda #0 lda #0
@ -118,49 +158,60 @@ HERO_SPRITE equ SPRITE_16X16+1
brl :do_render brl :do_render
:do_more :do_more
and #$007F and #$007F
cmp #'a' cmp #'a' ; Put in single-step advance mode
bne :skip_a 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 ScreenX
inc ScreenY
pei ScreenX pei ScreenX
pei ScreenY pei ScreenY
_GTESetBG0Origin _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 _GTERender
; Update the performance counters ; Update the performance counters
inc FrameCount inc frameCount
pha pha
_GTEGetSeconds _GTEGetSeconds
pla pla
cmp LastSecond cmp OldOneSecondCounter
beq :no_fps beq :noudt
sta LastSecond sta OldOneSecondCounter
jsr UdtOverlay
; lda FrameCount stz frameCount
; ldx #0 :noudt
; ldy #$FFFF rts
; jsr DrawWord
stz FrameCount
:no_fps
brl :evt_loop
; Shut down everything ; Shut down everything
Exit Exit
@ -170,11 +221,17 @@ qtRec adrl $0000
da $00 da $00
; Array of sprite positions and velocities ; 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 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 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 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 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 _moveSprites
stz Tmp0 stz Tmp0
:loop :loop
@ -280,15 +337,15 @@ _fillTileStore
jsr _drawTree jsr _drawTree
lda Tmp1 lda Tmp1
inc clc
inc adc #2
sta Tmp1 sta Tmp1
cmp #40 cmp #40
bcc :iloop bcc :iloop
lda Tmp0 lda Tmp0
inc clc
inc adc #2
sta Tmp0 sta Tmp0
cmp #25 cmp #25
bcc :oloop bcc :oloop
@ -427,11 +484,12 @@ _drawTreeHV
_GTESetTile _GTESetTile
rts rts
MyDirectPage ds 2
MyUserId ds 2 MyUserId ds 2
FrameCount ds 2 palette dw $0000,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$0FD7,$0F59,$0000,$01CE,$0EDA,$0EEE
LastSecond dw 0
palette dw $0000,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$023E,$0,$0,$0,$0,$0
PUT ../kfest-2022/StartUp.s PUT ../kfest-2022/StartUp.s
PUT App.Msg.s PUT ../shell/Overlay.s
PUT font.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_BG1_ROTATION equ $0008
RENDER_PER_SCANLINE equ $0010 RENDER_PER_SCANLINE equ $0010
RENDER_WITH_SHADOWING equ $0020 RENDER_WITH_SHADOWING equ $0020
RENDER_SPRITES_SORTED equ $0040
; Overlay flags ; Overlay flags
OVERLAY_MASKED equ $0000 ; Overlay has a mask, so the background must be draw first 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_BG1_ROTATION equ $0008
RENDER_PER_SCANLINE equ $0010 RENDER_PER_SCANLINE equ $0010
RENDER_WITH_SHADOWING equ $0020 RENDER_WITH_SHADOWING equ $0020
RENDER_SPRITES_SORTED equ $0040 ; Draw the sprites in y-sorted order. Otherwise, use the index.
; Overlay flags ; Overlay flags
OVERLAY_MASKED equ $0000 ; Overlay has a mask, so the background must be draw first 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 ; 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 ; support and is more of a low-level way to control the background rendering
_RenderScanlines _RenderScanlines
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
jsr _ApplyBG1YPos ; Set the y-register values of the blitter jsr _ApplyBG1YPos ; Set the y-register values of the blitter
@ -343,9 +342,6 @@ _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 _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
@ -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 ; 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. ; compiled sprites here, with limitations.
_DrawDirectSprites _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 ldx _SortedHead
bmi :empty bmi :empty
:loop :loop
lda _Sprites+SPRITE_ID,x jsr :render
bit #SPRITE_OVERLAY
bne :next
lda _Sprites+SPRITE_STATUS,x
bit #SPRITE_STATUS_HIDDEN
bne :next
phx
jsr _DrawStampToScreen
plx
bra :next
:next
lda _Sprites+SORTED_NEXT,x ; If there another sprite in the list? lda _Sprites+SORTED_NEXT,x ; If there another sprite in the list?
tax tax
bpl :loop bpl :loop
:empty :empty
rts 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, ; 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. ; _BltRange for clean backgrounds and Overlays as needed.
; ;
@ -653,7 +674,7 @@ _DrawFinalPass
bmi :empty bmi :empty
lda _Sprites+SPRITE_CLIP_TOP,x ; Load the first object's top edge 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 beq :loop ; If it's at the top edge of the screen, proceed. Othrewise _BltRange the top range
ldx #0 ldx #0
@ -669,7 +690,7 @@ _DrawFinalPass
lda _Sprites+SPRITE_CLIP_TOP,x lda _Sprites+SPRITE_CLIP_TOP,x
sta :curr_top sta :curr_top
lda _Sprites+SPRITE_CLIP_BOTTOM,x ; Optimistically set the end of the segment to the bottom of this object 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 :update
sta :curr_bottom sta :curr_bottom
@ -762,6 +783,8 @@ _DrawFinalPass
lda ScreenAddr,x lda ScreenAddr,x
clc clc
adc ScreenX0 adc ScreenX0
ldx :curr_top
ldy :curr_bottom
:disp jsl $000000 :disp jsl $000000
rts rts