4cade/src/textrank.a

240 lines
6.2 KiB
Plaintext
Raw Normal View History

2019-06-18 14:56:05 -04:00
;license:MIT
2020-04-01 11:57:21 -04:00
;(c) 2018-2020 by 4am & qkumba
2019-06-18 14:56:05 -04:00
;
; text rank - an implementation of the Quicksilver search rank algorithm
;
; Public functions
2021-10-28 01:26:21 -04:00
; - ReloadSearchIndex
2019-06-26 22:51:34 -04:00
; - ResetTextRank
2021-11-06 19:12:40 -04:00
; - FindTitleInCache
2019-06-18 14:56:05 -04:00
; - TextRankCallback (as okvs_iter_values callback)
;
; Public variables
2019-06-26 22:51:34 -04:00
; - InputLength ; [byte] number of characters typed in search mode
; - InputBuffer ; [25 bytes] characters typed in search mode
2020-04-01 11:57:21 -04:00
;
; Zero page variables
; - SelectedIndex ; [byte] index in gSearchStore of currently selected game in search mode
2019-06-26 22:51:34 -04:00
; - 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 gSearchStore of current best match (updated during TextRankCallback)
2019-06-18 14:56:05 -04:00
MaxInputLength = 26
2019-06-18 14:56:05 -04:00
InputLength
!byte 0
InputBuffer
!text " "
2020-04-01 11:57:21 -04:00
;------------------------------------------------------------------------------
2021-10-28 01:26:21 -04:00
; ReloadSearchIndex
;
; Load index to support search UI
2020-04-01 11:57:21 -04:00
;
; in: none
; out: gSearchStore populated
;------------------------------------------------------------------------------
2021-10-28 01:26:21 -04:00
ReloadSearchIndex
2021-10-23 00:53:23 -04:00
jsr LoadFile ; load appropriate search index into $8200
!word kRootDirectory
!word kSearchIndexFile
2021-11-06 19:12:40 -04:00
!word gSearchIndex
jsr LoadFile ; load appropriate search cache into $B000
!word kRootDirectory
!word kSearchCacheFile
!word gSearchCache
rts
FindTitleInCache
ldx InputLength
cpx #5
bcs @nomatch
lda #$20
sta InputBuffer, x
+LDADDR gSearchCache
+ST16 PTR
ldx #$FF
-- inx
ldy #0
- lda (PTR), y
beq @nomatch
cmp InputBuffer, x
beq @matchchar
iny
iny
iny
bne - ; always branches
@matchchar
iny
lda (PTR), y
pha
iny
lda (PTR), y
bpl @foundindex
sta PTR+1
pla
sta PTR
cpx InputLength
bcc --
@nomatch
sec
rts
@foundindex
sta BestMatchIndex+1
pla
sta BestMatchIndex
clc
rts
2019-06-18 13:52:35 -07:00
;------------------------------------------------------------------------------
; 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
2019-06-18 17:07:14 -04:00
dex
2019-06-18 13:52:35 -07:00
stx BestMatchIndex
2020-03-24 16:30:14 -04:00
stx BestMatchIndex+1
2019-06-18 13:52:35 -07:00
rts
2019-06-18 14:56:05 -04:00
;------------------------------------------------------------------------------
; TextRankCallback
; callback called by okvs_iter_values on gSearchStore
; to calculate a ranking score for a single game display name
2019-06-18 14:56:05 -04:00
; against the current InputBuffer
; in: A/Y contains address of game display name
2020-03-24 16:30:14 -04:00
; $WINDEX contains 0-based index of the current record in gSearchStore (word)
2019-06-18 14:56:05 -04:00
; out: all registers and flags clobbered
; MatchCount possibly incremented (if this game was a match at all)
; BestMatchScore and BestMatchIndex possibly updated (if this game
2019-06-18 14:56:05 -04:00
; was the best match so far)
;------------------------------------------------------------------------------
TextRankCallback
2020-03-24 16:30:14 -04:00
+ST16 zpstring ; A/Y = address of this game display name
2019-06-18 14:56:05 -04:00
+LDADDR InputLength
2020-03-24 16:30:14 -04:00
+ST16 zpword
2019-06-30 15:10:09 -04:00
ldy #0
lda (zpstring),y
2020-11-09 12:22:38 -08:00
tax
dex
cpx InputLength
2019-07-04 19:03:14 -07:00
bcc ++
sta gamelength
2019-09-23 17:01:42 -07:00
sty runningscore
sty runningscore+1
iny
2019-06-18 14:56:05 -04:00
sty startat
- sty i
lda (zpword),y
2020-11-09 12:22:38 -08:00
jsr tolower
2019-06-18 14:56:05 -04:00
sta tmp
ldy startat
-- lda (zpstring),y
2020-11-09 12:22:38 -08:00
jsr tolower
2019-06-18 14:56:05 -04:00
cmp tmp
beq +
cpy gamelength
iny
bcc --
2019-07-04 19:03:14 -07:00
++ rts ; no match :(
+ ldx #80
2019-06-18 14:56:05 -04:00
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
2019-07-04 19:03:14 -07:00
+ tya
2019-06-18 14:56:05 -04:00
ldy i
cpy InputLength
2019-07-04 19:03:14 -07:00
bcs +
2019-06-18 14:56:05 -04:00
iny
2019-07-04 19:03:14 -07:00
sta startat
inc startat
cmp gamelength
2019-06-18 14:56:05 -04:00
bcc -
2019-07-04 19:03:14 -07:00
rts ; no match :(
+ lda runningscore
2019-06-18 14:56:05 -04:00
ldx runningscore+1
ldy gamelength
jsr @div
sta tmp
lda runningscore
ldx runningscore+1
ldy InputLength
jsr @div
clc
adc tmp
lsr
2020-04-23 14:10:01 -07:00
adc #0 ; round fractions up
2019-06-18 14:56:05 -04:00
pha
ldy #1
lda (zpstring),y
2020-11-09 12:22:38 -08:00
jsr tolower
2019-06-18 14:56:05 -04:00
sta firstletter
pla
ldx InputBuffer
cpx firstletter
bne +
cmp #85
bcs +
adc #15
+ cmp BestMatchScore
2019-06-18 14:56:05 -04:00
bcc +
2019-06-27 13:15:48 -07:00
beq +
2019-06-18 14:56:05 -04:00
sta BestMatchScore
2020-03-24 16:30:14 -04:00
lda WINDEX
sta BestMatchIndex
lda WINDEX+1
sta BestMatchIndex+1
2019-06-18 14:56:05 -04:00
inc MatchCount
+ rts
2019-06-18 14:56:05 -04:00
@div
sta num1
stx num1+1
sty num2
2019-06-18 14:56:05 -04:00
lda #0
sta remainder
sta remainder+1
2019-06-18 14:56:05 -04:00
ldx #16
- asl num1
rol num1+1
rol remainder
rol remainder+1
lda remainder
2019-06-18 14:56:05 -04:00
sec
sbc num2
2019-06-18 14:56:05 -04:00
bcc +
sta remainder
dec remainder+1
inc num1
2019-06-18 14:56:05 -04:00
+ dex
bne -
lda num1
2019-06-18 14:56:05 -04:00
rts
2020-11-09 12:22:38 -08:00
tolower
cmp #$41
bcc +
cmp #$5B
bcs +
ora #$20
+ rts