;license:MIT ;(c) 2018-9 by 4am ; ; common UI functions ; ; Public functions ; - WaitForKeyFor30Seconds ; - GetOffscreenAddress ; - LoadTitleOffscreen ; - LoadCoverOffscreen ; - DrawSearchBarOffscreen ; - ClearOffscreen ; - ShowOtherPage ; - ToggleOffscreenPage ; - CoverFade ; - ResetInputTimeout ; - SoftBell ; - Home ; - BlankHGR ; - BlankDHGR ; Public variables ; - OffscreenPage ; - UILine1 ; - UILine2 ; - VisibleGameCount (set during init) ; !zone { OffscreenPage !byte 1 ; 0 = currently showing HGR page 2 ; (so offscreen is page 1 @ $2000) ; 1 = currently showing HGR page 1 ; (so offscreen is page 2 @ $4000) UILine1 !byte 0,0,0,0,0,0,0,0,0,0 !byte 0,0,0,0,0,0,0,0,0,0 !byte 0,0,0,0,0,0,0,0,0,0 !byte 0,0,0,0,0,0,0,0,0,0 UILine2 !byte 0,0,0,0,0,0,0,0,0,0 !byte 0,0,0,0,0,0,0,0,0,0 !byte 0,0,0,0,0,0,0,0,0,0 !byte 0 UI_ToPlay !byte 0,0,0,0,0,0,0,0,0 Instructions !text "[Type to search, " !byte $0B !text " to browse] " VisibleGameCount !text "000 games" ReturnToPlay !byte $0D !text " to play" GetOffscreenAddress ; in: none ; out: A = high byte of offscreen HGR page (#$20 or #$40) ; preserves X/Y lda OffscreenPage beq + lda #$40 rts + lda #$20 rts LoadTitleOffscreen ; clobbers all +LDADDR .TitleFile bne + ; Always branches, because Y is loaded ; last with the high byte of the address, ; which is never 0. I miss my 65c02. LoadCoverOffscreen ; clobbers all +LDADDR .CoverFile + jsr SetPath jsr GetOffscreenAddress sta + jsr LoadFileAt !byte $00 + !byte $FD ; SMC rts .TitleFile !byte 5 !text "TITLE" .CoverFile !byte 5 !text "COVER" CoverFade ; clobbers all jsr LoadCoverOffscreen jsr ShowOtherPage lda OffscreenPage bne + jsr LoadCoverOffscreen jsr ShowOtherPage + ; load transition effect code at $6000 +LDADDR kFXDirectory jsr SetPath +LDADDR @CoverFadeFile jsr AddToPath jsr LoadFile jmp $6000 ; exit via loaded code @CoverFadeFile !byte 9 !text "COVERFADE" DrawSearchBarOffscreen ; clobbers all LDA #22 ; draw visible search bar sta VTAB lda OffscreenPage ror ; draw on offscreen page +LDADDR UILine1 jsr Draw40Chars lda OffscreenPage ror ; draw on offscreen page +LDADDR UILine2 jmp Draw40Chars ShowOtherPage ; in: none ; out: A = new value of OffscreenPage ; preserves X/Y jsr ToggleOffscreenPage bne + bit PAGE2 ; show page 2 rts + bit PAGE1 ; show page 1 rts ToggleOffscreenPage ; in: none ; out: A = new value of OffscreenPage ; preserves X/Y lda OffscreenPage eor #$01 sta OffscreenPage rts ResetInputTimeout ; clobbers X, preserves A/Y ldx #$16 stx Timeout stx Timeout+1 stx Timeout+2 rts WaitForKeyFor30Seconds lda KBD bmi @gotKey inc RNDSEED+1 ; these are only ever incremented, never bne + ; reset (may be used as a pseudorandom inc RNDSEED ; seed) + dec Timeout ; these are a 3-byte timeout counter bne WaitForKeyFor30Seconds; that counts down from a number set dec Timeout+1 ; in .ResetInputTimeout and reset bne WaitForKeyFor30Seconds; on every keypress (whether or not dec Timeout+2 ; the key leads to an action) bne WaitForKeyFor30Seconds jsr CoverFade ; no input for ~30 seconds, switch to jmp MegaAttractMode ; mega-attract mode @gotKey rts ;------------------------------------------------------------------------------ ; SoftBell ; yell at the user, but, like, gently ; ; in: none ; out: all registers and flags preserved ;------------------------------------------------------------------------------ SoftBell php pha txa pha ldx #32 - lda #2 jsr @wait bit SPEAKER lda #33 jsr @wait bit SPEAKER dex bne - pla tax pla plp rts @wait ; identical to $FCA8 ROM routine, but ROM is switched out when we need it sec -- pha - sbc #1 bne - pla sbc #1 bne -- rts ;------------------------------------------------------------------------------ ; Home ; clear and display text screen (HARDER THAN IT SOUNDS) ; ; in: none ; out: $0106..$011F clobbered ;------------------------------------------------------------------------------ Home lda MachineStatus and #SUPPORTS_SHR beq @noSHR lda NEWVIDEO and #$3F sta NEWVIDEO ; get out of SHR mode and linear mode lda #$F0 sta TBCOLOR ; white text on black background lda #$00 sta CLOCKCTL ; black border sta CLOCKCTL ; set twice for VidHD @noSHR ldx #(@end-@start-1) - lda @start,x sta $106,x dex bpl - jmp $106 @start ; this will be run from main memory +READ_ROM_NO_WRITE sta CLR80VID ; get out of DHGR mode sta DHIRESOFF ; get out of DHGR mode jsr ROM_TEXT ; TEXT jsr ROM_HOME ; HOME +READ_RAM1_WRITE_RAM1 rts @end ;------------------------------------------------------------------------------ ; BlankHGR ; clear and show HGR page 1 without flickering ; ; in: none ; out: text page clobbered (but screen holes preserved) ; $2000..$3FFF cleared ;------------------------------------------------------------------------------ BlankHGR jsr Home jsr .ClearHGR1 ; clear hi-res screen 1 bit PAGE1 ; show hi-res screen 1 (now blank) +HGR_MODE rts ;------------------------------------------------------------------------------ ; BlankDHGR ; clear and show DHGR page 1 without flickering ; ; in: none ; out: text page clobbered (but screen holes preserved) ; $2000..$3FFF/main and /aux cleared ;------------------------------------------------------------------------------ BlankDHGR jsr Home jsr .ClearHGR1 ; clear hi-res screen 1 sta WRITEAUXMEM jsr .ClearHGR1 ; clear hi-res screen 1 in auxmem sta WRITEMAINMEM sta SET80VID bit PAGE1 +HGR_MODE sta DHIRESON rts ExecuteTransitionAndWait +STAY @j+1 @j jsr $FDFD ; SMC call transition effect code ldx #$20 ; picture is showing so now we wait - lda #0 jsr WaitForKeyWithTimeout bmi + dex bpl - + rts ;------------------------------------------------------------------------------ ; .ClearHGR1 [private] ; clear $2000..$3FFF in current memory bank (main or auxmem) ; does not change HGR mode ; ; in: none ; out: $2000..$3FFF cleared ; A = 0 ; X = 0 ; Y = 0 ; Z = 1 ;------------------------------------------------------------------------------ ClearOffscreen jsr GetOffscreenAddress +HIDE_NEXT_2_BYTES .ClearHGR1 lda #$20 sta @a+2 ldx #$20 lda #$80 ldy #0 @a sta $2000,y iny bne @a inc @a+2 dex bne @a rts }