mirror of
https://github.com/a2-4am/4cade.git
synced 2024-09-27 12:57:21 +00:00
255 lines
7.0 KiB
Plaintext
255 lines
7.0 KiB
Plaintext
;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"
|