;license:MIT ;(c) 2018-9 by 4am & qkumba ; ; text rank - an implementation of the Quicksilver search rank algorithm ; ; Public functions ; - ResetTextRank ; - TextRankCallback (as okvs_iter_values callback) ; ; Public variables ; - InputLength ; [byte] number of characters typed in search mode ; - InputBuffer ; [25 bytes] characters typed in search mode ; - SelectedIndex ; [byte] index in gGamesListStore of currently selected game in search mode ; - MatchCount ; [byte] number of games that match InputBuffer ; - BestMatchScore ; [byte] raw ranking score (0-100) of current best match (updated during TextRankCallback) ; - BestMatchIndex ; [byte] index in gGamesListStore of current best match (updated during TextRankCallback) MaxInputLength = 26 InputLength !byte 0 InputBuffer !text " " ;------------------------------------------------------------------------------ ; ResetTextRank ; reset the Match variables to allow re-scanning (e.g. because of backspace) ; in: nothing ; out: X, MatchCount, BestMatchScore, BestMatchIndex zeroed ;------------------------------------------------------------------------------ ResetTextRank ldx #0 stx MatchCount stx BestMatchScore dex stx BestMatchIndex rts ;------------------------------------------------------------------------------ ; TextRankCallback ; callback called by okvs_iter_values on gGamesListStore ; to calculate a ranking score for a single game title ; against the current InputBuffer ; in: A/Y contains address of game title ; X contains 0-based index of the current record in gGamesListStore ; out: all registers and flags clobbered ; MatchCount possibly incremented (if this title was a match at all) ; BestMatchScore and BestMatchIndex possibly updated (if this title ; was the best match so far) ;------------------------------------------------------------------------------ TextRankCallback stx tmpx ; X = OKVS index of this title +STAY zpstring ; A/Y = address of this title +LDADDR InputLength +STAY zpword ldy #0 lda (zpstring),y cmp InputLength bcc ++ sta gamelength sty runningscore sty runningscore+1 iny sty startat - sty i lda (zpword),y +LOW_ASCII_TO_LOWER sta tmp ldy startat -- lda (zpstring),y +LOW_ASCII_TO_LOWER cmp tmp beq + cpy gamelength iny bcc -- ++ rts ; no match :( + ldx #80 cpy startat beq + ldx #10 cpy #1 beq + dey lda (zpstring),y iny cmp #' ' bne + ldx #90 + txa clc adc runningscore sta runningscore bcc + inc runningscore+1 + tya ldy i cpy InputLength bcs + iny sta startat inc startat cmp gamelength bcc - rts ; no match :( + lda runningscore ldx runningscore+1 ldy gamelength jsr @div sta tmp lda runningscore ldx runningscore+1 ldy InputLength jsr @div clc adc tmp lsr pha ldy #1 lda (zpstring),y +LOW_ASCII_TO_LOWER sta firstletter pla ldx InputBuffer cpx firstletter bne + cmp #85 bcs + adc #15 + cmp BestMatchScore bcc + beq + sta BestMatchScore ldx tmpx stx BestMatchIndex inc MatchCount + rts @div sta num1 stx num1+1 sty num2 lda #0 sta remainder sta remainder+1 ldx #16 - asl num1 rol num1+1 rol remainder rol remainder+1 lda remainder sec sbc num2 bcc + sta remainder dec remainder+1 inc num1 + dex bne - lda num1 rts