demo [WIP] and sound stuff

sound routines now take list of acceptable keys to exit, with wildcard support

also lots of refactoring
This commit is contained in:
4am 2020-09-25 22:59:55 -04:00
parent 136b3ad470
commit 74ee53e015
16 changed files with 737 additions and 580 deletions

View File

@ -54,13 +54,10 @@ ROM_NORMAL = $FE84 ; NORMAL text (instead of INVERSE or FLASH)
ROM_IN0 = $FE89 ; SETKBD
ROM_PR0 = $FE93 ; SETVID
; zero page
; application-specific addresses
PARAM = $00 ; word (used by PARAMS_ON_STACK macro)
HTAB = $24 ; byte
VTAB = $25 ; byte
; application constants
; zero page
original_char = $ED ; byte
char = $EE ; byte
charrow = $EF ; byte

View File

@ -135,10 +135,10 @@
; play 2-voice music in Electric Duet format
;
; in: $1E/$1F points to music data
; $EE/$EF points to 0-terminated list of keys that will terminate
; out: all flags and registers clobbered
; will exit when it finishes playing (music data is 0-0-0 terminated)
; will also exit on keypress, but you must check $C000 yourself to see
; if that happened
; will also exit on keypress, but only if it appears in the ($EE) list
;------------------------------------------------------------------------------
!align $FF,0,0 ; align to page (essential)
ElectricDuet
@ -206,7 +206,7 @@ ED096A BPL ED096F ; 4 *!*
ED096C BIT $C030 ; 4
ED096F STA $4E ; 3
ED0971 BIT $C000 ; 4
ED0974 BMI ED0936 ; 4 *!*
ED0974 BMI EDCHECKKEY ; 4 *!*
ED0976 DEY ; 2
ED0977 BNE ED097B ; 4 *!*
ED0979 BEQ ED0981 ; 4 *!*
@ -249,3 +249,26 @@ ED09BB EOR #$80 ; 2 *!*
ED09BD BVS ED0962 ; 4 *!*
ED09BF NOP ; 2
ED09C0 BVC ED0965 ; 4 *!*
EDCHECKKEY
php
pha
tya
pha
ldy #0
EDCHECK lda ($EE), y
beq EDCONTINUE
bpl EDEXIT
iny
cmp $C000
bne EDCHECK
EDEXIT pla
pla
plp
rts
EDCONTINUE
bit $C010
pla
tay
pla
plp
jmp ED0976

View File

@ -4,9 +4,8 @@
; Public functions:
; - InitSound
; - ReinitSoundAfterPrefChange
; - LoopSound
; - PlaySound
; - PlaySoundToCompletion
; - PlaySound
; - InitPuzzleSound
; - PlayNextChord
; - PlayFinalChord
@ -19,9 +18,6 @@
gSoundPref
!byte 1 ; 0 = no sound, 1 = sound
mockingboardSlot ; [byte][private]
!byte 0 ; 0 = no Mockingboard, 0xC1..0xC7 = slot number
progressionIndex ; [byte][private]
!byte 0
@ -55,8 +51,6 @@ k16251Progression
!word M_V
kFinalChord
!word M_I_LONG
kErrorSound
!word M_ERROR
;------------------------------------------------------------------------------
; ReinitSoundAfterPrefChange
@ -66,7 +60,8 @@ kErrorSound
; out: all flags & registers clobbered
;------------------------------------------------------------------------------
ReinitSoundAfterPrefChange
ldx mockingboardSlot
mockingboardSlot=*+1
ldx #$FD ; SMC
; /!\ execution falls through to InitSound
;------------------------------------------------------------------------------
@ -80,6 +75,7 @@ InitSound
stx mockingboardSlot
lda gSoundPref
beq @theSoundOfSilence
kZeroByte=*+1
cpx #0
beq @playThroughSpeaker
+LDADDR MockingDuet
@ -93,71 +89,41 @@ InitSound
+ST16 SoundLibraryDispatch
rts
-
+LD16 $FE
; /!\ execution falls through to LoopSound
;------------------------------------------------------------------------------
; LoopSound
; play sound data repeatedly until keypress
;
; in: A/Y points to buffer containing sound data in Electric Duet format
; out: A = key pressed
; all other flags & registers clobbered
;------------------------------------------------------------------------------
LoopSound
sec
+HIDE_NEXT_BYTE
; /!\ execution falls through to PlaySound
;------------------------------------------------------------------------------
; PlaySound
; play sound data once, or until keypress, whichever comes first
;
; in: A/Y points to buffer containing sound data in Electric Duet format
; out: N = 1 if exited because key was pressed, and A = key pressed
; N = 0 if exited because all sound data was played
; all other flags & registers clobbered
;------------------------------------------------------------------------------
PlaySound
clc
php
+ST16 $1E
+ST16 $FE
SoundLibraryDispatch=*+1
jsr $FDFD ; SMC
plp
bcc +
lda KBD
bpl -
+ lda KBD
Silence rts
;------------------------------------------------------------------------------
; PlaySoundToCompletion
; play sound data once, ignoring keypresses
; play sound to completion, ignoring all keypresses
;
; in: A/Y points to buffer containing sound data in Electric Duet format
; out: all flags & registers clobbered
;------------------------------------------------------------------------------
PlaySoundToCompletion
pha
lda ED0974+1
sta @restoreED
lda MBKEYBRANCH+1
sta @restoreMB
lda #0 ; just self-modify sound routines to branch
sta ED0974+1 ; to next instruction on keypress, because
sta MBKEYBRANCH+1 ; cycle counts are critical
pla
jsr PlaySound
@restoreED=*+1
lda #$FD ; SMC
sta ED0974+1 ; restore sound routines
@restoreMB=*+1
lda #$FD ; SMC
sta MBKEYBRANCH+1
rts
ldx #<kZeroByte
stx $EE
ldx #>kZeroByte
stx $EF
; /!\ execution falls through to PlaySound
;------------------------------------------------------------------------------
; PlaySound
; play sound until keypress or completion (but see note about acceptable keys)
;
; in: A/Y points to buffer containing sound data in Electric Duet format
; $EE/$EF points to list of acceptable keys
; keys have high bit set
; list is 0x00-terminated
; if first byte in list is 0x00, no keys are accepted
; 0x01 acts as wildcard
; if first byte in list is 0x01, all keys are accepted
; out: N = 1 if exited because acceptable key was pressed, and A = key pressed
; N = 0 if exited because sound was played to completion
; all other flags & registers clobbered
;------------------------------------------------------------------------------
PlaySound
+ST16 $1E
SoundLibraryDispatch=*+1
jsr $FDFD ; SMC
lda KBD
Silence rts
;------------------------------------------------------------------------------
; InitPuzzleSound
@ -243,5 +209,5 @@ PlayFinalChord
; flags clobbered
;------------------------------------------------------------------------------
PlayErrorSound
+LD16 kErrorSound
+LDADDR M_ERROR
jmp PlaySoundToCompletion

View File

@ -76,10 +76,12 @@ Start ; X = Mockingboard slot (from init)
!source "src/ui.title.a"
!source "src/ui.main.menu.a"
!source "src/ui.select.world.a"
!source "src/ui.reveal.a"
!source "src/ui.about.a"
!source "src/ui.interstitial.a"
!source "src/ui.play.a"
!source "src/ui.demo.a"
!source "src/ui.help.a"
!source "src/ui.message.a"
!source "src/ui.common.a"

View File

@ -36,6 +36,7 @@ FMDEST sta $4000, x
bcs FM
jsr GetMockingboardSlot
;ldx #0 ; [DEBUG] uncomment to disable Mockingboard support
cpx #0
beq +
; set up MockingDuet routine with the Mockingboard slot number

View File

@ -21,6 +21,8 @@
; changes to original (by 4am):
; - fixes for stereo output
; - labels for slot independence (see million.init.a)
; - MBCHECKKEY to check against a list of keys that will exit
;
CHN = $1D
SONG = $1E
@ -55,6 +57,19 @@ LOOP LDY #$00
END JSR RESET
RTS
MBCHECKKEY
ldy #0
MBCHECK lda ($EE), y
beq MBCONTINUE
bpl END
iny
cmp $C000
beq END
bne MBCHECK ; always branches
MBCONTINUE
bit $C010
jmp NEXT
SETNOTE STA DURATION
LDA #LEFTCHN
SEND STA CHN
@ -92,7 +107,7 @@ W2 DEC TEMP
BNE W1
BIT $C000
MBKEYBRANCH
BMI END
BMI MBCHECKKEY
JMP NEXT
CONVFREQ LDX OCTAVE
@ -109,7 +124,6 @@ DECOCT DEX
LOBYTE STA TONE
RTS
RESET LDA #$00
MBSLOT09 STA $C400
MBSLOT10 STA $C480

View File

@ -7,58 +7,6 @@
; - AboutPage
;
revealindex = $F5
revealStringsLo
!byte <kAboutWritten
!byte <kAboutTested
!byte <kAboutTested2
!byte <kAboutMusic
!byte <kAboutElectricDuet
!byte <kAboutMockingDuet
!byte 0
revealStringsHi
!byte >kAboutWritten
!byte >kAboutTested
!byte >kAboutTested2
!byte >kAboutMusic
!byte >kAboutElectricDuet
!byte >kAboutMockingDuet
!byte 0
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
kAboutWritten
!byte 14
!raw "WRITTEN BY 4AM"
kAboutTested
!byte 21
!raw "PLAYTESTED BY OPTION8"
kAboutTested2
!byte 10
!raw "AND BESLEY"
kAboutMusic
!byte 22
!raw "MUSIC BY GABRIEL FAURE"
kAboutElectricDuet
!byte 28
!raw "SOUND ROUTINES BY PAUL LUTUS"
kAboutMockingDuet
!byte 35
!raw "MOCKINGBOARD ROUTINES BY CYBERNESTO"
;------------------------------------------------------------------------------
; AboutPage
; display animated credits page
@ -70,23 +18,69 @@ AboutPage
jsr Home
@outerloop
lda #0
sta revealindex
@loop ldx revealindex
lda revealVTABs, x
sta @loop+1
@loop ldx #$FD ; SMC
lda aboutVTABs, x
sta targetVTAB
lda revealHTABs, x
lda aboutHTABs, x
sta minHTAB
lda revealStringsHi, x
lda aboutStringsHi, x
beq @outerloop
tay
lda revealStringsLo, x
lda aboutStringsLo, x
jsr HeavySilkReveal
ldx #10
lda #0
- jsr WaitForKeyWithTimeout
bmi @exit
dex
bpl -
inc revealindex
bne @loop
inc @loop+1
ldx #11
jsr LongWaitForKeyWithTimeout
bpl @loop
@exit rts
aboutStringsLo
!byte <sAboutWritten
!byte <sAboutTested
!byte <sAboutTested2
!byte <sAboutMusic
!byte <sAboutElectricDuet
!byte <sAboutMockingDuet
!byte 0
aboutStringsHi
!byte >sAboutWritten
!byte >sAboutTested
!byte >sAboutTested2
!byte >sAboutMusic
!byte >sAboutElectricDuet
!byte >sAboutMockingDuet
!byte 0
aboutVTABs
!byte 4
!byte 20
!byte 21
!byte 9
!byte 14
!byte 19
aboutHTABs
!byte 5
!byte 16
!byte 20
!byte 17
!byte 9
!byte 1
sAboutWritten
!byte 14
!raw "WRITTEN BY 4AM"
sAboutTested
!byte 21
!raw "PLAYTESTED BY OPTION8"
sAboutTested2
!byte 10
!raw "AND BESLEY"
sAboutMusic
!byte 22
!raw "MUSIC BY GABRIEL FAURE"
sAboutElectricDuet
!byte 28
!raw "SOUND ROUTINES BY PAUL LUTUS"
sAboutMockingDuet
!byte 35
!raw "MOCKINGBOARD ROUTINES BY CYBERNESTO"

View File

@ -6,6 +6,7 @@
; Public functions:
; - Home
; - WaitForKeyWithTimeout
; - LongWaitForKeyWithTimeout
; - ScrollDown
; - ScrollDownBy
; - ScrollUp
@ -81,6 +82,8 @@ Home
; in: A = timeout length (like standard $FCA8 wait routine)
; out: A = 0
; X/Y preserved
; N = 1 if key was pressed to exit early
; N = 0 if time ran out
;------------------------------------------------------------------------------
WaitForKeyWithTimeout
sec
@ -94,6 +97,24 @@ WaitForKeyWithTimeout
bne @wait1
@exit rts
;------------------------------------------------------------------------------
; LongWaitForKeyWithTimeout
; just what it says on the tin
;
; in: X = number of iterations for an A=0 wait loop
; out: A,X = 0
; Y preserved
; N = 1 if key was pressed to exit early
; N = 0 if time ran out
;------------------------------------------------------------------------------
LongWaitForKeyWithTimeout
lda #0
- jsr WaitForKeyWithTimeout
bmi +
dex
bne -
+ rts
;------------------------------------------------------------------------------
; ScrollDown
; scroll a single puzzle column down 16 HGR rows

150
src/ui.demo.a Normal file
View File

@ -0,0 +1,150 @@
;license:MIT
;(c) 2020 by 4am
;
; self-running demo
;
; Public functions:
; - RunDemo
;
; puzzle 0:
; AOCD,LTLE,IBUH|ABLE,ITCH,LOUD
;------------------------------------------------------------------------------
; RunDemo
; run self-running demo until keypress or completion
;
; in: none
; out: C = 1
; all other registers & flags clobbered
;------------------------------------------------------------------------------
RunDemo
+LDADDR DemoCode
+ST16 GetNextDemoByte+1
- jsr GetNextDemoByte
lda DemoDispatchLo, x
sta @j+1
lda DemoDispatchHi, x
sta @j+2
@j jsr $FDFD ; SMC
lda KBD
bpl -
jsr DemoOnEXIT ; does not return
LoadDemoPuzzle
; TODO
rts
DrawDemoPuzzleChrome
; TODO
rts
DemoOnEXIT
lda #$FF
sta gWorldID ; invalidate cache
pla
pla
sec
rts
DemoOnLOAD
jsr GetNextDemoByte
stx gPuzzleID
jsr GetNextDemoByte
stx gWorldID
lda kWorldLeftMargins, x
sta GlobalLeftMargin
lda kPuzzleWidths, x
jsr InitPuzzleStorage
jsr InitPuzzleSound
ldx gPuzzleID
jsr LoadDemoPuzzle
lda #0
sta gSelectedLogicalColumn
jsr DrawDemoPuzzleChrome
jsr DrawPuzzle
jsr AnimatePuzzleIntoPlace
jmp DrawColumnSelectionIndicator
DemoOnSHOW
jsr GetNextDemoByte
txa
pha
jsr GetNextDemoByte
txa
tay
pla
jsr SetNextMessage
jmp ShowMessage
DemoOnHIDE=HideMessage
DemoOnLEFT=PlayEventLeftArrow
DemoOnRIGHT=PlayEventRightArrow
DemoOnUP=PlayEventUpArrow
DemoOnDOWN=PlayEventDownArrow
DemoOnWAIT
jsr GetNextDemoByte
jmp LongWaitForKeyWithTimeout
GetNextDemoByte
ldx $FDFD ; SMC
inc GetNextDemoByte+1
bne +
inc GetNextDemoByte+2
+ rts
DemoDispatchLo
!byte <DemoOnEXIT
!byte <DemoOnLOAD
!byte <DemoOnSHOW
!byte <DemoOnHIDE
!byte <DemoOnLEFT
!byte <DemoOnRIGHT
!byte <DemoOnUP
!byte <DemoOnDOWN
!byte <DemoOnWAIT
DemoDispatchHi
!byte >DemoOnEXIT
!byte >DemoOnLOAD
!byte >DemoOnSHOW
!byte >DemoOnHIDE
!byte >DemoOnLEFT
!byte >DemoOnRIGHT
!byte >DemoOnUP
!byte >DemoOnDOWN
!byte >DemoOnWAIT
; opcodes
EXIT = 0
LOAD = 1
SHOW = 2
HIDE = 3
LEFT = 4
RIGHT = 5
UP = 6
DOWN = 7
WAIT = 8
sUpDown
!byte 24
!raw "MOVE COLUMNS UP AND DOWN"
sColumns
!byte 20
!raw "MOVE BETWEEN COLUMNS"
DemoCode
!byte LOAD ,0,0
!byte SHOW ,<sUpDown,>sUpDown
!byte WAIT ,10
!byte HIDE
!byte UP
!byte WAIT ,5
!byte UP
!byte WAIT ,5
!byte DOWN
!byte WAIT ,5
!byte SHOW ,<sColumns,>sColumns
!byte WAIT ,10
!byte HIDE
!byte EXIT

View File

@ -7,54 +7,6 @@
; - HelpEventLoop
;
;0123456789012345678901234567890123456789
;
;
;
; MOVE COLUMNS TO FORM WORDS
;
; USE ALL LETTERS TO ADVANCE
;
;
; *
;
;
;LEFT/RIGHT ARROWS..........SELECT COLUMN
;
;UP/DOWN ARROWS...............MOVE COLUMN
;
;A-Z.......................MOVE TO LETTER
;
;CTRL-R....................RESTART PUZZLE
;
;ESC............................MAIN MENU
;
;
;
;
help_info1
!byte 26
!raw "MOVE COLUMNS TO FORM WORDS"
help_info2
!byte 26
!raw "USE ALL LETTERS TO ADVANCE"
help_leftright
!byte 40
!raw "LEFT/RIGHT ARROWS..........SELECT COLUMN"
help_updown
!byte 40
!raw "UP/DOWN ARROWS...............MOVE COLUMN"
help_az
!byte 40
!raw "A-Z.......................MOVE TO LETTER"
help_ctrlr
!byte 40
!raw "CTRL-R....................RESTART PUZZLE"
help_esc
!byte 40
!raw "ESC............................MAIN MENU"
;------------------------------------------------------------------------------
; HelpEventLoop
; display help subpage
@ -69,20 +21,41 @@ HelpEventLoop
bit CLEARKBD
- lda KBD
bpl -
bit CLEARKBD
sec
rts
DrawHelpText
; [private]
bit TEXTMODE
+PRINT_AT help_info1, 3, 7
+PRINT_AT help_info2, 5, 7
+PRINT_AT asterisk, 8, 20
+PRINT_AT help_leftright, 11, 0
+PRINT_AT help_updown, 13, 0
+PRINT_AT help_az, 15, 0
+PRINT_AT help_ctrlr, 17, 0
+PRINT_AT help_esc, 19, 0
+PRINT_AT sHelpHeader1, 3, 7
+PRINT_AT sHelpHeader2, 5, 7
+PRINT_AT sAsterisk, 8, 20
+PRINT_AT sHelpLeftRight, 11, 0
+PRINT_AT sHelpUpDown, 13, 0
+PRINT_AT sHelpLetters, 15, 0
+PRINT_AT sHelpRestart, 17, 0
+PRINT_AT sHelpQuit, 19, 0
bit GFXMODE
rts
sHelpHeader1
!byte 26
!raw "MOVE COLUMNS TO FORM WORDS"
sHelpHeader2
!byte 26
!raw "USE ALL LETTERS TO ADVANCE"
sHelpLeftRight
!byte 40
!raw "LEFT/RIGHT ARROWS..........SELECT COLUMN"
sHelpUpDown
!byte 40
!raw "UP/DOWN ARROWS...............MOVE COLUMN"
sHelpLetters
!byte 40
!raw "A-Z.......................MOVE TO LETTER"
sHelpRestart
!byte 40
!raw "CTRL-R....................RESTART PUZZLE"
sHelpQuit
!byte 40
!raw "ESC............................MAIN MENU"

View File

@ -8,83 +8,6 @@
; - 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
; display interstitial progress animation after every 10 completed puzzles
@ -142,20 +65,87 @@ ShowInterstitialWorldComplete
lda progressStringsLo, x
jsr HeavySilkReveal
lda KBD
bmi @exit
bmi +
; wildcard, will allow any key to terminate sound
+LDADDR sOneSpace
+ST16 $EE
+LDADDR InterstitialProgressMusic
jsr PlaySound
ldx #20
lda #0
- jsr WaitForKeyWithTimeout
ldx #21
jsr LongWaitForKeyWithTimeout
bmi +
dex
bpl -
+ lda KBD
bmi @exit
lda #0
sta targetVTAB
sta minHTAB
+LDADDR kEmptyString
+LDADDR sOneSpace
jsr HeavySilkReveal
@exit jmp Home
+ jmp Home
progressStringsLo
!byte <sProgress10
!byte <sProgress20
!byte <sProgress30
!byte <sProgress40
!byte <sProgress50
!byte <sProgress60
!byte <sProgress70
!byte <sProgress80
!byte <sProgress90
!byte <sProgress100
progressStringsHi
!byte >sProgress10
!byte >sProgress20
!byte >sProgress30
!byte >sProgress40
!byte >sProgress50
!byte >sProgress60
!byte >sProgress70
!byte >sProgress80
!byte >sProgress90
!byte >sProgress100
progressHTABs
!byte 7
!byte 8
!byte 8
!byte 8
!byte 7
!byte 2
!byte 9
!byte 7
!byte 6
!byte 4
sProgress10
!byte 25
!raw "10% COMPLETE! KEEP IT UP!"
sProgress20
!byte 24
!raw "20% COMPLETE! WAY TO GO!"
sProgress30
!byte 24
!raw "30% COMPLETE! FANTASTIC!"
sProgress40
!byte 24
!raw "40% COMPLETE! EXCELLENT!"
sProgress50
!byte 26
!raw "WHOA, WE'RE HALFWAY THERE!"
sProgress60
!byte 36
!raw "60% OF THE TIME, IT WORKS EVERY TIME"
sProgress70
!byte 22
!raw "70% COMPLETE! AMAZING!"
sProgress80
!byte 25
!raw "80% COMPLETE! PHENOMENAL!"
sProgress90
!byte 28
!raw "90% COMPLETE! INCONCEIVABLE!"
sProgress100
!byte 31
!raw "100% COMPLETE! CONGRATULATIONS!"
sOneSpace
!byte 1
!raw " "

View File

@ -1,7 +1,7 @@
;license:MIT
;(c) 2020 by 4am
;
; main menu & select world screen
; main menu
;
; Public functions:
; - MainMenuEventLoop
@ -14,14 +14,16 @@ kStartPlaying = 2
kMainMenuKeys ; must keep in sync with kMainMenuKeyHandlersLo/Hi arrays
; except for last byte ($00) which doesn't need an associated handler
!byte $0D ; Return
!byte $43 ; C/c
!byte $03 ; Ctrl-C
!byte $53 ; S/s
!byte $13 ; Ctrl-S
!byte $51 ; Q/q
!byte $11 ; Ctrl-Q
!byte $1B ; Esc
!byte $8D ; Return
!byte $C3 ; C
!byte $E3 ; c
!byte $D3 ; S
!byte $F3 ; s
!byte $C4 ; D
!byte $E4 ; d
!byte $D1 ; Q
!byte $F1 ; q
!byte $9B ; Esc
!byte $00
kMainMenuKeyHandlersLo
@ -30,6 +32,8 @@ kMainMenuKeyHandlersLo
!byte <MainMenuEventC
!byte <MainMenuEventS
!byte <MainMenuEventS
!byte <MainMenuEventD
!byte <MainMenuEventD
!byte <MainMenuEventQ
!byte <MainMenuEventQ
!byte <MainMenuEventQ
@ -40,6 +44,8 @@ kMainMenuKeyHandlersHi
!byte >MainMenuEventC
!byte >MainMenuEventS
!byte >MainMenuEventS
!byte >MainMenuEventD
!byte >MainMenuEventD
!byte >MainMenuEventQ
!byte >MainMenuEventQ
!byte >MainMenuEventQ
@ -63,27 +69,24 @@ MainMenuEventLoop
+ jsr DrawMainMenuText
bit CLEARKBD
+LDADDR MainMenuMusic
jsr LoopSound
bit CLEARKBD
and #$7F
cmp #$7B
bcs +
cmp #$61
bcc +
sbc #$20 ; a-z -> A-Z
+ sta gLastKeyPressed
LoopMusic
+LDADDR kMainMenuKeys
+ST16 $EE
+LDADDR MainMenuMusic
jsr PlaySound
bpl LoopMusic ; music played to completion, so start over
bit CLEARKBD
+ sta gLastKeyPressed
ldx #0
- ldy kMainMenuKeys, x
beq MainMenuEventLoop
cpy gLastKeyPressed
beq @dispatch
beq +
inx
bne -
beq MainMenuEventLoop
@dispatch
lda kMainMenuKeyHandlersLo, x
; /!\ execution never reaches here
brk
+ lda kMainMenuKeyHandlersLo, x
sta @j+1
lda kMainMenuKeyHandlersHi, x
sta @j+2
@ -99,6 +102,10 @@ MainMenuEventReturn
; A=world ID (from SelectWorld)
rts
MainMenuEventD
jsr RunDemo
bcs + ; always branches
MainMenuEventC
jsr AboutPage
+ ldx #kStayOnMainMenu ; Z=1 so caller will stay in main menu event loop
@ -126,13 +133,13 @@ DrawMainMenuTitle
sta GlobalLeftMargin
ldy #3
- ldx #1
lda kTitleLine1-2, y
lda sTitleLine1-2, y
jsr DrawLargeCharacter
inx
lda kTitleLine2-2, y
lda sTitleLine2-2, y
jsr DrawLargeCharacter
inx
lda kTitleLine3-2, y
lda sTitleLine3-2, y
jsr DrawLargeCharacter
iny
cpy #$0A
@ -140,259 +147,50 @@ DrawMainMenuTitle
rts
DrawMainMenuText
+PRINT_AT asterisk, 2, 30
+PRINT_AT version, 11, 26
+PRINT_AT mainmenu_play, 15, 10
+PRINT_AT mainmenu_sound, 16, 10
+PRINT_AT sAsterisk, 2, 30
+PRINT_AT sVersion, 11, 26
+PRINT_AT sMainMenuPlay, 15, 10
+PRINT_AT sMainMenuSound, 16, 10
lda gSoundPref
beq @theSoundOfSilence
+LDADDR mainmenu_sound_on
+LDADDR sMainMenuSoundOn
bne + ; always branches
@theSoundOfSilence
+LDADDR mainmenu_sound_off
+LDADDR sMainMenuSoundOff
+ jsr DrawHeavySilkString
+PRINT_AT mainmenu_about, 17, 10
+PRINT_AT mainmenu_quit, 18, 10
+PRINT_AT disclaimer, 23, 0
+PRINT_AT sMainMenuAbout, 17, 10
+PRINT_AT sMainMenuDemo, 18, 10
+PRINT_AT sMainMenuQuit, 19, 10
+PRINT_AT sMainMenuDisclaimer, 23, 0
rts
counter = $F2
selectedworld = $F3
SelectWorld
; [private]
; in: none
; out: C clear if world was selected, and
; A = 0-based world ID
; C set if no world was selected and A is undefined
jsr Home
jsr UpdateWorldPercents
+LDADDR worlddescriptions
+ST16 $FE
lda #0
sta counter
sta selectedworld
lda #6
sta VTAB
- lda #10
sta HTAB
+LD16 $FE
ldx counter
cpx selectedworld
beq +
ldx #20
jsr DrawHeavySilkBuffer
jmp ++
+ ldx #20
jsr DrawHeavySilkBufferInverse
++ inc VTAB
lda $FE
clc
adc #20
sta $FE
bcc +
inc $FF
+ inc counter
lda counter
cmp #12
bcc -
+PRINT_AT worldhelp, 23, 0
bit CLEARKBD
@selectWorldLoop
lda KBD
bpl @selectWorldLoop
bit CLEARKBD
and #$7F
cmp #$0B ; up arrow
beq @eventUpArrow
cmp #$0A ; down arrow
beq @eventDownArrow
cmp #$08 ; left arrow
beq @eventLeftArrow
cmp #$15 ; right arrow
beq @eventRightArrow
cmp #$0D
beq @eventReturn
cmp #$1B
beq @eventEsc
rts
@eventReturn
jsr Home
lda selectedworld
clc
rts
@eventEsc
sec
rts
@eventLeftArrow
@eventUpArrow
jsr RedrawPreviouslySelectedWorld
ldx selectedworld
bne +
ldx #12
+ dex
stx selectedworld
jsr DrawNewlySelectedWorld
jmp @selectWorldLoop
@eventRightArrow
@eventDownArrow
jsr RedrawPreviouslySelectedWorld
ldx selectedworld
cpx #11
bne +
ldx #$FF
+ inx
stx selectedworld
jsr DrawNewlySelectedWorld
jmp @selectWorldLoop
RedrawPreviouslySelectedWorld
lda selectedworld
tax
clc
adc #6
sta VTAB
lda #10
sta HTAB
jsr GetWorldDescription
+LD16 $FE
ldx #20
jmp DrawHeavySilkBuffer
DrawNewlySelectedWorld
lda selectedworld
tax
clc
adc #6
sta VTAB
lda #10
sta HTAB
jsr GetWorldDescription
+LD16 $FE
ldx #20
jmp DrawHeavySilkBufferInverse
GetWorldDescription
; in: X = 0-based world ID
; out: $FE/$FF points to world description buffer
+LDADDR worlddescriptions
+ST16 $FE
jmp +
- lda $FE
clc
adc #20
sta $FE
bcc +
inc $FF
+ dex
bpl -
rts
worldindex=$FB
UpdateWorldPercents
+LDADDR worlddescriptions
+ST16 $FC
lda #0
sta worldindex
-- jsr FindPackedProgressAddr
ldy #$0E
lda ($FE), y
tax
lda #$20
jsr ToASCIIString
ldx #2
ldy #17
- lda $F2, x
sta ($FC), y
dey
dex
bpl -
lda $FC
clc
adc #20
sta $FC
bcc +
inc $FD
+ inc worldindex
lda worldindex
cmp #12
bne --
rts
asterisk
sAsterisk
!byte 1
!byte "*"
version
sVersion
!byte 4
!raw "V0.4"
mainmenu_play
sMainMenuPlay
!byte 20
!raw "RETURN.....PLAY GAME"
mainmenu_sound
sMainMenuSound
!byte 18
!raw " S.....SOUND ("
mainmenu_sound_on
sMainMenuSoundOn
!byte 4
!raw "ON) "
mainmenu_sound_off
sMainMenuSoundOff
!byte 4
!raw "OFF)"
mainmenu_about
sMainMenuAbout
!byte 18
!raw " C.....CREDITS"
mainmenu_quit
sMainMenuDemo
!byte 15
!raw " D.....DEMO"
sMainMenuQuit
!byte 15
!raw " Q.....QUIT"
disclaimer
sMainMenuDisclaimer
!byte 40
!raw "* NOT GUARANTEED, ACTUAL COUNT MAY VARY."
worlddescriptions
!raw " 4X3 EASY 0% "
!raw " 5X3 BASIC 0% "
!raw " 6X3 SIMPLE 0% "
!raw " 7X3 RELAXED 0% "
!raw " 4X4 FAIR 0% "
!raw " 5X4 QUICK 0% "
!raw " 6X4 MEDIUM 0% "
!raw " 7X4 AVERAGE 0% "
!raw " 4X5 HARD 0% "
!raw " 5X5 TOUGH 0% "
!raw " 6X5 TRICKY 0% "
!raw " 7X5 COMPLEX 0% "
kWorldShortNames
!byte 3
!raw "4X3"
!byte 3
!raw "5X3"
!byte 3
!raw "6X3"
!byte 3
!raw "7X3"
!byte 3
!raw "4X4"
!byte 3
!raw "5X4"
!byte 3
!raw "6X4"
!byte 3
!raw "7X4"
!byte 3
!raw "4X5"
!byte 3
!raw "5X5"
!byte 3
!raw "6X5"
!byte 3
!raw "7X5"
kDash
!byte 1
!raw "-"
worldhelp
!byte 40
!raw "ARROWS TO SELECT, RETURN TO PLAY, OR ESC"

View File

@ -79,7 +79,7 @@ kPlayKeyHandlersHi
; in: puzzle has been loaded into memory, drawn on screen, animated, &c.
; and is ready to play
; out: X = reason why event loop ended (see list above)
; all other registers and flags clobbered
; all other registers & flags clobbered
;------------------------------------------------------------------------------
PlayEventLoop
bit CLEARKBD
@ -310,14 +310,11 @@ AnimatePuzzleIntoPlace
; in: none
; out: all registers and flags clobbered
;------------------------------------------------------------------------------
kLevel
!byte 5
!raw "LEVEL"
DrawPuzzleChrome
+PRINT_AT kTitleLine1, 0, 0
+PRINT_AT kTitleLine2, 1, 0
+PRINT_AT kTitleLine3, 2, 0
+PRINT_AT kLevel, 0, 34
+PRINT_AT sTitleLine1, 0, 0
+PRINT_AT sTitleLine2, 1, 0
+PRINT_AT sTitleLine3, 2, 0
+PRINT_AT sLevel, 0, 34
+LDADDR kWorldShortNames
+ST16 $FE
lda gWorldID
@ -465,3 +462,7 @@ DrawOneSelectionIndicator
dex
bne -
rts
sLevel
!byte 5
!raw "LEVEL"

View File

@ -16,7 +16,10 @@ randomchar = $F3
revealchar = $F4
revealtext = $FE
HeavySilkReveal
;------------------------------------------------------------------------------
; HeavySilkReveal
; display animation with small letters to reveal hidden text
;
; 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)
@ -26,7 +29,8 @@ HeavySilkReveal
; randomchar clobbered
; revealchar clobbered
; revealtext clobbered [word]
;------------------------------------------------------------------------------
HeavySilkReveal
+ST16 revealtext
ldy #0
lda (revealtext), y
@ -101,8 +105,7 @@ HeavySilkReveal
sta @revealStartingChar
lda #$20
bne @outerloop ; always branches
@exit
rts
@exit rts
@draw
; check if this position is part of the reveal text
lda VTAB

225
src/ui.select.world.a Normal file
View File

@ -0,0 +1,225 @@
;license:MIT
;(c) 2020 by 4am
;
; select world screen
;
; Public functions:
; - SelectWorld
;
counter = $F2
selectedworld = $F3
;------------------------------------------------------------------------------
; SelectWorld
; allow user to select world for playing
;
; in: none
; out: C clear if world was selected, and
; A = 0-based world ID
; C set if no world was selected and A is undefined
;------------------------------------------------------------------------------
SelectWorld
jsr Home
jsr UpdateWorldPercents
+LDADDR worlddescriptions
+ST16 $FE
lda #0
sta counter
sta selectedworld
lda #6
sta VTAB
- lda #10
sta HTAB
+LD16 $FE
ldx counter
cpx selectedworld
beq +
ldx #20
jsr DrawHeavySilkBuffer
jmp ++
+ ldx #20
jsr DrawHeavySilkBufferInverse
++ inc VTAB
lda $FE
clc
adc #20
sta $FE
bcc +
inc $FF
+ inc counter
lda counter
cmp #12 ; ignore world 13 (that's for self-running demo)
bcc -
+PRINT_AT worldhelp, 23, 0
bit CLEARKBD
@selectWorldLoop
lda KBD
bpl @selectWorldLoop
bit CLEARKBD
and #$7F
cmp #$0B ; up arrow
beq @eventUpArrow
cmp #$0A ; down arrow
beq @eventDownArrow
cmp #$08 ; left arrow
beq @eventLeftArrow
cmp #$15 ; right arrow
beq @eventRightArrow
cmp #$0D
beq @eventReturn
cmp #$1B
beq @eventEsc
rts
@eventReturn
jsr Home
lda selectedworld
clc
rts
@eventEsc
sec
rts
@eventLeftArrow
@eventUpArrow
jsr RedrawPreviouslySelectedWorld
ldx selectedworld
bne +
ldx #12
+ dex
stx selectedworld
jsr DrawNewlySelectedWorld
jmp @selectWorldLoop
@eventRightArrow
@eventDownArrow
jsr RedrawPreviouslySelectedWorld
ldx selectedworld
cpx #11
bne +
ldx #$FF
+ inx
stx selectedworld
jsr DrawNewlySelectedWorld
jmp @selectWorldLoop
RedrawPreviouslySelectedWorld
lda selectedworld
tax
clc
adc #6
sta VTAB
lda #10
sta HTAB
jsr GetWorldDescription
+LD16 $FE
ldx #20
jmp DrawHeavySilkBuffer
DrawNewlySelectedWorld
lda selectedworld
tax
clc
adc #6
sta VTAB
lda #10
sta HTAB
jsr GetWorldDescription
+LD16 $FE
ldx #20
jmp DrawHeavySilkBufferInverse
GetWorldDescription
; in: X = 0-based world ID
; out: $FE/$FF points to world description buffer
+LDADDR worlddescriptions
+ST16 $FE
jmp +
- lda $FE
clc
adc #20
sta $FE
bcc +
inc $FF
+ dex
bpl -
rts
worldindex=$FB
UpdateWorldPercents
+LDADDR worlddescriptions
+ST16 $FC
lda #0
sta worldindex
-- jsr FindPackedProgressAddr
ldy #$0E
lda ($FE), y
tax
lda #$20
jsr ToASCIIString
ldx #2
ldy #17
- lda $F2, x
sta ($FC), y
dey
dex
bpl -
lda $FC
clc
adc #20
sta $FC
bcc +
inc $FD
+ inc worldindex
lda worldindex
cmp #12
bne --
rts
worlddescriptions
!raw " 4X3 EASY 0% "
!raw " 5X3 BASIC 0% "
!raw " 6X3 SIMPLE 0% "
!raw " 7X3 RELAXED 0% "
!raw " 4X4 FAIR 0% "
!raw " 5X4 QUICK 0% "
!raw " 6X4 MEDIUM 0% "
!raw " 7X4 AVERAGE 0% "
!raw " 4X5 HARD 0% "
!raw " 5X5 TOUGH 0% "
!raw " 6X5 TRICKY 0% "
!raw " 7X5 COMPLEX 0% "
kWorldShortNames
!byte 3
!raw "4X3"
!byte 3
!raw "5X3"
!byte 3
!raw "6X3"
!byte 3
!raw "7X3"
!byte 3
!raw "4X4"
!byte 3
!raw "5X4"
!byte 3
!raw "6X4"
!byte 3
!raw "7X4"
!byte 3
!raw "4X5"
!byte 3
!raw "5X5"
!byte 3
!raw "6X5"
!byte 3
!raw "7X5"
kDash
!byte 1
!raw "-"
worldhelp
!byte 40
!raw "ARROWS TO SELECT, RETURN TO PLAY, OR ESC"

View File

@ -7,22 +7,17 @@
; Public functions:
; - TitlePage
;
; Public constants:
; - kTitleLine1
; - kTitleLine2
; - kTitleLine3
titlechar = $FD
kTitleLine1
!byte 7
!raw "MILLION"
kTitleLine2
!byte 7
!raw "PERFECT"
kTitleLine3
!byte 7
!raw "LETTERS"
;------------------------------------------------------------------------------
; TitlePage
; display animated title page until keypress or completion
;
; in: none
; out: C = 0 if animation completed
; C = 1 if key was pressed to exit animation prematurely
;------------------------------------------------------------------------------
TitlePage
jsr Home
lda #$01
@ -51,9 +46,6 @@ TitlePage
lda @rnd1+1
eor #$41
sta @rnd1+1
;lda @rnd2+1
;eor #$00
;sta @rnd2+1
+
cpy #$76
bcs @loop
@ -79,11 +71,11 @@ TitlePage
beq @line3
@random lda titlechar
jmp + ; can't use a BNE because <titlechar> will actually be 0 the third time around
@line1 lda kTitleLine1-2, y
@line1 lda sTitleLine1-2, y
bne +
@line2 lda kTitleLine2-2, y
@line2 lda sTitleLine2-2, y
bne +
@line3 lda kTitleLine3-2, y
@line3 lda sTitleLine3-2, y
+ jsr DrawLargeCharacter
lda titlechar
beq +
@ -110,12 +102,9 @@ TitlePage
cmp #1
bne @loop
ldx #3
- lda #$00
jsr WaitForKeyWithTimeout
ldx #4
jsr LongWaitForKeyWithTimeout
bmi @prematureexit
dex
bne -
lda titlechar
beq @phase2
@ -141,3 +130,13 @@ TitlePage
cpy #$0A
bne --
beq @exit ; always branches
sTitleLine1
!byte 7
!raw "MILLION"
sTitleLine2
!byte 7
!raw "PERFECT"
sTitleLine3
!byte 7
!raw "LETTERS"