From 11bc2afe5f93330b676eb950d48541e62b52abe0 Mon Sep 17 00:00:00 2001 From: "Matthew D. Steele" Date: Sat, 14 Sep 2024 17:14:26 -0400 Subject: [PATCH] Add music for orc attack in TownOutdoors --- nsf/nsf.cfg | 1 + src/audio.asm | 22 +++++++++---------- src/music.asm | 2 ++ src/music.inc | 1 + src/music/attack.sng | 42 ++++++++++++++++++++++++++++++++++++ src/nmi.asm | 4 ++++ src/room.asm | 43 +++++++++++++++++++++---------------- src/rooms/temple_foyer.asm | 2 +- src/rooms/town_outdoors.asm | 12 +++++++++++ 9 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 src/music/attack.sng diff --git a/nsf/nsf.cfg b/nsf/nsf.cfg index 25937d46..3a08c3ba 100644 --- a/nsf/nsf.cfg +++ b/nsf/nsf.cfg @@ -50,6 +50,7 @@ SEGMENTS { PRGC_Prison: load=PRG, type=ro; PRGC_Temple: load=PRG, type=ro; PRGC_Title: load=PRG, type=ro; + PRGC_Town: load=PRG, type=ro; # Sample data: PRGE_InstSample: load=SMP, type=ro, align=$40; } diff --git a/src/audio.asm b/src/audio.asm index f5169cd7..b01a422c 100644 --- a/src/audio.asm +++ b/src/audio.asm @@ -266,18 +266,11 @@ _CopyMusicStruct: .assert .sizeof(sMusic) <= $80, error bpl @loop _ResetChannels: - ldx #0 - stx Zp_MusicOpcodeIndex_u8 - @loop: - lda #Data_Empty_bChain_arr - sta Zp_Music_sChanNext_arr + sChanNext::Next_bChain_ptr + 1, x - lda #Data_Empty_sPhrase - sta Zp_Music_sChanNext_arr + sChanNext::PhraseNext_ptr + 1, x lda #0 + sta Zp_MusicOpcodeIndex_u8 + tax ; now X is zero + @loop: + ;; At this point, A is still zero. sta Ram_Music_sChanNote_arr + sChanNote::ElapsedFrames_u8, x sta Ram_Music_sChanNote_arr + sChanNote::DurationFrames_u8, x sta Ram_Music_sChanNote_arr + sChanNote::TimerLo_byte, x @@ -285,6 +278,13 @@ _ResetChannels: sta Ram_Music_sChanInst_arr + sChanInst::Instrument_eInst, x sta Ram_Music_sChanInst_arr + sChanInst::Param_byte, x sta Ram_Music_sChanInst_arr + sChanInst::RepeatCount_u8, x + .assert Data_Empty_bChain_arr = Data_Empty_sPhrase, error + ldy #Data_Empty_bChain_arr + sty Zp_Music_sChanNext_arr + sChanNext::Next_bChain_ptr + 1, x + sty Zp_Music_sChanNext_arr + sChanNext::PhraseNext_ptr + 1, x .repeat .sizeof(sChanNext) inx .endrepeat diff --git a/src/music.asm b/src/music.asm index 2f1c24ef..0d3a94f7 100644 --- a/src/music.asm +++ b/src/music.asm @@ -30,6 +30,7 @@ .IMPORT DataC_Temple_TemplePlaceholder_sMusic .IMPORT DataC_Title_Credits_sMusic .IMPORT DataC_Title_Title_sMusic +.IMPORT DataC_Town_Attack_sMusic .IMPORT Data_Calm_sMusic .IMPORT Data_Empty_bMusic_arr .IMPORT Data_Upgrade_sMusic @@ -46,6 +47,7 @@ D_TABLE_HI table, Data_Music_sMusic_ptr_1_arr D_TABLE .enum, eMusic d_entry table, Silence, Data_Silence_sMusic + d_entry table, Attack, DataC_Town_Attack_sMusic d_entry table, Boss1, DataC_Boss_BossPlaceholder_sMusic d_entry table, Boss2, DataC_Core_Boss2_sMusic d_entry table, Calm, Data_Calm_sMusic diff --git a/src/music.inc b/src/music.inc index f0b3fdde..30689230 100644 --- a/src/music.inc +++ b/src/music.inc @@ -20,6 +20,7 @@ ;;; Music songs that can be played. .ENUM eMusic Silence + Attack Boss1 Boss2 Calm diff --git a/src/music/attack.sng b/src/music/attack.sng new file mode 100644 index 00000000..c64ca80e --- /dev/null +++ b/src/music/attack.sng @@ -0,0 +1,42 @@ +@PRGC_Town + +!DPCM K Data_SampleKickDrum_arr657 657 + +!SONG Attack "aA ?1b A ?1b A bB ?0a C" + +=tempo q28 +=key 3# % F# minor + +!INST 1A PulseBasic $0c d3/4 +!INST 1E PulseBasic $0a d1/8 % echo 1 +!INST 1F PulseBasic $07 d1/8 % echo 2 +!INST 1G PulseBasic $04 d1/8 % echo 3 +!INST 2A PulseBasic $0c d1/8 +!INST 2B Constant $0a d1/8 +!INST TK TriangleDrum $20 % kick drum +!INST ND Staccato $0c +!INST DK Constant $4e % kick drum + +!PART A + +1| p(iA c5e c ' ds de ds)1A ' c5e c ' dq | +2| p(iA c4e c ' ds de ds)2A ' c4e c ' dq | +T| iK c4e re ' e4e re :2 | +N| iD x1e x6 ' x3s x3e x3s :2 | +D| p(iK sK13h)DK :2 | + +!PART B + +1| p1A ' f5s fN e d ' c bv a g | +2| p2A ' iB f4s fN e d ' c bv a g | +T=:AT +N=:AN +D=:AD + +!PART C + +1| iA f4e re ' iE f3e re ' iF f3e re ' iG f3e | +2| iB f3e ' +T| iK c4e ' +N| iD xAe ' +D| pDK ' diff --git a/src/nmi.asm b/src/nmi.asm index ce4fd852..645285be 100644 --- a/src/nmi.asm +++ b/src/nmi.asm @@ -159,6 +159,10 @@ _DoneUpdatingPpu: stax Zp_NextIrq_int_ptr ;; Everything up until this point *must* finish before VBlank ends, while ;; everything after this point is safe to extend past the VBlank period. + ;; Just in case it does, we'll re-enable IRQs for the remainder of this NMI + ;; handler, so that HBlank interrupts can still happen while we're working + ;; on e.g. audio processing. + cli _AfterVBlank: ;; These updates should only happen this frame if the main thread was ready ;; for this NMI, but unlike the above, they don't need to happen during diff --git a/src/room.asm b/src/room.asm index 52e1cf37..67df40e9 100644 --- a/src/room.asm +++ b/src/room.asm @@ -270,25 +270,8 @@ Zp_RoomState: .res kRoomStateSize ;;; @param Y The eMusic value for the music to play in the new room. .EXPORT FuncM_SwitchPrgcAndLoadRoomWithMusic .PROC FuncM_SwitchPrgcAndLoadRoomWithMusic -_ChangeMusicIfNeeded: - ;; If the music will be different in the new room, then we need to disable - ;; audio before performing the PRGC bank switch (since the old music may be - ;; in the old PRGC bank). - cpy Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic - beq @done - sty Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic - lda #0 - sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool - txa ; eRoom to load - pha ; eRoom to load - jsr Func_ProcessFrame - lda #$ff - sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool - pla ; eRoom to load - tax ; eRoom to load - @done: -_LoadNewRoom: main_prga_bank DataA_Room_Banks_u8_arr + jsr FuncA_Room_ChangeMusicIfNeeded ; preserves X main_prgc DataA_Room_Banks_u8_arr, x jmp FuncA_Room_Load .ENDPROC @@ -647,6 +630,30 @@ _PrisonMusic: D_END .ENDPROC +;;; If the specified music is different than what's currently playing, disables +;;; the audio system (processing an extra frame to do so), then sets up +;;; Zp_Next_sAudioCtrl to re-enable the audio system and play the new music +;;; next frame. +;;; @prereq Rendering is disabled. +;;; @param Y The eMusic value for the music to play in the new room. +;;; @preserve X +.PROC FuncA_Room_ChangeMusicIfNeeded + cpy Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic + beq @done + lda #0 + sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool + sty T1 ; eMusic to play + stx T0 + jsr Func_ProcessFrame ; preserves T0+ + ldx T0 + lda #$ff + sta Zp_Next_sAudioCtrl + sAudioCtrl::Enable_bool + lda T1 ; eMusic to play + sta Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic + @done: + rts +.ENDPROC + ;;; Loads and initializes data for the specified room. ;;; @prereq Zp_Current_eRoom and Zp_Current_sRoom are initialized. ;;; @prereq The correct PRGC bank has been set for the new room to be loaded. diff --git a/src/rooms/temple_foyer.asm b/src/rooms/temple_foyer.asm index eecd8d3b..9fe4be7e 100644 --- a/src/rooms/temple_foyer.asm +++ b/src/rooms/temple_foyer.asm @@ -232,7 +232,7 @@ _Passages_sPassage_arr: .PROC FuncC_Temple_Foyer_EnterRoom ;; Clear the music flag. - lda #bMusic::UsesFlag + lda #bMusic::UsesFlag | 0 sta Zp_Next_sAudioCtrl + sAudioCtrl::MusicFlag_bMusic ;; Remove the upgrade if it's already been collected. flag_bit Sram_ProgressFlags_arr, kUpgradeFlag diff --git a/src/rooms/town_outdoors.asm b/src/rooms/town_outdoors.asm index a518cfc1..63bd1872 100644 --- a/src/rooms/town_outdoors.asm +++ b/src/rooms/town_outdoors.asm @@ -21,6 +21,7 @@ .INCLUDE "../actors/adult.inc" .INCLUDE "../actors/child.inc" .INCLUDE "../actors/orc.inc" +.INCLUDE "../audio.inc" .INCLUDE "../avatar.inc" .INCLUDE "../cpu.inc" .INCLUDE "../cutscene.inc" @@ -29,6 +30,7 @@ .INCLUDE "../irq.inc" .INCLUDE "../macros.inc" .INCLUDE "../mmc3.inc" +.INCLUDE "../music.inc" .INCLUDE "../oam.inc" .INCLUDE "../platform.inc" .INCLUDE "../portrait.inc" @@ -86,6 +88,7 @@ .IMPORTZP Zp_Camera_bScroll .IMPORTZP Zp_NextIrq_int_ptr .IMPORTZP Zp_Next_eCutscene +.IMPORTZP Zp_Next_sAudioCtrl .IMPORTZP Zp_PpuScrollX_u8 .IMPORTZP Zp_RoomScrollX_u16 .IMPORTZP Zp_RoomScrollY_u8 @@ -309,6 +312,8 @@ _DetectAvatarDeath: lda #0 sta Zp_AvatarHarmTimer_u8 jsr Func_HarmAvatar + lda #bMusic::UsesFlag | bMusic::FlagMask + sta Zp_Next_sAudioCtrl + sAudioCtrl::MusicFlag_bMusic lda #eCutscene::TownOutdoorsGetCaught sta Zp_Next_eCutscene @done: @@ -395,6 +400,7 @@ _AlexStanding: dlg_Text ChildAlex, DataA_Text0_TownOutdoorsAlex3_WhaWhat_u8_arr dlg_Call _RaiseGrontaArms dlg_Text OrcGrontaShout, DataA_Text0_TownOutdoorsAlex3_Attack1_u8_arr + dlg_Call _StartAttackMusic dlg_Text ChildAlexShout, DataA_Text0_TownOutdoorsAlex3_Attack2_u8_arr dlg_Call _MakeOrcGruntsJump dlg_Done @@ -412,6 +418,12 @@ _RaiseGrontaArms: lda #eNpcOrc::GrontaArmsRaised sta Ram_ActorState1_byte_arr + kGrontaActorIndex rts +_StartAttackMusic: + lda #eMusic::Attack + sta Zp_Next_sAudioCtrl + sAudioCtrl::Music_eMusic + lda #bMusic::UsesFlag | 0 + sta Zp_Next_sAudioCtrl + sAudioCtrl::MusicFlag_bMusic + rts _MakeOrcGruntsJump: lda #30 sta Zp_RoomState + sState::OrcJumpTimer_u8