mirror of
https://github.com/a2-4am/4cade.git
synced 2024-11-27 08:50:01 +00:00
Browse Mode
This commit is contained in:
parent
045fe1cfef
commit
a37dd59b4f
@ -65,6 +65,7 @@ RestoreStackNextTime
|
||||
|
||||
; these routines will only be called after relocating to language card
|
||||
!source "src/ui.search.mode.a"
|
||||
!source "src/ui.browse.mode.a"
|
||||
!source "src/ui.attract.mode.a"
|
||||
!source "src/ui.attract.hgr.a"
|
||||
!source "src/ui.attract.dhgr.a"
|
||||
@ -81,6 +82,8 @@ RestoreStackNextTime
|
||||
!source "src/ui.common.a"
|
||||
MachineStatus
|
||||
!byte 0
|
||||
GameCount
|
||||
!byte 0
|
||||
gAttractModeStore
|
||||
gFXStore
|
||||
gDFXStore
|
||||
|
@ -117,6 +117,7 @@ OneTimeSetup
|
||||
|
||||
jsr okvs_len
|
||||
!word gGamesListStore
|
||||
sta GameCount
|
||||
sta SAVE
|
||||
; calculate and update visible game count (3-digit decimal number as ASCII string)
|
||||
ldy #0
|
||||
|
@ -5,6 +5,7 @@
|
||||
;
|
||||
; Public functions
|
||||
; - PlayGameFromSearch
|
||||
; - PlayGameFromBrowse
|
||||
; - PlayGameFromAttract
|
||||
; - Prelaunch
|
||||
; - Launch
|
||||
@ -17,6 +18,7 @@
|
||||
!zone {
|
||||
|
||||
PlayGameFromSearch
|
||||
PlayGameFromBrowse
|
||||
stx @gameIndex
|
||||
jsr okvs_nth
|
||||
!word gGamesListStore
|
||||
|
217
src/ui.browse.mode.a
Normal file
217
src/ui.browse.mode.a
Normal file
@ -0,0 +1,217 @@
|
||||
;license:MIT
|
||||
;(c) 2018-9 by 4am
|
||||
;
|
||||
; Browse Mode - main UI
|
||||
;
|
||||
; Public functions
|
||||
; - BrowseMode
|
||||
;
|
||||
|
||||
!zone {
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; BrowseMode
|
||||
; main entry point for Browse Mode, which allows the user to browse the game
|
||||
; catalog in alphabetical order and launch games
|
||||
;
|
||||
; in: none
|
||||
; out: never returns to caller (may JMP to other major modes)
|
||||
;------------------------------------------------------------------------------
|
||||
BrowseMode
|
||||
+READ_RAM1_WRITE_RAM1
|
||||
ldx #$FF
|
||||
txs
|
||||
ldx SelectedIndex
|
||||
stx BrowseSelectedIndex
|
||||
|
||||
.BrowseModeInputLoop
|
||||
lda KBD
|
||||
bmi @gotKey
|
||||
|
||||
inc RNDSEED+1 ; these are only ever incremented, never
|
||||
bne + ; reset (may be used as a pseudorandom
|
||||
inc RNDSEED ; seed)
|
||||
+
|
||||
dec Timeout ; these are a 3-byte timeout counter
|
||||
bne .BrowseModeInputLoop ; that counts down from a number set
|
||||
dec Timeout+1 ; in .ResetInputTimeout and reset
|
||||
bne .BrowseModeInputLoop ; on every keypress (whether or not
|
||||
dec Timeout+2 ; the key leads to an action)
|
||||
bne .BrowseModeInputLoop
|
||||
; jsr .CoverFade ; no input for ~30 seconds, switch to
|
||||
jmp MegaAttractMode ; mega-attract mode
|
||||
|
||||
@gotKey
|
||||
bit CLEARKBD
|
||||
jsr ResetInputTimeout
|
||||
|
||||
cmp #$88 ; left arrow = previous
|
||||
bne +
|
||||
- ldx #kBrowsePrevious
|
||||
bne @BrowseDispatch ; always branches
|
||||
+ cmp #$8B ; up arrow is same as left arrow
|
||||
beq -
|
||||
|
||||
cmp #$95 ; right arrow = next
|
||||
bne +
|
||||
- ldx #kBrowseNext
|
||||
bne @BrowseDispatch ; always branches
|
||||
+ cmp #$8A ; down arrow is same as right arrow
|
||||
beq -
|
||||
|
||||
cmp #$9B ; Esc switches to search mode
|
||||
bne +
|
||||
ldx #kBrowseExitMode
|
||||
bne @BrowseDispatch ; always branches
|
||||
+
|
||||
cmp #$8D ; ENTER launches the current game
|
||||
bne +
|
||||
ldx #kBrowseLaunch
|
||||
bne @BrowseDispatch ; always branches
|
||||
+
|
||||
cmp #$89 ; TAB switches to mini attract mode
|
||||
bne + ; temporarily
|
||||
ldx #kBrowseTab
|
||||
bne @BrowseDispatch ; always branches
|
||||
+
|
||||
and #$7F ; strip high bit for search characters
|
||||
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
|
||||
@badkey
|
||||
jsr SoftBell ; beep on invalid input
|
||||
jmp .BrowseModeInputLoop ; and start over
|
||||
|
||||
@goodkey
|
||||
ldx #kBrowseSearch
|
||||
; execution falls through here
|
||||
@BrowseDispatch
|
||||
pha ; save key pressed
|
||||
txa
|
||||
asl
|
||||
tax
|
||||
lda .BrowseDispatchTable,x
|
||||
sta @j+1
|
||||
lda .BrowseDispatchTable+1,x
|
||||
sta @j+2
|
||||
pla ; restore key pressed
|
||||
@j jsr $FDFD ; SMC
|
||||
bcs +
|
||||
jmp .BrowseModeInputLoop ; if carry is clear, we're done
|
||||
; TODO
|
||||
+ jmp BrowseMode ; if carry is set, force full redraw
|
||||
|
||||
.OnSearch
|
||||
sta InputBuffer
|
||||
lda #$01
|
||||
sta InputLength
|
||||
jmp SearchMode
|
||||
|
||||
.OnPrevious
|
||||
dec BrowseSelectedIndex
|
||||
jmp +
|
||||
.OnNext
|
||||
inc BrowseSelectedIndex
|
||||
+
|
||||
ldx BrowseSelectedIndex
|
||||
cpx #$FF
|
||||
bne @notTooSmall
|
||||
ldx GameCount
|
||||
dex
|
||||
bne @done ; always branches
|
||||
@notTooSmall
|
||||
cpx GameCount
|
||||
bcc @done
|
||||
ldx #0
|
||||
@done stx BrowseSelectedIndex
|
||||
jmp .OnBrowseChanged
|
||||
|
||||
.OnTab
|
||||
ldx BrowseSelectedIndex
|
||||
jsr MiniAttractMode
|
||||
cmp #$8D
|
||||
beq .OnLaunch
|
||||
; TODO redraw
|
||||
rts
|
||||
|
||||
.OnLaunch
|
||||
ldx BrowseSelectedIndex
|
||||
jsr PlayGameFromBrowse
|
||||
jmp BrowseMode
|
||||
|
||||
.OnBrowseChanged
|
||||
stx @index
|
||||
jsr okvs_nth ; get the name of the new game
|
||||
!word gGamesListStore
|
||||
@index !byte $FD
|
||||
+STAY @key
|
||||
jsr GetOffscreenAddress ; load new title screenshot offscreen
|
||||
sta + ; new title screenshot (offscreen)
|
||||
+LDADDR kHGRTitleDirectory
|
||||
jsr SetPath
|
||||
+LDAY @key
|
||||
jsr AddToPath
|
||||
jsr LoadFileAt
|
||||
!byte $00
|
||||
+ !byte $FD ; SMC
|
||||
|
||||
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 @printTitleChar
|
||||
lda #" "
|
||||
+HIDE_NEXT_2_BYTES
|
||||
@printTitleChar
|
||||
lda (SRC),y ; copy game title to UI line 2
|
||||
sta UILine2,y
|
||||
cpy #MaxInputLength+1
|
||||
bcc -
|
||||
ldx #40
|
||||
lda #0
|
||||
- sta UILine1-1,x ; reset UI line 1
|
||||
dex
|
||||
bne -
|
||||
jsr DrawSearchBarOffscreen ; actually draw the search UI (offscreen)
|
||||
jmp ShowOtherPage ; now show everything at once
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
; indices into BrowseDispatchTable
|
||||
kBrowseSearch = 0
|
||||
kBrowsePrevious = 1
|
||||
kBrowseNext = 2
|
||||
kBrowseExitMode = 3
|
||||
kBrowseTab = 4
|
||||
kBrowseLaunch = 5
|
||||
|
||||
.BrowseDispatchTable
|
||||
!word .OnSearch
|
||||
!word .OnPrevious
|
||||
!word .OnNext
|
||||
!word SearchMode
|
||||
!word .OnTab
|
||||
!word .OnLaunch
|
||||
|
||||
BrowseSelectedIndex
|
||||
!byte $FF
|
||||
|
||||
}
|
@ -4,13 +4,96 @@
|
||||
; common UI functions
|
||||
;
|
||||
; Public functions
|
||||
; - GetOffscreenAddress
|
||||
; - DrawSearchBarOffscreen
|
||||
; - ShowOtherPage
|
||||
; - ToggleOffscreenPage
|
||||
; - ResetInputTimeout
|
||||
; - SoftBell
|
||||
; - Home
|
||||
; - BlankHGR
|
||||
; - BlankDHGR
|
||||
|
||||
; Public variables
|
||||
; - OffscreenPage
|
||||
; - UILine1
|
||||
; - UILine2
|
||||
; - VisibleGameCount (set during init)
|
||||
;
|
||||
|
||||
!zone {
|
||||
OffscreenPage
|
||||
!byte 1 ; 0 = currently showing HGR page 2
|
||||
; (so offscreen is page 1 @ $2000)
|
||||
; 1 = currently showing HGR page 1
|
||||
; (so offscreen is page 2 @ $4000)
|
||||
|
||||
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 "] "
|
||||
VisibleGameCount
|
||||
!text "000"
|
||||
!text " games"
|
||||
|
||||
GetOffscreenAddress
|
||||
; in: none
|
||||
; out: A = high byte of offscreen HGR page (#$20 or #$40)
|
||||
; preserves X/Y
|
||||
lda OffscreenPage
|
||||
beq +
|
||||
lda #$40
|
||||
rts
|
||||
+ lda #$20
|
||||
rts
|
||||
|
||||
DrawSearchBarOffscreen
|
||||
; clobbers all
|
||||
LDA #22 ; draw visible search bar
|
||||
sta VTAB
|
||||
lda OffscreenPage
|
||||
ror ; draw on offscreen page
|
||||
+LDADDR UILine1
|
||||
jsr Draw40Chars
|
||||
lda OffscreenPage
|
||||
ror ; draw on offscreen page
|
||||
+LDADDR UILine2
|
||||
jmp Draw40Chars
|
||||
|
||||
ShowOtherPage
|
||||
; in: none
|
||||
; out: A = new value of OffscreenPage
|
||||
; preserves X/Y
|
||||
jsr ToggleOffscreenPage
|
||||
bne +
|
||||
bit PAGE2 ; show page 2
|
||||
rts
|
||||
+ bit PAGE1 ; show page 1
|
||||
rts
|
||||
|
||||
ToggleOffscreenPage
|
||||
; in: none
|
||||
; out: A = new value of OffscreenPage
|
||||
; preserves X/Y
|
||||
lda OffscreenPage
|
||||
eor #$01
|
||||
sta OffscreenPage
|
||||
rts
|
||||
|
||||
ResetInputTimeout
|
||||
; clobbers X, preserves A/Y
|
||||
ldx #$16
|
||||
stx Timeout
|
||||
stx Timeout+1
|
||||
stx Timeout+2
|
||||
rts
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; SoftBell
|
||||
|
@ -6,8 +6,6 @@
|
||||
; Public functions
|
||||
; - SearchMode
|
||||
;
|
||||
; Public addresses
|
||||
; - VisibleGameCount (set during init)
|
||||
|
||||
!zone {
|
||||
|
||||
@ -25,12 +23,12 @@ SearchMode
|
||||
txs
|
||||
stx SelectedIndex ; no game selected
|
||||
inx
|
||||
stx .OffscreenPage
|
||||
stx OffscreenPage
|
||||
jsr Home ; clear screen
|
||||
jsr .OnInputChanged ; draw UI on HGR page 1
|
||||
+HGR_MODE ; show HGR
|
||||
bit CLEARKBD
|
||||
jsr .ResetInputTimeout
|
||||
jsr ResetInputTimeout
|
||||
|
||||
.SearchModeInputLoop
|
||||
lda KBD
|
||||
@ -42,7 +40,7 @@ SearchMode
|
||||
+
|
||||
dec Timeout ; these are a 3-byte timeout counter
|
||||
bne .SearchModeInputLoop ; that counts down from a number set
|
||||
dec Timeout+1 ; in .ResetInputTimeout and reset
|
||||
dec Timeout+1 ; in ResetInputTimeout and reset
|
||||
bne .SearchModeInputLoop ; on every keypress (whether or not
|
||||
dec Timeout+2 ; the key leads to an action)
|
||||
bne .SearchModeInputLoop
|
||||
@ -50,8 +48,19 @@ SearchMode
|
||||
jmp MegaAttractMode ; mega-attract mode
|
||||
|
||||
@gotKey
|
||||
cmp #$88 ; left arrow switches to browse mode
|
||||
beq @arrow
|
||||
cmp #$8B ; also right arrow
|
||||
beq @arrow
|
||||
cmp #$95 ; also up arrow
|
||||
beq @arrow
|
||||
cmp #$8A ; also down arrow
|
||||
bne @notArrow
|
||||
@arrow ldx #kInputBrowse
|
||||
bne @InputDispatch ; always branches
|
||||
@notArrow
|
||||
bit CLEARKBD
|
||||
jsr .ResetInputTimeout
|
||||
jsr ResetInputTimeout
|
||||
|
||||
cmp #$9B ; Esc clears the input buffer (if any)
|
||||
bne + ; or switches to mega attract mode
|
||||
@ -65,12 +74,9 @@ SearchMode
|
||||
+
|
||||
cmp #$FF ; delete key
|
||||
bne +
|
||||
- ldx #kInputBack
|
||||
ldx #kInputBack
|
||||
bne @InputDispatch ; always branches
|
||||
|
||||
+ cmp #$88 ; left arrow = delete
|
||||
beq -
|
||||
|
||||
+
|
||||
cmp #$89 ; TAB switches to mini attract mode
|
||||
bne + ; if there is a game selected
|
||||
ldx #kInputTab
|
||||
@ -171,19 +177,19 @@ SearchMode
|
||||
sta SelectedIndex ; no game selected
|
||||
ldx #40 ; reset visible line
|
||||
lda #0
|
||||
- sta .UILine1-1,x
|
||||
- sta UILine1-1,x
|
||||
dex
|
||||
bne -
|
||||
ldy #MaxInputLength ; clear visible search bar
|
||||
lda #" "
|
||||
- sta .UILine2+1,y
|
||||
- sta UILine2+1,y
|
||||
dey
|
||||
bne -
|
||||
lda #$7F
|
||||
sta .UILine2+1
|
||||
sta UILine2+1
|
||||
jsr .LoadTitleOffscreen
|
||||
jsr .DrawSearchBarOffscreen
|
||||
jsr .ShowOtherPage
|
||||
jsr DrawSearchBarOffscreen
|
||||
jsr ShowOtherPage
|
||||
clc
|
||||
rts
|
||||
@findMatchingTitle
|
||||
@ -211,12 +217,12 @@ SearchMode
|
||||
+STAY @key
|
||||
plp
|
||||
bne +
|
||||
lda .OffscreenPage ; since we're not loading a new screenshot
|
||||
eor #$01 ; we fake switching the 'offscreen' page
|
||||
sta .OffscreenPage ; in order to draw on the visible page
|
||||
jsr ToggleOffscreenPage ; Since we're not loading a new screenshot
|
||||
; we fake switching the 'offscreen' page
|
||||
; in order to draw on the visible page.
|
||||
bpl @skipload ; always branches
|
||||
+
|
||||
jsr .GetOffscreenAddress ; we have a new best match, so load the
|
||||
jsr GetOffscreenAddress ; we have a new best match, so load the
|
||||
sta + ; new title screenshot (offscreen)
|
||||
+LDADDR kHGRTitleDirectory
|
||||
jsr SetPath
|
||||
@ -246,12 +252,12 @@ SearchMode
|
||||
+HIDE_NEXT_2_BYTES
|
||||
@printTitleChar
|
||||
lda (SRC),y ; copy game title to search UI
|
||||
sta .UILine2,y
|
||||
sta UILine2,y
|
||||
cpy #MaxInputLength+1
|
||||
bcc -
|
||||
ldx #40
|
||||
lda #0
|
||||
- sta .UILine1-1,x ; reset search bar
|
||||
- sta UILine1-1,x ; reset search bar
|
||||
dex
|
||||
bne -
|
||||
tay
|
||||
@ -260,7 +266,7 @@ SearchMode
|
||||
cmp InputBuffer,x
|
||||
bne +
|
||||
lda #$0B ; add dots to highlight matched characters
|
||||
sta .UILine1,y
|
||||
sta UILine1,y
|
||||
inx
|
||||
cpx InputLength
|
||||
beq @doneHighlight
|
||||
@ -269,28 +275,24 @@ SearchMode
|
||||
cpy #40
|
||||
bne -
|
||||
@doneHighlight
|
||||
jsr .DrawSearchBarOffscreen; actually draw the search UI (offscreen)
|
||||
jmp .ShowOtherPage ; now show everything at once
|
||||
jsr DrawSearchBarOffscreen; actually draw the search UI (offscreen)
|
||||
jmp ShowOtherPage ; now show everything at once
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.GetOffscreenAddress
|
||||
; in: none
|
||||
; out: A = high byte of offscreen HGR page (#$20 or #$40)
|
||||
; preserves X/Y
|
||||
lda .OffscreenPage
|
||||
beq +
|
||||
lda #$40
|
||||
rts
|
||||
+ lda #$20
|
||||
rts
|
||||
|
||||
.LoadTitleOffscreen
|
||||
; clobbers all
|
||||
jsr .GetOffscreenAddress
|
||||
sta +
|
||||
; [private] clobbers all
|
||||
+LDADDR @TitleFile
|
||||
bne + ; Always branches, because Y is loaded
|
||||
; last with the high byte of the address,
|
||||
; which is never 0. I miss my 65c02.
|
||||
.LoadCoverOffscreen
|
||||
; [private] clobbers all
|
||||
+LDADDR @CoverFile
|
||||
+
|
||||
jsr SetPath
|
||||
jsr GetOffscreenAddress
|
||||
sta +
|
||||
jsr LoadFileAt
|
||||
!byte $00
|
||||
+ !byte $FD ; SMC
|
||||
@ -298,61 +300,18 @@ SearchMode
|
||||
@TitleFile
|
||||
!byte 5
|
||||
!text "TITLE"
|
||||
|
||||
.LoadCoverOffscreen
|
||||
; clobbers all
|
||||
jsr .GetOffscreenAddress
|
||||
sta +
|
||||
+LDADDR @CoverFile
|
||||
jsr SetPath
|
||||
jsr LoadFileAt
|
||||
!byte $00
|
||||
+ !byte $FD ; SMC
|
||||
rts
|
||||
@CoverFile
|
||||
!byte 5
|
||||
!text "COVER"
|
||||
|
||||
.DrawSearchBarOffscreen
|
||||
; clobbers all
|
||||
LDA #22 ; draw visible search bar
|
||||
sta VTAB
|
||||
lda .OffscreenPage
|
||||
ror ; draw on offscreen page
|
||||
+LDADDR .UILine1
|
||||
jsr Draw40Chars
|
||||
lda .OffscreenPage
|
||||
ror ; draw on offscreen page
|
||||
+LDADDR .UILine2
|
||||
jmp Draw40Chars
|
||||
|
||||
.ShowOtherPage
|
||||
; clobbers A, preserves X/Y
|
||||
lda .OffscreenPage
|
||||
eor #$01
|
||||
sta .OffscreenPage
|
||||
bne +
|
||||
bit PAGE2 ; show page 2
|
||||
rts
|
||||
+ bit PAGE1 ; show page 1
|
||||
rts
|
||||
|
||||
.ResetInputTimeout
|
||||
; clobbers X, preserves A/Y
|
||||
ldx #$16
|
||||
stx Timeout
|
||||
stx Timeout+1
|
||||
stx Timeout+2
|
||||
rts
|
||||
|
||||
.CoverFade
|
||||
; clobbers all
|
||||
; [private] clobbers all
|
||||
jsr .LoadCoverOffscreen
|
||||
jsr .ShowOtherPage
|
||||
lda .OffscreenPage
|
||||
jsr ShowOtherPage
|
||||
lda OffscreenPage
|
||||
bne +
|
||||
jsr .LoadCoverOffscreen
|
||||
jsr .ShowOtherPage
|
||||
jsr ShowOtherPage
|
||||
+
|
||||
; load transition effect code at $6000
|
||||
+LDADDR kFXDirectory
|
||||
@ -365,38 +324,19 @@ SearchMode
|
||||
!byte 9
|
||||
!text "COVERFADE"
|
||||
|
||||
.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 "] "
|
||||
VisibleGameCount
|
||||
!text "000"
|
||||
!text " games"
|
||||
|
||||
.OffscreenPage
|
||||
!byte 1 ; 0 = currently showing HGR page 2
|
||||
; (so offscreen is page 1 @ $2000)
|
||||
; 1 = currently showing HGR page 1
|
||||
; (so offscreen is page 2 @ $4000)
|
||||
|
||||
; indices into InputDispatchTable
|
||||
kInputSearch = 0
|
||||
kInputClear = 1
|
||||
kInputBack = 2
|
||||
kInputTab = 3
|
||||
kInputLaunch = 4
|
||||
kInputBrowse = 3
|
||||
kInputTab = 4
|
||||
kInputLaunch = 5
|
||||
|
||||
.InputDispatchTable
|
||||
!word .OnSearch
|
||||
!word .OnClear
|
||||
!word .OnBack
|
||||
!word BrowseMode
|
||||
!word .OnTab
|
||||
!word .OnLaunch
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user