;license:MIT ;(c) 2018 by 4am ; ; Search Mode - incrementally search game catalog ; ; Public functions ; - SearchMode ; ; indices into InputDispatchTable kInputSearchKey= 0 kInputBackspace= 1 kInputEnter = 2 InputDispatchTable !word OnSearchKey !word OnBackspace !word OnEnter SearchMode jsr Home ; switches to text mode lda #0 sta InputLength jsr OnInputChanged bit $C054 ; show it bit $C052 bit $C057 bit $C050 bit $C010 InputLoop - lda $C000 bpl - bit $C010 and #$7F cmp #$7F ; delete key bne + - jsr ResetTextRank ldx #kInputBackspace bne InputDispatch ; always branches + cmp #$08 ; left arrow = delete beq - cmp #$0D ; ENTER launches the current game (if any) bne + ldx #kInputEnter bne InputDispatch ; always branches + cmp #$30 ; control keys and punctuation ignored bcc @badkey cmp #$3A ; numbers are good input bcc @goodkey cmp #$41 ; more punctuation (also ignored) bcc @badkey cmp #$5B ; uppercase letters are good input bcs + ora #$20 ; convert uppercase letters to lowercase bne @goodkey ; always branches + cmp #$61 ; more punctuation (also ignored) bcc @badkey cmp #$7B ; lowercase letters are good input bcc @goodkey ; execution falls through here @badkey jsr SoftBell ; beep on invalid input jmp InputLoop ; and start over @goodkey ldx #kInputSearchKey ; execution falls through here InputDispatch pha ; save key pressed txa asl tax lda InputDispatchTable,x sta @j+1 lda InputDispatchTable+1,x sta @j+2 pla ; restore key pressed @j jsr $FDFD ; SMC jmp InputLoop OnBackspace ldx InputLength bne + jsr SoftBell rts + dec InputLength jmp OnInputChanged OnEnter ; TODO rts OnSearchKey ldx InputLength cpx #MaxInputLength bne + jsr SoftBell rts + sta InputBuffer,x inc InputLength ; execution falls through here OnInputChanged lda InputLength bne @findMatchingTitle ; no input, reset params and UI lda #$FF sta SelectedIndex ; reset selected index ldx #40 ; reset visible line lda #0 - sta UILine1-1,x dex bne - ldy #MaxInputLength ; clear visible search bar lda #" " - sta UILine2+1,y dey bne - lda #$7F sta UILine2+1 +LDADDR Cover jsr SetPath jsr LoadFile ; load default background at $2000 lda #22 ; draw visible search bar sta VTAB clc ; on page 1 +LDADDR UILine1 jsr Draw40Chars clc +LDADDR UILine2 jmp Draw40Chars @findMatchingTitle jsr ResetTextRank jsr okvs_iter_values ; iterate through all game titles !word gGamesListStore ; and rank them for the best match !word TextRankCallback ; to the current input buffer lda MatchCount ; check match count bne @yeschange jsr SoftBell ; no matches for this input buffer, beep dec InputLength ; and ignore the last key typed @nochange rts @yeschange lda BestMatchIndex cmp SelectedIndex ; we found a 'new' best match but it's the beq @nochange ; same as the current match, so we're done ; TODO re-highlight here sta SelectedIndex ; we have a new best match, so load the sta @index ; new title screenshot and display the jsr okvs_nth ; new game title in the search bar !word gGamesListStore @index !byte $FD +STAY @key ; load game title page at $4000 (page 2, not currently visible) +LOAD_FILE kHGRTitleDirectory, @key jsr okvs_get !word gGamesListStore @key !word $FDFD +STAY SRC ; A/Y points to game title (in OKVS) ldy #0 ; copy game title into search bar buffer lda (SRC),y sta SAVE ; game title length inc SAVE - iny cpy SAVE bcc + lda #" " +HIDE_NEXT_2_BYTES + lda (SRC),y sta UILine2,y cpy #MaxInputLength+1 bcc - ldx #40 lda #0 - sta UILine1-1,x dex bne - tay - lda (SRC),y +LOW_ASCII_TO_LOWER cmp InputBuffer,x bne + lda #$0B ; dot to highlight matched character sta UILine1,y inx cpx InputLength beq @doneHighlight + inc HTAB iny cpy #40 bne - @doneHighlight lda #22 ; draw search bar sta VTAB sec ; on page 2, not currently visible +LDADDR UILine1 jsr Draw40Chars sec +LDADDR UILine2 jsr Draw40Chars dec VTAB bit $C055 ; show page 2 ldx #$20 ; copy back to page 1 stx @b+2 ; TODO delete this and use LoadFileAt lda #$40 ; to load title screenshots on different sta @a+2 ; pages ldy #0 @a lda $4000,y @b sta $2000,y iny bne @a inc @a+2 inc @b+2 dex bne @a bit $C054 ; show page 1 rts ;------------------------------------------------------------------------------ Cover !byte 5 !text "COVER" 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 !text "[" !byte $7F !text " " !text "] 000 games"