4cade/src/ui.search.mode.a

285 lines
8.9 KiB
Plaintext
Raw Normal View History

2018-12-23 16:13:47 +00:00
;license:MIT
;(c) 2018-9 by 4am
2018-12-23 16:13:47 +00:00
;
; Search Mode - main UI
2018-12-23 16:13:47 +00:00
;
; Public functions
; - SearchMode
;
2019-06-27 15:37:23 +00:00
!zone {
2018-12-23 16:13:47 +00:00
;------------------------------------------------------------------------------
; SearchMode
; main entry point for Search Mode, which allows the user to search the game
; catalog and launch games
;
; in: none
; out: never returns to caller (may JMP to other major modes)
;------------------------------------------------------------------------------
2018-12-23 16:13:47 +00:00
SearchMode
2019-06-27 14:55:07 +00:00
+READ_RAM1_WRITE_RAM1
ldx #$FF
txs
2019-09-06 19:21:38 +00:00
stx SelectedIndex ; $FF = no game selected
inx
2019-09-06 19:21:38 +00:00
stx OffscreenPage ; $00 = currently showing HGR page 2
jsr Home ; clear screen
2019-06-27 15:37:23 +00:00
jsr .OnInputChanged ; draw UI on HGR page 1
+HGR_MODE ; show HGR
2019-06-27 14:55:07 +00:00
bit CLEARKBD
2019-07-03 22:31:50 +00:00
jsr ResetInputTimeout
2019-06-21 17:10:29 +00:00
2019-06-27 15:37:23 +00:00
.SearchModeInputLoop
jsr WaitForKeyFor30Seconds
2019-06-21 17:10:29 +00:00
; Don't clear keyboard strobe yet. If the user pressed an arrow key,
; we want to switch to Browse Mode with the keyboard still hot so
; that mode finds and dispatches the arrow key.
2019-06-21 17:17:57 +00:00
cmp #$8B ; right arrow switches to browse mode
2019-07-03 22:31:50 +00:00
beq @arrow
cmp #$95 ; also up arrow
beq @arrow
cmp #$8A ; also down arrow
bne @notArrow
@arrow ldx #kInputBrowse
bne @InputDispatch ; always branches
@notArrow
jsr ResetInputTimeout
2019-06-20 18:18:23 +00:00
2019-09-06 19:21:38 +00:00
ldy #kNumBrowseKeys
- dey
bmi @noKeyMatch
cmp .InputKeys,y
bne -
ldx .InputKeyDispatch,y
2019-07-10 17:37:59 +00:00
bne @InputDispatch ; always branches
2019-09-06 19:21:38 +00:00
@noKeyMatch
jsr IsSearchKey
2019-09-06 19:21:38 +00:00
beq @foundSearchKey
ldx #kInputError
+HIDE_NEXT_2_BYTES
@foundSearchKey
ldx #kInputSearch
2019-06-18 18:56:05 +00:00
; execution falls through here
2019-06-27 15:37:23 +00:00
@InputDispatch
2019-09-06 19:21:38 +00:00
ldy .InputDispatchTableLo,x
sty @j+1
ldy .InputDispatchTableHi,x
sty @j+2
2019-06-18 18:56:05 +00:00
@j jsr $FDFD ; SMC
2019-09-06 19:21:38 +00:00
bcc .SearchModeInputLoop ; if carry is clear, we're done
bcs SearchMode ; if carry is set, force full redraw
2018-12-23 16:13:47 +00:00
2019-06-27 15:37:23 +00:00
.OnClear
ldx InputLength
bne +
jsr CoverFade ; Esc with no input switches to
jmp MegaAttractMode ; mega-attract mode
+ ldx #0 ; Esc with input clears the input
stx InputLength
2019-06-27 15:37:23 +00:00
jmp .OnInputChanged
2019-06-27 15:37:23 +00:00
.OnBack
2018-12-23 16:13:47 +00:00
ldx InputLength
2019-06-18 18:56:05 +00:00
bne +
2019-09-06 19:21:38 +00:00
jmp SoftBell
2019-06-18 18:56:05 +00:00
+ dec InputLength
2019-06-27 15:37:23 +00:00
jmp .OnInputChanged
2018-12-23 16:13:47 +00:00
2019-06-27 15:37:23 +00:00
.OnTab
2019-06-27 02:51:34 +00:00
ldx SelectedIndex
cpx #$FF
2019-09-06 19:21:38 +00:00
beq .ClearAndReturn
2019-06-27 02:51:34 +00:00
jsr MiniAttractMode
2019-06-27 15:37:23 +00:00
cmp #$8D ; if we exited mini attract mode
beq .OnLaunch ; by pressing Enter, launch the game
2019-06-27 02:51:34 +00:00
sec ; tell caller to redraw UI
rts
2019-06-27 15:37:23 +00:00
.OnLaunch
2019-06-20 18:18:23 +00:00
ldx SelectedIndex
cpx #$FF
2019-09-06 19:21:38 +00:00
beq .ClearAndReturn
jsr PlayGameFromSearch
sec ; tell caller to redraw UI
rts
2018-12-23 16:13:47 +00:00
2019-06-27 15:37:23 +00:00
.OnSearch
2019-06-18 18:56:05 +00:00
ldx InputLength
cpx #MaxInputLength
bne +
2019-09-06 19:21:38 +00:00
.OnError
jsr SoftBell ; Beep on invalid input and start over.
.ClearAndReturn
2019-06-24 23:20:00 +00:00
clc
2019-06-18 18:56:05 +00:00
rts
+ sta InputBuffer,x
inc InputLength
; execution falls through here
2019-06-27 15:37:23 +00:00
.OnInputChanged
2019-06-18 18:56:05 +00:00
lda InputLength
bne @findMatchingTitle
; no input, reset params and UI
lda #$FF
sta SelectedIndex ; no game selected
ldx #39 ; reset visible line
- lda #0
sta UILine1,x
lda Instructions,x
sta UILine2,x
2019-06-18 21:07:14 +00:00
dex
bpl -
jsr LoadTitleOffscreen
2019-07-03 22:31:50 +00:00
jsr DrawSearchBarOffscreen
jsr ShowOtherPage
clc
rts
2019-09-06 19:21:38 +00:00
2019-06-18 18:56:05 +00:00
@findMatchingTitle
2019-06-18 21:07:14 +00:00
jsr ResetTextRank
2018-12-23 16:13:47 +00:00
2019-06-18 21:07:14 +00:00
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
2018-12-23 16:13:47 +00:00
lda MatchCount ; any matches at all?
bne +
2019-09-06 19:21:38 +00:00
; no matches for this input buffer
dec InputLength ; ignore the last key typed
jmp .OnError ; beep and return
+
lda BestMatchIndex ; check if the new best match is the same
cmp SelectedIndex ; as the current best match
php ; (we'll use this later to skip reloading)
sta SelectedIndex
sta @index
2019-06-27 15:37:23 +00:00
jsr okvs_nth ; get the name of the new best match
2018-12-23 16:13:47 +00:00
!word gGamesListStore
@index !byte $FD
+STAY @key
plp
bne +
2019-07-03 22:31:50 +00:00
jsr ToggleOffscreenPage ; Since we're not loading a new screenshot
; we fake switching the 'offscreen' page
; in order to draw on the visible page.
2019-06-27 15:37:23 +00:00
bpl @skipload ; always branches
+
2019-07-03 22:31:50 +00:00
jsr GetOffscreenAddress ; we have a new best match, so load the
2019-06-27 15:37:23 +00:00
sta + ; new title screenshot (offscreen)
+LDADDR kHGRTitleDirectory
jsr SetPath
+LDAY @key
jsr AddToPath
jsr LoadFileAt
2019-06-27 15:37:23 +00:00
!byte $00
+ !byte $FD ; SMC
2018-12-23 16:13:47 +00:00
@skipload
2018-12-23 16:13:47 +00:00
jsr okvs_get
!word gGamesListStore
@key !word $FDFD
2019-06-18 18:56:05 +00:00
+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
2019-06-20 03:05:48 +00:00
bcc @printTitleChar
beq @printCursor
2019-06-18 18:56:05 +00:00
lda #" "
+HIDE_NEXT_2_BYTES
2019-06-20 03:05:48 +00:00
@printCursor
lda #$7F
+HIDE_NEXT_2_BYTES
@printTitleChar
lda (SRC),y ; copy game title to search UI
2019-07-03 22:31:50 +00:00
sta UILine2,y
2019-06-18 18:56:05 +00:00
cpy #MaxInputLength+1
bcc -
ldx #8
- lda ReturnToPlay,x ; replace games count with 'to play' label
sta UI_ToPlay,x
dex
bpl -
2019-06-18 21:07:14 +00:00
ldx #40
lda #0
2019-07-03 22:31:50 +00:00
- sta UILine1-1,x ; reset search bar
2019-06-18 21:07:14 +00:00
dex
bne -
tay
@dotloop
iny
lda (SRC),y
2019-06-18 20:54:15 +00:00
+LOW_ASCII_TO_LOWER
cmp InputBuffer,x
bne +
lda #$11 ; add dots to highlight matched characters
2019-07-03 22:31:50 +00:00
sta UILine1,y
2019-06-18 20:54:15 +00:00
inx
cpx InputLength ; if input buffer is exhausted, we're done
2019-06-18 20:54:15 +00:00
beq @doneHighlight
+ inc HTAB
cpy SAVE ; if game name is exhausted, we're done
bne @dotloop
2019-06-18 20:54:15 +00:00
@doneHighlight
2019-07-03 22:31:50 +00:00
jsr DrawSearchBarOffscreen; actually draw the search UI (offscreen)
jmp ShowOtherPage ; now show everything at once
2018-12-23 16:13:47 +00:00
;------------------------------------------------------------------------------
2018-12-23 16:13:47 +00:00
; indices into InputDispatchTable
kInputSearch = 0
kInputClear = 1
kInputBack = 2
2019-07-03 22:31:50 +00:00
kInputBrowse = 3
kInputTab = 4
kInputLaunch = 5
2019-07-10 17:37:59 +00:00
kInputCredits = 6
2019-09-06 19:21:38 +00:00
kInputError = 7
2019-09-06 19:21:38 +00:00
.InputDispatchTableLo
!byte <.OnSearch
!byte <.OnClear
!byte <.OnBack
!byte <BrowseMode
!byte <.OnTab
!byte <.OnLaunch
!byte <Credits
!byte <.OnError
.InputDispatchTableHi
!byte >.OnSearch
!byte >.OnClear
!byte >.OnBack
!byte >BrowseMode
!byte >.OnTab
!byte >.OnLaunch
!byte >Credits
!byte >.OnError
2019-06-27 15:37:23 +00:00
2019-09-06 19:21:38 +00:00
kNumInputKeys = 8 ; number of entries in next 2 tables (each)
.InputKeys
!byte $AF ; '/' = credits
!byte $BF ; '?' = credits
!byte $A0 ; Space = mini attract mode
!byte $89 ; TAB = mini attract mode
!byte $88 ; left arrow = delete (may as well, since
; popular emulators remap this anyway)
!byte $FF ; backspace = delete
!byte $8D ; ENTER = launch current game (if any)
!byte $9B ; Esc = clear input buffer (if any)
; or switch to mega attract mode
.InputKeyDispatch
!byte kInputCredits
!byte kInputCredits
!byte kInputTab
!byte kInputTab
!byte kInputBack
!byte kInputBack
!byte kInputLaunch
!byte kInputClear
2019-06-27 15:37:23 +00:00
}