mirror of
https://github.com/a2-4am/pitch-dark.git
synced 2024-09-29 17:55:56 +00:00
409 lines
13 KiB
Plaintext
409 lines
13 KiB
Plaintext
;license:MIT
|
|
;(c) 2018 by 4am
|
|
;
|
|
; User interface - views and paint routines for main screen
|
|
;
|
|
; Public functions
|
|
; - MainScreen
|
|
;
|
|
; Public variables
|
|
; - gMainScreenPaintDirty byte 0=false, nonzero=true
|
|
;
|
|
|
|
; View IDs (application-specific, acceptable range 0..15, no duplicates)
|
|
ID_PREVIOUS = 1
|
|
ID_OPTIONS = 2
|
|
ID_NEXT = 3
|
|
ID_PLAY = 4
|
|
ID_BOXART = 5
|
|
ID_HINTS = 6
|
|
ID_VERSIONS = 7
|
|
ID_INFO = 8
|
|
ID_DESCRIPTION = 9
|
|
|
|
gMainScreenPaintDirty
|
|
!byte 0
|
|
|
|
kInfoPaintWidth = 65
|
|
kDescriptionPaintWidth = 78
|
|
|
|
;------------------------------------------------------------------------------
|
|
; MainScreen
|
|
; display main screen and run to completion
|
|
;------------------------------------------------------------------------------
|
|
MainScreen
|
|
ldx #$FF
|
|
txs
|
|
jsr PaintMain ; create all WeeGUI views (UI elements) and paint them
|
|
jsr ClearPendingInput
|
|
- jsr RepaintMainIfDirty
|
|
ldx #WGPendingViewAction
|
|
jsr WeeGUI ; handle mouse movement and clicks
|
|
lda $C000
|
|
bpl -
|
|
jsr ClearPendingInput
|
|
jsr HandleKey ; handle keypresses
|
|
bra -
|
|
|
|
;------------------------------------------------------------------------------
|
|
; internal functions
|
|
|
|
;------------------------------------------------------------------------------
|
|
; PaintMain/RepaintMainIfDirty
|
|
; call WeeGUI to create all application views and paint them
|
|
; PaintMain entry point will clear the screen and unconditionally paint everything
|
|
; RepaintMainIfDirty will only repaint certain views that vary between games,
|
|
; and only if gMainScreenPaintDirty=1
|
|
;
|
|
; in: WeeGUI initialized
|
|
; out: all registers and flags clobbered
|
|
;------------------------------------------------------------------------------
|
|
PaintMain
|
|
jsr HardResetWeeGUI
|
|
ldx #1 ; flag - clear screen before painting
|
|
stx gMainScreenPaintDirty
|
|
+HIDE_NEXT_2_BYTES
|
|
RepaintMainIfDirty
|
|
ldx #0 ; flag - do not clear screen before painting
|
|
lda gMainScreenPaintDirty
|
|
bne +
|
|
rts
|
|
+ stz gMainScreenPaintDirty ; clear dirty flag
|
|
phx ; push 'clear screen' flag (will pop at end of procedure)
|
|
|
|
jsr CreateButton ; create 'previous' button
|
|
!word kViewPrevious
|
|
|
|
jsr CreateButton ; create 'settings' button
|
|
!word kViewOptions
|
|
|
|
jsr CreateButton ; create 'next game' button
|
|
!word kViewNext
|
|
|
|
lda gHasSavedGames ; create 'play game' or 'resume game' button
|
|
beq @wantPlayButton
|
|
jsr CreateButton
|
|
!word kViewResume
|
|
bra @donePlayOrResume
|
|
@wantPlayButton
|
|
jsr CreateButton
|
|
!word kViewPlay
|
|
@donePlayOrResume
|
|
|
|
jsr CreateOrDestroyButton ; create or destroy 'artwork' button
|
|
!byte ID_BOXART
|
|
!word kViewBoxArt
|
|
!word kHasArtwork
|
|
|
|
jsr CreateOrDestroyButton ; create or destroy 'hints' button
|
|
!byte ID_HINTS
|
|
!word kViewHints
|
|
!word kHasHints
|
|
|
|
jsr CreateOrDestroyButton ; create or destroy 'revisions' button
|
|
!byte ID_VERSIONS
|
|
!word kViewVersions
|
|
!word kHasVersions
|
|
|
|
pla ; clear screen before repainting?
|
|
beq @nohome ; no -> repaint over existing screen, YOLO
|
|
|
|
ldx #WGClearScreen ; clear screen
|
|
jsr WeeGUI
|
|
|
|
jsr PaintTitleBar ; paint top bar
|
|
|
|
lda #4 ; paint horizontal separator bar
|
|
sta PARAM1
|
|
ldy #78
|
|
lda #83
|
|
- sty PARAM0
|
|
ldx #WGSetGlobalCursor
|
|
jsr WeeGUI
|
|
ldx #WGPlot
|
|
jsr WeeGUI
|
|
dey
|
|
bne -
|
|
ldx #WGSyncGlobalCursor
|
|
jsr WeeGUI
|
|
@nohome
|
|
ldx #WGSelectView ; delete info box but leave its contents on screen
|
|
lda #ID_INFO ; (harmless if it doesn't exist yet)
|
|
jsr WeeGUI
|
|
ldx #WGResetView
|
|
jsr WeeGUI
|
|
|
|
ldx #WGSelectView ; delete description box but leave its contents on screen
|
|
lda #ID_DESCRIPTION ; (harmless if it doesn't exist yet)
|
|
jsr WeeGUI
|
|
ldx #WGResetView
|
|
jsr WeeGUI
|
|
|
|
ldx #WGSelectView ; WeeGUI does NOT like repainting if the selected view does not exist
|
|
lda #ID_PREVIOUS
|
|
jsr WeeGUI
|
|
|
|
ldx #WGViewPaintAll ; repaint all WeeGUI-controlled UI elements
|
|
jsr WeeGUI
|
|
|
|
ldx #WGCreateView ; (re)create borderless frame for game title and info
|
|
+LDADDR kViewInfo ; (has the nice side effect of resetting the scroll)
|
|
+STAY PARAM0
|
|
jsr WeeGUI
|
|
jsr PaintInfoView ; paint contents of info box
|
|
|
|
ldx #WGCreateView ; (re)create scrollable frame for game description text
|
|
+LDADDR kViewDescription
|
|
+STAY PARAM0
|
|
jsr WeeGUI
|
|
ldx #WGViewSetAction ; set view action (called automatically after scrolling)
|
|
+LDADDR PaintDescriptionView
|
|
+STAY PARAM0
|
|
jsr WeeGUI
|
|
ldx #WGPaintView ; paint frame of description box
|
|
jsr WeeGUI
|
|
jmp PaintDescriptionView ; paint contents of description box
|
|
|
|
;------------------------------------------------------------------------------
|
|
; CreateOrDestroyButton
|
|
; create or destroy a WeeGUI Button view, based on per-game options
|
|
; and whether the button already exists
|
|
;
|
|
; in: WeeGUI initialized
|
|
; gOptionsStore populated
|
|
; stack contains 5 bytes of parameters:
|
|
; +1 [byte] WeeGUI view ID
|
|
; +2 [word] address of WeeGUI view configuration record
|
|
; +4 [word] address of length-prefixed key into gOptionsStore
|
|
; out: all registers and flags clobbered
|
|
;------------------------------------------------------------------------------
|
|
CreateOrDestroyButton
|
|
+PARAMS_ON_STACK 5
|
|
|
|
ldy #1
|
|
lda (PARAM),y
|
|
pha ; A = WeeGUI view ID
|
|
|
|
+LDPARAM 2
|
|
+STAY @vcr
|
|
|
|
+LDPARAM 4
|
|
+STAY @key
|
|
|
|
jsr okvs_get
|
|
!word gOptionsStore
|
|
@key !word $FDFD ; SMC
|
|
plx ; X = WeeGUI view ID
|
|
jsr okvs_as_boolean
|
|
beq @destroy
|
|
|
|
lda gViewInUse,x ; create button if it doesn't exist
|
|
bne @exit ; oh it does exist, so we're done
|
|
lda #1
|
|
sta gViewInUse,x
|
|
jsr CreateButton
|
|
@vcr !word $FDFD ; SMC
|
|
@exit rts
|
|
|
|
@destroy
|
|
lda gViewInUse,x ; destroy button if it exists
|
|
beq @exit ; oh it doesn't exist, so we're done
|
|
lda #0
|
|
sta gViewInUse,x
|
|
txa ; A = WeeGUI view ID
|
|
ldx #WGSelectView
|
|
jsr WeeGUI
|
|
ldx #WGEraseView
|
|
jsr WeeGUI
|
|
ldx #WGResetView
|
|
jmp WeeGUI
|
|
|
|
PaintDescriptionView
|
|
ldx #WGSelectView
|
|
lda #ID_DESCRIPTION
|
|
jsr WeeGUI
|
|
|
|
+LDAY addrDescription
|
|
ldx #kDescriptionPaintWidth
|
|
jsr MultiPrint
|
|
|
|
lda SAVE
|
|
cmp #10
|
|
bcs +
|
|
lda #10 ; minimum content height
|
|
+ ldx #WGSetContentHeight ; set content height so we stop scrolling on the last line of text
|
|
jmp WeeGUI
|
|
|
|
PaintInfoView
|
|
ldx #WGSelectView
|
|
lda #ID_INFO
|
|
jsr WeeGUI
|
|
|
|
+LDAY addrInfo
|
|
ldx #kInfoPaintWidth
|
|
phx
|
|
jsr MultiPrint
|
|
|
|
jsr okvs_get ; get shortname of current game
|
|
!word gGlobalPrefsStore
|
|
!word kLastPlayed
|
|
+STAY + ; A/Y contains address
|
|
|
|
jsr okvs_get ; get selected version of this game
|
|
!word gGlobalPrefsStore
|
|
+ !word $FDFD ; SMC
|
|
+STAY + ; A/Y contains address
|
|
|
|
jsr okvs_get ; get long description of this version
|
|
!word gVersionsStore
|
|
+ !word $FDFD ; SMC
|
|
; A/Y contains address
|
|
plx ; X = width a.k.a. where to put the null (rest is padded with spaces)
|
|
jsr CreateNullTerminatedString ; copies string to kNullTerminatedBuffer
|
|
|
|
+LDADDR kNullTerminatedBuffer ; now use that as the buffer to print the last line
|
|
+HIDE_NEXT_2_BYTES
|
|
MultiPrint
|
|
stz SAVE ; VTAB, but 0-indexed
|
|
stx @linelen
|
|
+STAY SRC
|
|
@loop stz PARAM0
|
|
lda SAVE
|
|
sta PARAM1
|
|
ldx #WGSetCursor
|
|
jsr WeeGUI
|
|
+LDAY SRC
|
|
+STAY PARAM0
|
|
bit MAGICRTS ; set overflow bit to trigger raw printing (with mousetext)
|
|
ldx #WGPrint
|
|
jsr WeeGUI
|
|
lda SRC
|
|
clc
|
|
@linelen=*+1
|
|
adc #$FD ; SMC
|
|
sta SRC
|
|
bcc +
|
|
inc SRC+1
|
|
+ inc SAVE
|
|
lda (SRC)
|
|
bne @loop
|
|
rts
|
|
|
|
;------------------------------------------------------------------------------
|
|
; WeeGUI view configuration records
|
|
|
|
kViewPrevious
|
|
!byte ID_PREVIOUS ; view ID
|
|
!byte 1 ; left
|
|
!byte 2 ; top
|
|
!byte 13 ; width
|
|
!word callback_previous ; callback
|
|
!word kStringPrevious ; caption
|
|
|
|
kViewNext
|
|
!byte ID_NEXT ; view ID
|
|
!byte 66 ; left
|
|
!byte 2 ; top
|
|
!byte 13 ; width
|
|
!word callback_next ; callback
|
|
!word kStringNext ; caption
|
|
|
|
kViewOptions
|
|
!byte ID_OPTIONS ; view ID
|
|
!byte 34 ; left
|
|
!byte 2 ; top
|
|
!byte 12 ; width
|
|
!word OptionsDialog ; callback
|
|
!word kStringOptions
|
|
|
|
kViewPlay
|
|
!byte ID_PLAY ; view ID
|
|
!byte 66 ; left
|
|
!byte 6 ; top
|
|
!byte 13 ; width
|
|
!word LaunchInterpreterWithNewGame ; callback
|
|
!word kStringPlay ; caption
|
|
|
|
kViewResume
|
|
!byte ID_PLAY ; view ID
|
|
!byte 66 ; left
|
|
!byte 6 ; top
|
|
!byte 13 ; width
|
|
!word ResumeDialog ; callback
|
|
!word kStringResume ; caption
|
|
|
|
kViewBoxArt
|
|
!byte ID_BOXART ; view ID
|
|
!byte 66 ; left
|
|
!byte 8 ; top
|
|
!byte 13 ; width
|
|
!word DisplayArtwork ; callback
|
|
!word kStringBoxArt ; caption
|
|
|
|
kViewHints
|
|
!byte ID_HINTS ; view ID
|
|
!byte 66 ; left
|
|
!byte 10 ; top
|
|
!byte 13 ; width
|
|
!word LaunchInterpreterWithHints ; callback
|
|
!word kStringHints ; caption
|
|
|
|
kViewVersions
|
|
!byte ID_VERSIONS ; view ID
|
|
!byte 66 ; left
|
|
!byte 12 ; top
|
|
!byte 13 ; width
|
|
!word VersionsDialog ; callback
|
|
!word kStringVersions ; caption
|
|
|
|
kViewInfo
|
|
!byte ID_INFO ; view ID
|
|
!byte 0 ; style
|
|
!byte 0 ; left
|
|
!byte 6 ; top
|
|
!byte 65 ; visible width
|
|
!byte 6 ; visible height
|
|
!byte 65 ; width
|
|
!byte 6 ; height
|
|
|
|
kViewDescription
|
|
!byte ID_DESCRIPTION ; view ID
|
|
!byte 2 ; style
|
|
!byte 1 ; left
|
|
!byte 15 ; top
|
|
!byte 77 ; visible width
|
|
!byte 8 ; visible height
|
|
!byte 77 ; width
|
|
!byte 39 ; height
|
|
|
|
kStringPrevious
|
|
!text "< "
|
|
!byte $10 ; 'P' inverse
|
|
!text "revious",0
|
|
kStringNext
|
|
!byte $0E ; 'N' inverse
|
|
!text "ext game >",0
|
|
|
|
kStringOptions
|
|
!byte $13 ; 'S' inverse
|
|
!text "ettings",0
|
|
kStringPlay
|
|
!byte 144
|
|
!text "lay "
|
|
!byte $67 ; 'g' inverse
|
|
!text "ame",0
|
|
kStringResume
|
|
!byte 146
|
|
!text "esume "
|
|
!byte $67 ; 'g' inverse
|
|
!text "ame",0
|
|
kStringBoxArt
|
|
!byte $01 ; 'A' inverse
|
|
!text "rtwork",0
|
|
kStringHints
|
|
!byte $08 ; 'H' inverse
|
|
!text "ints",0
|
|
kStringVersions
|
|
!byte $16 ; 'V' inverse
|
|
!text "ersion",0
|