2018-04-02 19:43:11 +00:00
|
|
|
;license:MIT
|
|
|
|
;(c) 2018 by 4am
|
|
|
|
;
|
|
|
|
; User interface - views and paint routines for 'resume game' screen
|
|
|
|
;
|
|
|
|
; Public functions
|
|
|
|
; - ResumeGameDialog
|
|
|
|
;
|
|
|
|
|
|
|
|
; View IDs (application-specific, acceptable range 0..15, no duplicates)
|
|
|
|
ID_RESUME_FRAME = 0
|
|
|
|
ID_RESUME_SLOT0 = 1
|
|
|
|
ID_RESUME_SLOT1 = 2
|
|
|
|
ID_RESUME_SLOT2 = 3
|
|
|
|
ID_RESUME_SLOT3 = 4
|
|
|
|
ID_RESUME_SLOT4 = 5
|
|
|
|
ID_RESUME_SLOT5 = 6
|
|
|
|
ID_RESUME_SLOT6 = 7
|
|
|
|
ID_RESUME_SLOT7 = 8
|
|
|
|
ID_RESUME_NEWGAME = 9
|
|
|
|
ID_RESUME_OK = 10
|
|
|
|
ID_RESUME_CANCEL = 11
|
|
|
|
|
|
|
|
gResumeViewInUse
|
|
|
|
!byte 1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0
|
|
|
|
|
|
|
|
; action keys for options screen
|
2018-04-18 19:28:55 +00:00
|
|
|
kResumeKeys
|
2018-04-02 19:43:11 +00:00
|
|
|
!byte $CF,ID_RESUME_OK ; O
|
|
|
|
!byte $EF,ID_RESUME_OK ; o
|
|
|
|
!byte $8D,ID_RESUME_OK ; Return
|
|
|
|
!byte $C3,ID_RESUME_CANCEL ; C
|
|
|
|
!byte $E3,ID_RESUME_CANCEL ; c
|
|
|
|
!byte $9B,ID_RESUME_CANCEL ; Esc
|
|
|
|
!byte $B0,ID_RESUME_SLOT0 ; 0
|
|
|
|
!byte $B1,ID_RESUME_SLOT1 ; 1
|
|
|
|
!byte $B2,ID_RESUME_SLOT2 ; 2
|
|
|
|
!byte $B3,ID_RESUME_SLOT3 ; 3
|
|
|
|
!byte $B4,ID_RESUME_SLOT4 ; 4
|
|
|
|
!byte $B5,ID_RESUME_SLOT5 ; 5
|
|
|
|
!byte $B6,ID_RESUME_SLOT6 ; 6
|
|
|
|
!byte $B7,ID_RESUME_SLOT7 ; 7
|
|
|
|
!byte $CE,ID_RESUME_NEWGAME ; N
|
|
|
|
!byte $EE,ID_RESUME_NEWGAME ; n
|
|
|
|
!byte $88,ID_RESUME_PREVIOUS; left arrow
|
|
|
|
!byte $95,ID_RESUME_NEXT ; right arrow
|
|
|
|
!byte $8B,ID_RESUME_PREVIOUS; up arrow
|
|
|
|
!byte $8A,ID_RESUME_NEXT ; down arrow
|
2018-04-18 19:28:55 +00:00
|
|
|
_endResumeKeys
|
2018-04-02 19:43:11 +00:00
|
|
|
|
|
|
|
; IDs of actions that do not correspond to WeeGUI view IDs have high bit set
|
|
|
|
ID_RESUME_PREVIOUS = $81
|
|
|
|
ID_RESUME_NEXT = $82
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; ResumeDialog
|
|
|
|
; call WeeGUI to create and paint 'resume game' screen, and run to completion
|
|
|
|
;
|
|
|
|
; in: WeeGUI initialized
|
2018-04-17 17:56:50 +00:00
|
|
|
; out: exits via MainScreen, LaunchInterpreterWithSavedGame, or LaunchInterpreterWithNewGame
|
2018-04-02 19:43:11 +00:00
|
|
|
;------------------------------------------------------------------------------
|
2018-04-18 19:28:55 +00:00
|
|
|
!zone {
|
2018-04-02 19:43:11 +00:00
|
|
|
ResumeDialog
|
|
|
|
ldx #$FF
|
|
|
|
txs
|
2018-04-17 19:43:00 +00:00
|
|
|
jsr HardResetWeeGUI
|
2018-04-02 19:43:11 +00:00
|
|
|
|
2018-04-18 00:32:31 +00:00
|
|
|
ldx #ID_RESUME_SLOT7
|
|
|
|
- stz gResumeViewInUse,x ; reset flags for which radio buttons are in use
|
|
|
|
dex
|
|
|
|
bne -
|
|
|
|
|
2018-04-17 19:43:00 +00:00
|
|
|
jsr LoadSavedGameInfo ; call ZINFO to get the information we need for this dialog
|
2018-04-17 03:48:30 +00:00
|
|
|
|
2018-04-17 19:43:00 +00:00
|
|
|
lda gSavedGamesSlotsInUse ; populated by LoadSavedGameInfo
|
2018-04-17 17:17:55 +00:00
|
|
|
asl
|
|
|
|
clc
|
|
|
|
adc #3
|
|
|
|
sta kViewResumeFrame+5 ; frame visible height = 3 + (2 * usedSlots)
|
|
|
|
sta kViewResumeFrame+7 ; frame height
|
|
|
|
lda #11
|
|
|
|
sec
|
|
|
|
sbc gSavedGamesSlotsInUse
|
|
|
|
sta kViewResumeFrame+3 ; frame top = 11 - usedSlots
|
|
|
|
inc
|
|
|
|
sta iResumeVTAB ; top of first radio button
|
|
|
|
sta kViewResumeOK+2 ; OK top
|
|
|
|
inc
|
|
|
|
inc
|
|
|
|
sta kViewResumeCancel+2 ; Cancel top
|
2018-04-11 19:12:36 +00:00
|
|
|
|
|
|
|
jsr CreateDialog
|
|
|
|
!word kViewResumeFrame
|
|
|
|
!word kStringResumeFrame
|
2018-04-02 19:43:11 +00:00
|
|
|
|
|
|
|
jsr CreateButton ; create UI controls
|
2018-04-11 19:12:36 +00:00
|
|
|
!word kViewResumeOK
|
2018-04-02 19:43:11 +00:00
|
|
|
jsr CreateButton
|
2018-04-11 19:12:36 +00:00
|
|
|
!word kViewResumeCancel
|
|
|
|
|
2018-04-17 03:48:30 +00:00
|
|
|
jsr okvs_iter
|
|
|
|
!word gSavedGamesStore
|
|
|
|
!word CreateResumeRadioCallback
|
|
|
|
|
2018-04-17 17:17:55 +00:00
|
|
|
lda iResumeVTAB
|
|
|
|
sta kViewResumeNewGameTop
|
2018-04-11 19:12:36 +00:00
|
|
|
jsr CreateRadio
|
2018-04-17 03:48:30 +00:00
|
|
|
!word kViewResumeNewGame
|
|
|
|
|
2018-04-18 01:49:48 +00:00
|
|
|
lda gLastSavedGameSlot ; initial checked radio button = last save slot + 1
|
|
|
|
bmi +
|
|
|
|
inc
|
2018-04-18 02:28:22 +00:00
|
|
|
+HIDE_NEXT_2_BYTES
|
2018-04-18 01:49:48 +00:00
|
|
|
+ lda #ID_RESUME_NEWGAME ; if last save slot is invalid, just check 'new game'
|
2018-04-17 03:48:30 +00:00
|
|
|
ldx #WGSelectView
|
|
|
|
jsr WeeGUI
|
|
|
|
lda #1
|
|
|
|
sta PARAM0
|
|
|
|
ldx #WGSetState
|
|
|
|
jsr WeeGUI
|
2018-04-02 19:43:11 +00:00
|
|
|
|
|
|
|
ldx #WGDesktop ; paint background
|
|
|
|
jsr WeeGUI
|
|
|
|
|
|
|
|
ldx #WGViewPaintAll ; paint UI controls (window frame, buttons, checkboxes, radio buttons)
|
|
|
|
jsr WeeGUI
|
|
|
|
|
|
|
|
jsr PaintTitleBar ; paint top title bar
|
|
|
|
|
2018-04-17 03:48:30 +00:00
|
|
|
ldx #WGSelectView ; select frame (required for print routines that follow)
|
2018-04-02 19:43:11 +00:00
|
|
|
lda #ID_RESUME_FRAME
|
|
|
|
jsr WeeGUI
|
|
|
|
|
2018-04-17 03:48:30 +00:00
|
|
|
lda #1 ; WeeGUI radio buttons are limited to 15 characters, so we
|
2018-04-17 17:17:55 +00:00
|
|
|
sta iResumeVTAB ; print the longer labels separately
|
2018-04-17 03:48:30 +00:00
|
|
|
jsr okvs_iter_values
|
|
|
|
!word gSavedGamesStore
|
|
|
|
!word PrintResumeLabelCallback
|
|
|
|
|
2018-04-02 19:43:11 +00:00
|
|
|
.runLoop
|
|
|
|
ldx #WGPendingViewAction
|
|
|
|
jsr WeeGUI
|
|
|
|
lda $c000
|
|
|
|
bpl .runLoop
|
|
|
|
bit $c010
|
2018-04-11 19:12:36 +00:00
|
|
|
jsr HandleResumeKey
|
2018-04-02 19:43:11 +00:00
|
|
|
bra .runLoop
|
2018-04-18 19:28:55 +00:00
|
|
|
}
|
2018-04-02 19:43:11 +00:00
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; internal functions
|
|
|
|
|
2018-04-18 19:28:55 +00:00
|
|
|
!zone {
|
|
|
|
HandleResumeKey
|
|
|
|
; A = key pressed
|
|
|
|
; out: all registers and flags clobbered
|
|
|
|
ldx #_endResumeKeys-kResumeKeys
|
|
|
|
- cmp kResumeKeys,x
|
|
|
|
beq .foundKey
|
|
|
|
dex
|
|
|
|
dex
|
|
|
|
bpl -
|
|
|
|
jmp SoftBell
|
|
|
|
.foundKey
|
|
|
|
; TODO need to handle up and down arrow keys like versions dialog
|
|
|
|
lda kResumeKeys+1,x
|
|
|
|
ldx #WGSelectView
|
|
|
|
jsr WeeGUI
|
|
|
|
jmp SimulateClick
|
|
|
|
}
|
|
|
|
|
|
|
|
!zone {
|
2018-04-17 03:48:30 +00:00
|
|
|
CreateResumeRadioCallback
|
2018-04-17 17:17:55 +00:00
|
|
|
; called via okvs_iter
|
2018-04-17 03:48:30 +00:00
|
|
|
; X = index (0-based) into gSavedGamesStore, which is also the slot number
|
2018-04-17 17:17:55 +00:00
|
|
|
; A/Y points to okvs record key, which we use as the radio button caption
|
|
|
|
; (length-prefixed and null-terminated, length=0 if slot is unused and should be skipped)
|
2018-04-17 03:48:30 +00:00
|
|
|
;
|
2018-04-17 17:17:55 +00:00
|
|
|
+STAY PTR
|
|
|
|
lda (PTR)
|
2018-04-17 03:48:30 +00:00
|
|
|
sta gResumeViewInUse+1,x ; mark whether this view is in use (hotkeys activate based on this array)
|
2018-04-17 17:17:55 +00:00
|
|
|
beq .createResumeRadioDone; length=0 means this slot is unused, so we're done
|
|
|
|
|
|
|
|
lda PTR
|
|
|
|
inc ; skip over length byte
|
|
|
|
bne +
|
|
|
|
iny
|
|
|
|
+
|
|
|
|
+STAY kViewResumeRadioCaption ; A/Y -> null-terminated string, which is what WeeGUI wants
|
|
|
|
inx
|
|
|
|
stx kViewResumeRadioSlot ; WeeGUI view ID = X + 1
|
|
|
|
lda iResumeVTAB
|
|
|
|
sta kViewResumeRadioTop ; radio button top = frame top + 1 + (2 * X)
|
2018-04-17 03:48:30 +00:00
|
|
|
jsr CreateRadio ; create radio button for this version (will print label later)
|
2018-04-17 17:17:55 +00:00
|
|
|
!word kViewResumeRadio
|
|
|
|
inc iResumeVTAB
|
|
|
|
inc iResumeVTAB
|
2018-04-17 03:48:30 +00:00
|
|
|
.createResumeRadioDone
|
|
|
|
rts
|
2018-04-18 19:28:55 +00:00
|
|
|
}
|
2018-04-17 03:48:30 +00:00
|
|
|
|
2018-04-18 19:28:55 +00:00
|
|
|
!zone {
|
2018-04-17 03:48:30 +00:00
|
|
|
PrintResumeLabelCallback
|
2018-04-17 17:17:55 +00:00
|
|
|
; called via okvs_iter_values
|
|
|
|
; X = index (0-based) into gSavedGamesStore, which is also the slot number
|
|
|
|
; A/Y points to okvs record value, which we use as a printable label
|
|
|
|
; (length-prefixed and null-terminated, length=0 if slot is unused and should be skipped)
|
|
|
|
+STAY PTR
|
|
|
|
lda (PTR)
|
|
|
|
beq .printResumeLabelDone ; length=0 means this slot is unused, so we're done
|
|
|
|
|
|
|
|
lda PTR
|
|
|
|
inc ; skip over length byte
|
|
|
|
bne +
|
|
|
|
iny
|
|
|
|
+
|
|
|
|
+STAY .printResumeLabel ; A/Y -> null-terminated string
|
2018-04-17 03:48:30 +00:00
|
|
|
jsr PrintAt
|
2018-04-17 17:17:55 +00:00
|
|
|
!byte 14 ; htab (constant)
|
|
|
|
iResumeVTAB
|
2018-04-17 03:48:30 +00:00
|
|
|
!byte $FD ; SMC
|
2018-04-17 17:17:55 +00:00
|
|
|
.printResumeLabel
|
|
|
|
!word $FDFD ; SMC
|
|
|
|
inc iResumeVTAB
|
|
|
|
inc iResumeVTAB
|
|
|
|
.printResumeLabelDone
|
2018-04-17 03:48:30 +00:00
|
|
|
rts
|
2018-04-18 19:28:55 +00:00
|
|
|
}
|
2018-04-17 03:48:30 +00:00
|
|
|
|
2018-04-18 19:28:55 +00:00
|
|
|
!zone {
|
|
|
|
ResumeOKCallback
|
2018-04-17 17:56:50 +00:00
|
|
|
lda #ID_RESUME_SLOT0
|
|
|
|
ldy #ID_RESUME_NEWGAME+1
|
|
|
|
jsr GetCheckedRadioButton ; returns A = WeeGUI view ID
|
|
|
|
cmp #ID_RESUME_NEWGAME
|
|
|
|
bne +
|
|
|
|
lda #0
|
|
|
|
+ dec ; A = saved game slot (which is WeeGUI view ID - 1) or #$FF
|
2018-04-17 18:06:41 +00:00
|
|
|
jmp LaunchInterpreterWithGame
|
2018-04-18 19:28:55 +00:00
|
|
|
}
|
2018-04-17 17:56:50 +00:00
|
|
|
|
2018-04-18 19:28:55 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; WeeGUI view configuration records
|
2018-04-02 19:43:11 +00:00
|
|
|
|
|
|
|
kViewResumeFrame
|
|
|
|
!byte ID_RESUME_FRAME ; view ID
|
|
|
|
!byte 2 ; style (decorated frame)
|
2018-04-11 19:12:36 +00:00
|
|
|
!byte 5 ; left
|
2018-04-02 19:43:11 +00:00
|
|
|
!byte $FD ; top
|
2018-04-11 19:12:36 +00:00
|
|
|
!byte 70 ; visible width
|
2018-04-02 19:43:11 +00:00
|
|
|
!byte $FD ; visible height
|
2018-04-11 19:12:36 +00:00
|
|
|
!byte 70 ; width
|
|
|
|
!byte $FD ; height
|
2018-04-02 19:43:11 +00:00
|
|
|
|
2018-04-11 19:12:36 +00:00
|
|
|
kViewResumeOK
|
2018-04-02 19:43:11 +00:00
|
|
|
!byte ID_RESUME_OK ; view ID
|
2018-04-11 19:12:36 +00:00
|
|
|
!byte 63 ; left
|
2018-04-02 19:43:11 +00:00
|
|
|
!byte $FD ; top
|
|
|
|
!byte 10 ; width
|
2018-04-18 19:28:55 +00:00
|
|
|
!word ResumeOKCallback ; callback
|
2018-04-02 19:43:11 +00:00
|
|
|
!word kStringOK ; caption
|
|
|
|
|
2018-04-11 19:12:36 +00:00
|
|
|
kViewResumeCancel
|
|
|
|
!byte ID_RESUME_CANCEL ; view ID
|
|
|
|
!byte 63 ; left
|
|
|
|
!byte $FD ; top
|
2018-04-02 19:43:11 +00:00
|
|
|
!byte 10 ; width
|
2018-04-18 19:28:55 +00:00
|
|
|
!word MainScreen ; callback
|
2018-04-02 19:43:11 +00:00
|
|
|
!word kStringCancel ; caption
|
|
|
|
|
2018-04-17 17:17:55 +00:00
|
|
|
kViewResumeRadio ; reused for each slot
|
|
|
|
kViewResumeRadioSlot
|
|
|
|
!byte $FD ; view ID (SMC)
|
2018-04-11 19:12:36 +00:00
|
|
|
!byte 8 ; left
|
2018-04-17 17:17:55 +00:00
|
|
|
kViewResumeRadioTop
|
|
|
|
!byte $FD ; top (SMC)
|
|
|
|
kViewResumeRadioCaption
|
|
|
|
!word $FDFD ; caption (SMC)
|
2018-04-11 19:12:36 +00:00
|
|
|
|
2018-04-17 03:48:30 +00:00
|
|
|
kViewResumeNewGame
|
|
|
|
!byte ID_RESUME_NEWGAME ; view ID
|
|
|
|
!byte 8 ; left
|
2018-04-17 17:17:55 +00:00
|
|
|
kViewResumeNewGameTop
|
|
|
|
!byte $FD ; top (SMC)
|
2018-04-17 03:48:30 +00:00
|
|
|
!word kStringNewGame ; caption
|
|
|
|
|
2018-04-18 19:28:55 +00:00
|
|
|
kStringResumeFrame
|
|
|
|
!text "Resume Game",0
|
2018-04-17 03:48:30 +00:00
|
|
|
kStringNewGame
|
|
|
|
!text " Start ",110,"ew game",0
|