;license:MIT ;(c) 2018 by 4am ; ; User interface - views and paint routines for 'resume game' screen ; ; Public functions ; - ResumeDialog ; ; 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 ; action keys for options screen kResumeKeys !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_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 _endResumeKeys ;------------------------------------------------------------------------------ ; ResumeDialog ; call WeeGUI to create and paint 'resume game' screen, and run to completion ; ; in: WeeGUI initialized ; out: exits via MainScreen, LaunchInterpreterWithSavedGame, or LaunchInterpreterWithNewGame ;------------------------------------------------------------------------------ ResumeDialog ldx #$FF txs jsr HardResetWeeGUI jsr LoadSavedGameInfo ; call ZINFO to get the information we need for this dialog lda gSavedGamesSlotsInUse ; populated by LoadSavedGameInfo 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 jsr CreateDialog ; create decorated frame !word kViewResumeFrame !word kStringResumeFrame jsr CreateButton ; create OK/Cancel buttons !word kViewResumeOK jsr CreateButton !word kViewResumeCancel jsr okvs_iter ; create radio buttons for saved games !word gSavedGamesStore !word CreateResumeRadioCallback lda iResumeVTAB ; create 'new game' radio button sta kViewResumeNewGameTop jsr CreateRadio !word kViewResumeNewGame lda gLastSavedGameSlot ; initial checked radio button = last save slot + 1 bmi + inc +HIDE_NEXT_2_BYTES + lda #ID_RESUME_NEWGAME ; if last save slot is invalid, just check 'new game' ldx #WGSelectView jsr WeeGUI lda #1 sta PARAM0 ldx #WGSetState jsr WeeGUI 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 ldx #WGSelectView ; select frame (required for print routines that follow) lda #ID_RESUME_FRAME jsr WeeGUI lda #1 ; WeeGUI radio buttons are limited to 15 characters, so we sta iResumeVTAB ; print the longer labels separately jsr okvs_iter_values !word gSavedGamesStore !word PrintResumeLabelCallback jsr ClearPendingInput - ldx #WGPendingViewAction jsr WeeGUI lda $C000 bpl - jsr ClearPendingInput jsr HandleResumeKey bra - ;------------------------------------------------------------------------------ ; internal functions ;------------------------------------------------------------------------------ ; HandleResumeKey ; ; in: A = key pressed ; out: all registers and flags clobbered ;------------------------------------------------------------------------------ HandleResumeKey ldx #(_endResumeKeys-kResumeKeys)-2 - cmp kResumeKeys,x beq @found dex dex bpl - @error jmp SoftBell @found lda kResumeKeys+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_RESUME_SLOT0 ldy #ID_RESUME_NEWGAME jmp HandleUpDownRadio ;------------------------------------------------------------------------------ ; CreateResumeRadioCallback ; called via okvs_iter ; ; in: X = index (0-based) into gSavedGamesStore, which is also the slot number ; 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) ; out: all registers and flags clobbered ;------------------------------------------------------------------------------ CreateResumeRadioCallback +STAY PTR lda (PTR) beq @exit ; 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) jsr CreateRadio ; create radio button for this version (will print label later) !word kViewResumeRadio inc iResumeVTAB inc iResumeVTAB @exit rts ;------------------------------------------------------------------------------ ; PrintResumeLabelCallback ; called via okvs_iter_values ; ; in: 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) ; out: all registers and flags clobbered ;------------------------------------------------------------------------------ PrintResumeLabelCallback +STAY PTR lda (PTR) beq .printResumeExit ; 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 jsr PrintAt !byte 14 ; htab (constant) iResumeVTAB !byte $FD ; SMC .printResumeLabel !word $FDFD ; SMC inc iResumeVTAB inc iResumeVTAB .printResumeExit rts ;------------------------------------------------------------------------------ ; ResumeOKCallback ; called via OK button activation ; ; in: none ; out: exits via LaunchInterpreterWithGame ;------------------------------------------------------------------------------ ResumeOKCallback ldx #ID_RESUME_SLOT0 ldy #ID_RESUME_NEWGAME jsr GetCheckedRadioButton ; returns A = WeeGUI view ID cmp #ID_RESUME_NEWGAME bne + lda #0 + dec ; A = saved game slot or #$FF jmp LaunchInterpreterWithGame ;------------------------------------------------------------------------------ ; WeeGUI view configuration records kViewResumeFrame !byte ID_RESUME_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 kViewResumeOK !byte ID_RESUME_OK ; view ID !byte 63 ; left !byte $FD ; top !byte 10 ; width !word ResumeOKCallback ; callback !word kStringOK ; caption kViewResumeCancel !byte ID_RESUME_CANCEL ; view ID !byte 63 ; left !byte $FD ; top !byte 10 ; width !word MainScreen ; callback !word kStringCancel ; caption kViewResumeRadio ; reused for each slot kViewResumeRadioSlot !byte $FD ; view ID (SMC) !byte 8 ; left kViewResumeRadioTop !byte $FD ; top (SMC) kViewResumeRadioCaption !word $FDFD ; caption (SMC) kViewResumeNewGame !byte ID_RESUME_NEWGAME ; view ID !byte 8 ; left kViewResumeNewGameTop !byte $FD ; top (SMC) !word kStringNewGame ; caption kStringResumeFrame !text "Resume Game",0 kStringNewGame !text " Start ",110,"ew game",0