;License:MIT ;(c) 2018-2020 by 4am ; ; routines for drawing the UI overlay (search bar, browse bar, instructions, cheat mode) ; on top of whatever else is on the screen ; ; Public functions ; - DrawUIWithoutDots ; - DrawUI ; ; Public variables ; - VisibleGameCount (set during init) ; Instructions !text "[Type to search, ? for help ] " VisibleGameCount !text "000 games" ReturnToPlay !byte $0D !text " to play" kCheatsEnabled = 8 ; index of 'cheats enabled' string in following table kCheatDescriptionLo !byte sNoCheats !byte >sInfiniteLives !byte >sInfiniteWeapons !byte >sInfiniteLivesAndWeapons !byte >sInfiniteLivesAndTime !byte >sInfiniteTime !byte >sInvincibility !byte >sInGame !byte >sCheatsEnabled sNoCheats !byte 8 ; length !text "no cheat" sInfiniteLives !byte 18 ; length !byte $16 ; padlock character !text " " !text "infinite lives" !text " " !byte $16 ; padlock character sInfiniteWeapons !byte 20 ; length !byte $16 ; padlock character !text " " !text "infinite weapons" !text " " !byte $16 ; padlock character sInfiniteLivesAndWeapons !byte 28 ; length !byte $16 ; padlock character !text " " !text "infinite lives & weapons" !text " " !byte $16 ; padlock character sInfiniteLivesAndTime !byte 25 ; length !byte $16 ; padlock character !text " " !text "infinite lives & time" !text " " !byte $16 ; padlock character sInfiniteTime !byte 17 ; length !byte $16 ; padlock character !text " " !text "infinite time" !text " " !byte $16 ; padlock character sInvincibility !byte 14 ; length !byte $16 ; padlock character !text " " !text "invincible" !text " " !byte $16 ; padlock character sInGame !byte 18 ; length !byte $16 ; padlock character !text " " !text "in-game cheats" !text " " !byte $16 ; padlock character sCheatsEnabled !byte 18 ; length !byte $16 ; padlock character !text " " !text "cheats enabled" !text " " !byte $16 ; padlock character sCheatDescriptionPrefix !byte 2 ; length !byte $03 ; vertical line character !text " " sCheatDescriptionSuffix !byte 2 ; length !text " " !byte $03 ; vertical line character ;------------------------------------------------------------------------------ ; DrawUIWithoutDots/DrawUI ; draw 2- or 4-line UI on the HGR page that is not currently showing, then ; show that HGR page ; ; in: gGameToLaunch = game index (word), or #$FFFF if no game is selected ; out: all flags and registers clobbered ;------------------------------------------------------------------------------ DrawUIWithoutDots lda #$40 ; " " * 2 +HIDE_NEXT_2_BYTES DrawUI lda #$FF ; #$7F * 2 lsr sta @printCursor+1 ; set up cursor printing based on entry point php ldy #39 - lda Instructions,y sta UILine2,y ; copy instructions to UI line 2 lda #$00 ; horizontal bar character sta UILine1,y ; reset UI line 1 to solid bar sta gPathname,y ; reset cheat UI line 1 to solid bar dey bpl - sta gGameToLaunchInfo ; reset gGameToLaunchInfo lda #40 sta gPathname ; hack, used by first RedrawForDHGR which follows ; Draw40Chars which doesn't set gPathname jsr GetGameToLaunch ; get current game, if any bcs @doneWithLine2 ; if no game, nothing more to do on UI line 2 ; A/Y -> key of current game (in gSearchStore) jsr okvs_next_field ; (PTR) -> display name of current game ; Y = 0 lda (PTR), y tay iny sty SAVE iny lda (PTR), y ; A = game info bitfield sta gGameToLaunchInfo ldy #0 - iny @printCursor lda #$FD ; SMC cpy SAVE bcc @printTitleChar beq @printChar lda #" " +HIDE_NEXT_2_BYTES @printTitleChar lda (PTR),y @printChar sta UILine2,y cpy #MaxInputLength+1 bcc - ldx #8 ; replace games count with 'to play' label - lda ReturnToPlay,x sta UI_ToPlay,x dex bpl - @doneWithLine2 lda MachineStatus and #CHEATS_ENABLED beq @maybeDrawDots ; if cheat mode is disabled, we don't need ; any curves or spaces on UI line 1 jsr CheckCheats ; (SAVE) -> length-prefixed string ; (game-specific description or 'cheats enabled' message) ldy #0 lda (SAVE),y ; A = string length clc adc #4 ; extra padding (2 on each side) sta @len lda #40 sec sbc @len lsr tax lda #$09 ; rounded bottom-right character sta UILine1,x iny ; fill the proper width with spaces lda #$20 ; space character - inx sta UILine1,x iny @len=*+1 cpy #$FD ; SMC bne - lda #$0C ; rounded bottom-left character sta UILine1,x @maybeDrawDots plp bcc @doneHighlight ; if caller asked for no dots, then we're done building UI line 1 ldx #0 ldy #0 @dotloop iny lda (PTR),y ; (PTR) still points to game display name ora #$20 ; force lower-case always cmp InputBuffer,x bne + lda #$11 ; dot character sta UILine1,y inx cpx InputLength ; if input buffer is exhausted, we're done drawing dots beq @doneHighlight + inc HTAB cpy SAVE ; if game name is exhausted, we're done drawing dots bne @dotloop @doneHighlight lda #22 sta VTAB lda OffscreenPage ror php +LDADDR UILine1 jsr Draw40Chars ; draw UI line 1 on offscreen page jsr MaybeRedrawUIForDHGR ; transform for DHGR if this is a DHGR title screen plp gDrawingOnscreen=*+1 lda #$00 ; SMC, might be 1 bne @uidone +LDADDR UILine2 jsr Draw40Chars ; draw UI line 2 on offscreen page jsr MaybeRedrawUIForDHGR ; transform for DHGR if this is a DHGR title screen lda MachineStatus and #CHEATS_ENABLED beq @uidone ; if cheats are disabled, then we're done drawing UI ; (SAVE) still points to length-prefixed cheat description ldy #0 lda (SAVE),y ; A = length of cheat description clc adc #4 ; extra padding (2 on each side) sta gPathname ; gPathname = length tax lda #$07 ; gPathname+length = top-right rounded corner character sta gPathname,x lda #$06 ; gPathname+1 = top-left rounded corner character sta gPathname+1 lda #20 sta VTAB lda OffscreenPage ror php +LDADDR gPathname jsr DrawCenteredString ; draw cheat UI line 1 jsr MaybeRedrawUIForDHGR ; transform for DHGR if this is a DHGR title screen jsr CheckCheats ; (SAVE) -> length-prefixed cheat description +LDADDR sCheatDescriptionPrefix jsr SetPath +LD16 SAVE jsr AddToPath +LDADDR sCheatDescriptionSuffix jsr AddToPath plp +LDADDR gPathname jsr DrawCenteredString ; draw cheat UI line 2 jsr MaybeRedrawUIForDHGR ; transform for DHGR if this is a DHGR title screen @uidone lda #0 sta gDrawingOnscreen bit MachineStatus bvc + bit gGameToLaunchInfo bpl + jmp ShowOtherDHGRPage + jmp ShowOtherPage ;------------------------------------------------------------------------------ ; internal functions CheckCheats ; out: (SAVE) -> length-prefixed string, either a game-specific description ; or the global 'cheats enabled' message ldx #kCheatsEnabled jsr AnyGameSelected bcs + gGameToLaunchInfo=*+1 lda #$FD ; SMC and #CHEAT_CATEGORY tax + lda kCheatDescriptionLo,x sta SAVE lda kCheatDescriptionHi,x sta SAVE+1 OVERLAYRTS rts MaybeRedrawUIForDHGR ; If this is a DHGR title screen, then redraw the already-drawn overlay ; for double hi-res. This allows us to use a single font and drawing ; routines for both HGR and DHGR. There is a small amount of flicker ; if we're redrawing directly on the visible screen without swapping ; pages (e.g. adding a dot without changing the selected game), but ; gDrawingOnscreen tracks this and we reduce the redrawing to an ; absolute minimum to reduce flicker. bit MachineStatus bvc OVERLAYRTS bit gGameToLaunchInfo bpl OVERLAYRTS jmp RedrawForDHGR