Added some border effects to title screen

Also added support for interactive stateful animations
This commit is contained in:
blondie7575 2023-07-29 16:31:17 -07:00
parent dae1462c97
commit 3199c94eb5
5 changed files with 363 additions and 29 deletions

View File

@ -80,7 +80,6 @@
70E266E31F6F262D005AC7E4 /* circleTable.s */,
70F0869F1F413A89002446C3 /* player.s */,
70BCB0CE2A4FC92D00B19803 /* sound.s */,
709816A32A53B21800108D9C /* GenerateSoundBank.sh */,
705456882A4D336200A2B866 /* animation.s */,
700B5E6F2069831000B31C00 /* inventory.s */,
700F21DF1F4A364600D7007D /* projectile.s */,
@ -94,6 +93,7 @@
7076E9222A57AED90006E295 /* CompileFont.py */,
70FE79D21F8814A600E0095C /* MerlinToCA65.sh */,
700F72872112428D00225B17 /* RenumberSpriteFiles.sh */,
709816A32A53B21800108D9C /* GenerateSoundBank.sh */,
701E70912A6DA4D80030C35D /* GenerateRawImage.py */,
7088096D1F2ECE8D00D4C950 /* GenerateRenderSpans.py */,
7059502B1F37A0BE00BBE90F /* GenerateVRAMTable.py */,

View File

@ -7,11 +7,115 @@
ANIMATION_SIZE_16x16=0
ANIMATION_SIZE_16x32=2
MAX_TICKS = 180
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; startAnimation
;
; Starts a stated animation, which allows interactivity, but requires ticking
;
; Y = Base sprite index
; X = Number of frames
; A = Animation size (use constants above)
; PARAML0 = Pointer to X,Y (16 bits each, Y is bottom relative)
;
; Trashes A,X,Y,PARAML0
;
startAnimation:
sta animationState+AS_SIZE
sty animationState+AS_BASESPRITE
sty animationState+AS_CURRENTFRAME
; Compute final frame
stx animationState+AS_FINALFRAME
tya
clc
adc animationState+AS_FINALFRAME
sta animationState+AS_FINALFRAME
jsr vramPtr
cpx #$ffff
beq startAnimationSkip
stx animationState+AS_VRAM
lda #MAX_TICKS
sta animationState+AS_TICKS
; Preserve background
ldy animationState+AS_VRAM
ldx animationState+AS_SIZE
jsr (protectionRoutines,x)
; Render first animation frame
ldy animationState+AS_VRAM
lda animationState+AS_CURRENTFRAME
jsr drawSpriteBankSafe
startAnimationSkip:
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; tickAnimation
;
; Call this once per frame to update the current stated animation
;
; A->0 if finished
;
tickAnimation:
SAVE_XY
; Advance tick
dec animationState+AS_TICKS
bne tickAnimationSkip
; Reset tick count
lda #MAX_TICKS
sta animationState+AS_TICKS
; Advance frame
lda animationState+AS_CURRENTFRAME
inc
cmp animationState+AS_FINALFRAME
beq tickAnimationDone
sta animationState+AS_CURRENTFRAME
; Restore background
ldy animationState+AS_VRAM
ldx animationState+AS_SIZE
jsr (unrenderRoutines,x)
; Render new animation frame
ldy animationState+AS_VRAM
lda animationState+AS_CURRENTFRAME
jsr drawSpriteBankSafe
bra tickAnimationSkip
tickAnimationDone:
; Restore background
ldy animationState+AS_VRAM
ldx animationState+AS_SIZE
jsr (unrenderRoutines,x)
lda #$ffff
sta animationState+AS_CURRENTFRAME
lda #0
RESTORE_XY
rts
tickAnimationSkip:
lda #1
RESTORE_XY
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderAnimation
;
; Plays an entire animation statelessly, which is easier if you don't need interactivity
;
; Y = Base sprite index
; X = Number of frames
; A = Animation size (use constants above)
@ -25,7 +129,6 @@ renderAnimation:
phx ; Calculate VRAM position
jsr vramPtr
BREAK
cpx #$ffff
beq renderAnimationSkip
stx SCRATCHL2
@ -78,6 +181,21 @@ protectionRoutines:
unrenderRoutines:
.word unrenderAnimation16x16,unrenderAnimation16x32
animationState:
.word $ffff ; Current frame ff = inactive
.word 0 ; Total Frames
.word 0 ; Ticks until next frame
.word 0 ; Animation size
.word 0 ; VRAM Position
.word 0 ; Base Sprite
AS_CURRENTFRAME = 0
AS_FINALFRAME = 2 ; Actually final frame +1
AS_TICKS = 4
AS_SIZE = 6
AS_VRAM = 8
AS_BASESPRITE = 10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; protectAnimation16x16

View File

@ -82,16 +82,212 @@ bottomFillLoop:
initSCBs:
lda #0
ldx #$0100 ;set all $100 scbs to A
ldx #200 ;set all 200 scbs to A
initSCBsLoop:
dex
dex
sta $e19d00,x
bne initSCBsLoop
jsr setScanLineInterruptVector
jsr setVBLInterruptVector
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; setScanLineInterruptVector
;
; Install scanline interrupt handler
;
setScanLineInterruptVector:
; Save current handler
lda $e10029
sta scanlineHandlerCache
BITS8A
lda $e1002b
sta scanlineHandlerCache+2
BITS16
; Set our handler
lda #scanLineInterruptHandler
sta $e10029
BITS8A
lda #2 ; This code bank
sta $e1002b
BITS16
rts
scanlineHandlerCache:
.byte 0,0,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; unsetScanLineInterruptVector
;
; Remove scanline interrupt handler
;
unsetScanLineInterruptVector:
; Turn off scanline interrupts
BITS8A
lda $e0c023 ; Disable scaline interrupts
and #%11111101
sta $e0c023
BITS16
; Restore saved handler
lda scanlineHandlerCache
sta $e10029
BITS8A
lda scanlineHandlerCache+2
sta $e1002b
BITS16
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; setVBLInterruptVector
;
; Install VBL interrupt handler
;
setVBLInterruptVector:
; Save current handler
lda $e10031
sta vblHandlerCache
BITS8A
lda $e10033
sta vblHandlerCache+2
BITS16
; Set our handler
lda #vblInterruptHandler
sta $e10031
BITS8A
lda #2 ; This code bank
sta $e10033
BITS16
; Enable VBL interrupts
lda $e0c041
ora #%00001000
sta $e0c041
rts
vblHandlerCache:
.byte 0,0,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; unsetVBLInterruptVector
;
; Remove VBL handler
;
unsetVBLInterruptVector:
; Turn off VBL interrupts
BITS8A
lda $e0c041 ; Disable VBL interrupts
and #%11110111
sta $e0c041
BITS16
; Restore saved handler
lda vblHandlerCache
sta $e10031
BITS8A
lda vblHandlerCache+2
sta $e10033
BITS16
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; vblInterruptHandler
;
; Handler for IRQ.VBL (vector E1/0030-0033)
;
vblInterruptHandler:
OP8
lda #0 ; Clear scanline interrupt source
sta $e0c047
; lda BORDERCOLOR
; and #$f0
; ora #$7 ; Set to sky at bottom of screen
; sta BORDERCOLOR
clc
rtl
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; setBorderAtScanLine
;
; X = Scan Line Number
;
; Trashes A
;
setBorderAtScanLine:
dex ; Scanline interrupts technically fire on the previous line
BITS8A
lda $e19d00,x ; Enable interrupt on requested scanline
ora #%01000000
sta $e19d00,x
; lda $e19dc7 ; Enable interrupt on scanline 199
; ora #%01000000
; sta $e19dc7
lda $e0c023 ; Enable scaline interrupts, if needed
ora #%00000010
sta $e0c023
BITS16
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; scanLineInterruptHandler
;
; Handler for IRQ.SCAN (vector E1/0028-002B)
;
scanLineInterruptHandler:
OP8
lda $e0c032 ; Clear scanline interrupt source
and #%11011111
sta $e0c032
; lda scanLineColorChangePhaseCounter
; beq scanLineInterruptHandler0
; lda BORDERCOLOR ; Set border color
; and #$f0
; ora #$7 ; Set to sky at bottom of screen
; sta BORDERCOLOR
; dec scanLineColorChangePhaseCounter
; bra scanLineInterruptHandlerDone
scanLineInterruptHandler0:
lda BORDERCOLOR ; Set border color to grass at given scanline
and #$f0
ora #$4
sta BORDERCOLOR
; inc scanLineColorChangePhaseCounter
scanLineInterruptHandlerDone:
clc
rtl
scanLineColorChangePhaseCounter:
.byte 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; setScanlinePalette
; Set the palette for a given scan line
@ -192,29 +388,26 @@ drawSpriteBankSafe:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Alternate vertical blank checkers
; syncOverscanBottom
;
.if 0
; The Brutal Deluxe version, taken from LemminGS
;
nextVBL:
lda #75
pha
nextVBL0:
lda $e0c02e
and #$7f
cmp 1,s
blt nextVBL0
cmp #100
bge nextVBL0
pla
waitVBL:
lda $e0c018
bpl waitVBL
; Waits for the bottom edge of the overscan region (give or take)
syncOverscanBottom:
BITS8
syncOverscanBottom0:
ldaA $C02f
asl ; VA is now in the Carry flag
ldaA $C02e
rol ; Roll Carry into bit 0
cmp #215 ; A now contains line number
blt syncOverscanBottom0
BITS16
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Alternate vertical blank checkers
;
; The Apple version, taken from GS Tech Note 039
;
syncVBL:
@ -245,6 +438,6 @@ waitVBLToStart:
BITS16
rts
.endif
.include "spritebank.s"

View File

@ -25,6 +25,8 @@ mainBank2:
jmp titleScreen
quitGame:
jsr unsetVBLInterruptVector
jsr unsetScanLineInterruptVector
NORMALMEMORY
CLASSICVIDEO
jml (PRODOSRETURN)

View File

@ -23,7 +23,6 @@ CAT1_VRAM = $5da0
; Shows the title screen and main game menu
;
titleScreen:
lda #%10000000 ; Set all SCBs to 320, no interrupts, palette 0
jsr initSCBs
stz leftScreenEdge
@ -52,6 +51,9 @@ titleScreenCopyLoop:
; Render menu text
jsr titleScreenRenderMenu
ldx #147
jsr setBorderAtScanLine
; Fade in
lda #titlePalette
sta PARAML2
@ -63,44 +65,60 @@ titleScreenCopyLoop:
titleScreenMainLoop:
; Track animations
jsr nextVBL
;jsr syncOverscanBottom
jsr syncVBL
BORDER_COLOR #$7
lda titleAnimationCounter
inc
cmp TITLE_ANIMATION_FRAMES
jsr titleScreenResetAnimation
; Time animations of cats
; Update current animation if needed
lda animationState+AS_CURRENTFRAME
bmi titleScreenIdle
jsr tickAnimation
bra titleScreenKeyboard
titleScreenIdle:
; Time start of cat 0 animation
lda animationDelay0
dec
bne titleScreenStillCat
lda #CAT_DELAY
sta animationDelay0
; Start new cat 0 animation
ldy #CAT0_VRAM
jsr unrenderAnimation16x16
; Render next frame of cats
lda #titleAnimationPos0
sta PARAML0
ldx #TITLE_ANIMATION_FRAMES
ldy #30
lda #ANIMATION_SIZE_16x32
jsr renderAnimation
jsr startAnimation
bra titleScreenNextCat
titleScreenStillCat:
; Render idle cat 0
sta animationDelay0
ldy #CAT0_VRAM
lda #29
jsr drawSpriteBankSafe
titleScreenNextCat:
; Time start of cat 1 animation
lda animationDelay1
dec
bne titleScreenStillCat2
lda #CAT_DELAY
sta animationDelay1
; Start new cat 1 animation
ldy #CAT1_VRAM
jsr unrenderAnimation16x16
@ -109,16 +127,19 @@ titleScreenNextCat:
ldx #TITLE_ANIMATION_FRAMES
ldy #21
lda #ANIMATION_SIZE_16x32
jsr renderAnimation
jsr startAnimation
bra titleScreenKeyboard
titleScreenStillCat2:
; Render idle cat 1
sta animationDelay1
ldy #CAT1_VRAM
lda #20
jsr drawSpriteBankSafe
titleScreenKeyboard:
; Check for selection
jsr kbdScanTitle
jsr kbdScanDebug