interstitial after every 10% progress

This commit is contained in:
4am 2020-09-23 14:01:27 -04:00
parent 3f4c7a640b
commit 7c31356d14
17 changed files with 327 additions and 236 deletions

BIN
res/M.ERROR Normal file

Binary file not shown.

Binary file not shown.

BIN
res/M.JOY01 Normal file

Binary file not shown.

BIN
res/PROGRESS.0 Normal file

Binary file not shown.

BIN
res/PROGRESS.9 Normal file

Binary file not shown.

BIN
res/PROGRESS.99 Normal file

Binary file not shown.

View File

@ -6,7 +6,7 @@
; - ReinitSoundAfterPrefChange
; - LoopSound
; - PlaySound
; - SoftBell
; - ErrorSound
;
gMockingboardSlot
@ -48,6 +48,8 @@ k16251Progression
!word M_V
kFinalChord
!word M_I_LONG
kErrorSound
!word M_ERROR
ReinitSoundAfterPrefChange
ldx gMockingboardSlot
@ -135,22 +137,6 @@ PlayFinalChord
tax
rts
;------------------------------------------------------------------------------
; SoftBell
;
; in: none
; out: all registers and flags clobbered
;------------------------------------------------------------------------------
SoftBell
lda gSoundPref
beq +
ldx #32
- lda #2
jsr ROM_WAIT
bit SPEAKER
lda #33
jsr ROM_WAIT
bit SPEAKER
dex
bne -
+ rts
ErrorSound
+LD16 kErrorSound
jmp PlaySound

View File

@ -1,41 +0,0 @@
;license:MIT
;(c) 2020 by qkumba
;
; Functions to enable and disable VBL polling on various Apple II models
WaitForVBL
jmp WaitForVBL_iie ; SMC to RTS on a II+
UnwaitForVBL
rts ; SMC to JMP on a IIc
!word iUnwaitForVBL
iWaitForVBL
sei ; IIc is special
sta $C07F ; enable access to VBL register
sta $C05B ; enable VBL polling
sta $C07E ; disable access to VBL register
WaitForVBL_iie ; IIe/IIgs have a relatively sane VBL
; but it's reversed between the two
; so we default to IIe, and patch in
; the reverse case if it's a IIGS.
- bit $C019
patch_VBL_iigs1
bpl -
patch_VBL_iic1
- lda $C019 ; $c019 bit 7 is sticky, reset it (SMC->#$70 for IIc)
patch_VBL_iic2
patch_VBL_iigs2
bmi -
WaitForVBL_nop ; II/II+ have no easy VBL
rts
iUnwaitForVBL
- bit $C019
bpl -
lda $C070 ; $c019 bit 7 is sticky, reset it
sta $C07F ; enable access to VBL register
sta $C05A ; disable VBL polling
sta $C07E ; disable access to VBL register
cli
rts

View File

@ -1,45 +0,0 @@
;license:MIT
;(c) 2020 by qkumba
;
; Identify platform and construct appropriate VBL routine
romid = $FBB3
; $38=][, $EA=][+, $06=//e compatible
ROMID_IIECOMPAT = 6
romid_ec = $FBC0
; $EA=//e original, $E0=//e enhanced, $E1=//e EDM, $00=//c
; IIGS
idroutine = $FE1F ; SEC, JSR $FE1F, BCS notgs
InitVBL
ldx romid
cpx #ROMID_IIECOMPAT
bne @build_none ; not a //e
lda romid_ec
beq @build_iic ; //c family
sec
jsr idroutine ; check for IIgs
bcs @NotGS
lda #$30
sta patch_VBL_iigs1
lda #$10
sta patch_VBL_iigs2
@NotGS
rts
@build_iic
lda #$70
sta patch_VBL_iic1+1
lda #$60
sta patch_VBL_iic2
lda #<iWaitForVBL
sta WaitForVBL+1
lda #>iWaitForVBL
sta WaitForVBL+2
lda #$4C
sta UnwaitForVBL
rts
@build_none
lda #$60
sta WaitForVBL
rts

View File

@ -14,7 +14,6 @@
!source "src/macros.a" ; no code
!source "src/million.init.a" ; one-time initialization code, exits via Start
!source "src/hw.mockingboard.a"
!source "src/hw.vbl.init.a"
FirstMover
!pseudopc $4000 {
@ -28,15 +27,15 @@ Start
; (e.g. title sequence ended prematurely, or we're
; returning from another screen)
jsr MainMenuEventLoop
; A = world ID
bcc +
jmp Quit
+
; A = world ID (from MainMenu)
sta gWorldID
jsr MaybeLoadWorldFromDisk
bcs @GoToMainMenu
jsr LoadProgressFromMemory
; A = next puzzle ID (from LoadProgressFromMemory)
; A = next puzzle ID
@Play
sta gPuzzleID
ldx gWorldID
@ -60,8 +59,11 @@ Start
jsr AnimatePuzzleCompleted
ldx gPuzzleID
jsr MarkPuzzleCompleted
; A = next puzzle ID (from MarkPuzzleCompleted)
jmp @Play
; A = next puzzle ID
; X = number of puzzles completed
jsr MaybeShowInterstitial
bcc @Play
bcs @GoToMainMenu
+
cpx #kRequestedRestart
bne +
@ -69,12 +71,14 @@ Start
lda gPuzzleID
jmp @Play
+
sec ; full redraw
sec ; C=1 triggers full redraw
bcs @GoToMainMenu
!source "src/ui.title.a"
!source "src/ui.main.menu.a"
!source "src/ui.reveal.a"
!source "src/ui.about.a"
!source "src/ui.interstitial.a"
!source "src/ui.play.a"
!source "src/ui.help.a"
!source "src/ui.message.a"
@ -84,7 +88,6 @@ Start
!source "src/prefs.a"
!source "src/glue.sound.a"
!source "src/glue.mli.a"
!source "src/hw.vbl.a"
!source "src/ui.font.courier.double.prime.a"
!source "src/ui.font.courier.double.prime.data.a"
!source "src/ui.font.heavy.silk.a"
@ -93,10 +96,13 @@ Start
!source "src/mockingduet.a"
MainMenuMusic
!bin "res/M.SICILIENNE"
InterstitialProgressMusic
!bin "res/M.JOY01"
M_ii !bin "res/M.II"
M_V !bin "res/M.V"
M_I !bin "res/M.I"
M_I_LONG !bin "res/M.I.LONG"
M_vi6 !bin "res/M.VI6"
M_ERROR !bin "res/M.ERROR"
}
LastMover

View File

@ -35,8 +35,6 @@ FMDEST sta $4000, x
cmp #$40
bcs FM
jsr InitVBL
jsr GetMockingboardSlot
cpx #0
beq +

View File

@ -265,7 +265,8 @@ HasPuzzleBeenCompleted
; MarkPuzzleCompleted
;
; in: X = puzzle ID
; out: all registers and flags clobbered
; out: A = next puzzle ID
; X = number of puzzles completed in this world (0x01..0x64)
;------------------------------------------------------------------------------
MarkPuzzleCompleted
; Completion status for the current world (100 puzzles) is stored unpacked in
@ -360,6 +361,7 @@ MarkPuzzleCompleted
cpy #$0D
bne --
pla ; A = next puzzle ID (pushed earlier)
pha
sta ($FE), y
eor checksum
sta checksum
@ -372,6 +374,7 @@ MarkPuzzleCompleted
+ dex
bpl -
tya ; A = number of puzzles completed (out of 100, so also the percent complete)
pha
ldy #$0E
sta ($FE), y
eor checksum
@ -385,8 +388,9 @@ MarkPuzzleCompleted
!word $00C0
lda progressRefNum
jsr FlushFile
ldy #$0D
lda ($FE), y
pla
tax
pla
rts
FindPackedProgressAddr

View File

@ -1,5 +1,4 @@
;license:MIT
;(c) 2019 by qkumba
;(c) 2020 by 4am
;
; animated about screen
@ -8,17 +7,12 @@
; - AboutPage
;
targetVTAB = $F0
minHTAB = $F1
maxHTAB = $F2
randomchar = $F3
revealchar = $F4
revealindex = $F5
revealtext = $FE
revealStringsLo
!byte <kAboutWritten
!byte <kAboutTested
!byte <kAboutTested2
!byte <kAboutMusic
!byte <kAboutElectricDuet
!byte <kAboutMockingDuet
@ -26,6 +20,7 @@ revealStringsLo
revealStringsHi
!byte >kAboutWritten
!byte >kAboutTested
!byte >kAboutTested2
!byte >kAboutMusic
!byte >kAboutElectricDuet
!byte >kAboutMockingDuet
@ -34,12 +29,14 @@ revealStringsHi
revealVTABs
!byte 4
!byte 20
!byte 21
!byte 9
!byte 14
!byte 19
revealHTABs
!byte 5
!byte 16
!byte 20
!byte 17
!byte 9
!byte 1
@ -49,6 +46,9 @@ kAboutWritten
kAboutTested
!byte 21
!raw "PLAYTESTED BY OPTION8"
kAboutTested2
!byte 10
!raw "AND BESLEY"
kAboutMusic
!byte 22
!raw "MUSIC BY GABRIEL FAURE"
@ -60,6 +60,8 @@ kAboutMockingDuet
!raw "MOCKINGBOARD ROUTINES BY CYBERNESTO"
AboutPage
; in: none
; out: everything clobbered
jsr Home
@outerloop
lda #0
@ -74,7 +76,7 @@ AboutPage
tay
lda revealStringsLo, x
jsr HeavySilkReveal
ldx #5
ldx #10
lda #0
- jsr WaitForKeyWithTimeout
bmi @exit
@ -83,107 +85,3 @@ AboutPage
inc revealindex
bne @loop
@exit rts
HeavySilkReveal
+ST16 revealtext
ldy #0
lda (revealtext), y
clc
adc minHTAB
sta maxHTAB
RevealStartingChar=*+1
lda #$41 ; 'A'
@outerloop
sta randomchar
; init RNG
ldy #1
sty @rnd1+1
dey
sty @rnd2+1
@loop
; generate next value in linear feedback shift register (LFSR)
ldy @rnd1+1
ldx @rnd2+1
lsr @rnd2+1
ror @rnd1+1
bcc +
; feedback polynomial form #$03FC for period of 1023
; https://en.wikipedia.org/wiki/Linear-feedback_shift_register
; https://users.ece.cmu.edu/~koopman/lfsr/index.html
lda @rnd1+1
eor #$FC
sta @rnd1+1
lda @rnd2+1
eor #$03
sta @rnd2+1
; calculate VTAB/HTAB from 2-byte LFSR value
+ lda #24
sta VTAB
dey
cpy #$FF
bne +
dex
+ tya
- dec VTAB
bmi @loop
sec
sbc #40
bcs -
dex
bpl -
eor #$FF
sta HTAB
jsr @draw
lda randomchar
cmp #$20
beq +
inc randomchar
cmp #$5A
bcc +
sbc #$19
sta randomchar
; wait after drawing each letter, while checking for keypress
+ lda #$0A
jsr WaitForKeyWithTimeout
bmi @exit
; exit conditions for feedback polynomial
@rnd2 lda #0 ; SMC
bne @loop
@rnd1 lda #0 ; SMC
cmp #1
bne @loop
; loop back to do the reveal
lda randomchar
cmp #$20
beq @exit
sta RevealStartingChar
lda #$20
bne @outerloop ; always branches
@exit
rts
@draw
; check if this position is part of the reveal text
lda VTAB
cmp targetVTAB
bne @drawRandom
lda HTAB
cmp minHTAB
bcc @drawRandom
cmp maxHTAB
bcc @drawReveal
@drawRandom
; draw 'random' character
lda #randomchar
- ldy #$00
ldx #$01
jmp DrawHeavySilkBuffer
@drawReveal
; draw character from reveal text
sec
sbc minHTAB
tay
iny
lda (revealtext), y
sta revealchar
lda #revealchar
bne - ; always branches

View File

@ -23,6 +23,9 @@ GlobalLeftMargin
Home
; in: none, but assumes text screen 1 is clear (this is done at program startup)
; out: hi-res page 1 cleared and displayed
; X preserved
; A/Y clobbered
; flags clobbered
bit PAGE1
bit FULLGFX
bit HIRES
@ -92,9 +95,7 @@ ScrollDownBy
tax
jsr LogicalColumnToPhysicalColumn
jsr InitScrollStorage
jsr WaitForVBL
jsr GENSCROLLDOWN
jsr UnwaitForVBL
@x ldx #$FD ; SMC
@y ldy #$FD ; SMC
rts
@ -110,9 +111,7 @@ ScrollUpBy
tax
jsr LogicalColumnToPhysicalColumn
jsr InitScrollStorage
jsr WaitForVBL
jsr GENSCROLLUP
jsr UnwaitForVBL
@x ldx #$FD ; SMC
@y ldy #$FD ; SMC
rts

155
src/ui.interstitial.a Normal file
View File

@ -0,0 +1,155 @@
;license:MIT
;(c) 2019 by qkumba
;(c) 2020 by 4am
;
; animated interstitial screen
;
; Public functions:
; - MaybeShowInterstitial
;
targetVTAB = $F0
minHTAB = $F1
maxHTAB = $F2
randomchar = $F3
revealchar = $F4
revealindex = $F5
revealtext = $FE
progressStringsLo
!byte <kProgress10
!byte <kProgress20
!byte <kProgress30
!byte <kProgress40
!byte <kProgress50
!byte <kProgress60
!byte <kProgress70
!byte <kProgress80
!byte <kProgress90
!byte <kProgress100
progressStringsHi
!byte >kProgress10
!byte >kProgress20
!byte >kProgress30
!byte >kProgress40
!byte >kProgress50
!byte >kProgress60
!byte >kProgress70
!byte >kProgress80
!byte >kProgress90
!byte >kProgress100
progressHTABs
!byte 7
!byte 8
!byte 8
!byte 8
!byte 7
!byte 2
!byte 9
!byte 7
!byte 6
!byte 4
kProgress10
!byte 25
!raw "10% COMPLETE! KEEP IT UP!"
kProgress20
!byte 24
!raw "20% COMPLETE! WAY TO GO!"
kProgress30
!byte 24
!raw "30% COMPLETE! FANTASTIC!"
kProgress40
!byte 24
!raw "40% COMPLETE! EXCELLENT!"
kProgress50
!byte 26
!raw "WHOA, WE'RE HALFWAY THERE!"
kProgress60
!byte 36
!raw "60% OF THE TIME, IT WORKS EVERY TIME"
kProgress70
!byte 22
!raw "70% COMPLETE! AMAZING!"
kProgress80
!byte 25
!raw "80% COMPLETE! PHENOMENAL!"
kProgress90
!byte 28
!raw "90% COMPLETE! INCONCEIVABLE!"
kProgress100
!byte 31
!raw "100% COMPLETE! CONGRATULATIONS!"
kEmptyString
!byte 1
!raw " "
MaybeShowInterstitial
; in: A = next puzzle ID (in this world)
; X = # of puzzles completed (in this world)
; out: preserves A
; C set if all puzzles were completed
; C clear if there are more puzzles in this world (and A = next puzzle ID)
; Y, other flags clobbered
pha
cpx #100
bne +
ldy #10
jsr ShowInterstitialWorldComplete
sec
bcs @exit ; always branches
+ ldy #0
- iny
dex
dex
dex
dex
dex
dex
dex
dex
dex
dex ; don't judge me
bmi +
bne -
jsr ShowInterstitialWorldProgress
+ clc
@exit pla
rts
ShowInterstitialWorldProgress
ShowInterstitialWorldComplete
; in: Y = which progress string to display (1..9)
; out: all registers and flags clobbered
bit CLEARKBD
tya
tax
dex
jsr Home
lda #11
sta targetVTAB
lda progressHTABs, x
sta minHTAB
lda progressStringsHi, x
tay
lda progressStringsLo, x
jsr HeavySilkReveal
lda KBD
bmi @exit
+LDADDR InterstitialProgressMusic
jsr PlaySound
ldx #20
lda #0
- jsr WaitForKeyWithTimeout
bmi +
dex
bpl -
+ lda KBD
bmi @exit
lda #0
sta targetVTAB
sta minHTAB
+LDADDR kEmptyString
jsr HeavySilkReveal
@exit jmp Home

View File

@ -145,7 +145,7 @@ PlayEventDownArrow
jsr ScrollPuzzleDown
bcc +
CantMove
jsr SoftBell
jsr ErrorSound
KeepPlaying
ldx #kKeepPlaying
rts
@ -198,7 +198,7 @@ PlayEventLetter
ldy gSelectedLogicalColumn
jsr FindLetterInColumn
bcc +
jsr SoftBell ; didn't find letter, we're done
jsr ErrorSound ; didn't find letter, we're done
ldx #kKeepPlaying
rts
+ beq PlayEventRightArrow ; found letter but it's already on center row, we're done, exit through right arrow handler

131
src/ui.reveal.a Normal file
View File

@ -0,0 +1,131 @@
;license:MIT
;(c) 2019 by qkumba
;(c) 2020 by 4am
;
; graphic text animation routine
; used by credits page and interstitials during play
;
; Public functions:
; - HeavySilkReveal
;
targetVTAB = $F0
minHTAB = $F1
maxHTAB = $F2
randomchar = $F3
revealchar = $F4
revealtext = $FE
HeavySilkReveal
; in: A/Y points to length-prefixed string to reveal
; targetVTAB contains 0-based row for reveal string (0..39 but no wrapping so be careful)
; minHTAB contains starting 0-based column for reveal string (0..23)
; out: VTAB clobbered
; HTAB clobbered
; maxHTAB clobbered
; randomchar clobbered
; revealchar clobbered
; revealtext clobbered [word]
+ST16 revealtext
ldy #0
lda (revealtext), y
clc
adc minHTAB
sta maxHTAB
@revealStartingChar=*+1
lda #$41 ; 'A'
@outerloop
sta randomchar
; init RNG
ldy #1
sty @rnd1+1
dey
sty @rnd2+1
@loop
; generate next value in linear feedback shift register (LFSR)
ldy @rnd1+1
ldx @rnd2+1
lsr @rnd2+1
ror @rnd1+1
bcc +
; feedback polynomial form #$03FC for period of 1023
; https://en.wikipedia.org/wiki/Linear-feedback_shift_register
; https://users.ece.cmu.edu/~koopman/lfsr/index.html
lda @rnd1+1
eor #$FC
sta @rnd1+1
lda @rnd2+1
eor #$03
sta @rnd2+1
; calculate VTAB/HTAB from 2-byte LFSR value
+ lda #24
sta VTAB
dey
cpy #$FF
bne +
dex
+ tya
- dec VTAB
bmi @loop
sec
sbc #40
bcs -
dex
bpl -
eor #$FF
sta HTAB
jsr @draw
lda randomchar
cmp #$20
beq +
inc randomchar
cmp #$5A
bcc +
sbc #$19
sta randomchar
; wait after drawing each letter, while checking for keypress
+ lda #$0A
jsr WaitForKeyWithTimeout
bmi @exit
; exit conditions for feedback polynomial
@rnd2 lda #0 ; SMC
bne @loop
@rnd1 lda #0 ; SMC
cmp #1
bne @loop
; loop back to do the reveal
lda randomchar
cmp #$20
beq @exit
sta @revealStartingChar
lda #$20
bne @outerloop ; always branches
@exit
rts
@draw
; check if this position is part of the reveal text
lda VTAB
cmp targetVTAB
bne @drawRandom
lda HTAB
cmp minHTAB
bcc @drawRandom
cmp maxHTAB
bcc @drawReveal
@drawRandom
; draw 'random' character
lda #randomchar
- ldy #$00
ldx #$01
jmp DrawHeavySilkBuffer
@drawReveal
; draw character from reveal text
sec
sbc minHTAB
tay
iny
lda (revealtext), y
sta revealchar
lda #revealchar
bne - ; always branches