diff --git a/nsf/nsf.asm b/nsf/nsf.asm
index bb2280c7..a5d02e86 100644
--- a/nsf/nsf.asm
+++ b/nsf/nsf.asm
@@ -93,9 +93,8 @@ kSoundChip = 0 ; 0 = no extra sound chips
.assert eMusic::Silence = 0, error
iny
sty Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic
- lda #$ff
- sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool
- sta Zp_Next_sAudioCtrl + sAudioCtrl::MasterVolume_u8
+ lda #bAudio::Enable
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
jmp Func_AudioSync
.ENDPROC
diff --git a/src/audio.asm b/src/audio.asm
index 6ed82ad1..a548a36a 100644
--- a/src/audio.asm
+++ b/src/audio.asm
@@ -75,6 +75,10 @@ Zp_Next_sAudioCtrl: .tag sAudioCtrl
.EXPORTZP Zp_Next_sChanSfx_arr
Zp_Next_sChanSfx_arr: .res .sizeof(sChanSfx) * kNumApuChannels
+;;; The current settings for whether audio is enabled.
+.EXPORTZP Zp_Current_bAudio
+Zp_Current_bAudio: .res 1
+
;;; The currently-playing music.
Zp_Current_eMusic: .res 1
@@ -89,16 +93,6 @@ Zp_Current_sMusic: .tag sMusic
;;; indexing by APU channel number.
Zp_Music_sChanNext_arr: .res .sizeof(sChanNext) * kNumApuChannels
-;;; If true ($ff), then Func_AudioUpdate will perform audio playback; if false
-;;; ($00), then Func_AudioUpdate is a no-op. Invariant: all APU channels are
-;;; disabled when this is false.
-Zp_AudioEnabled_bool: .res 1
-
-;;; Master volume that is applied to all channels in conjunction with their
-;;; individual volume envelopes. The bottom four bits of this variable are
-;;; always zero.
-Zp_MasterVolume_u8: .res 1
-
;;; This must be all zero bits except for bMusic::FlagMask; those bits indicate
;;; the current music flag value.
Zp_MusicFlag_bMusic: .res 1
@@ -165,7 +159,7 @@ Ram_Sound_sChanSfx_arr: .res .sizeof(sChanSfx) * kNumApuChannels
dex
bpl @loop
;; Disable audio and reset music flag.
- sta Zp_AudioEnabled_bool
+ sta Zp_Current_bAudio
sta Zp_MusicFlag_bMusic
_HaltMusic:
.assert eMusic::Silence = 0, error
@@ -186,17 +180,16 @@ _HaltSfx:
;;; @prereq Caller is within the NMI handler, and Func_ProcessFrame is pending.
.EXPORT Func_AudioSync
.PROC Func_AudioSync
- lda <(Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool)
+ lda Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
+ .assert bAudio::Enable = bProc::Negative, error
bmi _Enable
_Disable:
- bit Zp_AudioEnabled_bool
+ bit Zp_Current_bAudio
+ .assert bAudio::Enable = bProc::Negative, error
bmi Func_AudioReset
rts
_Enable:
- sta Zp_AudioEnabled_bool
- lda <(Zp_Next_sAudioCtrl + sAudioCtrl::MasterVolume_u8)
- and #$f0
- sta Zp_MasterVolume_u8
+ sta Zp_Current_bAudio
_SyncMusicFlag:
lda Zp_Next_sAudioCtrl + sAudioCtrl::MusicFlag_bMusic
.assert bMusic::UsesFlag = bProc::Negative, error
@@ -299,7 +292,8 @@ _ResetChannels:
;;; @prereq Caller is within the NMI handler.
.EXPORT Func_AudioUpdate
.PROC Func_AudioUpdate
- bit Zp_AudioEnabled_bool
+ bit Zp_Current_bAudio
+ .assert bAudio::Enable = bProc::Negative, error
bmi _Enabled
rts
_Enabled:
@@ -532,6 +526,10 @@ _NoteToneOrSame:
cpx #eChan::Dmc
bne @notDmc
@isDmc:
+ ;; Skip DMC notes entirely when music volume is reduced.
+ bit Zp_Current_bAudio
+ .assert bAudio::ReduceMusic = bProc::Overflow, error
+ bvs _SkipToneOrSame
lda #$40
bne @setSweep ; unconditional
@notDmc:
diff --git a/src/audio.inc b/src/audio.inc
index 2e074830..64214ca3 100644
--- a/src/audio.inc
+++ b/src/audio.inc
@@ -70,6 +70,20 @@
;;;=========================================================================;;;
+;;; Flags for controlling whether audio is enabled.
+.SCOPE bAudio
+ ;; Controls whether audio is enabled. When audio is disabled, all music
+ ;; and sound effects are stopped, all APU channels are muted, and the audio
+ ;; driver will not read any more audio data until audio is re-enabled.
+ ;; Note that since this game generally stores music data in PRGC, it is
+ ;; only safe to switch PRGC banks when audio is disabled.
+ Enable = %10000000
+ ;; Controls the music volume. When this bit is set, certain music
+ ;; instruments will play at reduced volume or not at all. Sound effects
+ ;; are unaffected.
+ ReduceMusic = %01000000
+.ENDSCOPE
+
;;; Instructions to be sent to the audio driver the next time Func_ProcessFrame
;;; is called.
.STRUCT sAudioCtrl
@@ -78,22 +92,18 @@
;; driver will not read any more audio data until audio is re-enabled.
;; Note that since this game generally stores music data in PRGC, it is
;; only safe to switch PRGC banks when audio is disabled.
- Enable_bool .byte
- ;; Sets the master volume (0-255). This should normally be left at 255
- ;; (full volume), but can be reduced over the course of several frames to
- ;; fade out audio before disabling it. Note that only the top four bits
- ;; are actually used.
- MasterVolume_u8 .byte
+ Next_bAudio .byte
+ ;; Controls which music to play. When Func_ProcessFrame is called, if this
+ ;; is different than the currently-playing music (and audio is enabled),
+ ;; then the current music will be stopped, and this music will be started
+ ;; from the beginning.
+ Music_eMusic .byte
;; Controls the music flag. If bMusic::UsesFlag is set, then the music
;; flag will be set to this & bMusic::FlagMask when Func_ProcessFrame is
;; called; otherwise, the music flag will be unchanged. Either way, this
;; field will be updated to the (new) current value of the of the music
;; flag when Func_ProcessFrame is called.
MusicFlag_bMusic .byte
- ;; Controls which music to play. When Func_ProcessFrame is called, if this
- ;; is different than the currently-playing music, then the current music
- ;; will be stopped, and this music will be started from the beginning.
- Music_eMusic .byte
.ENDSTRUCT
;;;=========================================================================;;;
diff --git a/src/console.asm b/src/console.asm
index bb654834..ced1c565 100644
--- a/src/console.asm
+++ b/src/console.asm
@@ -17,6 +17,7 @@
;;; with Annalog. If not, see . ;;;
;;;=========================================================================;;;
+.INCLUDE "audio.inc"
.INCLUDE "avatar.inc"
.INCLUDE "charmap.inc"
.INCLUDE "console.inc"
@@ -55,6 +56,7 @@
.IMPORT Func_ProcessFrame
.IMPORT Func_SetLastSpawnPoint
.IMPORT Func_SetMachineIndex
+.IMPORT Func_SetMusicVolumeForCurrentRoom
.IMPORT Func_TickAllDevices
.IMPORT Func_Window_GetRowPpuAddr
.IMPORT Func_Window_PrepareRowTransfer
@@ -78,6 +80,7 @@
.IMPORTZP Zp_Current_sProgram_ptr
.IMPORTZP Zp_FloatingHud_bHud
.IMPORTZP Zp_MachineMaxInstructions_u8
+.IMPORTZP Zp_Next_sAudioCtrl
.IMPORTZP Zp_P1ButtonsPressed_bJoypad
.IMPORTZP Zp_PpuTransferLen_u8
.IMPORTZP Zp_ScrollGoalX_u16
@@ -219,6 +222,7 @@ _UpdateScrolling:
_Done:
lda #$ff
sta Zp_ConsoleMachineIndex_u8
+ jsr Func_SetMusicVolumeForCurrentRoom
jmp Main_Explore_Continue
.ENDPROC
@@ -280,6 +284,9 @@ _Tick:
;;; and resets the machine if it's not Halted/Error.
;;; @param X The console device index.
.PROC FuncA_Room_BeginUsingConsoleDevice
+ ;; Reduce music volume while the console is open.
+ lda #bAudio::Enable | bAudio::ReduceMusic
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
_SetSpawnPoint:
txa ; console device index
ora #bSpawn::Device ; param: bSpawn value
diff --git a/src/inst.asm b/src/inst.asm
index ed976424..5c383a25 100644
--- a/src/inst.asm
+++ b/src/inst.asm
@@ -19,6 +19,7 @@
.INCLUDE "apu.inc"
.INCLUDE "audio.inc"
+.INCLUDE "cpu.inc"
.INCLUDE "inst.inc"
.INCLUDE "macros.inc"
.INCLUDE "music.inc"
@@ -27,6 +28,7 @@
.IMPORT Ram_Music_sChanNote_arr
.IMPORTZP Zp_AudioTmp1_byte
.IMPORTZP Zp_AudioTmp2_byte
+.IMPORTZP Zp_Current_bAudio
;;;=========================================================================;;;
@@ -166,6 +168,11 @@ _Decay:
;;; @return A The duty/envelope byte to use.
;;; @preserve X
.PROC Func_CombineVolumeWithDuty
+ bit Zp_Current_bAudio
+ .assert bAudio::ReduceMusic = bProc::Overflow, error
+ bvc @noReduce
+ div #2
+ @noReduce:
sta Zp_AudioTmp1_byte ; volume
lda Ram_Music_sChanInst_arr + sChanInst::Param_byte, x
and #bEnvelope::DutyMask
diff --git a/src/pause.asm b/src/pause.asm
index 22aae479..ec387b2d 100644
--- a/src/pause.asm
+++ b/src/pause.asm
@@ -17,6 +17,7 @@
;;; with Annalog. If not, see . ;;;
;;;=========================================================================;;;
+.INCLUDE "audio.inc"
.INCLUDE "charmap.inc"
.INCLUDE "cpu.inc"
.INCLUDE "devices/flower.inc"
@@ -55,6 +56,7 @@
.IMPORT Func_FillLowerAttributeTable
.IMPORT Func_FillUpperAttributeTable
.IMPORT Func_IsFlagSet
+.IMPORT Func_SetMusicVolumeForCurrentRoom
.IMPORT Func_Window_Disable
.IMPORT Func_Window_ScrollDown
.IMPORT Func_Window_ScrollUp
@@ -72,6 +74,7 @@
.IMPORTZP Zp_Current_sRoom
.IMPORTZP Zp_FrameCounter_u8
.IMPORTZP Zp_NextIrq_int_ptr
+.IMPORTZP Zp_Next_sAudioCtrl
.IMPORTZP Zp_P1ButtonsPressed_bJoypad
.IMPORTZP Zp_PaperCursorRow_u8
.IMPORTZP Zp_PpuScrollX_u8
@@ -131,7 +134,7 @@ Zp_ActivatedBreakers_byte: .res 1
main_chr0c_bank Ppu_ChrBgMinimap
main_chr18_bank Ppu_ChrObjPause
jsr FuncA_Pause_InitAndFadeIn
- .assert * = MainA_Pause_Minimap, error, "fallthrough"
+ fall MainA_Pause_Minimap
.ENDPROC
;;; Mode for running the pause screen while the minimap is visible.
@@ -151,13 +154,14 @@ _CheckForUnpause:
lda Zp_P1ButtonsPressed_bJoypad
and #bJoypad::Start | bJoypad::BButton
beq _GameLoop
- .assert * = MainA_Pause_FadeOut, error, "fallthrough"
+ fall MainA_Pause_FadeOut
.ENDPROC
;;; Mode for fading out the pause screen and resuming explore mode.
;;; @prereq Rendering is enabled.
.PROC MainA_Pause_FadeOut
jsr Func_FadeOutToBlack
+ jsr Func_SetMusicVolumeForCurrentRoom
jmp Main_Explore_FadeIn
.ENDPROC
@@ -174,7 +178,7 @@ _GameLoop:
jsr Func_Window_ScrollUp ; sets C if fully scrolled in
bcc _GameLoop
jsr FuncA_Pause_MovePaperCursorNext
- .assert * = MainA_Pause_Papers, error, "fallthrough"
+ fall MainA_Pause_Papers
.ENDPROC
;;; Mode for running the pause screen while the papers window is visible.
@@ -246,6 +250,10 @@ _InitActivatedBreakers:
dex
cpx #kFirstBreakerFlag
bge @loop
+_ReduceMusic:
+ ;; Reduce music volume while on the pause screen.
+ lda #bAudio::Enable | bAudio::ReduceMusic
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
_DrawScreen:
ldy #$00 ; param: fill byte
jsr Func_FillUpperAttributeTable ; preserves Y
@@ -385,7 +393,7 @@ _FinishLowerNametable:
bne @loop
jsr FuncA_Pause_DirectDrawWindowBottomBorder
ldy #kScreenWidthTiles * 5 ; param: num blank tiles to draw
- .assert * = FuncA_Pause_DirectDrawBlankTiles, error, "fallthrough"
+ fall FuncA_Pause_DirectDrawBlankTiles
.ENDPROC
;;; Draws the specified number of blank BG tiles to Hw_PpuData_rw.
@@ -520,7 +528,7 @@ _CircuitBreakers_byte_arr8_arr6:
jsr FuncA_Pause_DirectDrawWindowLineSide ; preserves X and T0+
ldy #kScreenWidthTiles - 6 ; param: num blank tiles to draw
jsr FuncA_Pause_DirectDrawBlankTiles ; preserves X and T0+
- .assert * = FuncA_Pause_DirectDrawWindowLineSide, error, "fallthrough"
+ fall FuncA_Pause_DirectDrawWindowLineSide ; preserves X and T0+
.ENDPROC
;;; Draws the left or right side of one pause window line, including margins;
diff --git a/src/prologue.asm b/src/prologue.asm
index 2077de4f..2e1e0837 100644
--- a/src/prologue.asm
+++ b/src/prologue.asm
@@ -83,7 +83,7 @@ Ppu_PrologueTextRow3Start = Ppu_Nametable0_sName + sName::Tiles_u8_arr + \
jsr Func_ClearRestOfOam
;; Disable audio.
lda #0
- sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
jsr Func_ProcessFrame
;; Clear the upper nametable.
ldxy #Ppu_Nametable0_sName ; param: nametable addr
diff --git a/src/room.asm b/src/room.asm
index 2a5e81e8..3bcefe30 100644
--- a/src/room.asm
+++ b/src/room.asm
@@ -251,6 +251,19 @@ Zp_RoomState: .res kRoomStateSize
.SEGMENT "PRG8"
+;;; Enables audio and sets the music volume according to the current room's
+;;; bRoom::ReduceMusic flag.
+.EXPORT Func_SetMusicVolumeForCurrentRoom
+.PROC Func_SetMusicVolumeForCurrentRoom
+ lda Zp_Current_sRoom + sRoom::Flags_bRoom
+ and #bRoom::ReduceMusic
+ .assert bRoom::ReduceMusic << 1 = bAudio::ReduceMusic, error
+ asl a
+ ora #bAudio::Enable
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
+ rts
+.ENDPROC
+
;;; Queues up the music for the specified room (if it's not already playing),
;;; switches PRGC banks, then loads and initializes data for the room.
;;; @prereq Rendering is disabled.
@@ -641,13 +654,13 @@ _PrisonMusic:
cpy Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic
beq @done
lda #0
- sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
sty T1 ; eMusic to play
stx T0
jsr Func_ProcessFrame ; preserves T0+
ldx T0
- lda #$ff
- sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool
+ lda #bAudio::Enable
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
lda T1 ; eMusic to play
sta Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic
@done:
@@ -889,7 +902,7 @@ _SetVars:
stx Zp_AvatarPlatformIndex_u8
stx Zp_ConsoleMachineIndex_u8
stx Zp_FloatingHud_bHud ; disable the floating HUD
- rts
+ jmp Func_SetMusicVolumeForCurrentRoom
.ENDPROC
;;; Calls the current room's Tick_func_ptr function.
diff --git a/src/room.inc b/src/room.inc
index 40a94964..aa612cb0 100644
--- a/src/room.inc
+++ b/src/room.inc
@@ -210,10 +210,20 @@ kMaxPassages = 8
;;; Flag bits for a room.
.SCOPE bRoom
- Unsafe = %10000000 ; while set, this room won't be set as spawn point
- Tall = %01000000 ; if set, room is kTallRoomHeightBlocks blocks tall
- ShareState = %00100000 ; don't zero room state between two rooms with this
- AreaMask = %00001111 ; mask for this room's eArea value
+ ;; When set, passages and devices in this room won't be set as safe spawn
+ ;; points. This can be dynamically disabled for a room (e.g. when a boss
+ ;; is defeated) by calling Func_MarkRoomSafe.
+ Unsafe = %10000000
+ ;; If set, this room's terrain is kTallRoomHeightBlocks blocks tall instead
+ ;; of kScreenHeightBlocks blocks tall.
+ Tall = %01000000
+ ;; If set, music is played at a reduced volume in this room.
+ ReduceMusic = %00100000
+ ;; If two rooms both have this bit set, then Zp_RoomState will not be
+ ;; zeroed by default when moving directly between those two rooms.
+ ShareState = %00010000
+ ;; Bits used for storing this room's eArea value.
+ AreaMask = %00001111
.ENDSCOPE
;;; Assert that an eArea value will fit into the AreaMask.
diff --git a/src/rooms/city_building1.asm b/src/rooms/city_building1.asm
index 13c399e4..3cfb0e99 100644
--- a/src/rooms/city_building1.asm
+++ b/src/rooms/city_building1.asm
@@ -38,7 +38,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::City
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::City
d_byte MinimapStartRow_u8, 2
d_byte MinimapStartCol_u8, 17
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/city_building2.asm b/src/rooms/city_building2.asm
index 3bdd2e79..b4071f5f 100644
--- a/src/rooms/city_building2.asm
+++ b/src/rooms/city_building2.asm
@@ -69,7 +69,7 @@ kPerDigitSpinFrames = 10
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, bRoom::ShareState | eArea::City
+ d_byte Flags_bRoom, bRoom::ReduceMusic | bRoom::ShareState | eArea::City
d_byte MinimapStartRow_u8, 1
d_byte MinimapStartCol_u8, 19
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/city_building3.asm b/src/rooms/city_building3.asm
index 6e75bf16..daa924ec 100644
--- a/src/rooms/city_building3.asm
+++ b/src/rooms/city_building3.asm
@@ -145,7 +145,7 @@ kLeverRightDeviceIndex = 1
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::City
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::City
d_byte MinimapStartRow_u8, 2
d_byte MinimapStartCol_u8, 19
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/city_building4.asm b/src/rooms/city_building4.asm
index 9eb159d2..02f16b68 100644
--- a/src/rooms/city_building4.asm
+++ b/src/rooms/city_building4.asm
@@ -38,7 +38,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, bRoom::Tall | eArea::City
+ d_byte Flags_bRoom, bRoom::Tall | bRoom::ReduceMusic | eArea::City
d_byte MinimapStartRow_u8, 1
d_byte MinimapStartCol_u8, 20
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/city_building5.asm b/src/rooms/city_building5.asm
index 2f30908d..c3f7bdd6 100644
--- a/src/rooms/city_building5.asm
+++ b/src/rooms/city_building5.asm
@@ -38,7 +38,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::City
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::City
d_byte MinimapStartRow_u8, 2
d_byte MinimapStartCol_u8, 21
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/city_building6.asm b/src/rooms/city_building6.asm
index f4749007..0fc6187a 100644
--- a/src/rooms/city_building6.asm
+++ b/src/rooms/city_building6.asm
@@ -49,7 +49,7 @@ kLockedDoorDeviceIndex = 1
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, bRoom::Tall | eArea::City
+ d_byte Flags_bRoom, bRoom::Tall | bRoom::ReduceMusic | eArea::City
d_byte MinimapStartRow_u8, 1
d_byte MinimapStartCol_u8, 22
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/city_building7.asm b/src/rooms/city_building7.asm
index d7e2b8ea..0d5a1491 100644
--- a/src/rooms/city_building7.asm
+++ b/src/rooms/city_building7.asm
@@ -36,7 +36,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::City
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::City
d_byte MinimapStartRow_u8, 3
d_byte MinimapStartCol_u8, 23
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/city_flower.asm b/src/rooms/city_flower.asm
index 5f3072ff..dbd0f578 100644
--- a/src/rooms/city_flower.asm
+++ b/src/rooms/city_flower.asm
@@ -64,7 +64,7 @@ kOrcDeviceIndexRight = 1
D_STRUCT sRoom
d_byte MinScrollX_u8, $00
d_word MaxScrollX_u16, $00
- d_byte Flags_bRoom, bRoom::Unsafe | eArea::City
+ d_byte Flags_bRoom, bRoom::Unsafe | bRoom::ReduceMusic | eArea::City
d_byte MinimapStartRow_u8, 3
d_byte MinimapStartCol_u8, 20
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/mermaid_cellar.asm b/src/rooms/mermaid_cellar.asm
index 213e4dd8..61c8cf96 100644
--- a/src/rooms/mermaid_cellar.asm
+++ b/src/rooms/mermaid_cellar.asm
@@ -48,7 +48,7 @@ kUpgradeFlag = eFlag::UpgradeOpBeep
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Mermaid
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Mermaid
d_byte MinimapStartRow_u8, 11
d_byte MinimapStartCol_u8, 12
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/mermaid_hut1.asm b/src/rooms/mermaid_hut1.asm
index 31a1bd48..e42e5ba1 100644
--- a/src/rooms/mermaid_hut1.asm
+++ b/src/rooms/mermaid_hut1.asm
@@ -98,7 +98,7 @@ kEireneActorIndex = 2
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Mermaid
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Mermaid
d_byte MinimapStartRow_u8, 10
d_byte MinimapStartCol_u8, 12
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/mermaid_hut2.asm b/src/rooms/mermaid_hut2.asm
index fa6ed5dd..bc91225a 100644
--- a/src/rooms/mermaid_hut2.asm
+++ b/src/rooms/mermaid_hut2.asm
@@ -43,7 +43,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Mermaid
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Mermaid
d_byte MinimapStartRow_u8, 10
d_byte MinimapStartCol_u8, 13
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/mermaid_hut3.asm b/src/rooms/mermaid_hut3.asm
index 09baf540..345ffa0e 100644
--- a/src/rooms/mermaid_hut3.asm
+++ b/src/rooms/mermaid_hut3.asm
@@ -44,7 +44,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Mermaid
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Mermaid
d_byte MinimapStartRow_u8, 11
d_byte MinimapStartCol_u8, 11
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/mermaid_hut5.asm b/src/rooms/mermaid_hut5.asm
index 3cbed799..c9a66ead 100644
--- a/src/rooms/mermaid_hut5.asm
+++ b/src/rooms/mermaid_hut5.asm
@@ -63,7 +63,7 @@ kNinaActorIndex = 2
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Mermaid
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Mermaid
d_byte MinimapStartRow_u8, 11
d_byte MinimapStartCol_u8, 13
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/town_house1.asm b/src/rooms/town_house1.asm
index 19ff8853..be73b1b6 100644
--- a/src/rooms/town_house1.asm
+++ b/src/rooms/town_house1.asm
@@ -41,7 +41,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Town
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Town
d_byte MinimapStartRow_u8, 0
d_byte MinimapStartCol_u8, 11
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/town_house2.asm b/src/rooms/town_house2.asm
index f4cf311f..b3da11a2 100644
--- a/src/rooms/town_house2.asm
+++ b/src/rooms/town_house2.asm
@@ -62,7 +62,7 @@ kAnnaSleepPositionY = $c1
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Town
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Town
d_byte MinimapStartRow_u8, 0
d_byte MinimapStartCol_u8, 11
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/town_house3.asm b/src/rooms/town_house3.asm
index 39d1a0e7..87048797 100644
--- a/src/rooms/town_house3.asm
+++ b/src/rooms/town_house3.asm
@@ -60,7 +60,7 @@ kSmithActorIndex = 0
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Town
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Town
d_byte MinimapStartRow_u8, 0
d_byte MinimapStartCol_u8, 12
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/town_house4.asm b/src/rooms/town_house4.asm
index 04ee086d..7faa2028 100644
--- a/src/rooms/town_house4.asm
+++ b/src/rooms/town_house4.asm
@@ -72,7 +72,7 @@ kHobokActorIndex = 3
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Town
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Town
d_byte MinimapStartRow_u8, 0
d_byte MinimapStartCol_u8, 13
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/town_house5.asm b/src/rooms/town_house5.asm
index 7c6cf03f..373bfb8b 100644
--- a/src/rooms/town_house5.asm
+++ b/src/rooms/town_house5.asm
@@ -44,7 +44,7 @@
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Town
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Town
d_byte MinimapStartRow_u8, 0
d_byte MinimapStartCol_u8, 14
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/rooms/town_house6.asm b/src/rooms/town_house6.asm
index e5cd2514..5ab5ce00 100644
--- a/src/rooms/town_house6.asm
+++ b/src/rooms/town_house6.asm
@@ -60,7 +60,7 @@ kElderActorIndex = 0
D_STRUCT sRoom
d_byte MinScrollX_u8, $0
d_word MaxScrollX_u16, $0
- d_byte Flags_bRoom, eArea::Town
+ d_byte Flags_bRoom, bRoom::ReduceMusic | eArea::Town
d_byte MinimapStartRow_u8, 0
d_byte MinimapStartCol_u8, 15
d_addr TerrainData_ptr, _TerrainData
diff --git a/src/title.asm b/src/title.asm
index a50e1a11..eed79db8 100644
--- a/src/title.asm
+++ b/src/title.asm
@@ -456,9 +456,8 @@ _BeginNewGame:
lda #<.bank(Ppu_ChrBgFontUpper)
sta Zp_Chr04Bank_u8
_StartMusic:
- lda #$ff
- sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool
- sta Zp_Next_sAudioCtrl + sAudioCtrl::MasterVolume_u8
+ lda #bAudio::Enable
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
lda #eMusic::Title
sta Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic
_ClearNametables:
diff --git a/src/upgrade.asm b/src/upgrade.asm
index 5fdc2ce8..9b801a90 100644
--- a/src/upgrade.asm
+++ b/src/upgrade.asm
@@ -54,6 +54,7 @@
.IMPORT Func_AllocObjects
.IMPORT Func_SetFlag
.IMPORT Func_SetLastSpawnPointToActiveDevice
+.IMPORT Func_SetMusicVolumeForCurrentRoom
.IMPORT Func_Window_PrepareRowTransfer
.IMPORT Func_Window_ScrollDown
.IMPORT Func_Window_ScrollUp
@@ -165,6 +166,7 @@ _UpdateScrolling:
_ResumeExploring:
lda Zp_UpgradePrev_eMusic
sta Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic
+ jsr Func_SetMusicVolumeForCurrentRoom
jmp Main_Explore_Continue
.ENDPROC
@@ -225,6 +227,9 @@ _StartMusic:
sta Zp_UpgradePrev_eMusic
lda #eMusic::Upgrade
sta Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic
+ ;; Set music to full volume (no ReduceMusic flag).
+ lda #bAudio::Enable
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
_CollectUpgrade:
jsr Func_SetLastSpawnPointToActiveDevice
lda Zp_Nearby_bDevice
diff --git a/tests/audio.asm b/tests/audio.asm
index ec4eb22a..2249bbdb 100644
--- a/tests/audio.asm
+++ b/tests/audio.asm
@@ -142,9 +142,8 @@ ResetAudio:
ldy #$00
jsr Func_ExpectAEqualsY
EnableAndStartMusic:
- lda #$ff
- sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool
- sta Zp_Next_sAudioCtrl + sAudioCtrl::MasterVolume_u8
+ lda #bAudio::Enable
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
lda #bMusic::UsesFlag
sta Zp_Next_sAudioCtrl + sAudioCtrl::MusicFlag_bMusic
lda #0
@@ -189,8 +188,8 @@ PlayMusic:
ldy #0
jsr Func_ExpectAEqualsY
DisableAudio:
- lda #$00
- sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool
+ lda #0
+ sta Zp_Next_sAudioCtrl + sAudioCtrl::Next_bAudio
jsr Func_AudioSync
lda Hw_ApuStatus_rw
ldy #0