animated credits

This commit is contained in:
4am 2018-07-06 18:29:15 -04:00
parent c9dce65e42
commit 135ecb96bd
9 changed files with 361 additions and 315 deletions

View File

@ -1,90 +1 @@
Pitch Dark is a frontend for exploring and playing Infocom text adventures. Copyright 2018 4am https://github.com/a2-4am/pitch-dark ~ On Beyond Z-Machine! is a ProDOS port of Infocom's Z-Machine interpreters. Copyright 2018 qkumba based on code from six different games copyright 1979-1988 Infocom, Inc. ~ WeeGUI is a compact, easy-to-use GUI library for 8-bit Apple II computers. Copyright 2014-8 Quinn Dunki https://github.com/blondie7575/WeeGUI/ ~ Artwork was scanned from original retail boxes and converted to Apple II native formats with the help of Bmp2DHR copyright 2014 Bill Buckels A2FCBmp copyright 2012-5 Bill Buckels buckshot copyright 2017 Dagen Brock http://www.appleoldies.ca/bmp2dhr/ https://apple2.gs/buckshot/ ~ The PRIZM Project (Pretty Reliable Invisiclues for Z-Machine) are genuine Infocom Invisiclues, accessible in your favorite Z-Machine interpreter. Copyright 1999 Digby McWiggle and Steven Marsh Compiled, edited, and Z-coded by Digby McWiggle and Steven Marsh from material supplied by Henrik Dittmann, Paul David Doherty, Volker Blasius, and Mike Threepoint Thanks also to Brian Hall, L. Ross Raszewski, and Graham Nelson http://www.waitingforgo.com/ ~ Games, descriptions, and artwork are copyright 1979-1988 Infocom, Inc. Invisiclues are copyright 1993, 1999 Activision, Inc. Zork and all other game names are registered trademarks of Activision. [EOF]
Games, descriptions, and artwork are
copyright 1979-1988 Infocom, Inc.
Invisiclues are copyright 1993, 1999
Activision, Inc.
Zork and all other game names are
registered trademarks of Activision.
~
Pitch Dark is a frontend for exploring
and playing Infocom text adventures.
Copyright 2018 4am
https://github.com/a2-4am/pitch-dark
~
On Beyond Z-Machine! is a ProDOS port
of Infocom's Z-Machine interpreters.
Copyright 2018 qkumba
based on code from six different games
copyright 1979-1988 Infocom, Inc.
~
WeeGUI is a compact and easy to use
GUI library for 8-bit Apple ][
computers.
Copyright 2014-8 Quinn Dunki
https://github.com/blondie7575/WeeGUI/
~
Artwork was scanned from original
retail boxes and converted to Apple II
native formats with the help of
Bmp2DHR copyright 2014 Bill Buckels
A2FCBmp copyright 2012-5 Bill Buckels
buckshot copyright 2017 Dagen Brock
http://www.appleoldies.ca/bmp2dhr/
https://apple2.gs/buckshot/
~
The PRIZM Project (Pretty Reliable
Invisiclues for Z-Machine) are genuine
Infocom Invisiclues, accessible in
your favorite Z-Machine interpreter.
Copyright 1999 Digby McWiggle and
Steven Marsh
Compiled, edited, and Z-coded by
Digby McWiggle
Steven Marsh
from material supplied by
Henrik Dittmann
Paul David Doherty
Volker Blasius
Mike Threepoint
Thanks also to
Brian Hall
L. Ross Raszewski
Graham Nelson
http://www.waitingforgo.com/
~
The authors also wish to express their
gratitude to their wonderfully patient
beta testers, who will be named here:
- TODO1
- TODO2
- TODO3
[EOF]

View File

@ -23,6 +23,7 @@ kGameInfoBuffer = $0800 ; used by LoadGameInfo
kProDOSFileBuffer = $1C00 ; 1K buffer for ProDOS MLI calls kProDOSFileBuffer = $1C00 ; 1K buffer for ProDOS MLI calls
kSystemAddress = $2000 ; used by LaunchInterpreter kSystemAddress = $2000 ; used by LaunchInterpreter
kGlobalPrefsBuffer = $2000 ; used by LoadGlobalPreferences/SaveGlobalPreferences kGlobalPrefsBuffer = $2000 ; used by LoadGlobalPreferences/SaveGlobalPreferences
kCreditsBuffer = $2000 ; used by CreditsDialog
gPathname = $3F00 ; used by ResetPath/AddToPath gPathname = $3F00 ; used by ResetPath/AddToPath
kNullTerminatedBuffer = $3F00 ; used by paintInfoView kNullTerminatedBuffer = $3F00 ; used by paintInfoView
gKeyLen = $3F00 ; used by ParseKeyValueText gKeyLen = $3F00 ; used by ParseKeyValueText

View File

@ -52,6 +52,11 @@
sty .ptr+1 sty .ptr+1
} }
; use BIT to swallow the following 1-byte opcode
!macro HIDE_NEXT_BYTE {
!byte $24
}
; use BIT to swallow the following 2-byte opcode ; use BIT to swallow the following 2-byte opcode
!macro HIDE_NEXT_2_BYTES { !macro HIDE_NEXT_2_BYTES {
!byte $2C !byte $2C

View File

@ -33,7 +33,7 @@
!source "src/glue.onbeyond.a" !source "src/glue.onbeyond.a"
!source "src/glue.zinfo.a" !source "src/glue.zinfo.a"
!source "src/ui.common.a" !source "src/ui.common.a"
!source "src/ui.sound.a" !source "src/ui.effects.a"
!source "src/ui.main.a" !source "src/ui.main.a"
!source "src/ui.main.keys.a" !source "src/ui.main.keys.a"
!source "src/ui.options.a" !source "src/ui.options.a"

View File

@ -75,15 +75,12 @@ DisplayArtwork
ora #$C1 ora #$C1
sta $C029 ; set GS NEWVIDEO mode to turn on SHR mode sta $C029 ; set GS NEWVIDEO mode to turn on SHR mode
@waitKey phx @waitKey
phx
jsr ClearPendingInput jsr ClearPendingInput
- ldx #WGPendingClick - jsr AnyKeyOrClick
jsr WeeGUI bcc -
cpx #$FF sta $C051 ; back to text
bne + ; X != #$FF -> user clicked mouse
lda $C000
bpl -
+ sta $C051 ; back to text
plx plx
bne + bne +
lda $C029 lda $C029

View File

@ -16,6 +16,7 @@
; - GetCheckedRadioButton ; - GetCheckedRadioButton
; - HandleUpDownRadio ; - HandleUpDownRadio
; - CreateNullTerminatedString ; - CreateNullTerminatedString
; - AnyKeyOrClick
; ;
; Public variables ; Public variables
; - gViewInUse array of byte (each 0=false, nonzero=true) ; - gViewInUse array of byte (each 0=false, nonzero=true)
@ -354,3 +355,27 @@ CreateNullTerminatedString
dey dey
bne - bne -
rts rts
;------------------------------------------------------------------------------
; AnyKeyOrClick
; check for any user input (keypress or mouse click)
;
; in: none
; out: C set if key has been pressed or mouse has been clicked
; C clear if there have been no user input events
; all other flags clobbered
; all registers preserved
;------------------------------------------------------------------------------
AnyKeyOrClick
phx
ldx #WGPendingClick
jsr WeeGUI
cpx #$FF
bne + ; X != #$FF -> user clicked mouse
ldx $C000
bmi +
clc
+HIDE_NEXT_BYTE
+ sec
plx
rts

View File

@ -7,19 +7,7 @@
; - CreditsDialog ; - CreditsDialog
; ;
; View IDs (application-specific, acceptable range 0..15, no duplicates) ID_CREDITS = 0
ID_CREDITS_FRAME = 1
ID_CREDITS_OK = 2
; action keys for credits screen
kCreditsKeys
!byte $CF,ID_CREDITS_OK ; O
!byte $EF,ID_CREDITS_OK ; o
!byte $8D,ID_CREDITS_OK ; Return
!byte $9B,ID_CREDITS_OK ; Esc
!byte $8B,ID_SCROLLUP ; up arrow
!byte $8A,ID_SCROLLDOWN ; down arrow
_endCreditsKeys
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; CreditsDialog ; CreditsDialog
@ -32,195 +20,236 @@ _endCreditsKeys
CreditsDialog CreditsDialog
ldx #$FF ldx #$FF
txs txs
jsr LoadCredits ; fetch contents from file
jsr ClearPendingInput
@creditsOuterLoop
lda #5
sta currentSection
@creditsInnerLoop
lda #$20 ; fade to white
jsr TextFizzle
jsr @ExitOnAnyInput
lda #' ' ; fade to black
jsr TextFizzle
jsr @ExitOnAnyInput
ldx currentSection ; set up border frame
lda kCreditsTop,x
sta kViewCreditsTop
lda kCreditsHeight,x
sta kViewCreditsVisibleHeight
sta kViewCreditsHeight
jsr HardResetWeeGUI jsr HardResetWeeGUI
ldx #WGCreateView
jsr CreateDialog ; create decorated frame +LDADDR kViewCredits
!word kViewCreditsFrame
!word kStringCreditsFrame
ldx #WGViewSetAction ; set view action (called automatically after scrolling)
+LDADDR PaintCreditsView
+STAY PARAM0 +STAY PARAM0
jsr WeeGUI jsr WeeGUI ; create border frame
jsr CreateButton ; create OK button
!word kViewCreditsOK
ldx #WGDesktop ; paint background
jsr WeeGUI
jsr PaintTitleBar ; paint top title bar
ldx #WGViewPaintAll ; paint UI controls (window frame, buttons, checkboxes, radio buttons)
jsr WeeGUI
jsr LoadCredits ; fetch contents for credits box
jsr PaintCreditsView ; paint contents of credits box
jsr ClearPendingInput
- ldx #WGPendingViewAction
jsr WeeGUI ; handle mouse movement and clicks
lda $C000
bpl -
jsr ClearPendingInput
jsr HandleCreditsKey ; handle keypresses
bra -
LoadCredits
jsr LoadFile ; load credits file at $2800
!word @kStringCreditsFilename
!word $2800
!word kProDOSFileBuffer
bcs @NoCredits
ldy #$20
lda #0
+STAY PARAM2
ldy #$28 ; doubles as 40-column width
+STAY PARAM0
stz CreditsMaxLine+1
-- lda (PARAM0)
inc PARAM0
bne +
inc PARAM1
+ cmp #$0D
beq ++ ; ignore CR entirely
ora #$80 ; set bit 7
tax
- cpx #$8A ; watch for LF
php
bne +
lda #$A0 ; switch to spaces
+ dey
beq +
sta (PARAM2)
inc PARAM2
bne +
inc PARAM3
+ plp
bne ++
tya
bne - ; pad line with spaces until width
inc CreditsMaxLine+1
tya
ldy #$29 ; reload 40-column width, +1 to compensate for DEY
tax ; replace cached char with #$00
beq - ; loop to store it and then resume
++ lda mliparam+6
bne +
dec mliparam+7
+ dec mliparam+6
dec
ora mliparam+7
bne --
@NoCredits
rts
@kStringCreditsFilename
!byte 11
!raw "CREDITS.TXT"
PaintCreditsView
ldx #WGSelectView ldx #WGSelectView
lda #ID_CREDITS_FRAME lda #ID_CREDITS
jsr WeeGUI jsr WeeGUI
lda #$20 ldx #WGPaintView
sta CreditsPosHi+1 jsr WeeGUI ; paint border frame
stz CreditsPosLo+1 jsr PaintCredits ; paint text
stz CreditsCurLine+1 jsr @ExitOnAnyInput
-- ldx currentSection ; wait a variable period of time
CreditsCurLine lda kCreditsHeight,x ; based on the number of lines of text
lda #$FD ; SMC asl
stz PARAM0 asl
sta PARAM1 tay
ldx #WGSetCursor - lda #0
jsr WeeGUI jsr WAIT
jsr @ExitOnAnyInput
dey
bpl -
CreditsPosHi dec currentSection
ldy #$20 lda currentSection
CreditsPosLo bpl @creditsInnerLoop
lda #0 bra @creditsOuterLoop
+STAY PARAM0
ldx #WGPrint
jsr WeeGUI
- lda (PARAM0)
inc PARAM0
bne +
inc PARAM1
+ tax
bne -
lda PARAM0
sta CreditsPosLo+1
lda PARAM1
sta CreditsPosHi+1
inc CreditsCurLine+1
lda CreditsCurLine+1
CreditsMaxLine @ExitOnAnyInput
cmp #$FD ; SMC jsr AnyKeyOrClick
bne -- bcs @exit
lda CreditsMaxLine+1 ; minimum content height rts
ldx #WGSetContentHeight ; set content height so we stop scrolling on the last line of text @exit
jmp WeeGUI jmp MainScreen
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; internal functions ; internal functions
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; HandleCredits ; LoadCredits
; load credits from file and convert it for use by WeeGUI
; ;
; in: A = key pressed ; NOTE: this routine assumes there are no more than 6 sections of credits.
; out: all registers and flags clobbered ; Section 1 starts at the beginning of the file.
; Sections 1-5 end with the '~' character.
; Sections 2-6 start at the first non-0x0D character after the '~' delimiter.
; Section 6 ends with '[' character (not '~')
; Text is stored on disk with high bit off.
; Each line must be no more than 40 characters.
; Parsing would obviously be easier if these constraints were different,
; but I like the way the file looks.
;
; in: WeeGUI initialized
; out: exits to caller
; all registers and flags clobbered
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
HandleCreditsKey LoadCredits
ldy #(_endCreditsKeys-kCreditsKeys)-2 jsr LoadFile ; load credits file at $2000
- cmp kCreditsKeys,y !word kCreditsFilename
beq @found !word kCreditsBuffer
dey !word kProDOSFileBuffer
dey
bpl - +LDADDR kCreditsBuffer
jmp SoftBell +STAY $FE ; ($FE) points to start of data buffer
@found ldx #WGSelectView ldy #$00 ; index into ($FE) pointing to current character
lda kCreditsKeys+1,y ldx #$0C ; (= 6 x 2) index into creditsSectionPointers array
bpl @activateView ; ID < #$80 is a WeeGUI view, so activate it lda ($FE)
ldy #$FF bra @saveSectionPointer
cmp #ID_SCROLLDOWN ; arrow keys scroll the description box
beq @scroll @convertSectionLoop
ldy #$01 jsr IncAndGetChar
@scroll phy @convertSectionNoInc
ldx #WGSelectView cmp #$7E ; '~' ends the section
lda #ID_CREDITS_FRAME beq @skipSectionDelimiter
jsr WeeGUI cmp #$5B ; '[' ends the parsing
ldx #WGScrollYBy beq @exit
cmp #$0D ; CR -> 0x00 (WeeGUI wants null-terminated strings)
beq @null
ora #$80 ; all other characters -> set high bit
+HIDE_NEXT_2_BYTES
@null lda #$00
sta ($FE),y
bra @convertSectionLoop
; We found the start of a new section, so skip to the first character on the next line
@skipSectionDelimiter
jsr IncAndGetChar
cmp #$0D ; CR
beq @skipSectionDelimiter
; We are at the start of a section, so save this address in the creditsSectionPointers array
@saveSectionPointer
pha
tya
clc
adc $FE
sta creditsSectionPointers-2,x
lda $FF
bcc +
inc
+ sta creditsSectionPointers-1,x
pla pla
dex
@activateView dex
jsr WeeGUI bpl @convertSectionNoInc
jmp SimulateClick @exit
rts
callback_credits_ok
jmp MainScreen
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; WeeGUI view configuration records ; PaintCredits
; paint one section of credits on the screen
;
; in: WeeGUI initialized
; out: exits to caller
; all registers and flags clobbered
;------------------------------------------------------------------------------
PaintCredits
lda currentSection
asl
tax
lda creditsSectionPointers,x
sta $FE
lda creditsSectionPointers+1,x
sta $FF ; ($FE) points to start of data buffer
ldy #0 ; index into ($FE) pointing to current character
stz @VTAB ; line number within WeeGUI view
@printLine
lda #1
sta PARAM0
inc @VTAB
@VTAB=*+1
lda #$FD
sta PARAM1
ldx #WGSetCursor
jsr WeeGUI ; set cursor to start of this line
tya
clc
adc $FE
sta PARAM0
lda $FF
bcc +
inc
+ sta PARAM1 ; calculate exact start of text for this line
lda (PARAM0) ; skip blank lines
beq @skipNull
ldx #WGPrint ; otherwise print it
jsr WeeGUI
@skipToNextLine
jsr IncAndGetChar
bne @notNull
@skipNull
jsr IncAndGetChar
bra @printLine
@notNull
cmp #$7E ; '~' ends section
beq @exit
cmp #$5B ; '[' ends section
bne @skipToNextLine
@exit
rts
kViewCreditsFrame ;------------------------------------------------------------------------------
!byte ID_CREDITS_FRAME ; view ID ; internal data
!byte 2 ; style (decorated frame)
!byte 1 ; left
!byte 3 ; top
!byte 77 ; visible width
!byte 20 ; visible height
!byte 77 ; width
!byte 100 ; height
kViewCreditsOK kCreditsFilename
!byte ID_CREDITS_OK ; view ID !byte 11
!byte 67 ; left !raw "CREDITS.TXT"
!byte 4 ; top
!byte 10 ; width
!word callback_credits_ok ; callback
!word kStringOK ; caption
kStringCreditsFrame currentSection ; used by PaintCredits
!text "Credits",0 !byte $FD
creditsSectionPointers ; [array of word] address of start of each page of credits
!word $FDFD
!word $FDFD
!word $FDFD
!word $FDFD
!word $FDFD
!word $FDFD
kCreditsTop ; [array of byte] top row to draw border for each section of credits
!byte 7 ; note: stored here in reverse order compared to the credits file
!byte 2
!byte 6
!byte 8
!byte 8
!byte 8
kCreditsHeight ; [array of byte] height of bounding box for each section of credits
!byte 10 ; note: stored here in reverse order compared to the credits file
!byte 20
!byte 12
!byte 8
!byte 9
!byte 8
kViewCredits
!byte ID_CREDITS ; view ID
!byte 1 ; style
!byte 19 ; left
kViewCreditsTop
!byte $FD ; top (SMC)
!byte 42 ; visible width
kViewCreditsVisibleHeight
!byte $FD ; visible height (SMC)
!byte 42 ; width
kViewCreditsHeight
!byte $FD ; height (SMC)

110
src/ui.effects.a Normal file
View File

@ -0,0 +1,110 @@
;license:MIT
;(c) 2018 by 4am
;TextFizzle routine (c) 2018 by qkumba
;
; Sound and animation effects
;
; Public functions
; - SoftBell
; - TextFizzle
;
;------------------------------------------------------------------------------
; SoftBell
;
; in: none
; out: all registers and flags preserved
;------------------------------------------------------------------------------
SoftBell
php
phx
pha
ldx #32
- lda #2
jsr WAIT
bit SPEAKER
lda #33
jsr WAIT
bit SPEAKER
dex
bne -
pla
plx
plp
rts
;------------------------------------------------------------------------------
; TextFizzle
;
; in: none
; out: all registers and flags clobbered
;------------------------------------------------------------------------------
TextFizzle
sta @src+1
sta $c005
ldy #0
@copy
lda TextFizzle,y
sta TextFizzle,y
iny
bne @copy
sta $c004
; init RNG
ldx #1
stx @rndval1+1
dex
stx @rndval2+1
@mainloop
ldy @rndval1+1
ldx @rndval2+1
lsr @rndval2+1
ror @rndval1+1
bcc +
; feedback polynomial forms #$402 for period of 2047
lda @rndval1+1
eor #2
sta @rndval1+1
lda @rndval2+1
eor #4
sta @rndval2+1
; little hack to avoid missing offset zero
; screen hole at $xxFF is missed instead
+ tya
eor #$ff
sta $26
and #$78
cmp #$78
beq @rndval2
txa
and #3
ora #4
sta $27
ldy #0
cpx #4
bcc @src
sta $c003
sta $c055
@src lda #$d1 ; SMC
sta ($26),y
sta $c002
sta $c054
lda #6
jsr WAIT
jsr AnyKeyOrClick
bcs @exit
@rndval2
lda #0
bne @mainloop
@rndval1
lda #0
cmp #1
bne @mainloop
@exit
rts

View File

@ -1,32 +0,0 @@
;license:MIT
;(c) 2018 by 4am
;
; Sound routines
;
; Public functions
; - SoftBell
;
;------------------------------------------------------------------------------
; SoftBell
;
; in: none
; out: all registers and flags preserved
;------------------------------------------------------------------------------
SoftBell
php
phx
pha
ldx #32
- lda #2
jsr WAIT
bit SPEAKER
lda #33
jsr WAIT
bit SPEAKER
dex
bne -
pla
plx
plp
rts