mirror of
https://github.com/a2-4am/4cade.git
synced 2024-11-26 17:49:43 +00:00
WIP search mode
This commit is contained in:
parent
007c25bd44
commit
cd689703a6
6
Makefile
6
Makefile
@ -101,9 +101,9 @@ dsk: md asm
|
||||
rsync -aP res/fx/* build/FX >>build/log
|
||||
$(CADIUS) ADDFOLDER build/"$(DISK)" "/${VOLUME}/FX" "build/FX" >>build/log
|
||||
$(CADIUS) CREATEFOLDER build/"$(DISK)" "/${VOLUME}/X/" >>build/log
|
||||
bin/do2po.py res/dsk/ build/po/
|
||||
rsync -a res/dsk/*.po build/po/
|
||||
bin/extract.py build/po/ | sh >>build/log
|
||||
# bin/do2po.py res/dsk/ build/po/
|
||||
# rsync -a res/dsk/*.po build/po/
|
||||
# bin/extract.py build/po/ | sh >>build/log
|
||||
rm -f build/X/**/.DS_Store
|
||||
rm -f build/X/**/PRODOS
|
||||
rm -f build/X/**/LOADER.SYSTEM
|
||||
|
BIN
bin/V2Make.scpt
BIN
bin/V2Make.scpt
Binary file not shown.
@ -45,7 +45,8 @@ Main
|
||||
jsr Play
|
||||
+
|
||||
bit $C010
|
||||
jsr AttractMode
|
||||
; jsr AttractMode
|
||||
jsr SearchMode
|
||||
jmp @loop
|
||||
|
||||
; these routines will only be called after relocating to language card
|
||||
@ -59,6 +60,7 @@ Main
|
||||
!source "src/glue.prorwts2.a"
|
||||
!source "src/okvs.a"
|
||||
!source "src/wait.a"
|
||||
!source "src/textrank.a"
|
||||
!source "src/parse.common.a"
|
||||
!source "src/parse.prefs.a"
|
||||
!source "src/parse.games.a"
|
||||
|
@ -108,3 +108,12 @@
|
||||
jsr LoadFile
|
||||
!word gPathname
|
||||
}
|
||||
|
||||
!macro LOW_ASCII_TO_LOWER {
|
||||
cmp #$41
|
||||
bcc +
|
||||
cmp #$5B
|
||||
bcs +
|
||||
ora #$20
|
||||
+
|
||||
}
|
||||
|
181
src/textrank.a
Normal file
181
src/textrank.a
Normal file
@ -0,0 +1,181 @@
|
||||
;license:MIT
|
||||
;(c) 2018 by 4am
|
||||
;
|
||||
; text rank - an implementation of the Quicksilver search rank algorithm
|
||||
;
|
||||
; Public functions
|
||||
; - TextRankCallback (as okvs_iter_values callback)
|
||||
;
|
||||
; Public variables
|
||||
; - InputLength
|
||||
; - InputBuffer
|
||||
; - SelectedIndex
|
||||
; - MatchCount
|
||||
; - BestMatchScore
|
||||
; - BestMatchIndex
|
||||
|
||||
zpword = $F0 ; word
|
||||
zpstring = $F2 ; word
|
||||
runningscore= $F4 ; word
|
||||
startat = $F6 ; byte
|
||||
i = $F7 ; byte
|
||||
tmp = $F8 ; byte
|
||||
gamelength= $F9 ; byte
|
||||
firstletter= $FA ; byte
|
||||
|
||||
MaxInputLength = 24
|
||||
InputLength
|
||||
!byte 0
|
||||
InputBuffer
|
||||
!text " "
|
||||
SelectedIndex
|
||||
!byte $FF
|
||||
MatchCount
|
||||
!byte 0
|
||||
BestMatchScore
|
||||
!byte 0
|
||||
BestMatchIndex
|
||||
!byte 0
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; 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 ; first we'll check for an exact match
|
||||
; lda (zpstring),y ; check length of this title against the input buffer
|
||||
; sta gamelength
|
||||
; cmp InputLength
|
||||
; bne + ; not equal, so can't be an exact match
|
||||
; tay ; check for exact match
|
||||
;- lda (zpword),y
|
||||
; cmp (zpstring),y
|
||||
; bne + ; nope, not an exact match
|
||||
; dey
|
||||
; bne -
|
||||
; inc MatchCount
|
||||
; lda #100 ; maximum possible score
|
||||
; sta BestMatchScore
|
||||
; ldx @tmpx ; save this game as the best match
|
||||
; stx BestMatchIndex
|
||||
; rts
|
||||
;+
|
||||
lda #0
|
||||
sta runningscore
|
||||
sta runningscore+1
|
||||
ldy #1
|
||||
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
|
||||
+ iny
|
||||
sty startat
|
||||
ldy i
|
||||
cpy InputLength
|
||||
iny
|
||||
bcc -
|
||||
|
||||
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
|
||||
sta firstletter
|
||||
pla
|
||||
ldx InputBuffer
|
||||
cpx firstletter
|
||||
bne +
|
||||
cmp #85
|
||||
bcs +
|
||||
adc #15
|
||||
+
|
||||
cmp BestMatchScore
|
||||
bcc +
|
||||
sta BestMatchScore
|
||||
ldx @tmpx
|
||||
stx BestMatchIndex
|
||||
inc MatchCount
|
||||
+
|
||||
rts
|
||||
|
||||
@div
|
||||
sta @num1
|
||||
stx @num1+1
|
||||
sty @num2
|
||||
|
||||
lda #0
|
||||
sta @rem
|
||||
sta @rem+1
|
||||
ldx #16
|
||||
- asl @num1
|
||||
rol @num1+1
|
||||
rol @rem
|
||||
rol @rem+1
|
||||
lda @rem
|
||||
sec
|
||||
sbc @num2
|
||||
bcc +
|
||||
sta @rem
|
||||
dec @rem+1
|
||||
inc @num1
|
||||
+ dex
|
||||
bne -
|
||||
lda @num1
|
||||
rts
|
||||
|
||||
@rem !word 0
|
||||
@num1 !word 0
|
||||
@num2 !byte 0
|
||||
@tmpx !byte $FD
|
@ -7,61 +7,157 @@
|
||||
; - SearchMode
|
||||
;
|
||||
|
||||
MaxInputLength = 24
|
||||
; indices into InputDispatchTable
|
||||
kInputBackspace= 1
|
||||
kInputEnter = 2
|
||||
kInputSearchKey= 3
|
||||
InputDispatchTable
|
||||
!word 0
|
||||
!word OnBackspace
|
||||
!word OnEnter
|
||||
!word OnKey
|
||||
|
||||
SearchMode
|
||||
jsr Home ; switches to text mode
|
||||
|
||||
jsr LoadFile ; load initial background at $2000
|
||||
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 +
|
||||
- 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
|
||||
jmp $ff59
|
||||
|
||||
OnKey
|
||||
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
|
||||
ldy #MaxInputLength ; clear visible search bar
|
||||
lda #" "
|
||||
- sta UILine2+1,y
|
||||
dey
|
||||
bne -
|
||||
lda #$7F
|
||||
sta UILine2+1
|
||||
|
||||
jsr LoadFile ; load default background at $2000
|
||||
!word Cover
|
||||
|
||||
lda #22 ; draw search UI on top of background
|
||||
lda #22 ; draw visible search bar
|
||||
sta VTAB
|
||||
clc ; draw on page 1
|
||||
clc ; on page 1
|
||||
+LDADDR UILine1
|
||||
jsr Draw40Chars
|
||||
clc
|
||||
+LDADDR UILine2
|
||||
jsr Draw40Chars
|
||||
jmp Draw40Chars
|
||||
|
||||
bit $c054 ; show it
|
||||
bit $c052
|
||||
bit $c057
|
||||
bit $c050
|
||||
|
||||
@loop
|
||||
bit $c010
|
||||
- lda $c000
|
||||
bpl -
|
||||
|
||||
ldx InputLength
|
||||
cpx MaxInputLength
|
||||
beq @loop
|
||||
|
||||
sta InputBuffer,x
|
||||
inc InputLength
|
||||
jsr OnInputChanged
|
||||
|
||||
jmp @loop
|
||||
|
||||
OnInputChanged
|
||||
lda #0
|
||||
sta MatchCount
|
||||
@findMatchingTitle
|
||||
lda #0 ; reset match count
|
||||
sta MatchCount ; TextRankCallback will increment this if
|
||||
; there are any matches
|
||||
|
||||
jsr okvs_iter_values
|
||||
!word gGamesListStore
|
||||
!word RankSearchResult
|
||||
|
||||
lda MatchCount
|
||||
beq @nomatches
|
||||
!word TextRankCallback
|
||||
|
||||
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
|
||||
beq @nochange
|
||||
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
|
||||
sta @index
|
||||
jsr okvs_nth
|
||||
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
|
||||
@ -72,58 +168,88 @@ OnInputChanged
|
||||
jsr okvs_get
|
||||
!word gGamesListStore
|
||||
@key !word $FDFD
|
||||
; TODO A/Y points to visible title string now
|
||||
+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 -
|
||||
|
||||
@nochange
|
||||
; TODO
|
||||
clc
|
||||
rts
|
||||
@nomatches
|
||||
; TODO
|
||||
lda #22 ; draw search bar
|
||||
sta VTAB
|
||||
sec ; on page 2, not currently visible
|
||||
+LDADDR UILine1
|
||||
jsr Draw40Chars
|
||||
sec
|
||||
+LDADDR UILine2
|
||||
jsr Draw40Chars
|
||||
|
||||
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
|
||||
|
||||
RankSearchResult
|
||||
zpword = $0
|
||||
zpstring = $2
|
||||
runningscore = $4
|
||||
startat = $6
|
||||
i = $7
|
||||
tmp = $8
|
||||
stx @tmpx
|
||||
+STAY zpstring
|
||||
+LDADDR InputLength
|
||||
+STAY zpword
|
||||
ldy #0
|
||||
lda (zpstring),y
|
||||
cmp InputLength
|
||||
bne +
|
||||
- lda (zpword),y
|
||||
cmp (zpstring),y
|
||||
bne +
|
||||
dey
|
||||
;------------------------------------------------------------------------------
|
||||
; SoftBell
|
||||
;
|
||||
; in: none
|
||||
; out: all registers and flags preserved
|
||||
;------------------------------------------------------------------------------
|
||||
SoftBell
|
||||
php
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
ldx #32
|
||||
- lda #2
|
||||
jsr Wait
|
||||
bit $C030
|
||||
lda #33
|
||||
jsr Wait
|
||||
bit $C030
|
||||
dex
|
||||
bne -
|
||||
lda #100
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
plp
|
||||
rts
|
||||
+
|
||||
@tmpx !byte $FD
|
||||
|
||||
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
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
Cover !byte 5
|
||||
!text "COVER"
|
||||
|
||||
InputLength
|
||||
!byte 0
|
||||
InputBuffer
|
||||
!text " "
|
||||
SelectedIndex ; only valid if InputLength > 0
|
||||
!byte $FF
|
||||
MatchCount ; only valid during OnInputChanged
|
||||
!byte 0
|
||||
BestMatchScore ; only valid during OnInputChanged
|
||||
!byte 0
|
||||
BestMatchIndex ; only valid during OnInputChanged, and only if MatchCount > 0
|
||||
!byte 0
|
||||
|
||||
UILine1
|
||||
!byte 0,0,0,0,0,0,0,0,0,0
|
||||
!byte 0,0,0,0,0,0,0,0,0,0
|
||||
@ -131,9 +257,7 @@ UILine1
|
||||
!byte 0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
UILine2
|
||||
; !text "0123456789012345678901234567890123456789"
|
||||
!text "["
|
||||
!byte $7F
|
||||
; !text "Championship Lode Runner_"
|
||||
!text " "
|
||||
!text "] 000 games"
|
||||
|
Loading…
Reference in New Issue
Block a user