diff --git a/res/WEEGUI b/res/WEEGUI index ded34fa..fcf83ad 100644 Binary files a/res/WEEGUI and b/res/WEEGUI differ diff --git a/res/pitch.dark.conf b/res/pitch.dark.conf new file mode 100644 index 0000000..be1e3d1 --- /dev/null +++ b/res/pitch.dark.conf @@ -0,0 +1,49 @@ +# Pitch Dark preferences file +# do not edit by hand + +# value=0|1 +FORCE40COLUMNS=0 + +# value=0|1 +FORCEUPPERCASE=0 + +# value=NAME|YEAR|GENRE|DIFFICULTY +SORT=NAME + +# value=game directory +LASTPLAYED=ZORK.I + +# key=game directory, value=filename of selected version +AMFV=R79.DEPROT.Z4 +BALLYHOO=R97.851218.Z3 +BEYOND.ZORK=R57.871221.Z5 +BORDER.ZONE=R9.871008.Z5 +BUREAUCRACY=R116.DEPROT.Z4 +CUTTHROATS=R23.840809.Z3 +DEADLINE=R27.831005.Z3 +ENCHANTER=R29.860820.Z3 +HGTTG=R59.851108.Z3 +HOLLYWOOD=R37.861215.Z3 +INFIDEL=R22.830916.Z3 +LGOP=R59.860730.Z3 +LURKING.HORROR=R221.870918.Z3 +MINI.ZORK=R34.871124.Z3 +MOONMIST=R9.861022.Z3 +NORD.AND.BERT=R19.870722.Z4 +PLANETFALL=R37.851003.Z3 +PLUNDERED=R26.870730.Z3 +SEASTALKER=R16B.850603.Z3 +SHERLOCK=R26.880127.Z5 +SORCERER=R18.DEPROT.Z3 +SPELLBREAKER=R87.DEPROT.Z3 +STARCROSS=R17.821021.Z3 +STATIONFALL=R107.DEPROT.Z3 +SUSPECT=R14.841005.Z3 +SUSPENDED=R8B.840521.Z3 +TRINITY=R12.860926.Z4 +WISHBRINGER=R69.850920.Z3 +WITNESS=R22.840924.Z3 +ZORK.I=R88.840726.Z3 +ZORK.II=R48.840904.Z3 +ZORK.III=R17.840727.Z3 +ZTUU=R16.970828.Z5 diff --git a/src/WeeGUI_MLI.s b/src/WeeGUI_MLI.s index 5009e7c..1d3bac3 100644 --- a/src/WeeGUI_MLI.s +++ b/src/WeeGUI_MLI.s @@ -69,3 +69,8 @@ WGExit = 70 WGCreateProgress = 72 WGSetState = 74 WGViewSetRawTitle = 76 +WGSetContentWidth = 78 +WGSetContentHeight = 80 +WGStrokeRoundRect = 82 +WGCreateRadio = 84 + diff --git a/src/action.a b/src/action.a index cfa464e..41c514c 100644 --- a/src/action.a +++ b/src/action.a @@ -28,7 +28,7 @@ kArtworkRootDirectory ; length-prefixed pathname of DHGR box art !byte $C1,ID_BOXART ; A !byte $E1,ID_BOXART ; a !byte $D3,ID_OPTIONS ; S - !byte $E3,ID_OPTIONS ; s + !byte $F3,ID_OPTIONS ; s !byte $D0,ID_PREVIOUS ; P !byte $F0,ID_PREVIOUS ; p !byte $88,ID_PREVIOUS ; left arrow @@ -120,7 +120,7 @@ callback_versions callback_clues rts callback_options - rts + jmp OptionsDialog !zone { callback_boxart diff --git a/src/memory.a b/src/memory.a index c165c9e..0279051 100644 --- a/src/memory.a +++ b/src/memory.a @@ -7,3 +7,4 @@ ; - kProDOSFileBuffer kProDOSFileBuffer = $1C00 +WGInit = $4000 diff --git a/src/paint.a b/src/paint.a index d5fd3bf..167c21f 100644 --- a/src/paint.a +++ b/src/paint.a @@ -10,12 +10,10 @@ ; ; ROM routines -INVERSE = $FE80 -NORMAL = $FE84 MAGICRTS = $FF58 ; used to set overflow bit ; View IDs (application-specific, acceptable range 0..15, no duplicates) -ID_TITLE = 0 +; ID_TITLE is defined in paintcommon.a ID_PREVIOUS = 1 ID_OPTIONS = 2 ID_NEXT = 3 @@ -38,18 +36,7 @@ ID_DESCRIPTION = 13 ; all flags clobbered ;------------------------------------------------------------------------------ CreateViews - ldx #WGCreateView ; create title bar on top line - lda #<.viewTitle - sta PARAM0 - lda #>.viewTitle - sta PARAM1 - jsr WeeGUI - ldx #WGViewSetAction - lda #<.paintTitleView - sta PARAM0 - lda #>.paintTitleView - sta PARAM1 - jsr WeeGUI + jsr CreateTitleView ldx #WGCreateView ; create horizontal rule lda #<.viewHR @@ -57,26 +44,20 @@ CreateViews lda #>.viewHR sta PARAM1 jsr WeeGUI - ldx #WGViewSetAction - lda #<.paintHRView - sta PARAM0 - lda #>.paintHRView - sta PARAM1 - jsr WeeGUI - jsr .createButton ; create various buttons + jsr CreateButton ; create various buttons !word .viewPrevious - jsr .createButton + jsr CreateButton !word .viewNext - jsr .createButton + jsr CreateButton !word .viewPlay - jsr .createButton + jsr CreateButton !word .viewVersions - jsr .createButton + jsr CreateButton !word .viewBoxArt - jsr .createButton + jsr CreateButton !word .viewClues - jsr .createButton + jsr CreateButton !word .viewOptions ldx #WGCreateView ; create borderless frame for game title and info @@ -118,7 +99,7 @@ CreateViews PaintAllViews ldx #WGViewPaintAll ; repaint all views that can be painted automatically jsr WeeGUI - jsr .paintTitleView + jsr PaintTitleView jsr .paintHRView jsr .paintInfoView jmp .paintDescriptionView @@ -141,29 +122,20 @@ RepaintSomeViews ;------------------------------------------------------------------------------ -.paintTitleView - ldx #WGSelectView - lda #ID_TITLE - jsr WeeGUI - jsr INVERSE - ldx #WGPrint - lda #<.stringTitle - sta PARAM0 - lda #>.stringTitle - sta PARAM1 - jsr WeeGUI - jmp NORMAL - .paintHRView ldx #WGSelectView lda #ID_HR jsr WeeGUI - ldx #WGPrint - lda #<.stringHR + lda #1 sta PARAM0 - lda #>.stringHR + lda #5 sta PARAM1 - bit MAGICRTS ; set overflow bit + lda #78 + sta PARAM2 + lda #0 + sta PARAM3 + ldy #83 + ldx #WGFillRect jmp WeeGUI .paintDescriptionView @@ -178,8 +150,8 @@ RepaintSomeViews cmp #10 bcs + lda #10 -+ sta $59B6 ; HACKHACKHACK set view height inside WeeGUI internals (WG_VIEWRECORDS) - rts ++ ldx #WGSetContentHeight + jmp WeeGUI .paintInfoView ldx #WGSelectView @@ -224,32 +196,6 @@ RepaintSomeViews .printDone rts -.createButton - pla - sta $00 - pla - sta $01 - tax - lda #$02 - clc - adc $00 - bcc + - inx -+ phx - pha - ldy #$01 - lda ($00),y - sta PARAM0 - iny - lda ($00),y - sta PARAM1 - ldx #WGCreateButton - jsr WeeGUI - ldx #WGViewSetRawTitle - lda #1 - sta PARAM0 - jmp WeeGUI - .resetDescriptionViewScrolling ldx #WGSelectView lda #ID_DESCRIPTION @@ -261,18 +207,6 @@ RepaintSomeViews lda #0 jmp WeeGUI -.viewTitle - !byte ID_TITLE ; view ID - !byte 0 ; style - !byte 0 ; left - !byte 0 ; top - !byte 80 ; visible width - !byte 1 ; visible height - !byte 80 ; width - !byte 1 ; height -.stringTitle - !raw " Pitch Dark ",0 - .viewPrevious !byte ID_PREVIOUS ; view ID !byte 1 ; left @@ -316,9 +250,6 @@ RepaintSomeViews !byte 1 ; visible height !byte 78 ; width !byte 1 ; height -.stringHR - !fill 78,83 - !byte 0 .viewPlay !byte ID_PLAY ; view ID diff --git a/src/paintcommon.a b/src/paintcommon.a new file mode 100644 index 0000000..780b019 --- /dev/null +++ b/src/paintcommon.a @@ -0,0 +1,100 @@ +;license:MIT +;(c) 2018 by 4am +; +; User interface - common views and paint routines across screens +; +; Public functions +; - CreateRadio +; - CreateCheckbox +; - CreateButton +; - CreateTitleView +; - PaintTitleView +; - DeleteAllViews +; + +; ROM routines +INVERSE = $FE80 +NORMAL = $FE84 + +; View IDs (application-specific, acceptable range 0..15, no duplicates) +ID_TITLE = 0 + +!zone { +CreateRadio + ldx #WGCreateRadio + !byte $2C ; hide next 2 bytes +CreateCheckbox + ldx #WGCreateCheckbox + !byte $2C ; hide next 2 bytes +CreateButton + ldx #WGCreateButton + stx .type+1 + pla + sta $00 + pla + sta $01 + tax + lda #$02 + clc + adc $00 + bcc + + inx ++ phx + pha + ldy #$01 + lda ($00),y + sta PARAM0 + iny + lda ($00),y + sta PARAM1 +.type + ldx #$FD ; set at runtime + jsr WeeGUI + ldx #WGViewSetRawTitle + lda #1 + sta PARAM0 + jmp WeeGUI + +CreateTitleView + ldx #WGCreateView ; create title bar on top line + lda #viewTitle + sta PARAM1 + jmp WeeGUI + +PaintTitleView + ldx #WGSelectView + lda #ID_TITLE + jsr WeeGUI + jsr INVERSE + ldx #WGPrint + lda #<.stringTitle + sta PARAM0 + lda #>.stringTitle + sta PARAM1 + jsr WeeGUI + jmp NORMAL + +viewTitle + !byte ID_TITLE ; view ID + !byte 0 ; style + !byte 0 ; left + !byte 0 ; top + !byte 80 ; visible width + !byte 1 ; visible height + !byte 80 ; width + !byte 1 ; height +.stringTitle + !raw " Pitch Dark ",0 + +DeleteAllViews + lda #15 +- ldx #WGSelectView + jsr WeeGUI + ldx #WGDeleteView + jsr WeeGUI + dec + bpl - + rts +} diff --git a/src/paintoptions.a b/src/paintoptions.a new file mode 100644 index 0000000..663047c --- /dev/null +++ b/src/paintoptions.a @@ -0,0 +1,265 @@ +;license:MIT +;(c) 2018 by 4am +; +; User interface - views and paint routines for options screen +; +; Public functions +; - OptionsDialog +; + +; View IDs (application-specific, acceptable range 0..15, no duplicates) +; ID_TITLE is defined in paintcommon.a +ID_OPTIONS_FRAME = 1 +ID_OPTIONS_NAME = 2 +ID_OPTIONS_YEAR = 3 +ID_OPTIONS_GENRE = 4 +ID_OPTIONS_DIFFICULTY = 5 +ID_OPTIONS_FORCE40 = 6 +ID_OPTIONS_FORCEUPPER = 7 +ID_OPTIONS_OK = 8 +ID_OPTIONS_CANCEL = 9 + +!zone { +;------------------------------------------------------------------------------ +; OptionsDialog +; call WeeGUI to create and paint all option screen views +; +; in: WeeGUI loaded and initialized +; out: all registers clobbered +; all flags clobbered +;------------------------------------------------------------------------------ +OptionsDialog + ldx #$FF + txs + jsr WGInit ; reset WeeGUI + + jsr CreateTitleView ; create title bar (defined in paintcommon.a) + + ldx #WGCreateView ; create frame + lda #<.viewFrame + sta PARAM0 + lda #>.viewFrame + sta PARAM1 + jsr WeeGUI + ldx #WGViewSetTitle + lda #<.stringFrame + sta PARAM0 + lda #>.stringFrame + sta PARAM1 + jsr WeeGUI + + jsr CreateButton ; create UI controls + !word .viewOK + jsr CreateButton + !word .viewCancel + jsr CreateRadio + !word .viewName + ldx #WGSetState ; TODO: set the appropriate radio button based on preferences + lda #1 + jsr WeeGUI + jsr CreateRadio + !word .viewYear + jsr CreateRadio + !word .viewGenre + jsr CreateRadio + !word .viewDifficulty + jsr CreateCheckbox + !word .viewForce40 + jsr CreateCheckbox + !word .viewForceUpper + + ldx #WGDesktop ; paint background + jsr WeeGUI + + ldx #WGViewPaintAll ; paint UI controls (window frame, buttons, checkboxes, radio buttons) + jsr WeeGUI + + jsr PaintTitleView ; paint top title bar + + ldx #WGSelectView + lda #ID_OPTIONS_FRAME + jsr WeeGUI + + ldx #WGSetCursor ; paint static text labels + lda #2 + sta PARAM0 + lda #1 + sta PARAM1 + jsr WeeGUI + ldx #WGPrint + lda #<.stringSortBy + sta PARAM0 + lda #>.stringSortBy + sta PARAM1 + jsr WeeGUI + + ldx #WGSetCursor + lda #2 + sta PARAM0 + lda #12 + sta PARAM1 + jsr WeeGUI + ldx #WGPrint + lda #<.stringGameplay + sta PARAM0 + lda #>.stringGameplay + sta PARAM1 + jsr WeeGUI + +.runLoop + ldx #WGPendingViewAction + jsr WeeGUI + lda $c000 + bpl .runLoop + bit $c010 + jsr HandleOptionsKey + bra .runLoop + +; action keys for options screen +.keys + !byte $CF,ID_OPTIONS_OK ; O + !byte $EF,ID_OPTIONS_OK ; o + !byte $8D,ID_OPTIONS_OK ; Return + !byte $C3,ID_OPTIONS_CANCEL ; C + !byte $E3,ID_OPTIONS_CANCEL ; c + !byte $9B,ID_OPTIONS_CANCEL ; Esc + !byte $CE,ID_OPTIONS_NAME ; N + !byte $EE,ID_OPTIONS_NAME ; n + !byte $D9,ID_OPTIONS_YEAR ; Y + !byte $F9,ID_OPTIONS_YEAR ; y + !byte $C7,ID_OPTIONS_GENRE ; G + !byte $E7,ID_OPTIONS_GENRE ; g + !byte $C4,ID_OPTIONS_DIFFICULTY ; D + !byte $E4,ID_OPTIONS_DIFFICULTY ; d + !byte $B4,ID_OPTIONS_FORCE40 ; 4 + !byte $D5,ID_OPTIONS_FORCEUPPER ; U + !byte $F5,ID_OPTIONS_FORCEUPPER ; u +.endkeys + +HandleOptionsKey + ldx #.endkeys-.keys +- cmp .keys,x + beq .foundKey + dex + dex + bpl - + rts +.foundKey + lda .keys+1,x + ldx #WGSelectView + jsr WeeGUI + ldx #WGViewFocus + jsr WeeGUI + ldx #WGViewFocusAction + jsr WeeGUI + ldx #WGViewUnfocus + jmp WeeGUI + +callback_options_ok +; TODO set preferences +callback_options_cancel + ldx #$FF + txs + jsr WGInit + jmp MainScreen + +.viewFrame + !byte ID_OPTIONS_FRAME ; view ID + !byte 2 ; style (decorated frame) + !byte 22 ; left + !byte 3 ; top + !byte 36 ; visible width + !byte 18 ; visible height + !byte 36 ; width + !byte 18 ; height +.stringFrame + !text "Settings",0 + +.viewOK + !byte ID_OPTIONS_OK ; view ID + !byte 46 ; left + !byte 4 ; top + !byte 10 ; width + !word callback_options_ok ; callback + !word .stringOK ; caption +.stringOK + !byte $0F ; 'P' inverse + !byte 139,0 + +.viewCancel + !byte ID_OPTIONS_CANCEL ; view ID + !byte 46 ; left + !byte 6 ; top + !byte 10 ; width + !word callback_options_cancel ; callback + !word .stringCancel ; caption +.stringCancel + !byte $03 ; 'C' inverse + !text "ancel",0 + +.viewName + !byte ID_OPTIONS_NAME ; view ID + !byte 26 ; left + !byte 6 ; top + !word .stringName +.stringName + !text " " + !byte $0E ; 'N' inverse + !text "ame",0 + +.viewYear + !byte ID_OPTIONS_YEAR ; view ID + !byte 26 ; left + !byte 8 ; top + !word .stringYear +.stringYear + !text " " + !byte $19 ; 'Y' inverse + !text "ear",0 + +.viewGenre + !byte ID_OPTIONS_GENRE ; view ID + !byte 26 ; left + !byte 10 ; top + !word .stringGenre +.stringGenre + !text " " + !byte $07 ; 'G' inverse + !text "enre",0 + +.viewDifficulty + !byte ID_OPTIONS_DIFFICULTY ; view ID + !byte 26 ; left + !byte 12 ; top + !word .stringDifficulty +.stringDifficulty + !text " " + !byte $04 ; 'D' inverse + !text "ifficulty",0 + +.viewForce40 + !byte ID_OPTIONS_FORCE40 ; view ID + !byte 26 ; left + !byte 17 ; top + !word .stringForce40 ; caption +.stringForce40 + !text "Force " + !byte $34 ; '4' inverse + !text "0 column",0 + +.viewForceUpper + !byte ID_OPTIONS_FORCEUPPER ; view ID + !byte 26 ; left + !byte 19 ; top + !word .stringForceUpper ; caption +.stringForceUpper + !text "Force " + !byte $75 ; 'u' inverse + !text "ppercase",0 + +.stringSortBy + !raw "Browse games by",0 + +.stringGameplay + !raw "During gameplay:",0 +} diff --git a/src/pitchdark.a b/src/pitchdark.a index e761ad6..4cb8a75 100644 --- a/src/pitchdark.a +++ b/src/pitchdark.a @@ -19,7 +19,9 @@ !source "src/prefs.a" !source "src/config.a" !source "src/action.a" + !source "src/paintcommon.a" !source "src/paint.a" + !source "src/paintoptions.a" Start lda MACHID and #$30 @@ -30,21 +32,23 @@ Start bit $C010 jsr LoadFile ; load WEEGUI binary at $4000 !word .weeguiFilename - !word $4000 + !word WGInit !word $2000 !word kProDOSFileBuffer - jsr $4000 ; initialize WeeGUI + jsr WGInit ; initialize WeeGUI jsr LoadGlobalPreferences ; get current game jsr LoadGameInfo ; load and parse game description text + ldx #WGEnableMouse ; enable mouse support + jsr WeeGUI + +MainScreen jsr CreateViews ; create all WeeGUI views (UI elements) ldx #WGClearScreen ; clear screen jsr WeeGUI jsr PaintAllViews ; draw all UI elements - ldx #WGEnableMouse ; enable mouse support - jsr WeeGUI .runLoop ldx #WGPendingViewAction jsr WeeGUI