pitch-dark/src/ui.versions.a

342 lines
11 KiB
Plaintext

;license:MIT
;(c) 2018 by 4am
;
; User interface - views and paint routines for versions screen
;
; Public functions
; - VersionsDialog
;
; View IDs (application-specific, acceptable range 0..15, no duplicates)
ID_VERSIONS_FRAME = 0
ID_VERSIONS_1 = 1 ; WARNING lots of logic in this screen assumes that the radio
ID_VERSIONS_2 = 2 ; buttons for each version are sequentially numbered starting at 1
ID_VERSIONS_3 = 3 ; and it would be very difficult to untangle if that suddenly
ID_VERSIONS_4 = 4 ; stopped being true
ID_VERSIONS_5 = 5
ID_VERSIONS_6 = 6
ID_VERSIONS_7 = 7
ID_VERSIONS_8 = 8
ID_VERSIONS_9 = 9
ID_VERSIONS_OK = 10
ID_VERSIONS_CANCEL = 11
; action keys for versions screen
kVersionsKeys
!byte $CF,ID_VERSIONS_OK ; O
!byte $EF,ID_VERSIONS_OK ; o
!byte $8D,ID_VERSIONS_OK ; Return
!byte $C3,ID_VERSIONS_CANCEL; C
!byte $E3,ID_VERSIONS_CANCEL; c
!byte $9B,ID_VERSIONS_CANCEL; Esc
!byte $B1,ID_VERSIONS_1 ; 1
!byte $B2,ID_VERSIONS_2 ; 2
!byte $B3,ID_VERSIONS_3 ; 3
!byte $B4,ID_VERSIONS_4 ; 4
!byte $B5,ID_VERSIONS_5 ; 5
!byte $B6,ID_VERSIONS_6 ; 6
!byte $B7,ID_VERSIONS_7 ; 7
!byte $B8,ID_VERSIONS_8 ; 8
!byte $B9,ID_VERSIONS_9 ; 9
!byte $88,ID_RADIO_PREVIOUS ; left arrow
!byte $95,ID_RADIO_NEXT ; right arrow
!byte $8B,ID_RADIO_PREVIOUS ; up arrow
!byte $8A,ID_RADIO_NEXT ; down arrow
_endVersionsKeys
;------------------------------------------------------------------------------
; VersionsDialog
; call WeeGUI to create and paint 'select version' dialog, and run to completion
;
; in: WeeGUI initialized
; out: exits via MainScreen
; all registers and flags clobbered
;------------------------------------------------------------------------------
VersionsDialog
ldx #$FF
txs
jsr HardResetWeeGUI
jsr okvs_len
!word gVersionsStore
sta iNumVersions
asl
inc
sta kViewVersionsFrame+5 ; frame visible height = 1 + (2 * numVersions)
sta kViewVersionsFrame+7 ; frame height
lda #12
sec
sbc iNumVersions
sta kViewVersionsFrame+3 ; frame top = 12 - numVersions
inc
sta kViewVersionsOK+2 ; OK top = frame top + 1
inc
inc
sta kViewVersionsCancel+2 ; Cancel top = OK top + 2
jsr CreateDialog ; create decorated frame
!word kViewVersionsFrame
!word kStringVersionsFrame
jsr CreateButton ; create UI controls
!word kViewVersionsOK
jsr CreateButton
!word kViewVersionsCancel
ldx #0 ; X = index of radio button (0-based)
.createRadioLoop
phx
txa
asl
tax
lda kViewVersionsArray,x
ldy kViewVersionsArray+1,x
+STAY +
+STAY SRC
txa
inc
clc
adc kViewVersionsFrame+3
ldy #2
sta (SRC),y ; radio button top = frame top + 1 + (2 * X)
jsr CreateRadio ; create radio button for this version (will print label later)
+ !word $FDFD ; SMC
plx
inx
iNumVersions=*+1
cpx #$FD ; SMC
bne .createRadioLoop
jsr okvs_get ; get current version and check appropriate radio button
!word gGlobalPrefsStore
!word kLastPlayed
+STAY +
jsr okvs_get
!word gGlobalPrefsStore
+ !word $FDFD ; SMC
+STAY +
jsr okvs_get
!word gVersionsStore
+ !word $FDFD ; SMC
; X = 0-based index of current version in the list of versions for this game
inx ; X = 1-based index of current version, which is the WeeGUI view ID
txa
ldx #WGSelectView
jsr WeeGUI
lda #1
sta PARAM0
ldx #WGSetState
jsr WeeGUI
ldx #WGDesktop ; paint background
jsr WeeGUI
jsr PaintTitleBar ; paint top title bar
ldx #WGViewPaintAll ; paint UI controls (window frame, buttons, checkboxes, radio buttons)
jsr WeeGUI
ldx #WGSelectView ; select frame (required for print routines that follow)
lda #ID_VERSIONS_FRAME
jsr WeeGUI
lda #1 ; WeeGUI radio buttons are limited to 15 characters, so we have just the
sta iVersionsVTAB ; hotkeys (1-9) 'in' the radio button then print the labels separately
jsr okvs_iter_values
!word gVersionsStore
!word PrintVersionLabelCallback
jsr ClearPendingInput
- ldx #WGPendingViewAction
jsr WeeGUI ; handle mouse movement and clicks
lda $C000
bpl -
jsr ClearPendingInput
jsr HandleVersionsKey ; handle keypresses
bra -
;------------------------------------------------------------------------------
; internal functions
;------------------------------------------------------------------------------
; HandleVersionsKey
;
; in: A = key pressed
; out: all registers and flags clobbered
;------------------------------------------------------------------------------
HandleVersionsKey
ldx #(_endVersionsKeys-kVersionsKeys)-2
- cmp kVersionsKeys,x
beq @found
dex
dex
bpl -
@error jmp SoftBell
@found lda kVersionsKeys+1,x ; get action ID associated with this key
bmi @updown
tax ; action ID < #$80 is a WeeGUI view, so activate it
ldy gViewInUse,x
beq @error
ldx #WGSelectView
jsr WeeGUI
jmp SimulateClick
@updown ldx #ID_VERSIONS_1
ldy iNumVersions
jmp HandleUpDownRadio
PrintVersionLabelCallback
; called via okvs_iter_values
; X = index (0-based) into gVersionsStore
; A/Y points to okvs record value, which we use to create a printable label
ldx #50
jsr CreateNullTerminatedString
jsr PrintAt
!byte 7 ; htab (constant)
iVersionsVTAB
!byte $FD ; SMC
!word kNullTerminatedBuffer
inc iVersionsVTAB
inc iVersionsVTAB
rts
VersionsOKCallback
ldx #ID_VERSIONS_1
ldy iNumVersions
jsr GetCheckedRadioButton ; figure out which radio button is checked
dec
sta @n
jsr okvs_nth
!word gVersionsStore
@n !byte $FD ; SMC
+STAY @value
jsr okvs_get
!word gGlobalPrefsStore
!word kLastPlayed
+STAY @key
jsr okvs_update
!word gGlobalPrefsStore
@key !word $FDFD ; SMC
@value !word $FDFD ; SMC
lda #1
sta gGlobalPrefsDirty ; must set, otherwise SaveGlobalPreferences does nothing
jsr SaveGlobalPreferences ; immediately write new preferences to disk
jsr CheckForSavedGames ; recheck whether the newly selected version has saved games (affects painting in main screen)
jmp MainScreen ; exit via main screen
;------------------------------------------------------------------------------
; WeeGUI view configuration records
kViewVersionsFrame
!byte ID_VERSIONS_FRAME ; view ID
!byte 2 ; style (decorated frame)
!byte 5 ; left
!byte $FD ; top
!byte 70 ; visible width
!byte $FD ; visible height
!byte 70 ; width
!byte $FD ; height
kViewVersionsOK
!byte ID_VERSIONS_OK ; view ID
!byte 63 ; left
!byte $FD ; top
!byte 10 ; width
!word VersionsOKCallback ; callback
!word kStringOK ; caption
kViewVersionsCancel
!byte ID_VERSIONS_CANCEL ; view ID
!byte 63 ; left
!byte $FD ; top
!byte 10 ; width
!word MainScreen ; callback
!word kStringCancel ; caption
kViewVersionsArray
!word kViewVersions1
!word kViewVersions2
!word kViewVersions3
!word kViewVersions4
!word kViewVersions5
!word kViewVersions6
!word kViewVersions7
!word kViewVersions8
!word kViewVersions9
kViewVersions1
!byte ID_VERSIONS_1 ; view ID
!byte 8 ; left
!byte 4 ; top
!word kString1 ; caption
kViewVersions2
!byte ID_VERSIONS_2 ; view ID
!byte 8 ; left
!byte 6 ; top
!word kString2 ; caption
kViewVersions3
!byte ID_VERSIONS_3 ; view ID
!byte 8 ; left
!byte 8 ; top
!word kString3 ; caption
kViewVersions4
!byte ID_VERSIONS_4 ; view ID
!byte 8 ; left
!byte 10 ; top
!word kString4 ; caption
kViewVersions5
!byte ID_VERSIONS_5 ; view ID
!byte 8 ; left
!byte 12 ; top
!word kString5 ; caption
kViewVersions6
!byte ID_VERSIONS_6 ; view ID
!byte 8 ; left
!byte 14 ; top
!word kString6 ; caption
kViewVersions7
!byte ID_VERSIONS_7 ; view ID
!byte 8 ; left
!byte 16 ; top
!word kString7 ; caption
kViewVersions8
!byte ID_VERSIONS_8 ; view ID
!byte 8 ; left
!byte 18 ; top
!word kString8 ; caption
kViewVersions9
!byte ID_VERSIONS_9 ; view ID
!byte 8 ; left
!byte 20 ; top
!word kString9 ; caption
kStringVersionsFrame
!text "Select Version",0
kString1
!text " ",$31,0
kString2
!text " ",$32,0
kString3
!text " ",$33,0
kString4
!text " ",$34,0
kString5
!text " ",$35,0
kString6
!text " ",$36,0
kString7
!text " ",$37,0
kString8
!text " ",$38,0
kString9
!text " ",$39,0