pitch-dark/src/ui.main.a

410 lines
13 KiB
Plaintext
Raw Normal View History

2018-02-07 14:05:24 +00:00
;license:MIT
;(c) 2018 by 4am
;
2018-03-27 20:55:31 +00:00
; User interface - views and paint routines for main screen
2018-02-07 14:05:24 +00:00
;
; Public functions
2018-04-01 22:26:54 +00:00
; - PaintMain
; - RepaintMainIfDirty
2018-02-07 14:05:24 +00:00
;
2018-04-01 22:44:00 +00:00
; Public variables
; - gMainScreenPaintDirty
; - gViewInUse
;
2018-02-07 14:05:24 +00:00
; View IDs (application-specific, acceptable range 0..15, no duplicates)
2018-02-24 20:25:41 +00:00
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
2018-04-01 22:26:54 +00:00
gMainScreenPaintDirty
!byte 0 ; 0=false, 1=true
2018-04-01 22:44:00 +00:00
gViewInUse
2018-04-01 22:26:54 +00:00
!byte 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0
2018-02-07 14:05:24 +00:00
;------------------------------------------------------------------------------
2018-04-01 22:26:54 +00:00
; 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
2018-02-07 14:05:24 +00:00
;
; in: WeeGUI loaded and initialized
2018-03-27 21:17:47 +00:00
; out: all registers and flags clobbered
2018-02-07 14:05:24 +00:00
;------------------------------------------------------------------------------
!zone {
2018-04-01 22:26:54 +00:00
PaintMain
ldx #WGResetAll
2018-04-01 22:26:54 +00:00
jsr WeeGUI
2018-04-01 22:44:00 +00:00
stz gViewInUse+ID_BOXART
stz gViewInUse+ID_HINTS
stz gViewInUse+ID_VERSIONS
2018-04-01 22:26:54 +00:00
ldx #1 ; flag - clear screen before painting
stx gMainScreenPaintDirty
!byte $2C
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
2018-04-01 22:26:54 +00:00
jsr CreateButton ; create 'settings' button
!word kViewOptions
2018-04-01 22:26:54 +00:00
jsr CreateButton ; create 'next game' button
!word kViewNext
2018-04-01 22:26:54 +00:00
lda gHasSavedGames ; create 'play game' or 'resume game' button
beq .wantPlayButton
2018-03-01 16:06:00 +00:00
jsr CreateButton
!word kViewResume
bra .donePlayOrResume
.wantPlayButton
2018-03-01 16:06:00 +00:00
jsr CreateButton
!word kViewPlay
.donePlayOrResume
2018-04-01 22:44:00 +00:00
jsr CreateOrDestroyButton ; create or destroy 'artwork' button
!byte ID_BOXART
!word kViewBoxArt
!word kHasArtwork
2018-04-01 22:44:00 +00:00
jsr CreateOrDestroyButton ; create or destroy 'hints' button
!byte ID_HINTS
!word kViewHints
!word kHasHints
2018-04-01 22:44:00 +00:00
jsr CreateOrDestroyButton ; create or destroy 'revisions' button
!byte ID_VERSIONS
!word kViewVersions
!word kHasVersions
2018-02-07 14:05:24 +00:00
2018-04-01 22:26:54 +00:00
pla ; clear screen before repainting?
beq .nohome ; no -> repaint over existing screen, YOLO
2018-04-01 22:26:54 +00:00
ldx #WGClearScreen ; clear screen
jsr WeeGUI
2018-04-01 22:26:54 +00:00
jsr PaintTitleBar ; paint top bar
2018-02-07 14:05:24 +00:00
2018-04-01 22:26:54 +00:00
lda #4 ; paint horizontal separator bar
2018-02-24 20:25:41 +00:00
sta PARAM1
ldy #78
lda #83
- sty PARAM0
ldx #WGSetGlobalCursor
jsr WeeGUI
ldx #WGPlot
jsr WeeGUI
dey
bne -
ldx #WGSyncGlobalCursor
2018-04-01 22:26:54 +00:00
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
2018-04-01 22:26:54 +00:00
jsr WeeGUI
jmp PaintDescriptionView ; paint contents of description box
2018-04-01 22:26:54 +00:00
}
;------------------------------------------------------------------------------
2018-04-01 22:44:00 +00:00
; CreateOrDestroyButton
; create or destroy a WeeGUI Button view, based on per-game options
; and whether the button already exists
2018-04-01 22:26:54 +00:00
;
; in: WeeGUI loaded and 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
;------------------------------------------------------------------------------
!zone {
2018-04-01 22:44:00 +00:00
CreateOrDestroyButton
2018-04-01 22:26:54 +00:00
+PARAMS_ON_STACK 5
ldy #1
lda (PARAM),y
sta .viewID
ldy #3
lda (PARAM),y
pha
dey
lda (PARAM),y
ply
+STAY .viewConfigurationRecord
ldy #5
lda (PARAM),y
pha
dey
lda (PARAM),y
ply
+STAY .optionsStoreKey
jsr okvs_get
!word gOptionsStore
.optionsStoreKey
!word $FDFD ; SMC
.viewID=*+1
ldx #$FD ; SMC (X = WeeGUI view ID)
jsr okvs_as_boolean
2018-04-01 22:44:00 +00:00
beq .destroy
lda gViewInUse,x ; create button if it doesn't exist
bne .done ; oh it does exist, so we're done
2018-04-01 22:26:54 +00:00
lda #1
2018-04-01 22:44:00 +00:00
sta gViewInUse,x
2018-04-01 22:26:54 +00:00
jsr CreateButton
.viewConfigurationRecord
!word $FDFD ; SMC
bra .done
2018-04-01 22:44:00 +00:00
.destroy lda gViewInUse,x ; destroy button if it exists
beq .done ; oh it doesn't exist, so we're done
2018-04-01 22:26:54 +00:00
lda #0
2018-04-01 22:44:00 +00:00
sta gViewInUse,x
2018-04-01 22:26:54 +00:00
txa ; A = WeeGUI view ID
ldx #WGSelectView
jsr WeeGUI
ldx #WGEraseView
2018-04-01 22:26:54 +00:00
jsr WeeGUI
ldx #WGResetView
jsr WeeGUI
2018-04-01 22:26:54 +00:00
.done rts
}
!zone {
PaintDescriptionView
2018-02-07 14:05:24 +00:00
ldx #WGSelectView
2018-02-08 02:41:07 +00:00
lda #ID_DESCRIPTION
2018-02-07 14:05:24 +00:00
jsr WeeGUI
2018-04-01 23:12:39 +00:00
2018-03-29 02:49:51 +00:00
+LDAY addrDescription
ldx #kDescriptionPaintWidth
2018-04-01 22:26:54 +00:00
jsr MultiPrint
2018-04-01 23:12:39 +00:00
lda SAVE
cmp #10 ; minimum content height
bcs +
lda #10
2018-04-01 23:12:39 +00:00
+ ldx #WGSetContentHeight ; set content height so we stop scrolling on the last line of text
2018-03-01 16:06:00 +00:00
jmp WeeGUI
2018-04-01 22:26:54 +00:00
PaintInfoView
ldx #WGSelectView
2018-02-08 21:28:49 +00:00
lda #ID_INFO
jsr WeeGUI
2018-04-01 23:12:39 +00:00
2018-03-29 02:49:51 +00:00
+LDAY addrInfo
ldx #kInfoPaintWidth
2018-04-01 23:16:36 +00:00
phx
2018-04-01 22:26:54 +00:00
jsr MultiPrint
2018-03-28 15:48:47 +00:00
jsr okvs_get ; get shortname of current game
!word gGlobalPrefsStore
!word kLastPlayed
2018-03-31 14:22:09 +00:00
+STAY + ; A/Y contains address
2018-03-28 15:48:47 +00:00
jsr okvs_get ; get selected version of this game
!word gGlobalPrefsStore
2018-03-29 02:49:51 +00:00
+ !word $FDFD ; SMC
2018-03-31 14:22:09 +00:00
+STAY + ; A/Y contains address
2018-03-28 15:48:47 +00:00
jsr okvs_get ; get long description of this version
!word gVersionsStore
2018-03-29 02:49:51 +00:00
+ !word $FDFD ; SMC
2018-03-31 14:22:09 +00:00
; A/Y contains address
2018-04-01 23:16:36 +00:00
plx ; X = width a.k.a. where to put the null (rest is padded with spaces)
2018-04-01 23:12:39 +00:00
jsr CreateNullTerminatedString ; copies string to kNullTerminatedBuffer
2018-04-01 23:12:39 +00:00
+LDADDR kNullTerminatedBuffer ; now use that as the buffer to print the last line
!byte $2C
; execution falls through here
2018-04-01 22:26:54 +00:00
MultiPrint
2018-04-01 23:16:36 +00:00
stz SAVE ; VTAB, but 0-indexed
2018-03-31 14:28:36 +00:00
stx .printLineLength+1
2018-04-01 23:12:39 +00:00
+STAY SRC
2018-02-07 14:05:24 +00:00
.printLoop
2018-04-01 23:12:39 +00:00
stz PARAM0
lda SAVE
2018-02-07 14:05:24 +00:00
sta PARAM1
2018-04-01 23:12:39 +00:00
ldx #WGSetCursor
2018-02-07 14:05:24 +00:00
jsr WeeGUI
2018-04-01 23:12:39 +00:00
+LDAY SRC
+STAY PARAM0
bit MAGICRTS ; set overflow bit to trigger raw printing (with mousetext)
2018-02-07 14:05:24 +00:00
ldx #WGPrint
jsr WeeGUI
2018-04-01 23:12:39 +00:00
lda SRC
2018-02-08 21:28:49 +00:00
clc
.printLineLength
2018-04-01 23:12:39 +00:00
adc #$FD ; SMC
sta SRC
2018-02-08 21:28:49 +00:00
bcc +
2018-04-01 23:12:39 +00:00
inc SRC+1
+ inc SAVE
lda (SRC)
2018-02-07 14:05:24 +00:00
bne .printLoop
rts
2018-04-01 23:16:36 +00:00
}
;------------------------------------------------------------------------------
2018-02-07 14:05:24 +00:00
kViewPrevious
2018-02-07 14:05:24 +00:00
!byte ID_PREVIOUS ; view ID
!byte 1 ; left
!byte 2 ; top
!byte 13 ; width
2018-02-07 14:05:24 +00:00
!word callback_previous ; callback
!word kStringPrevious ; caption
kStringPrevious
2018-02-24 20:25:41 +00:00
!text "< "
!byte $10 ; 'P' inverse
!text "revious",0
2018-02-07 14:05:24 +00:00
kViewNext
2018-02-07 14:05:24 +00:00
!byte ID_NEXT ; view ID
2018-02-24 20:25:41 +00:00
!byte 66 ; left
2018-02-07 14:05:24 +00:00
!byte 2 ; top
!byte 13 ; width
!word callback_next ; callback
!word kStringNext ; caption
kStringNext
2018-02-07 14:05:24 +00:00
!byte $0E ; 'N' inverse
!text "ext game >",0
kViewOptions
2018-02-24 20:25:41 +00:00
!byte ID_OPTIONS ; view ID
!byte 34 ; left
!byte 2 ; top
!byte 12 ; width
!word callback_options ; callback
!word kStringOptions
kStringOptions
2018-02-24 20:25:41 +00:00
!byte $13 ; 'S' inverse
!text "ettings",0
kViewPlay
2018-02-07 14:05:24 +00:00
!byte ID_PLAY ; view ID
2018-02-24 20:25:41 +00:00
!byte 66 ; left
!byte 6 ; top
2018-02-07 14:05:24 +00:00
!byte 13 ; width
!word callback_play ; callback
!word kStringPlay ; caption
kStringPlay
2018-02-24 20:25:41 +00:00
!byte 144
!text "lay "
!byte $67 ; 'g' inverse
!text "ame",0
2018-02-07 14:05:24 +00:00
kViewResume
!byte ID_PLAY ; view ID
!byte 66 ; left
!byte 6 ; top
!byte 13 ; width
!word callback_resume ; callback
!word kStringResume ; caption
kStringResume
!byte 146
!text "esume "
!byte $67 ; 'g' inverse
!text "ame",0
kViewBoxArt
2018-02-07 14:05:24 +00:00
!byte ID_BOXART ; view ID
!byte 66 ; left
2018-02-24 20:25:41 +00:00
!byte 8 ; top
!byte 13 ; width
2018-02-07 14:05:24 +00:00
!word callback_boxart ; callback
!word kStringBoxArt ; caption
kStringBoxArt
2018-02-24 20:25:41 +00:00
!byte $01 ; 'A' inverse
!text "rtwork",0
2018-02-07 14:05:24 +00:00
kViewHints
!byte ID_HINTS ; view ID
2018-02-07 14:05:24 +00:00
!byte 66 ; left
2018-02-24 20:25:41 +00:00
!byte 10 ; top
!byte 13 ; width
!word callback_clues ; callback
!word kStringHints ; caption
kStringHints
2018-02-24 20:25:41 +00:00
!byte $08 ; 'H' inverse
!text "ints",0
kViewVersions
2018-02-24 20:25:41 +00:00
!byte ID_VERSIONS ; view ID
!byte 66 ; left
!byte 12 ; top
!byte 13 ; width
!word callback_versions ; callback
!word kStringVersions ; caption
kStringVersions
2018-02-24 20:25:41 +00:00
!byte $12 ; 'R' inverse
!text "evisions",0
2018-02-07 14:05:24 +00:00
kViewInfo
2018-02-07 14:05:24 +00:00
!byte ID_INFO ; view ID
!byte 0 ; style
2018-02-24 20:25:41 +00:00
!byte 0 ; left
!byte 6 ; top
!byte 65 ; visible width
!byte 6 ; visible height
!byte 65 ; width
!byte 6 ; height
2018-02-07 14:05:24 +00:00
kViewDescription
2018-02-07 14:05:24 +00:00
!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