million-perfect-letters/src/glue.sound.a

222 lines
6.2 KiB
Plaintext

;license:MIT
;(c) 2020-2 by 4am
;
; convenience functions for playing sounds through different libraries
;
; Public functions:
; - InitSound
; - ToggleSoundPref
; - ReinitSoundAfterPrefChange
; - PlaySoundToCompletion
; - PlaySound
; - InitPuzzleSound
; - PlayNextChord
; - PlayFinalChord
; - ErrorSound
;
; Public variables:
; - gSoundPref
;
gSoundPref
!byte 1 ; 0 = no sound, 1 = sound
progressionIndex ; [byte][private]
!byte 0
kProgressionsByWorld ; chord progression to use on each world (index=world)
!word k251Progression
!word k251Progression
!word k251Progression
!word k251Progression
!word k6251Progression
!word k6251Progression
!word k6251Progression
!word k6251Progression
!word k16251Progression
!word k16251Progression
!word k16251Progression
!word k16251Progression
k251Progression
!byte 2
!word M_ii
!word M_V
k6251Progression
!byte 3
!word M_vi6
!word M_ii
!word M_V
k16251Progression
!byte 4
!word M_I
!word M_vi6
!word M_ii
!word M_V
ToggleSoundPref
lda gSoundPref
eor #$01
sta gSoundPref
jsr SavePrefs
; /!\ execution falls through to ReinitSoundAfterPrefChange
;------------------------------------------------------------------------------
; ReinitSoundAfterPrefChange
; reinitialize self-modified code that relies on preference values
;
; in: none
; out: all flags & registers clobbered
;------------------------------------------------------------------------------
ReinitSoundAfterPrefChange
mockingboardSlot=*+1
ldx #$FD ; SMC
; /!\ execution falls through to InitSound
;------------------------------------------------------------------------------
; InitSound
; initialize self-modified code for playing music and sound
;
; in: X = Mockingboard slot, or 0 if no Mockingboard present
; out: all flags & registers clobbered
;------------------------------------------------------------------------------
InitSound
stx mockingboardSlot
lda gSoundPref
beq @theSoundOfSilence
kZeroByte=*+1
cpx #0
beq @playThroughSpeaker
+LDADDR MockingDuet
bne + ; always branches
@playThroughSpeaker
+LDADDR ElectricDuet
bne + ; always branches
@theSoundOfSilence
+LDADDR Silence
+
+ST16 SoundLibraryDispatch
rts
;------------------------------------------------------------------------------
; PlaySoundToCompletion
; 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
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
; initialize chord progression at the start of a new puzzle
;
; in: none
; out: A clobbered
; N = 1
; Z = 0
; all other flags & registers preserved
;------------------------------------------------------------------------------
InitPuzzleSound
lda #$FF
sta progressionIndex
rts
;------------------------------------------------------------------------------
; PlayNextChord
; play next chord progression during a puzzle
;
; in: none
; out: A, Y clobbered
; X preserved
; flags clobbered
;------------------------------------------------------------------------------
PlayNextChord
txa
pha
lda gWorldID
asl
tax
lda kProgressionsByWorld, x
sta $FE
inx
lda kProgressionsByWorld, x
sta $FF
inc progressionIndex
ldy #0
lda ($FE), y
cmp progressionIndex
bne +
dec progressionIndex
+ lda progressionIndex
asl
tay
iny
lda ($FE), y
pha
iny
lda ($FE), y
tay
pla
jsr PlaySoundToCompletion
pla
tax
rts
;------------------------------------------------------------------------------
; PlayFinalChord
; play final chord progression when completing a puzzle
;
; in: none
; out: A, Y clobbered
; X preserved
; flags clobbered
;------------------------------------------------------------------------------
PlayFinalChord
txa
pha
+LDADDR M_I_LONG
jsr PlaySoundToCompletion
pla
tax
rts
;------------------------------------------------------------------------------
; PlayErrorChord
; play error sound when attempting an illegal move
;
; in: none
; out: A, Y clobbered
; X preserved
; flags clobbered
;------------------------------------------------------------------------------
PlayErrorSound
+LDADDR M_ERROR
jmp PlaySoundToCompletion