summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIIMarckus <iimarckus@gmail.com>2019-08-16 01:03:03 -0600
committerIIMarckus <iimarckus@gmail.com>2019-08-16 01:03:03 -0600
commit2176239aa565126b528facc9041ed3b58eaade90 (patch)
tree4589377cff104542abb2ee309496b5e4786eb59f
parent901e6f25deda73fa7053942d7d094108a73e2bea (diff)
Incorporate the rest of the audio engine.
-rw-r--r--audio/cry_pointers.asm69
-rw-r--r--audio/drumkits.asm261
-rw-r--r--audio/engine.asm2850
-rwxr-xr-xaudio/music_pointers.asm189
-rw-r--r--audio/notes.asm26
-rw-r--r--audio/sfx_pointers.asm190
-rw-r--r--audio/wave_samples.asm13
-rwxr-xr-xconstants/audio_constants.asm163
-rw-r--r--data/trainers/encounter_music.asm75
-rwxr-xr-xengine/events/overworld.asm8
-rwxr-xr-xengine/main_menu.asm2
-rwxr-xr-xengine/overworld/player_movement.asm10
-rwxr-xr-xengine/specials.asm2
-rwxr-xr-xengine/variables.asm2
-rw-r--r--home/audio.asm58
-rw-r--r--home/cry.asm9
-rw-r--r--home/init.asm4
-rw-r--r--home/text.asm2
-rw-r--r--home/vblank.asm24
-rwxr-xr-xitems/item_effects.asm8
-rw-r--r--macros.asm51
-rw-r--r--macros/code.asm106
-rwxr-xr-xmacros/wram.asm24
-rw-r--r--main.asm67
-rw-r--r--wram.asm6
25 files changed, 3930 insertions, 289 deletions
diff --git a/audio/cry_pointers.asm b/audio/cry_pointers.asm
new file mode 100644
index 00000000..ec6b17e0
--- /dev/null
+++ b/audio/cry_pointers.asm
@@ -0,0 +1,69 @@
+Cries:
+ dba Cry_Nidoran_M
+ dba Cry_Nidoran_F
+ dba Cry_Slowpoke
+ dba Cry_Kangaskhan
+ dba Cry_Charmander
+ dba Cry_Grimer
+ dba Cry_Voltorb
+ dba Cry_Muk
+ dba Cry_Oddish
+ dba Cry_Raichu
+ dba Cry_Nidoqueen
+ dba Cry_Diglett
+ dba Cry_Seel
+ dba Cry_Drowzee
+ dba Cry_Pidgey
+ dba Cry_Bulbasaur
+ dba Cry_Spearow
+ dba Cry_Rhydon
+ dba Cry_Golem
+ dba Cry_Blastoise
+ dba Cry_Pidgeotto
+ dba Cry_Weedle
+ dba Cry_Caterpie
+ dba Cry_Ekans
+ dba Cry_Fearow
+ dba Cry_Clefairy
+ dba Cry_Venonat
+ dba Cry_Lapras
+ dba Cry_Metapod
+ dba Cry_Squirtle
+ dba Cry_Paras
+ dba Cry_Growlithe
+ dba Cry_Krabby
+ dba Cry_Psyduck
+ dba Cry_Rattata
+ dba Cry_Vileplume
+ dba Cry_Vulpix
+ dba Cry_Weepinbell
+ dba Cry_Marill
+ dba Cry_Spinarak
+ dba Cry_Togepi
+ dba Cry_Girafarig
+ dba Cry_Raikou
+ dba Cry_Mareep
+ dba Cry_Togetic
+ dba Cry_Hoothoot
+ dba Cry_Sentret
+ dba Cry_Slowking
+ dba Cry_Cyndaquil
+ dba Cry_Chikorita
+ dba Cry_Totodile
+ dba Cry_Gligar
+ dba Cry_Cleffa
+ dba Cry_Slugma
+ dba Cry_Ledyba
+ dba Cry_Entei
+ dba Cry_Wooper
+ dba Cry_Mantine
+ dba Cry_Typhlosion
+ dba Cry_Natu
+ dba Cry_Teddiursa
+ dba Cry_Sunflora
+ dba Cry_Ampharos
+ dba Cry_Magcargo
+ dba Cry_Pichu
+ dba Cry_Aipom
+ dba Cry_Dunsparce
+ dba Cry_Donphan
diff --git a/audio/drumkits.asm b/audio/drumkits.asm
new file mode 100644
index 00000000..a4fa4109
--- /dev/null
+++ b/audio/drumkits.asm
@@ -0,0 +1,261 @@
+Drumkits:
+ dw Drumkit0
+ dw Drumkit1
+ dw Drumkit2
+ dw Drumkit3
+ dw Drumkit4
+ dw Drumkit5
+
+Drumkit0:
+ dw Drum00 ; rest
+ dw Snare1 ; c
+ dw Snare2 ; c#
+ dw Snare3 ; d
+ dw Snare4 ; d#
+ dw Drum05 ; e
+ dw Triangle1 ; f
+ dw Triangle2 ; f#
+ dw HiHat1 ; g
+ dw Snare5 ; g#
+ dw Snare6 ; a
+ dw Snare7 ; a#
+ dw HiHat2 ; b
+Drumkit1:
+ dw Drum00
+ dw HiHat1
+ dw Snare5
+ dw Snare6
+ dw Snare7
+ dw HiHat2
+ dw HiHat3
+ dw Snare8
+ dw Triangle3
+ dw Triangle4
+ dw Snare9
+ dw Snare10
+ dw Snare11
+Drumkit2:
+ dw Drum00
+ dw Snare1
+ dw Snare9
+ dw Snare10
+ dw Snare11
+ dw Drum05
+ dw Triangle1
+ dw Triangle2
+ dw HiHat1
+ dw Snare5
+ dw Snare6
+ dw Snare7
+ dw HiHat2
+Drumkit3:
+ dw Drum21
+ dw Snare12
+ dw Snare13
+ dw Snare14
+ dw Kick1
+ dw Triangle5
+ dw Drum20
+ dw Drum27
+ dw Drum28
+ dw Drum29
+ dw Drum21
+ dw Kick2
+ dw Crash2
+Drumkit4:
+ dw Drum21
+ dw Drum20
+ dw Snare13
+ dw Snare14
+ dw Kick1
+ dw Drum33
+ dw Triangle5
+ dw Drum35
+ dw Drum31
+ dw Drum32
+ dw Drum36
+ dw Kick2
+ dw Crash1
+Drumkit5:
+ dw Drum00
+ dw Snare9
+ dw Snare10
+ dw Snare11
+ dw Drum27
+ dw Drum28
+ dw Drum29
+ dw Drum05
+ dw Triangle1
+ dw Crash1
+ dw Snare14
+ dw Snare13
+ dw Kick2
+
+Drum00:
+; unused
+ noise C#, 1, $11, $00
+ endchannel
+
+Snare1:
+ noise C#, 1, $c1, $33
+ endchannel
+
+Snare2:
+ noise C#, 1, $b1, $33
+ endchannel
+
+Snare3:
+ noise C#, 1, $a1, $33
+ endchannel
+
+Snare4:
+ noise C#, 1, $81, $33
+ endchannel
+
+Drum05:
+ noise C#, 8, $84, $37
+ noise C#, 7, $84, $36
+ noise C#, 6, $83, $35
+ noise C#, 5, $83, $34
+ noise C#, 4, $82, $33
+ noise C#, 3, $81, $32
+ endchannel
+
+Triangle1:
+ noise C#, 1, $51, $2a
+ endchannel
+
+Triangle2:
+ noise C#, 2, $41, $2b
+ noise C#, 1, $61, $2a
+ endchannel
+
+HiHat1:
+ noise C#, 1, $81, $10
+ endchannel
+
+Snare5:
+ noise C#, 1, $82, $23
+ endchannel
+
+Snare6:
+ noise C#, 1, $82, $25
+ endchannel
+
+Snare7:
+ noise C#, 1, $82, $26
+ endchannel
+
+HiHat2:
+ noise C#, 1, $a1, $10
+ endchannel
+
+HiHat3:
+ noise C#, 1, $a2, $11
+ endchannel
+
+Snare8:
+ noise C#, 1, $a2, $50
+ endchannel
+
+Triangle3:
+ noise C#, 1, $a1, $18
+ noise C#, 1, $31, $33
+ endchannel
+
+Triangle4:
+ noise C#, 3, $91, $28
+ noise C#, 1, $71, $18
+ endchannel
+
+Snare9:
+ noise C#, 1, $91, $22
+ endchannel
+
+Snare10:
+ noise C#, 1, $71, $22
+ endchannel
+
+Snare11:
+ noise C#, 1, $61, $22
+ endchannel
+
+Drum20:
+ noise C#, 1, $11, $11
+ endchannel
+
+Drum21:
+ endchannel
+
+Snare12:
+ noise C#, 1, $91, $33
+ endchannel
+
+Snare13:
+ noise C#, 1, $51, $32
+ endchannel
+
+Snare14:
+ noise C#, 1, $81, $31
+ endchannel
+
+Kick1:
+ noise C#, 1, $88, $6b
+ noise C#, 1, $71, $00
+ endchannel
+
+Triangle5:
+ noise D_, 1, $91, $18
+ endchannel
+
+Drum27:
+ noise C#, 8, $92, $10
+ endchannel
+
+Drum28:
+ noise D_, 4, $91, $00
+ noise D_, 4, $11, $00
+ endchannel
+
+Drum29:
+ noise D_, 4, $91, $11
+ noise D_, 4, $11, $00
+ endchannel
+
+Crash1:
+ noise D_, 4, $88, $15
+ noise C#, 1, $65, $12
+ endchannel
+
+Drum31:
+ noise D_, 4, $51, $21
+ noise D_, 4, $11, $11
+ endchannel
+
+Drum32:
+ noise D_, 4, $51, $50
+ noise D_, 4, $11, $11
+ endchannel
+
+Drum33:
+ noise C#, 1, $a1, $31
+ endchannel
+
+Crash2:
+ noise C#, 1, $84, $12
+ endchannel
+
+Drum35:
+ noise D_, 4, $81, $00
+ noise D_, 4, $11, $00
+ endchannel
+
+Drum36:
+ noise D_, 4, $81, $21
+ noise D_, 4, $11, $11
+ endchannel
+
+Kick2:
+ noise C#, 1, $a8, $6b
+ noise C#, 1, $71, $00
+ endchannel
diff --git a/audio/engine.asm b/audio/engine.asm
new file mode 100644
index 00000000..6b0fe1a6
--- /dev/null
+++ b/audio/engine.asm
@@ -0,0 +1,2850 @@
+; The entire sound engine. Uses section "audio" in WRAM.
+
+; Interfaces are in bank 0.
+
+; Notable functions:
+; FadeMusic
+; PlayStereoSFX
+
+_MapSetup_Sound_Off::
+; restart sound operation
+; clear all relevant hardware registers & wram
+ push hl
+ push de
+ push bc
+ push af
+ call MusicOff
+ ld hl, rNR50 ; channel control registers
+ xor a
+ ld [hli], a ; rNR50 ; volume/vin
+ ld [hli], a ; rNR51 ; sfx channels
+ ld a, $80 ; all channels on
+ ld [hli], a ; ff26 ; music channels
+
+ ld hl, rNR10 ; sound channel registers
+ ld e, NUM_MUSIC_CHANS
+.clearsound
+; sound channel 1 2 3 4
+ xor a
+ ld [hli], a ; rNR10, rNR20, rNR30, rNR40 ; sweep = 0
+
+ ld [hli], a ; rNR11, rNR21, rNR31, rNR41 ; length/wavepattern = 0
+ ld a, $8
+ ld [hli], a ; rNR12, rNR22, rNR32, rNR42 ; envelope = 0
+ xor a
+ ld [hli], a ; rNR13, rNR23, rNR33, rNR43 ; frequency lo = 0
+ ld a, $80
+ ld [hli], a ; rNR14, rNR24, rNR34, rNR44 ; restart sound (freq hi = 0)
+ dec e
+ jr nz, .clearsound
+
+ ld hl, wChannels ; start of channel data
+ ld de, wChannelsEnd - wChannels ; length of area to clear (entire sound wram area)
+.clearchannels
+ xor a
+ ld [hli], a
+ dec de
+ ld a, e
+ or d
+ jr nz, .clearchannels
+ ld a, MAX_VOLUME
+ ld [wVolume], a
+ call MusicOn
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+
+MusicFadeRestart:
+; restart but keep the music id to fade in to
+ ld a, [wMusicFadeID + 1]
+ push af
+ ld a, [wMusicFadeID]
+ push af
+ call _MapSetup_Sound_Off
+ pop af
+ ld [wMusicFadeID], a
+ pop af
+ ld [wMusicFadeID + 1], a
+ ret
+
+MusicOn:
+ ld a, 1
+ ld [wMusicPlaying], a
+ ret
+
+MusicOff:
+ xor a
+ ld [wMusicPlaying], a
+ ret
+
+_UpdateSound::
+; called once per frame
+ ; no use updating audio if it's not playing
+ ld a, [wMusicPlaying]
+ and a
+ ret z
+ ; start at ch1
+ xor a
+ ld [wCurChannel], a ; just
+ ld [wSoundOutput], a ; off
+ ld bc, wChannel1
+.loop
+ ; is the channel active?
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_CHANNEL_ON, [hl]
+ jp z, .nextchannel
+ ; check time left in the current note
+ ld hl, CHANNEL_NOTE_DURATION
+ add hl, bc
+ ld a, [hl]
+ cp $2 ; 1 or 0?
+ jr c, .noteover
+ dec [hl]
+ jr .continue_sound_update
+
+.noteover
+ ; reset vibrato delay
+ ld hl, CHANNEL_VIBRATO_DELAY
+ add hl, bc
+ ld a, [hl]
+ ld hl, CHANNEL_VIBRATO_DELAY_COUNT
+ add hl, bc
+ ld [hl], a
+ ; turn vibrato off for now
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ res SOUND_PITCH_WHEEL, [hl]
+ ; get next note
+ call ParseMusic
+.continue_sound_update
+ call ApplyPitchWheel
+ ; duty cycle
+ ld hl, CHANNEL_DUTY_CYCLE
+ add hl, bc
+ ld a, [hli]
+ ld [wCurTrackDuty], a
+ ; intensity
+ ld a, [hli]
+ ld [wCurTrackIntensity], a
+ ; frequency
+ ld a, [hli]
+ ld [wCurTrackFrequency], a
+ ld a, [hl]
+ ld [wCurTrackFrequency + 1], a
+ ; vibrato, noise
+ call HandleTrackVibrato ; handle vibrato and other things
+ call HandleNoise
+ ; turn off music when playing sfx?
+ ld a, [wSFXPriority]
+ and a
+ jr z, .next
+ ; are we in a sfx channel right now?
+ ld a, [wCurChannel]
+ cp NUM_MUSIC_CHANS
+ jr nc, .next
+ ; are any sfx channels active?
+ ; if so, mute
+ ld hl, wChannel5Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .restnote
+ ld hl, wChannel6Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .restnote
+ ld hl, wChannel7Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .restnote
+ ld hl, wChannel8Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr z, .next
+.restnote
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_REST, [hl] ; Rest
+.next
+ ; are we in a sfx channel right now?
+ ld a, [wCurChannel]
+ cp NUM_MUSIC_CHANS
+ jr nc, .sfx_channel
+ ld hl, CHANNEL_STRUCT_LENGTH * NUM_MUSIC_CHANS + CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .sound_channel_on
+.sfx_channel
+ call UpdateChannels
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld a, [wSoundOutput]
+ or [hl]
+ ld [wSoundOutput], a
+.sound_channel_on
+ ; clear note flags
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ xor a
+ ld [hl], a
+.nextchannel
+ ; next channel
+ ld hl, CHANNEL_STRUCT_LENGTH
+ add hl, bc
+ ld c, l
+ ld b, h
+ ld a, [wCurChannel]
+ inc a
+ ld [wCurChannel], a
+ cp NUM_CHANNELS ; are we done?
+ jp nz, .loop ; do it all again
+
+ call PlayDanger
+ ; fade music in/out
+ call FadeMusic
+ ; write volume to hardware register
+ ld a, [wVolume]
+ ldh [rNR50], a
+ ; write SO on/off to hardware register
+ ld a, [wSoundOutput]
+ ldh [rNR51], a
+ ret
+
+UpdateChannels:
+ ld hl, .ChannelFnPtrs
+ ld a, [wCurChannel]
+ and $7
+ add a
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.ChannelFnPtrs:
+ dw .Channel1
+ dw .Channel2
+ dw .Channel3
+ dw .Channel4
+; sfx ch ptrs are identical to music chs
+; ..except 5
+ dw .Channel5
+ dw .Channel6
+ dw .Channel7
+ dw .Channel8
+
+.Channel1:
+ ld a, [wLowHealthAlarm]
+ bit DANGER_ON_F, a
+ ret nz
+.Channel5:
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ bit NOTE_UNKN_3, [hl]
+ jr z, .asm_e8159
+ ;
+ ld a, [wSoundInput]
+ ldh [rNR10], a
+.asm_e8159
+ bit NOTE_REST, [hl] ; rest
+ jr nz, .ch1rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .asm_e81a2
+ bit NOTE_FREQ_OVERRIDE, [hl]
+ jr nz, .frequency_override
+ bit NOTE_VIBRATO_OVERRIDE, [hl]
+ jr nz, .asm_e8184
+ jr .check_duty_override
+
+.frequency_override
+ ld a, [wCurTrackFrequency]
+ ldh [rNR13], a
+ ld a, [wCurTrackFrequency + 1]
+ ldh [rNR14], a
+.check_duty_override
+ bit NOTE_DUTY_OVERRIDE, [hl]
+ ret z
+ ld a, [wCurTrackDuty]
+ ld d, a
+ ldh a, [rNR11]
+ and $3f ; sound length
+ or d
+ ldh [rNR11], a
+ ret
+
+.asm_e8184
+ ld a, [wCurTrackDuty]
+ ld d, a
+ ldh a, [rNR11]
+ and $3f ; sound length
+ or d
+ ldh [rNR11], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR13], a
+ ret
+
+.ch1rest
+ ldh a, [rNR52]
+ and %10001110 ; ch1 off
+ ldh [rNR52], a
+ ld hl, rNR10
+ call ClearChannel
+ ret
+
+.asm_e81a2
+ ld hl, wCurTrackDuty
+ ld a, $3f ; sound length
+ or [hl]
+ ldh [rNR11], a
+ ld a, [wCurTrackIntensity]
+ ldh [rNR12], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR13], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR14], a
+ ret
+
+.Channel2:
+.Channel6:
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ bit NOTE_REST, [hl] ; rest
+ jr nz, .ch2rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .asm_e8204
+ bit NOTE_VIBRATO_OVERRIDE, [hl]
+ jr nz, .asm_e81e6
+ bit NOTE_DUTY_OVERRIDE, [hl]
+ ret z
+ ld a, [wCurTrackDuty]
+ ld d, a
+ ldh a, [rNR21]
+ and $3f ; sound length
+ or d
+ ldh [rNR21], a
+ ret
+
+.asm_e81db ; unused
+ ld a, [wCurTrackFrequency]
+ ldh [rNR23], a
+ ld a, [wCurTrackFrequency + 1]
+ ldh [rNR24], a
+ ret
+
+.asm_e81e6
+ ld a, [wCurTrackDuty]
+ ld d, a
+ ldh a, [rNR21]
+ and $3f ; sound length
+ or d
+ ldh [rNR21], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR23], a
+ ret
+
+.ch2rest
+ ldh a, [rNR52]
+ and %10001101 ; ch2 off
+ ldh [rNR52], a
+ ld hl, rNR20
+ call ClearChannel
+ ret
+
+.asm_e8204
+ ld hl, wCurTrackDuty
+ ld a, $3f ; sound length
+ or [hl]
+ ldh [rNR21], a
+ ld a, [wCurTrackIntensity]
+ ldh [rNR22], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR23], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80 ; initial (restart)
+ ldh [rNR24], a
+ ret
+
+.Channel3:
+.Channel7:
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ bit NOTE_REST, [hl] ; rest
+ jr nz, .ch3rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .asm_e824d
+ bit NOTE_VIBRATO_OVERRIDE, [hl]
+ jr nz, .asm_e823a
+ ret
+
+.asm_e822f ; unused
+ ld a, [wCurTrackFrequency]
+ ldh [rNR33], a
+ ld a, [wCurTrackFrequency + 1]
+ ldh [rNR34], a
+ ret
+
+.asm_e823a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR33], a
+ ret
+
+.ch3rest
+ ldh a, [rNR52]
+ and %10001011 ; ch3 off
+ ldh [rNR52], a
+ ld hl, rNR30
+ call ClearChannel
+ ret
+
+.asm_e824d
+ ld a, $3f ; sound length
+ ldh [rNR31], a
+ xor a
+ ldh [rNR30], a
+ call .asm_e8268
+ ld a, $80
+ ldh [rNR30], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR33], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR34], a
+ ret
+
+.asm_e8268
+ push hl
+ ld a, [wCurTrackIntensity]
+ and $f ; only 0-9 are valid
+ ld l, a
+ ld h, 0
+ ; hl << 4
+ ; each wavepattern is $f bytes long
+ ; so seeking is done in $10s
+rept 4
+ add hl, hl
+endr
+ ld de, WaveSamples
+ add hl, de
+ ; load wavepattern into rWave_0-rWave_f
+ ld a, [hli]
+ ldh [rWave_0], a
+ ld a, [hli]
+ ldh [rWave_1], a
+ ld a, [hli]
+ ldh [rWave_2], a
+ ld a, [hli]
+ ldh [rWave_3], a
+ ld a, [hli]
+ ldh [rWave_4], a
+ ld a, [hli]
+ ldh [rWave_5], a
+ ld a, [hli]
+ ldh [rWave_6], a
+ ld a, [hli]
+ ldh [rWave_7], a
+ ld a, [hli]
+ ldh [rWave_8], a
+ ld a, [hli]
+ ldh [rWave_9], a
+ ld a, [hli]
+ ldh [rWave_a], a
+ ld a, [hli]
+ ldh [rWave_b], a
+ ld a, [hli]
+ ldh [rWave_c], a
+ ld a, [hli]
+ ldh [rWave_d], a
+ ld a, [hli]
+ ldh [rWave_e], a
+ ld a, [hli]
+ ldh [rWave_f], a
+ pop hl
+ ld a, [wCurTrackIntensity]
+ and $f0
+ sla a
+ ldh [rNR32], a
+ ret
+
+.Channel4:
+.Channel8:
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ bit NOTE_REST, [hl] ; rest
+ jr nz, .ch4rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .asm_e82d4
+ ret
+
+.asm_e82c1 ; unused
+ ld a, [wCurTrackFrequency]
+ ldh [rNR43], a
+ ret
+
+.ch4rest
+ ldh a, [rNR52]
+ and %10000111 ; ch4 off
+ ldh [rNR52], a
+ ld hl, rNR40
+ call ClearChannel
+ ret
+
+.asm_e82d4
+ ld a, $3f ; sound length
+ ldh [rNR41], a
+ ld a, [wCurTrackIntensity]
+ ldh [rNR42], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR43], a
+ ld a, $80
+ ldh [rNR44], a
+ ret
+
+_CheckSFX:
+; return carry if any sfx channels are active
+ ld hl, wChannel5Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .sfxon
+ ld hl, wChannel6Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .sfxon
+ ld hl, wChannel7Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .sfxon
+ ld hl, wChannel8Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .sfxon
+ and a
+ ret
+
+.sfxon
+ scf
+ ret
+
+PlayDanger:
+ ld a, [wLowHealthAlarm]
+ bit DANGER_ON_F, a
+ ret z
+
+ ; Don't do anything if SFX is being played
+ and $ff ^ (1 << DANGER_ON_F)
+ ld d, a
+ call _CheckSFX
+ jr c, .increment
+
+ ; Play the high tone
+ and a
+ jr z, .begin
+
+ ; Play the low tone
+ cp 16
+ jr z, .halfway
+
+ jr .increment
+
+.halfway
+ ld hl, DangerSoundLow
+ jr .applychannel
+
+.begin
+ ld hl, DangerSoundHigh
+
+.applychannel
+ xor a
+ ldh [rNR10], a
+ ld a, [hli]
+ ldh [rNR11], a
+ ld a, [hli]
+ ldh [rNR12], a
+ ld a, [hli]
+ ldh [rNR13], a
+ ld a, [hli]
+ ldh [rNR14], a
+
+.increment
+ ld a, d
+ inc a
+ cp 30 ; Ending frame
+ jr c, .noreset
+ xor a
+.noreset
+ ; Make sure the danger sound is kept on
+ or 1 << DANGER_ON_F
+ ld [wLowHealthAlarm], a
+
+ ; Enable channel 1 if it's off
+ ld a, [wSoundOutput]
+ and $11
+ ret nz
+ ld a, [wSoundOutput]
+ or $11
+ ld [wSoundOutput], a
+ ret
+
+DangerSoundHigh:
+ db $80 ; duty 50%
+ db $e2 ; volume 14, envelope decrease sweep 2
+ db $50 ; frequency: $750
+ db $87 ; restart sound
+
+DangerSoundLow:
+ db $80 ; duty 50%
+ db $e2 ; volume 14, envelope decrease sweep 2
+ db $ee ; frequency: $6ee
+ db $86 ; restart sound
+
+FadeMusic:
+; fade music if applicable
+; usage:
+; write to wMusicFade
+; song fades out at the given rate
+; load song id in wMusicFadeID
+; fade new song in
+; notes:
+; max # frames per volume level is $3f
+
+ ; fading?
+ ld a, [wMusicFade]
+ and a
+ ret z
+ ; has the count ended?
+ ld a, [wMusicFadeCount]
+ and a
+ jr z, .update
+ ; count down
+ dec a
+ ld [wMusicFadeCount], a
+ ret
+
+.update
+ ld a, [wMusicFade]
+ ld d, a
+ ; get new count
+ and $3f
+ ld [wMusicFadeCount], a
+ ; get SO1 volume
+ ld a, [wVolume]
+ and VOLUME_SO1_LEVEL
+ ; which way are we fading?
+ bit MUSIC_FADE_IN_F, d
+ jr nz, .fadein
+ ; fading out
+ and a
+ jr z, .novolume
+ dec a
+ jr .updatevolume
+
+.novolume
+ ; make sure volume is off
+ xor a
+ ld [wVolume], a
+ ; did we just get on a bike?
+ ld a, [wPlayerState]
+ cp PLAYER_BIKE
+ jr z, .bicycle
+ push bc
+ ; restart sound
+ call MusicFadeRestart
+ ; get new song id
+ ld a, [wMusicFadeID]
+ and a
+ jr z, .quit ; this assumes there are fewer than 256 songs!
+ ld e, a
+ ld a, [wMusicFadeID + 1]
+ ld d, a
+ ; load new song
+ call _PlayMusic
+.quit
+ ; cleanup
+ pop bc
+ ; stop fading
+ xor a
+ ld [wMusicFade], a
+ ret
+
+.bicycle
+ push bc
+ ; restart sound
+ call MusicFadeRestart
+ ; this turns the volume up
+ ; turn it back down
+ xor a
+ ld [wVolume], a
+ ; get new song id
+ ld a, [wMusicFadeID]
+ ld e, a
+ ld a, [wMusicFadeID + 1]
+ ld d, a
+ ; load new song
+ call _PlayMusic
+ pop bc
+ ; fade in
+ ld hl, wMusicFade
+ set MUSIC_FADE_IN_F, [hl]
+ ret
+
+.fadein
+ ; are we done?
+ cp MAX_VOLUME & $f
+ jr nc, .maxvolume
+ ; inc volume
+ inc a
+ jr .updatevolume
+
+.maxvolume
+ ; we're done
+ xor a
+ ld [wMusicFade], a
+ ret
+
+.updatevolume
+ ; hi = lo
+ ld d, a
+ swap a
+ or d
+ ld [wVolume], a
+ ret
+
+LoadNote:
+ ; wait for pitch wheel to finish
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ bit SOUND_PITCH_WHEEL, [hl]
+ ret z
+ ; get note duration
+ ld hl, CHANNEL_NOTE_DURATION
+ add hl, bc
+ ld a, [hl]
+ ld hl, wCurNoteDuration
+ sub [hl]
+ jr nc, .ok
+ ld a, 1
+.ok
+ ld [hl], a
+ ; get frequency
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; get direction of pitch wheel
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld a, e
+ sub [hl]
+ ld e, a
+ ld a, d
+ sbc 0
+ ld d, a
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ sub [hl]
+ jr nc, .greater_than
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ set SOUND_PITCH_WHEEL_DIR, [hl]
+ ; get frequency
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; ????
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld a, [hl]
+ sub e
+ ld e, a
+ ld a, d
+ sbc 0
+ ld d, a
+ ; ????
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ ld a, [hl]
+ sub d
+ ld d, a
+ jr .resume
+
+.greater_than
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ res SOUND_PITCH_WHEEL_DIR, [hl]
+ ; get frequency
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; get distance from pitch wheel target
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld a, e
+ sub [hl]
+ ld e, a
+ ld a, d
+ sbc 0
+ ld d, a
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ sub [hl]
+ ld d, a
+.resume
+ ; de = x * [wCurNoteDuration] + y
+ ; x + 1 -> d
+ ; y -> a
+ push bc
+ ld hl, wCurNoteDuration
+ ld b, 0 ; quotient
+.loop
+ inc b
+ ld a, e
+ sub [hl]
+ ld e, a
+ jr nc, .loop
+ ld a, d
+ and a
+ jr z, .quit
+ dec d
+ jr .loop
+
+.quit
+ ld a, e ; remainder
+ add [hl]
+ ld d, b ; quotient
+ pop bc
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT
+ add hl, bc
+ ld [hl], d ; quotient
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT_FRACTION
+ add hl, bc
+ ld [hl], a ; remainder
+ ld hl, CHANNEL_FIELD25
+ add hl, bc
+ xor a
+ ld [hl], a
+ ret
+
+HandleTrackVibrato:
+; handle duty, cry pitch, and vibrato
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ bit SOUND_DUTY, [hl] ; duty
+ jr z, .next
+ ld hl, CHANNEL_SFX_DUTY_LOOP
+ add hl, bc
+ ld a, [hl]
+ rlca
+ rlca
+ ld [hl], a
+ and $c0
+ ld [wCurTrackDuty], a
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_DUTY_OVERRIDE, [hl]
+.next
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ bit SOUND_CRY_PITCH, [hl]
+ jr z, .vibrato
+ ld hl, CHANNEL_CRY_PITCH
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, wCurTrackFrequency
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ add hl, de
+ ld e, l
+ ld d, h
+ ld hl, wCurTrackFrequency
+ ld [hl], e
+ inc hl
+ ld [hl], d
+.vibrato
+ ; is vibrato on?
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ bit SOUND_VIBRATO, [hl] ; vibrato
+ jr z, .quit
+ ; is vibrato active for this note yet?
+ ; is the delay over?
+ ld hl, CHANNEL_VIBRATO_DELAY_COUNT
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr nz, .subexit
+ ; is the extent nonzero?
+ ld hl, CHANNEL_VIBRATO_EXTENT
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .quit
+ ; save it for later
+ ld d, a
+ ; is it time to toggle vibrato up/down?
+ ld hl, CHANNEL_VIBRATO_RATE
+ add hl, bc
+ ld a, [hl]
+ and $f ; count
+ jr z, .toggle
+.subexit
+ dec [hl]
+ jr .quit
+
+.toggle
+ ; refresh count
+ ld a, [hl]
+ swap [hl]
+ or [hl]
+ ld [hl], a
+ ; ????
+ ld a, [wCurTrackFrequency]
+ ld e, a
+ ; toggle vibrato up/down
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ bit SOUND_VIBRATO_DIR, [hl] ; vibrato up/down
+ jr z, .down
+; up
+ ; vibrato down
+ res SOUND_VIBRATO_DIR, [hl]
+ ; get the delay
+ ld a, d
+ and $f ; lo
+ ;
+ ld d, a
+ ld a, e
+ sub d
+ jr nc, .no_carry
+ ld a, 0
+ jr .no_carry
+
+.down
+ ; vibrato up
+ set SOUND_VIBRATO_DIR, [hl]
+ ; get the delay
+ ld a, d
+ and $f0 ; hi
+ swap a ; move it to lo
+ ;
+ add e
+ jr nc, .no_carry
+ ld a, $ff
+.no_carry
+ ld [wCurTrackFrequency], a
+ ;
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_VIBRATO_OVERRIDE, [hl]
+.quit
+ ret
+
+ApplyPitchWheel:
+ ; quit if pitch wheel inactive
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ bit SOUND_PITCH_WHEEL, [hl]
+ ret z
+ ; de = Frequency
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; check whether pitch wheel is going up or down
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ bit SOUND_PITCH_WHEEL_DIR, [hl]
+ jr z, .decreasing
+ ; frequency += [Channel*PitchWheelAmount]
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT
+ add hl, bc
+ ld l, [hl]
+ ld h, 0
+ add hl, de
+ ld d, h
+ ld e, l
+ ; [Channel*Field25] += [Channel*PitchWheelAmountFraction]
+ ; if rollover: Frequency += 1
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT_FRACTION
+ add hl, bc
+ ld a, [hl]
+ ld hl, CHANNEL_FIELD25
+ add hl, bc
+ add [hl]
+ ld [hl], a
+ ld a, 0
+ adc e
+ ld e, a
+ ld a, 0
+ adc d
+ ld d, a
+ ; Compare the dw at [Channel*PitchWheelTarget] to de.
+ ; If frequency is greater, we're finished.
+ ; Otherwise, load the frequency and set two flags.
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ ld a, [hl]
+ cp d
+ jp c, .finished_pitch_wheel
+ jr nz, .continue_pitch_wheel
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld a, [hl]
+ cp e
+ jp c, .finished_pitch_wheel
+ jr .continue_pitch_wheel
+
+.decreasing
+ ; frequency -= [Channel*PitchWheelAmount]
+ ld a, e
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT
+ add hl, bc
+ ld e, [hl]
+ sub e
+ ld e, a
+ ld a, d
+ sbc 0
+ ld d, a
+ ; [Channel*Field25] *= 2
+ ; if rollover: Frequency -= 1
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT_FRACTION
+ add hl, bc
+ ld a, [hl]
+ add a
+ ld [hl], a
+ ld a, e
+ sbc 0
+ ld e, a
+ ld a, d
+ sbc 0
+ ld d, a
+ ; Compare the dw at [Channel*PitchWheelTarget] to de.
+ ; If frequency is lower, we're finished.
+ ; Otherwise, load the frequency and set two flags.
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ ld a, d
+ cp [hl]
+ jr c, .finished_pitch_wheel
+ jr nz, .continue_pitch_wheel
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld a, e
+ cp [hl]
+ jr nc, .continue_pitch_wheel
+.finished_pitch_wheel
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ res SOUND_PITCH_WHEEL, [hl]
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ res SOUND_PITCH_WHEEL_DIR, [hl]
+ ret
+
+.continue_pitch_wheel
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_FREQ_OVERRIDE, [hl]
+ set NOTE_DUTY_OVERRIDE, [hl]
+ ret
+
+HandleNoise:
+ ; is noise sampling on?
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_NOISE, [hl] ; noise sampling
+ ret z
+ ; are we in a sfx channel?
+ ld a, [wCurChannel]
+ bit NOISE_CHAN_F, a
+ jr nz, .next
+ ; is ch8 on? (noise)
+ ld hl, wChannel8Flags1
+ bit SOUND_CHANNEL_ON, [hl] ; on?
+ jr z, .next
+ ; is ch8 playing noise?
+ bit SOUND_NOISE, [hl]
+ ret nz ; quit if so
+ ;
+.next
+ ld a, [wNoiseSampleDelay]
+ and a
+ jr z, ReadNoiseSample
+ dec a
+ ld [wNoiseSampleDelay], a
+ ret
+
+ReadNoiseSample:
+; sample struct:
+; [wx] [yy] [zz]
+; w: ? either 2 or 3
+; x: duration
+; zz: intensity
+; yy: frequency
+
+ ; de = [wNoiseSampleAddress]
+ ld hl, wNoiseSampleAddress
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+ ; is it empty?
+ ld a, e
+ or d
+ jr z, .quit
+
+ ld a, [de]
+ inc de
+
+ cp endchannel_cmd
+ jr z, .quit
+
+ and $f
+ inc a
+ ld [wNoiseSampleDelay], a
+ ld a, [de]
+ inc de
+ ld [wCurTrackIntensity], a
+ ld a, [de]
+ inc de
+ ld [wCurTrackFrequency], a
+ xor a
+ ld [wCurTrackFrequency + 1], a
+
+ ld hl, wNoiseSampleAddress
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_NOISE_SAMPLING, [hl]
+ ret
+
+.quit
+ ret
+
+ParseMusic:
+; parses until a note is read or the song is ended
+ call GetMusicByte ; store next byte in a
+ cp endchannel_cmd
+ jr z, .endchannel
+ cp FIRST_MUSIC_CMD
+ jr c, .readnote
+ ; then it's a command
+.readcommand
+ call ParseMusicCommand
+ jr ParseMusic ; start over
+
+.readnote
+; wCurMusicByte contains current note
+; special notes
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_SFX, [hl]
+ jp nz, ParseSFXOrRest
+ bit SOUND_REST, [hl] ; rest
+ jp nz, ParseSFXOrRest
+ bit SOUND_NOISE, [hl] ; noise sample
+ jp nz, GetNoiseSample
+; normal note
+ ; set note duration (bottom nybble)
+ ld a, [wCurMusicByte]
+ and $f
+ call SetNoteDuration
+ ; get note pitch (top nybble)
+ ld a, [wCurMusicByte]
+ swap a
+ and $f
+ jr z, .rest ; pitch 0-> rest
+ ; update pitch
+ ld hl, CHANNEL_PITCH
+ add hl, bc
+ ld [hl], a
+ ; store pitch in e
+ ld e, a
+ ; store octave in d
+ ld hl, CHANNEL_OCTAVE
+ add hl, bc
+ ld d, [hl]
+ ; update frequency
+ call GetFrequency
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ; ????
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_NOISE_SAMPLING, [hl]
+ jp LoadNote
+
+.rest
+; note = rest
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_REST, [hl] ; Rest
+ ret
+
+.endchannel
+; $ff is reached in music data
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_SUBROUTINE, [hl] ; in a subroutine?
+ jr nz, .readcommand ; execute
+ ld a, [wCurChannel]
+ cp CHAN5
+ jr nc, .chan_5to8
+ ; ????
+ ld hl, CHANNEL_STRUCT_LENGTH * NUM_MUSIC_CHANS + CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_CHANNEL_ON, [hl]
+ jr nz, .ok
+.chan_5to8
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_REST, [hl]
+ call nz, RestoreVolume
+ ; end music
+ ld a, [wCurChannel]
+ cp CHAN5
+ jr nz, .ok
+ ; ????
+ xor a
+ ldh [rNR10], a ; sweep = 0
+.ok
+; stop playing
+ ; turn channel off
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ res SOUND_CHANNEL_ON, [hl]
+ ; note = rest
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_REST, [hl]
+ ; clear music id & bank
+ ld hl, CHANNEL_MUSIC_ID
+ add hl, bc
+ xor a
+ ld [hli], a ; id hi
+ ld [hli], a ; id lo
+ ld [hli], a ; bank
+ ret
+
+RestoreVolume:
+ ; ch5 only
+ ld a, [wCurChannel]
+ cp CHAN5
+ ret nz
+ xor a
+ ld hl, wChannel6CryPitch
+ ld [hli], a
+ ld [hl], a
+ ld hl, wChannel8CryPitch
+ ld [hli], a
+ ld [hl], a
+ ld a, [wLastVolume]
+ ld [wVolume], a
+ xor a
+ ld [wLastVolume], a
+ ld [wSFXPriority], a
+ ret
+
+ParseSFXOrRest:
+ ; turn noise sampling on
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_NOISE_SAMPLING, [hl] ; noise sample
+ ; update note duration
+ ld a, [wCurMusicByte]
+ call SetNoteDuration ; top nybble doesnt matter?
+ ; update intensity from next param
+ call GetMusicByte
+ ld hl, CHANNEL_INTENSITY
+ add hl, bc
+ ld [hl], a
+ ; update lo frequency from next param
+ call GetMusicByte
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld [hl], a
+ ; are we on the last channel? (noise sampling)
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ cp CHAN4
+ ret z
+ ; update hi frequency from next param
+ call GetMusicByte
+ ld hl, CHANNEL_FREQUENCY + 1
+ add hl, bc
+ ld [hl], a
+ ret
+
+GetNoiseSample:
+; load ptr to sample header in wNoiseSampleAddress
+ ; are we on the last channel?
+ ld a, [wCurChannel]
+ and NUM_MUSIC_CHANS + -1
+ cp CHAN4
+ ; ret if not
+ ret nz
+ ; update note duration
+ ld a, [wCurMusicByte]
+ and $f
+ call SetNoteDuration
+ ; check current channel
+ ld a, [wCurChannel]
+ bit NOISE_CHAN_F, a
+ jr nz, .sfx
+ ld hl, wChannel8Flags1
+ bit SOUND_CHANNEL_ON, [hl] ; is ch8 on? (noise)
+ ret nz
+ ld a, [wMusicNoiseSampleSet]
+ jr .next
+
+.sfx
+ ld a, [wSFXNoiseSampleSet]
+.next
+ ; load noise sample set id into de
+ ld e, a
+ ld d, 0
+ ; load ptr to noise sample set in hl
+ ld hl, Drumkits
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ; get pitch
+ ld a, [wCurMusicByte]
+ swap a
+ ; non-rest note?
+ and $f
+ ret z
+ ; use 'pitch' to seek noise sample set
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ; load sample pointer into wNoiseSampleAddress
+ ld a, [hli]
+ ld [wNoiseSampleAddress], a
+ ld a, [hl]
+ ld [wNoiseSampleAddress + 1], a
+ ; clear ????
+ xor a
+ ld [wNoiseSampleDelay], a
+ ret
+
+ParseMusicCommand:
+ ; reload command
+ ld a, [wCurMusicByte]
+ ; get command #
+ sub FIRST_MUSIC_CMD
+ ld e, a
+ ld d, 0
+ ; seek command pointer
+ ld hl, MusicCommands
+ add hl, de
+ add hl, de
+ ; jump to the new pointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+MusicCommands:
+; entries correspond to macros/sound.asm enumeration
+ dw Music_Octave8 ; octave 8
+ dw Music_Octave7 ; octave 7
+ dw Music_Octave6 ; octave 6
+ dw Music_Octave5 ; octave 5
+ dw Music_Octave4 ; octave 4
+ dw Music_Octave3 ; octave 3
+ dw Music_Octave2 ; octave 2
+ dw Music_Octave1 ; octave 1
+ dw Music_NoteType ; note length + intensity
+ dw Music_ForceOctave ; set starting octave
+ dw Music_Tempo ; tempo
+ dw Music_DutyCycle ; duty cycle
+ dw Music_Intensity ; intensity
+ dw Music_SoundStatus ; update sound status
+ dw Music_SoundDuty ; sfx duty
+ dw Music_ToggleSFX ; sound on/off
+ dw Music_SlidePitchTo ; pitch wheel
+ dw Music_Vibrato ; vibrato
+ dw MusicE2 ; unused
+ dw Music_ToggleNoise ; music noise sampling
+ dw Music_Panning ; force panning
+ dw Music_Volume ; volume
+ dw Music_Tone ; tone
+ dw MusicE7 ; unused
+ dw MusicE8 ; unused
+ dw Music_TempoRelative ; global tempo
+ dw Music_RestartChannel ; restart current channel from header
+ dw Music_NewSong ; new song
+ dw Music_SFXPriorityOn ; sfx priority on
+ dw Music_SFXPriorityOff ; sfx priority off
+ dw MusicEE ; unused
+ dw Music_StereoPanning ; stereo panning
+ dw Music_SFXToggleNoise ; sfx noise sampling
+ dw MusicF1 ; nothing
+ dw MusicF2 ; nothing
+ dw MusicF3 ; nothing
+ dw MusicF4 ; nothing
+ dw MusicF5 ; nothing
+ dw MusicF6 ; nothing
+ dw MusicF7 ; nothing
+ dw MusicF8 ; nothing
+ dw MusicF9 ; unused
+ dw Music_SetCondition ; setcondition
+ dw Music_JumpIf ; jumpif
+ dw Music_JumpChannel ; jump
+ dw Music_LoopChannel ; loop
+ dw Music_CallChannel ; call
+ dw Music_EndChannel ; return
+
+MusicF1:
+MusicF2:
+MusicF3:
+MusicF4:
+MusicF5:
+MusicF6:
+MusicF7:
+MusicF8:
+ ret
+
+Music_EndChannel:
+; called when $ff is encountered w/ subroutine flag set
+; end music stream
+; return to caller of the subroutine
+ ; reset subroutine flag
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ res SOUND_SUBROUTINE, [hl]
+ ; copy LastMusicAddress to MusicAddress
+ ld hl, CHANNEL_LAST_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+Music_CallChannel:
+; call music stream (subroutine)
+; parameters: ll hh ; pointer to subroutine
+ ; get pointer from next 2 bytes
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ push de
+ ; copy MusicAddress to LastMusicAddress
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, CHANNEL_LAST_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ; load pointer into MusicAddress
+ pop de
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ; set subroutine flag
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_SUBROUTINE, [hl]
+ ret
+
+Music_JumpChannel:
+; jump
+; parameters: ll hh ; pointer
+ ; get pointer from next 2 bytes
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+Music_LoopChannel:
+; loops xx - 1 times
+; 00: infinite
+; params: 3
+; xx ll hh
+; xx : loop count
+; ll hh : pointer
+
+ ; get loop count
+ call GetMusicByte
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_LOOPING, [hl] ; has the loop been initiated?
+ jr nz, .checkloop
+ and a ; loop counter 0 = infinite
+ jr z, .loop
+ ; initiate loop
+ dec a
+ set SOUND_LOOPING, [hl] ; set loop flag
+ ld hl, CHANNEL_LOOP_COUNT
+ add hl, bc
+ ld [hl], a ; store loop counter
+.checkloop
+ ld hl, CHANNEL_LOOP_COUNT
+ add hl, bc
+ ld a, [hl]
+ and a ; are we done?
+ jr z, .endloop
+ dec [hl]
+.loop
+ ; get pointer
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ ; load new pointer into MusicAddress
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+.endloop
+ ; reset loop flag
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ res SOUND_LOOPING, [hl]
+ ; skip to next command
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc de ; skip
+ inc de ; pointer
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ ret
+
+Music_SetCondition:
+; set condition for a jump
+; used with FB
+; params: 1
+; xx ; condition
+
+ ; set condition
+ call GetMusicByte
+ ld hl, CHANNEL_CONDITION
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_JumpIf:
+; conditional jump
+; used with FA
+; params: 3
+; xx: condition
+; ll hh: pointer
+
+; check condition
+ ; a = condition
+ call GetMusicByte
+ ; if existing condition matches, jump to new address
+ ld hl, CHANNEL_CONDITION
+ add hl, bc
+ cp [hl]
+ jr z, .jump
+; skip to next command
+ ; get address
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; skip pointer
+ inc de
+ inc de
+ ; update address
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ ret
+
+.jump
+; jump to the new address
+ ; get pointer
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ ; update pointer in MusicAddress
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+MusicEE:
+; conditional jump
+; checks a byte in ram corresponding to the current channel
+; doesn't seem to be set by any commands
+; params: 2
+; ll hh ; pointer
+
+; if ????, jump
+ ; get channel
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ ld e, a
+ ld d, 0
+ ; hl = wChannel1JumpCondition + channel id
+ ld hl, wChannel1JumpCondition
+ add hl, de
+ ; if set, jump
+ ld a, [hl]
+ and a
+ jr nz, .jump
+; skip to next command
+ ; get address
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; skip pointer
+ inc de
+ inc de
+ ; update address
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ ret
+
+.jump
+ ; reset jump flag
+ ld [hl], 0
+ ; de = pointer
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ ; update address
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+MusicF9:
+; sets some flag
+; seems to be unused
+; params: 0
+ ld a, TRUE
+ ld [wUnusedMusicF9Flag], a
+ ret
+
+MusicE2:
+; seems to have been dummied out
+; params: 1
+ call GetMusicByte
+ ld hl, CHANNEL_FIELD2C
+ add hl, bc
+ ld [hl], a
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_UNKN_0B, [hl]
+ ret
+
+Music_Vibrato:
+; vibrato
+; params: 2
+; 1: [xx]
+ ; delay in frames
+; 2: [yz]
+ ; y: extent
+ ; z: rate (# frames per cycle)
+
+ ; set vibrato flag?
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_VIBRATO, [hl]
+ ; start at lower frequency (extent is positive)
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ res SOUND_VIBRATO_DIR, [hl]
+ ; get delay
+ call GetMusicByte
+; update delay
+ ld hl, CHANNEL_VIBRATO_DELAY
+ add hl, bc
+ ld [hl], a
+; update delay count
+ ld hl, CHANNEL_VIBRATO_DELAY_COUNT
+ add hl, bc
+ ld [hl], a
+; update extent
+; this is split into halves only to get added back together at the last second
+ ; get extent/rate
+ call GetMusicByte
+ ld hl, CHANNEL_VIBRATO_EXTENT
+ add hl, bc
+ ld d, a
+ ; get top nybble
+ and $f0
+ swap a
+ srl a ; halve
+ ld e, a
+ adc 0 ; round up
+ swap a
+ or e
+ ld [hl], a
+; update rate
+ ld hl, CHANNEL_VIBRATO_RATE
+ add hl, bc
+ ; get bottom nybble
+ ld a, d
+ and $f
+ ld d, a
+ swap a
+ or d
+ ld [hl], a
+ ret
+
+Music_SlidePitchTo:
+; set the target for pitch wheel
+; params: 2
+; note duration
+; target note
+ call GetMusicByte
+ ld [wCurNoteDuration], a
+
+ call GetMusicByte
+ ; pitch in e
+ ld d, a
+ and $f
+ ld e, a
+
+ ; octave in d
+ ld a, d
+ swap a
+ and $f
+ ld d, a
+ call GetFrequency
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld [hl], e
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ ld [hl], d
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_PITCH_WHEEL, [hl]
+ ret
+
+Music_Tone:
+; tone
+; params: 1 (dw)
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_CRY_PITCH, [hl]
+ ld hl, CHANNEL_CRY_PITCH + 1
+ add hl, bc
+ call GetMusicByte
+ ld [hld], a
+ call GetMusicByte
+ ld [hl], a
+ ret
+
+MusicE7:
+; unused
+; params: 1
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_UNKN_0E, [hl]
+ call GetMusicByte
+ ld hl, CHANNEL_FIELD29
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_SoundDuty:
+; sequence of 4 duty cycles to be looped
+; params: 1 (4 2-bit duty cycle arguments)
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_DUTY, [hl] ; duty cycle
+ ; sound duty sequence
+ call GetMusicByte
+ rrca
+ rrca
+ ld hl, CHANNEL_SFX_DUTY_LOOP
+ add hl, bc
+ ld [hl], a
+ ; update duty cycle
+ and $c0 ; only uses top 2 bits
+ ld hl, CHANNEL_DUTY_CYCLE
+ add hl, bc
+ ld [hl], a
+ ret
+
+MusicE8:
+; unused
+; params: 1
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_UNKN_0D, [hl]
+ call GetMusicByte
+ ld hl, CHANNEL_FIELD2A
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_ToggleSFX:
+; toggle something
+; params: none
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_SFX, [hl]
+ jr z, .on
+ res SOUND_SFX, [hl]
+ ret
+
+.on
+ set SOUND_SFX, [hl]
+ ret
+
+Music_ToggleNoise:
+; toggle music noise sampling
+; can't be used as a straight toggle since the param is not read from on->off
+; params:
+; noise on: 1
+; noise off: 0
+ ; check if noise sampling is on
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_NOISE, [hl]
+ jr z, .on
+ ; turn noise sampling off
+ res SOUND_NOISE, [hl]
+ ret
+
+.on
+ ; turn noise sampling on
+ set SOUND_NOISE, [hl]
+ call GetMusicByte
+ ld [wMusicNoiseSampleSet], a
+ ret
+
+Music_SFXToggleNoise:
+; toggle sfx noise sampling
+; params:
+; on: 1
+; off: 0
+ ; check if noise sampling is on
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_NOISE, [hl]
+ jr z, .on
+ ; turn noise sampling off
+ res SOUND_NOISE, [hl]
+ ret
+
+.on
+ ; turn noise sampling on
+ set SOUND_NOISE, [hl]
+ call GetMusicByte
+ ld [wSFXNoiseSampleSet], a
+ ret
+
+Music_NoteType:
+; note length
+; # frames per 16th note
+; intensity: see Music_Intensity
+; params: 2
+ ; note length
+ call GetMusicByte
+ ld hl, CHANNEL_NOTE_LENGTH
+ add hl, bc
+ ld [hl], a
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ cp CHAN4
+ ret z
+ ; intensity
+ call Music_Intensity
+ ret
+
+Music_SoundStatus:
+; update sound status
+; params: 1
+ call GetMusicByte
+ ld [wSoundInput], a
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_UNKN_3, [hl]
+ ret
+
+Music_DutyCycle:
+; duty cycle
+; params: 1
+ call GetMusicByte
+ rrca
+ rrca
+ and $c0
+ ld hl, CHANNEL_DUTY_CYCLE
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_Intensity:
+; intensity
+; params: 1
+; hi: pressure
+; lo: velocity
+ call GetMusicByte
+ ld hl, CHANNEL_INTENSITY
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_Tempo:
+; global tempo
+; params: 2
+; de: tempo
+ call GetMusicByte
+ ld d, a
+ call GetMusicByte
+ ld e, a
+ call SetGlobalTempo
+ ret
+
+Music_Octave8:
+Music_Octave7:
+Music_Octave6:
+Music_Octave5:
+Music_Octave4:
+Music_Octave3:
+Music_Octave2:
+Music_Octave1:
+; set octave based on lo nybble of the command
+ ld hl, CHANNEL_OCTAVE
+ add hl, bc
+ ld a, [wCurMusicByte]
+ and 7
+ ld [hl], a
+ ret
+
+Music_ForceOctave:
+; set starting octave
+; this forces all notes up by the starting octave
+; params: 1
+ call GetMusicByte
+ ld hl, CHANNEL_PITCH_OFFSET
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_StereoPanning:
+; stereo panning
+; params: 1
+ ; stereo on?
+ ld a, [wOptions]
+ bit STEREO, a
+ jr nz, Music_Panning
+ ; skip param
+ call GetMusicByte
+ ret
+
+Music_Panning:
+; force panning
+; params: 1
+ call SetLRTracks
+ call GetMusicByte
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ and [hl]
+ ld [hl], a
+ ret
+
+Music_Volume:
+; set volume
+; params: 1
+; see Volume
+ ; read param even if it's not used
+ call GetMusicByte
+ ; is the song fading?
+ ld a, [wMusicFade]
+ and a
+ ret nz
+ ; reload param
+ ld a, [wCurMusicByte]
+ ; set volume
+ ld [wVolume], a
+ ret
+
+Music_TempoRelative:
+; set global tempo to current channel tempo +/- param
+; params: 1 signed
+ call GetMusicByte
+ ld e, a
+ ; check sign
+ cp $80
+ jr nc, .negative
+;positive
+ ld d, 0
+ jr .ok
+
+.negative
+ ld d, -1
+.ok
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ add hl, de
+ ld e, l
+ ld d, h
+ call SetGlobalTempo
+ ret
+
+Music_SFXPriorityOn:
+; turn sfx priority on
+; params: none
+ ld a, 1
+ ld [wSFXPriority], a
+ ret
+
+Music_SFXPriorityOff:
+; turn sfx priority off
+; params: none
+ xor a
+ ld [wSFXPriority], a
+ ret
+
+Music_RestartChannel:
+; restart current channel from channel header (same bank)
+; params: 2 (5)
+; ll hh: pointer to new channel header
+; header format: 0x yy zz
+; x: channel # (0-3)
+; zzyy: pointer to new music data
+
+ ; update music id
+ ld hl, CHANNEL_MUSIC_ID
+ add hl, bc
+ ld a, [hli]
+ ld [wMusicID], a
+ ld a, [hl]
+ ld [wMusicID + 1], a
+ ; update music bank
+ ld hl, CHANNEL_MUSIC_BANK
+ add hl, bc
+ ld a, [hl]
+ ld [wMusicBank], a
+ ; get pointer to new channel header
+ call GetMusicByte
+ ld l, a
+ call GetMusicByte
+ ld h, a
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ push bc ; save current channel
+ call LoadChannel
+ call StartChannel
+ pop bc ; restore current channel
+ ret
+
+Music_NewSong:
+; new song
+; params: 2
+; de: song id
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ push bc
+ call _PlayMusic
+ pop bc
+ ret
+
+GetMusicByte:
+; returns byte from current address in a
+; advances to next byte in music data
+; input: bc = start of current channel
+ push hl
+ push de
+ ; load address into de
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld d, [hl]
+ ; load bank into a
+ ld hl, CHANNEL_MUSIC_BANK
+ add hl, bc
+ ld a, [hl]
+ ; get byte
+ call _LoadMusicByte ; load data into wCurMusicByte
+ inc de ; advance to next byte for next time this is called
+ ; update channeldata address
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld a, e
+ ld [hli], a
+ ld [hl], d
+ ; cleanup
+ pop de
+ pop hl
+ ; store channeldata in a
+ ld a, [wCurMusicByte]
+ ret
+
+GetFrequency:
+; generate frequency
+; input:
+; d: octave
+; e: pitch
+; output:
+; de: frequency
+
+; get octave
+ ; get starting octave
+ ld hl, CHANNEL_PITCH_OFFSET
+ add hl, bc
+ ld a, [hl]
+ swap a ; hi nybble
+ and $f
+ ; add current octave
+ add d
+ push af ; we'll use this later
+ ; get starting octave
+ ld hl, CHANNEL_PITCH_OFFSET
+ add hl, bc
+ ld a, [hl]
+ and $f ; lo nybble
+ ld l, a ; ok
+ ld d, 0
+ ld h, d
+ add hl, de ; add current pitch
+ add hl, hl ; skip 2 bytes for each
+ ld de, FrequencyTable
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; get our octave
+ pop af
+ ; shift right by [7 - octave] bits
+.loop
+ ; [7 - octave] loops
+ cp $7
+ jr nc, .ok
+ ; sra de
+ sra d
+ rr e
+ inc a
+ jr .loop
+
+.ok
+ ld a, d
+ and $7 ; top 3 bits for frequency (11 total)
+ ld d, a
+ ret
+
+SetNoteDuration:
+; input: a = note duration in 16ths
+ ; store delay units in de
+ inc a
+ ld e, a
+ ld d, 0
+ ; store NoteLength in a
+ ld hl, CHANNEL_NOTE_LENGTH
+ add hl, bc
+ ld a, [hl]
+ ; multiply NoteLength by delay units
+ ld l, 0 ; just multiply
+ call .Multiply
+ ld a, l ; low
+ ; store Tempo in de
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; add ???? to the next result
+ ld hl, CHANNEL_FIELD16
+ add hl, bc
+ ld l, [hl]
+ ; multiply Tempo by last result (NoteLength * LOW(delay))
+ call .Multiply
+ ; copy result to de
+ ld e, l
+ ld d, h
+ ; store result in ????
+ ld hl, CHANNEL_FIELD16
+ add hl, bc
+ ld [hl], e
+ ; store result in NoteDuration
+ ld hl, CHANNEL_NOTE_DURATION
+ add hl, bc
+ ld [hl], d
+ ret
+
+.Multiply:
+; multiplies a and de
+; adds the result to l
+; stores the result in hl
+ ld h, 0
+.loop
+ ; halve a
+ srl a
+ ; is there a remainder?
+ jr nc, .skip
+ ; add it to the result
+ add hl, de
+.skip
+ ; add de, de
+ sla e
+ rl d
+ ; are we done?
+ and a
+ jr nz, .loop
+ ret
+
+SetGlobalTempo:
+ push bc ; save current channel
+ ; are we dealing with music or sfx?
+ ld a, [wCurChannel]
+ cp CHAN5
+ jr nc, .sfxchannels
+ ld bc, wChannel1
+ call Tempo
+ ld bc, wChannel2
+ call Tempo
+ ld bc, wChannel3
+ call Tempo
+ ld bc, wChannel4
+ call Tempo
+ jr .end
+
+.sfxchannels
+ ld bc, wChannel5
+ call Tempo
+ ld bc, wChannel6
+ call Tempo
+ ld bc, wChannel7
+ call Tempo
+ ld bc, wChannel8
+ call Tempo
+.end
+ pop bc ; restore current channel
+ ret
+
+Tempo:
+; input:
+; de: note length
+ ; update Tempo
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ; clear ????
+ xor a
+ ld hl, CHANNEL_FIELD16
+ add hl, bc
+ ld [hl], a
+ ret
+
+StartChannel:
+ call SetLRTracks
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_CHANNEL_ON, [hl] ; turn channel on
+ ret
+
+SetLRTracks:
+; set tracks for a the current channel to default
+; seems to be redundant since this is overwritten by stereo data later
+ push de
+ ; store current channel in de
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ ld e, a
+ ld d, 0
+ ; get this channel's lr tracks
+ call GetLRTracks
+ add hl, de ; de = channel 0-3
+ ld a, [hl]
+ ; load lr tracks into Tracks
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld [hl], a
+ pop de
+ ret
+
+_PlayMusic::
+; load music
+ call MusicOff
+ ld hl, wMusicID
+ ld [hl], e ; song number
+ inc hl
+ ld [hl], d ; (always 0)
+ ld hl, Music
+ add hl, de ; three
+ add hl, de ; byte
+ add hl, de ; pointer
+ ld a, [hli]
+ ld [wMusicBank], a
+ ld e, [hl]
+ inc hl
+ ld d, [hl] ; music header address
+ call LoadMusicByte ; store first byte of music header in a
+ rlca
+ rlca
+ maskbits NUM_MUSIC_CHANS
+ inc a
+.loop
+; start playing channels
+ push af
+ call LoadChannel
+ call StartChannel
+ pop af
+ dec a
+ jr nz, .loop
+ xor a
+ ld [wUnusedMusicF9Flag], a
+ ld [wChannel1JumpCondition], a
+ ld [wChannel2JumpCondition], a
+ ld [wChannel3JumpCondition], a
+ ld [wChannel4JumpCondition], a
+ ld [wNoiseSampleAddress], a
+ ld [wNoiseSampleAddress + 1], a
+ ld [wNoiseSampleDelay], a
+ ld [wMusicNoiseSampleSet], a
+ call MusicOn
+ ret
+
+_PlayCry::
+; Play cry de using parameters:
+; wCryPitch
+; wCryLength
+
+ call MusicOff
+
+; Overload the music id with the cry id
+ ld hl, wMusicID
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+; 3-byte pointers (bank, address)
+ ld hl, Cries
+ add hl, de
+ add hl, de
+ add hl, de
+
+ ld a, [hli]
+ ld [wMusicBank], a
+
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+; Read the cry's sound header
+ call LoadMusicByte
+ ; Top 2 bits contain the number of channels
+ rlca
+ rlca
+ maskbits NUM_MUSIC_CHANS
+
+; For each channel:
+ inc a
+.loop
+ push af
+ call LoadChannel
+
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_REST, [hl]
+
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_CRY_PITCH, [hl]
+
+ ld hl, CHANNEL_CRY_PITCH
+ add hl, bc
+ ld a, [wCryPitch]
+ ld [hli], a
+ ld a, [wCryPitch + 1]
+ ld [hl], a
+
+; No tempo for channel 4
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ cp CHAN4
+ jr nc, .start
+
+; Tempo is effectively length
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
+ ld a, [wCryLength]
+ ld [hli], a
+ ld a, [wCryLength + 1]
+ ld [hl], a
+.start
+ call StartChannel
+ ld a, [wStereoPanningMask]
+ and a
+ jr z, .next
+
+; Stereo only: Play cry from the monster's side.
+; This only applies in-battle.
+
+ ld a, [wOptions]
+ bit STEREO, a
+ jr z, .next
+
+; [Tracks] &= [wCryTracks]
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld a, [hl]
+ ld hl, wCryTracks
+ and [hl]
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld [hl], a
+
+.next
+ pop af
+ dec a
+ jr nz, .loop
+
+; Cries play at max volume, so we save the current volume for later.
+ ld a, [wLastVolume]
+ and a
+ jr nz, .end
+
+ ld a, [wVolume]
+ ld [wLastVolume], a
+ ld a, MAX_VOLUME
+ ld [wVolume], a
+
+.end
+ ld a, 1 ; stop playing music
+ ld [wSFXPriority], a
+ call MusicOn
+ ret
+
+_PlaySFX::
+; clear channels if they aren't already
+ call MusicOff
+ ld hl, wChannel5Flags1
+ bit SOUND_CHANNEL_ON, [hl] ; ch5 on?
+ jr z, .ch6
+ res SOUND_CHANNEL_ON, [hl] ; turn it off
+ xor a
+ ldh [rNR11], a ; length/wavepattern = 0
+ ld a, $8
+ ldh [rNR12], a ; envelope = 0
+ xor a
+ ldh [rNR13], a ; frequency lo = 0
+ ld a, $80
+ ldh [rNR14], a ; restart sound (freq hi = 0)
+ xor a
+ ld [wSoundInput], a ; global sound off
+ ldh [rNR10], a ; sweep = 0
+.ch6
+ ld hl, wChannel6Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr z, .ch7
+ res SOUND_CHANNEL_ON, [hl] ; turn it off
+ xor a
+ ldh [rNR21], a ; length/wavepattern = 0
+ ld a, $8
+ ldh [rNR22], a ; envelope = 0
+ xor a
+ ldh [rNR23], a ; frequency lo = 0
+ ld a, $80
+ ldh [rNR24], a ; restart sound (freq hi = 0)
+.ch7
+ ld hl, wChannel7Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr z, .ch8
+ res SOUND_CHANNEL_ON, [hl] ; turn it off
+ xor a
+ ldh [rNR30], a ; sound mode #3 off
+ ldh [rNR31], a ; length/wavepattern = 0
+ ld a, $8
+ ldh [rNR32], a ; envelope = 0
+ xor a
+ ldh [rNR33], a ; frequency lo = 0
+ ld a, $80
+ ldh [rNR34], a ; restart sound (freq hi = 0)
+.ch8
+ ld hl, wChannel8Flags1
+ bit SOUND_CHANNEL_ON, [hl]
+ jr z, .chscleared
+ res SOUND_CHANNEL_ON, [hl] ; turn it off
+ xor a
+ ldh [rNR41], a ; length/wavepattern = 0
+ ld a, $8
+ ldh [rNR42], a ; envelope = 0
+ xor a
+ ldh [rNR43], a ; frequency lo = 0
+ ld a, $80
+ ldh [rNR44], a ; restart sound (freq hi = 0)
+ xor a
+ ld [wNoiseSampleAddress], a
+ ld [wNoiseSampleAddress + 1], a
+.chscleared
+; start reading sfx header for # chs
+ ld hl, wMusicID
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, SFX
+ add hl, de ; three
+ add hl, de ; byte
+ add hl, de ; pointers
+ ; get bank
+ ld a, [hli]
+ ld [wMusicBank], a
+ ; get address
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; get # channels
+ call LoadMusicByte
+ rlca ; top 2
+ rlca ; bits
+ maskbits NUM_MUSIC_CHANS
+ inc a ; # channels -> # loops
+.startchannels
+ push af
+ call LoadChannel ; bc = current channel
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_SFX, [hl]
+ call StartChannel
+ pop af
+ dec a
+ jr nz, .startchannels
+ call MusicOn
+ xor a
+ ld [wSFXPriority], a
+ ret
+
+PlayStereoSFX::
+; play sfx de
+
+ call MusicOff
+
+; standard procedure if stereo's off
+ ld a, [wOptions]
+ bit STEREO, a
+ jp z, _PlaySFX
+
+; else, let's go ahead with this
+ ld hl, wMusicID
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+; get sfx ptr
+ ld hl, SFX
+ add hl, de
+ add hl, de
+ add hl, de
+
+; bank
+ ld a, [hli]
+ ld [wMusicBank], a
+; address
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+; bit 2-3
+ call LoadMusicByte
+ rlca
+ rlca
+ maskbits NUM_MUSIC_CHANS
+ inc a
+
+.loop
+ push af
+ call LoadChannel
+
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_SFX, [hl]
+
+ push de
+ ; get tracks for this channel
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ ld e, a
+ ld d, 0
+ call GetLRTracks
+ add hl, de
+ ld a, [hl]
+ ld hl, wStereoPanningMask
+ and [hl]
+
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld [hl], a
+
+ ld hl, CHANNEL_FIELD30
+ add hl, bc
+ ld [hl], a
+
+ ld a, [wCryTracks]
+ cp 2 ; ch 1-2
+ jr c, .skip
+
+; ch3-4
+ ld a, [wSFXDuration]
+
+ ld hl, CHANNEL_FIELD2E
+ add hl, bc
+ ld [hl], a
+
+ ld hl, CHANNEL_FIELD2F
+ add hl, bc
+ ld [hl], a
+
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_UNKN_0F, [hl]
+
+.skip
+ pop de
+
+; turn channel on
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_CHANNEL_ON, [hl] ; on
+
+; done?
+ pop af
+ dec a
+ jr nz, .loop
+
+; we're done
+ call MusicOn
+ ret
+
+LoadChannel:
+; prep channel for use
+; input:
+; de:
+ ; get pointer to current channel
+ call LoadMusicByte
+ inc de
+ and $7 ; bit 0-2 (current channel)
+ ld [wCurChannel], a
+ ld c, a
+ ld b, 0
+ ld hl, ChannelPointers
+ add hl, bc
+ add hl, bc
+ ld c, [hl]
+ inc hl
+ ld b, [hl] ; bc = channel pointer
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ res SOUND_CHANNEL_ON, [hl] ; channel off
+ call ChannelInit
+ ; load music pointer
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ call LoadMusicByte
+ ld [hli], a
+ inc de
+ call LoadMusicByte
+ ld [hl], a
+ inc de
+ ; load music id
+ ld hl, CHANNEL_MUSIC_ID
+ add hl, bc
+ ld a, [wMusicID]
+ ld [hli], a
+ ld a, [wMusicID + 1]
+ ld [hl], a
+ ; load music bank
+ ld hl, CHANNEL_MUSIC_BANK
+ add hl, bc
+ ld a, [wMusicBank]
+ ld [hl], a
+ ret
+
+ChannelInit:
+; make sure channel is cleared
+; set default tempo and note length in case nothing is loaded
+; input:
+; bc = channel struct pointer
+ push de
+ xor a
+ ; get channel struct location and length
+ ld hl, CHANNEL_MUSIC_ID ; start
+ add hl, bc
+ ld e, CHANNEL_STRUCT_LENGTH ; channel struct length
+ ; clear channel
+.loop
+ ld [hli], a
+ dec e
+ jr nz, .loop
+ ; set tempo to default ($100)
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
+ xor a
+ ld [hli], a
+ inc a
+ ld [hl], a
+ ; set note length to default ($1) (fast)
+ ld hl, CHANNEL_NOTE_LENGTH
+ add hl, bc
+ ld [hl], a
+ pop de
+ ret
+
+LoadMusicByte::
+; input:
+; de = current music address
+; output:
+; a = wCurMusicByte
+ ld a, [wMusicBank]
+ call _LoadMusicByte
+ ld a, [wCurMusicByte]
+ ret
+
+INCLUDE "audio/notes.asm"
+
+INCLUDE "audio/wave_samples.asm"
+
+INCLUDE "audio/drumkits.asm"
+
+GetLRTracks:
+; gets the default sound l/r channels
+; stores mono/stereo table in hl
+ ld a, [wOptions]
+ bit STEREO, a
+ ; made redundant, could have had a purpose in gold
+ jr nz, .stereo
+ ld hl, MonoTracks
+ ret
+
+.stereo
+ ld hl, StereoTracks
+ ret
+
+MonoTracks:
+; bit corresponds to track #
+; hi: left channel
+; lo: right channel
+ db $11, $22, $44, $88
+
+StereoTracks:
+; made redundant
+; seems to be modified on a per-song basis
+ db $11, $22, $44, $88
+
+ChannelPointers:
+; music channels
+ dw wChannel1
+ dw wChannel2
+ dw wChannel3
+ dw wChannel4
+; sfx channels
+ dw wChannel5
+ dw wChannel6
+ dw wChannel7
+ dw wChannel8
+
+ClearChannels::
+; runs ClearChannel for all 4 channels
+; doesn't seem to be used, but functionally identical to MapSetup_Sound_Off
+ ld hl, rNR50
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld a, $80
+ ld [hli], a
+ ld hl, rNR10
+ ld e, NUM_MUSIC_CHANS
+.loop
+ call ClearChannel
+ dec e
+ jr nz, .loop
+ ret
+
+ClearChannel:
+; input: hl = beginning hw sound register (rNR10, rNR20, rNR30, rNR40)
+; output: 00 00 80 00 80
+
+; sound channel 1 2 3 4
+ xor a
+ ld [hli], a ; rNR10, rNR20, rNR30, rNR40 ; sweep = 0
+
+ ld [hli], a ; rNR11, rNR21, rNR31, rNR41 ; length/wavepattern = 0
+ ld a, $8
+ ld [hli], a ; rNR12, rNR22, rNR32, rNR42 ; envelope = 0
+ xor a
+ ld [hli], a ; rNR13, rNR23, rNR33, rNR43 ; frequency lo = 0
+ ld a, $80
+ ld [hli], a ; rNR14, rNR24, rNR34, rNR44 ; restart sound (freq hi = 0)
+ ret
+
+PlayTrainerEncounterMusic::
+; input: e = trainer type
+ ; turn fade off
+ xor a
+ ld [wMusicFade], a
+ ; play nothing for one frame
+ push de
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ ; play new song
+ call MaxVolume
+ pop de
+ ld d, $00
+ ld hl, TrainerEncounterMusic
+ add hl, de
+ ld e, [hl]
+ call PlayMusic
+ ret
diff --git a/audio/music_pointers.asm b/audio/music_pointers.asm
index b72aa344..2e467c0d 100755
--- a/audio/music_pointers.asm
+++ b/audio/music_pointers.asm
@@ -1,94 +1,97 @@
+; See song sections in audio.asm.
+
Music:
- dba Music_None
- dba Music_Title
- dba Music_Route1
- dba Music_Route3
- dba Music_Route12
- dba Music_MagnetTrain
- dba Music_KantoGymLeaderBattle
- dba Music_KantoTrainerBattle
- dba Music_KantoWildBattle
- dba Music_PokemonCenter
- dba Music_HikerEncounter
- dba Music_LassEncounter
- dba Music_OfficerEncounter
- dba Music_Heal
- dba Music_LavenderTown
- dba Music_Route2
- dba Music_MtMoon
- dba Music_ShowMeAround
- dba Music_GameCorner
- dba Music_Bicycle
- dba Music_HallOfFame
- dba Music_ViridianCity
- dba Music_CeladonCity
- dba Music_TrainerVictory
- dba Music_WildVictory
- dba Music_GymVictory
- dba Music_MtMoonSquare
- dba Music_Gym
- dba Music_PalletTown
- dba Music_PokemonTalk
- dba Music_ProfOak
- dba Music_RivalEncounter
- dba Music_RivalAfter
- dba Music_Surf
- dba Music_Evolution
- dba Music_NationalPark
- dba Music_Credits
- dba Music_AzaleaTown
- dba Music_CherrygroveCity
- dba Music_KimonoEncounter
- dba Music_UnionCave
- dba Music_JohtoWildBattle
- dba Music_JohtoTrainerBattle
- dba Music_Route30
- dba Music_EcruteakCity
- dba Music_VioletCity
- dba Music_JohtoGymLeaderBattle
- dba Music_ChampionBattle
- dba Music_RivalBattle
- dba Music_RocketBattle
- dba Music_ProfElm
- dba Music_DarkCave
- dba Music_Route29
- dba Music_Route36
- dba Music_SsAqua
- dba Music_YoungsterEncounter
- dba Music_BeautyEncounter
- dba Music_RocketEncounter
- dba Music_PokemaniacEncounter
- dba Music_SageEncounter
- dba Music_NewBarkTown
- dba Music_GoldenrodCity
- dba Music_VermilionCity
- dba Music_PokemonChannel
- dba Music_PokeFluteChannel
- dba Music_TinTower
- dba Music_SproutTower
- dba Music_BurnedTower
- dba Music_Lighthouse
- dba Music_LakeOfRage
- dba Music_IndigoPlateau
- dba Music_Route37
- dba Music_RocketHideout
- dba Music_DragonsDen
- dba Music_JohtoWildBattleNight
- dba Music_RuinsOfAlphRadio
- dba Music_Capture
- dba Music_Route26
- dba Music_Mom
- dba Music_VictoryRoad
- dba Music_PokemonLullaby
- dba Music_PokemonMarch
- dba Music_GsOpening
- dba Music_GsOpening2
- dba Music_MainMenu
- dba Music_RuinsOfAlphInterior
- dba Music_RocketOverture
- dba Music_DancingHall
- dba Music_BugCatchingContestRanking
- dba Music_BugCatchingContest
- dba Music_LakeOfRageRocketRadio
- dba Music_Printer
- dba Music_PostCredits
+; entries correspond to MUSIC_* constants
+ dba Music_Nothing
+ dba Music_TitleScreen
+ dba Music_Route1
+ dba Music_Route3
+ dba Music_Route12
+ dba Music_MagnetTrain
+ dba Music_KantoGymBattle
+ dba Music_KantoTrainerBattle
+ dba Music_KantoWildBattle
+ dba Music_PokemonCenter
+ dba Music_LookHiker
+ dba Music_LookLass
+ dba Music_LookOfficer
+ dba Music_HealPokemon
+ dba Music_LavenderTown
+ dba Music_Route2
+ dba Music_MtMoon
+ dba Music_ShowMeAround
+ dba Music_GameCorner
+ dba Music_Bicycle
+ dba Music_HallOfFame
+ dba Music_ViridianCity
+ dba Music_CeladonCity
+ dba Music_TrainerVictory
+ dba Music_WildPokemonVictory
+ dba Music_GymLeaderVictory
+ dba Music_MtMoonSquare
+ dba Music_Gym
+ dba Music_PalletTown
+ dba Music_ProfOaksPokemonTalk
+ dba Music_ProfOak
+ dba Music_LookRival
+ dba Music_AfterTheRivalFight
+ dba Music_Surf
+ dba Music_Evolution
+ dba Music_NationalPark
+ dba Music_Credits
+ dba Music_AzaleaTown
+ dba Music_CherrygroveCity
+ dba Music_LookKimonoGirl
+ dba Music_UnionCave
+ dba Music_JohtoWildBattle
+ dba Music_JohtoTrainerBattle
+ dba Music_Route30
+ dba Music_EcruteakCity
+ dba Music_VioletCity
+ dba Music_JohtoGymBattle
+ dba Music_ChampionBattle
+ dba Music_RivalBattle
+ dba Music_RocketBattle
+ dba Music_ElmsLab
+ dba Music_DarkCave
+ dba Music_Route29
+ dba Music_Route36
+ dba Music_SSAqua
+ dba Music_LookYoungster
+ dba Music_LookBeauty
+ dba Music_LookRocket
+ dba Music_LookPokemaniac
+ dba Music_LookSage
+ dba Music_NewBarkTown
+ dba Music_GoldenrodCity
+ dba Music_VermilionCity
+ dba Music_PokemonChannel
+ dba Music_PokeFluteChannel
+ dba Music_TinTower
+ dba Music_SproutTower
+ dba Music_BurnedTower
+ dba Music_Lighthouse
+ dba Music_LakeOfRage
+ dba Music_IndigoPlateau
+ dba Music_Route37
+ dba Music_RocketHideout
+ dba Music_DragonsDen
+ dba Music_JohtoWildBattleNight
+ dba Music_RuinsOfAlphRadio
+ dba Music_SuccessfulCapture
+ dba Music_Route26
+ dba Music_Mom
+ dba Music_VictoryRoad
+ dba Music_PokemonLullaby
+ dba Music_PokemonMarch
+ dba Music_GoldSilverOpening
+ dba Music_GoldSilverOpening2
+ dba Music_MainMenu
+ dba Music_RuinsOfAlphInterior
+ dba Music_RocketTheme
+ dba Music_DancingHall
+ dba Music_ContestResults
+ dba Music_BugCatchingContest
+ dba Music_LakeOfRageRocketRadio
+ dba Music_Printer
+ dba Music_PostCredits
diff --git a/audio/notes.asm b/audio/notes.asm
new file mode 100644
index 00000000..eeb84959
--- /dev/null
+++ b/audio/notes.asm
@@ -0,0 +1,26 @@
+FrequencyTable:
+ dw 0 ; __
+ dw $f82c ; C_
+ dw $f89d ; C#
+ dw $f907 ; D_
+ dw $f96b ; D#
+ dw $f9ca ; E_
+ dw $fa23 ; F_
+ dw $fa77 ; F#
+ dw $fac7 ; G_
+ dw $fb12 ; G#
+ dw $fb58 ; A_
+ dw $fb9b ; A#
+ dw $fbda ; B_
+ dw $fc16 ; C_
+ dw $fc4e ; C#
+ dw $fc83 ; D_
+ dw $fcb5 ; D#
+ dw $fce5 ; E_
+ dw $fd11 ; F_
+ dw $fd3b ; F#
+ dw $fd63 ; G_
+ dw $fd89 ; G#
+ dw $fdac ; A_
+ dw $fdcd ; A#
+ dw $fded ; B_
diff --git a/audio/sfx_pointers.asm b/audio/sfx_pointers.asm
new file mode 100644
index 00000000..9a8809dc
--- /dev/null
+++ b/audio/sfx_pointers.asm
@@ -0,0 +1,190 @@
+SFX:
+; entries correspond to SFX_* constants
+ dba Sfx_DexFanfare5079
+ dba Sfx_Item
+ dba Sfx_CaughtMon
+ dba Sfx_PokeballsPlacedOnTable
+ dba Sfx_Potion
+ dba Sfx_FullHeal
+ dba Sfx_Menu
+ dba Sfx_ReadText
+ dba Sfx_ReadText2
+ dba Sfx_DexFanfare2049
+ dba Sfx_DexFanfare80109
+ dba Sfx_Poison
+ dba Sfx_GotSafariBalls
+ dba Sfx_BootPc
+ dba Sfx_ShutDownPc
+ dba Sfx_ChoosePcOption
+ dba Sfx_EscapeRope
+ dba Sfx_PushButton
+ dba Sfx_SecondPartOfItemfinder
+ dba Sfx_WarpTo
+ dba Sfx_WarpFrom
+ dba Sfx_ChangeDexMode
+ dba Sfx_JumpOverLedge
+ dba Sfx_GrassRustle
+ dba Sfx_Fly
+ dba Sfx_Wrong
+ dba Sfx_Squeak
+ dba Sfx_Strength
+ dba Sfx_Boat
+ dba Sfx_WallOpen
+ dba Sfx_PlacePuzzlePieceDown
+ dba Sfx_EnterDoor
+ dba Sfx_SwitchPokemon
+ dba Sfx_Tally
+ dba Sfx_Transaction
+ dba Sfx_ExitBuilding
+ dba Sfx_Bump
+ dba Sfx_Save
+ dba Sfx_Pokeflute
+ dba Sfx_ElevatorEnd
+ dba Sfx_ThrowBall
+ dba Sfx_BallPoof
+ dba Sfx_Unknown3A
+ dba Sfx_Run
+ dba Sfx_SlotMachineStart
+ dba Sfx_Fanfare
+ dba Sfx_Peck
+ dba Sfx_Kinesis
+ dba Sfx_Lick
+ dba Sfx_Pound
+ dba Sfx_MovePuzzlePiece
+ dba Sfx_CometPunch
+ dba Sfx_MegaPunch
+ dba Sfx_Scratch
+ dba Sfx_Vicegrip
+ dba Sfx_RazorWind
+ dba Sfx_Cut
+ dba Sfx_WingAttack
+ dba Sfx_Whirlwind
+ dba Sfx_Bind
+ dba Sfx_VineWhip
+ dba Sfx_DoubleKick
+ dba Sfx_MegaKick
+ dba Sfx_Headbutt
+ dba Sfx_HornAttack
+ dba Sfx_Tackle
+ dba Sfx_PoisonSting
+ dba Sfx_Powder
+ dba Sfx_Doubleslap
+ dba Sfx_Bite
+ dba Sfx_JumpKick
+ dba Sfx_Stomp
+ dba Sfx_TailWhip
+ dba Sfx_KarateChop
+ dba Sfx_Submission
+ dba Sfx_WaterGun
+ dba Sfx_SwordsDance
+ dba Sfx_Thunder
+ dba Sfx_Supersonic
+ dba Sfx_Leer
+ dba Sfx_Ember
+ dba Sfx_Bubblebeam
+ dba Sfx_HydroPump
+ dba Sfx_Surf
+ dba Sfx_Psybeam
+ dba Sfx_Charge
+ dba Sfx_Thundershock
+ dba Sfx_Psychic
+ dba Sfx_Screech
+ dba Sfx_BoneClub
+ dba Sfx_Sharpen
+ dba Sfx_EggBomb
+ dba Sfx_Sing
+ dba Sfx_HyperBeam
+ dba Sfx_Shine
+ dba Sfx_Unknown5F
+ dba Sfx_Unknown60
+ dba Sfx_Unknown61
+ dba Sfx_SwitchPockets
+ dba Sfx_Unknown63
+ dba Sfx_Burn
+ dba Sfx_TitleScreenEntrance
+ dba Sfx_Unknown66
+ dba Sfx_GetCoinFromSlots
+ dba Sfx_PayDay
+ dba Sfx_Metronome
+ dba Sfx_Call
+ dba Sfx_HangUp
+ dba Sfx_NoSignal
+ dba Sfx_Sandstorm
+ dba Sfx_Elevator
+ dba Sfx_Protect
+ dba Sfx_Sketch
+ dba Sfx_RainDance
+ dba Sfx_Aeroblast
+ dba Sfx_Spark
+ dba Sfx_Curse
+ dba Sfx_Rage
+ dba Sfx_Thief
+ dba Sfx_Thief2
+ dba Sfx_SpiderWeb
+ dba Sfx_MindReader
+ dba Sfx_Nightmare
+ dba Sfx_Snore
+ dba Sfx_SweetKiss
+ dba Sfx_SweetKiss2
+ dba Sfx_BellyDrum
+ dba Sfx_Unknown7F
+ dba Sfx_SludgeBomb
+ dba Sfx_Foresight
+ dba Sfx_Spite
+ dba Sfx_Outrage
+ dba Sfx_PerishSong
+ dba Sfx_GigaDrain
+ dba Sfx_Attract
+ dba Sfx_Kinesis2
+ dba Sfx_ZapCannon
+ dba Sfx_MeanLook
+ dba Sfx_HealBell
+ dba Sfx_Return
+ dba Sfx_ExpBar
+ dba Sfx_MilkDrink
+ dba Sfx_Present
+ dba Sfx_MorningSun
+ dba Sfx_LevelUp
+ dba Sfx_KeyItem
+ dba Sfx_Fanfare2
+ dba Sfx_RegisterPhoneNumber
+ dba Sfx_3RdPlace
+ dba Sfx_GetEggFromDayCareMan
+ dba Sfx_GetEggFromDayCareLady
+ dba Sfx_MoveDeleted
+ dba Sfx_2ndPlace
+ dba Sfx_1stPlace
+ dba Sfx_ChooseACard
+ dba Sfx_GetTm
+ dba Sfx_GetBadge
+ dba Sfx_QuitSlots
+ dba Sfx_EggCrack
+ dba Sfx_DexFanfareLessThan20
+ dba Sfx_DexFanfare140169
+ dba Sfx_DexFanfare170199
+ dba Sfx_DexFanfare200229
+ dba Sfx_DexFanfare230Plus
+ dba Sfx_Evolved
+ dba Sfx_MasterBall
+ dba Sfx_EggHatch
+ dba Sfx_GsIntroCharizardFireball
+ dba Sfx_GsIntroPokemonAppears
+ dba Sfx_Flash
+ dba Sfx_GameFreakLogoGs
+ dba Sfx_NotVeryEffective
+ dba Sfx_Damage
+ dba Sfx_SuperEffective
+ dba Sfx_BallBounce
+ dba Sfx_Moonlight
+ dba Sfx_Encore
+ dba Sfx_BeatUp
+ dba Sfx_BatonPass
+ dba Sfx_BallWobble
+ dba Sfx_SweetScent
+ dba Sfx_SweetScent2
+ dba Sfx_HitEndOfExpBar
+ dba Sfx_GiveTrademon
+ dba Sfx_GetTrademon
+ dba Sfx_TrainArrived
+ dba Sfx_StopSlot
+ dba Sfx_2Boops
diff --git a/audio/wave_samples.asm b/audio/wave_samples.asm
new file mode 100644
index 00000000..81fee211
--- /dev/null
+++ b/audio/wave_samples.asm
@@ -0,0 +1,13 @@
+WaveSamples:
+ ; These are streams of 32 nybbles (4-bit values) used as wave patterns.
+ ; Plot them as a line chart to see the wave's shape.
+ dn 0, 2, 4, 6, 8, 10, 12, 14, 15, 15, 15, 14, 14, 13, 13, 12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 1, 1
+ dn 0, 2, 4, 6, 8, 10, 12, 14, 14, 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 1, 1
+ dn 1, 3, 6, 9, 11, 13, 14, 14, 14, 14, 15, 15, 15, 15, 14, 13, 13, 14, 15, 15, 15, 15, 14, 14, 14, 14, 13, 11, 9, 6, 3, 1
+ dn 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 15, 14, 13, 14, 15, 15, 14, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+ dn 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 14, 15, 7, 7, 15, 14, 14, 13, 12, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0
+ dn 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1, 1, 15, 15, 14, 14, 12, 12, 10, 10, 8, 8, 10, 10, 12, 12, 14, 14
+ dn 0, 2, 4, 6, 8, 10, 12, 14, 12, 11, 10, 9, 8, 7, 6, 5, 15, 15, 15, 14, 14, 13, 13, 12, 4, 4, 3, 3, 2, 2, 1, 1
+ dn 12, 0, 10, 9, 8, 7, 15, 5, 15, 15, 15, 14, 14, 13, 13, 12, 4, 4, 3, 3, 2, 2, 15, 1, 0, 2, 4, 6, 8, 10, 12, 14
+ dn 4, 4, 3, 3, 2, 2, 1, 15, 0, 0, 4, 6, 8, 10, 12, 14, 15, 8, 15, 14, 14, 13, 13, 12, 12, 11, 10, 9, 8, 7, 6, 5
+ dn 1, 1, 0, 0, 0, 0, 0, 8, 0, 0, 1, 3, 5, 7, 9, 10, 11, 4, 11, 10, 10, 9, 9, 8, 8, 7, 6, 5, 4, 3, 2, 1
diff --git a/constants/audio_constants.asm b/constants/audio_constants.asm
index a07887e0..1d092edf 100755
--- a/constants/audio_constants.asm
+++ b/constants/audio_constants.asm
@@ -1,63 +1,130 @@
-
-
; pitch
+; FrequencyTable indexes (see audio/notes.asm)
const_def
- const __
- const C_
- const C#
- const D_
- const D#
- const E_
- const F_
- const F#
- const G_
- const G#
- const A_
- const A#
- const B_
- const CC
+ const __ ; 0
+ const C_ ; 1
+ const C# ; 2
+ const D_ ; 3
+ const D# ; 4
+ const E_ ; 5
+ const F_ ; 6
+ const F# ; 7
+ const G_ ; 8
+ const G# ; 9
+ const A_ ; a
+ const A# ; b
+ const B_ ; c
+ const CC ; d (used for pitchoffset)
; channel
+; ChannelPointers indexes (see audio/engine.asm)
const_def
- const CHAN1
- const CHAN2
- const CHAN3
- const CHAN4
+ const CHAN1 ; 0
+ const CHAN2 ; 1
+ const CHAN3 ; 2
+ const CHAN4 ; 3
NUM_MUSIC_CHANS EQU const_value
-NUM_NOISE_CHANS EQU const_value
- const CHAN5
- const CHAN6
- const CHAN7
- const CHAN8
+ const CHAN5 ; 4
+ const CHAN6 ; 5
+ const CHAN7 ; 6
+ const CHAN8 ; 7
+NUM_NOISE_CHANS EQU const_value - NUM_MUSIC_CHANS
NUM_CHANNELS EQU const_value
+; channel_struct members (see macros/wram.asm)
+CHANNEL_MUSIC_ID EQUS "(wChannel1MusicID - wChannel1)"
+CHANNEL_MUSIC_BANK EQUS "(wChannel1MusicBank - wChannel1)"
+CHANNEL_FLAGS1 EQUS "(wChannel1Flags1 - wChannel1)"
+CHANNEL_FLAGS2 EQUS "(wChannel1Flags2 - wChannel1)"
+CHANNEL_FLAGS3 EQUS "(wChannel1Flags3 - wChannel1)"
+CHANNEL_MUSIC_ADDRESS EQUS "(wChannel1MusicAddress - wChannel1)"
+CHANNEL_LAST_MUSIC_ADDRESS EQUS "(wChannel1LastMusicAddress - wChannel1)"
+CHANNEL_NOTE_FLAGS EQUS "(wChannel1NoteFlags - wChannel1)"
+CHANNEL_CONDITION EQUS "(wChannel1Condition - wChannel1)"
+CHANNEL_DUTY_CYCLE EQUS "(wChannel1DutyCycle - wChannel1)"
+CHANNEL_INTENSITY EQUS "(wChannel1Intensity - wChannel1)"
+CHANNEL_FREQUENCY EQUS "(wChannel1Frequency - wChannel1)"
+CHANNEL_PITCH EQUS "(wChannel1Pitch - wChannel1)"
+CHANNEL_OCTAVE EQUS "(wChannel1Octave - wChannel1)"
+CHANNEL_PITCH_OFFSET EQUS "(wChannel1PitchOffset - wChannel1)"
+CHANNEL_NOTE_DURATION EQUS "(wChannel1NoteDuration - wChannel1)"
+CHANNEL_FIELD16 EQUS "(wChannel1Field16 - wChannel1)"
+CHANNEL_LOOP_COUNT EQUS "(wChannel1LoopCount - wChannel1)"
+CHANNEL_TEMPO EQUS "(wChannel1Tempo - wChannel1)"
+CHANNEL_TRACKS EQUS "(wChannel1Tracks - wChannel1)"
+CHANNEL_SFX_DUTY_LOOP EQUS "(wChannel1SFXDutyLoop - wChannel1)"
+CHANNEL_VIBRATO_DELAY_COUNT EQUS "(wChannel1VibratoDelayCount - wChannel1)"
+CHANNEL_VIBRATO_DELAY EQUS "(wChannel1VibratoDelay - wChannel1)"
+CHANNEL_VIBRATO_EXTENT EQUS "(wChannel1VibratoExtent - wChannel1)"
+CHANNEL_VIBRATO_RATE EQUS "(wChannel1VibratoRate - wChannel1)"
+CHANNEL_PITCH_WHEEL_TARGET EQUS "(wChannel1PitchWheelTarget - wChannel1)"
+CHANNEL_PITCH_WHEEL_AMOUNT EQUS "(wChannel1PitchWheelAmount - wChannel1)"
+CHANNEL_PITCH_WHEEL_AMOUNT_FRACTION EQUS "(wChannel1PitchWheelAmountFraction - wChannel1)"
+CHANNEL_FIELD25 EQUS "(wChannel1Field25 - wChannel1)"
+CHANNEL_CRY_PITCH EQUS "(wChannel1CryPitch - wChannel1)"
+CHANNEL_FIELD29 EQUS "(wChannel1Field29 - wChannel1)"
+CHANNEL_FIELD2A EQUS "(wChannel1Field2a - wChannel1)"
+CHANNEL_FIELD2C EQUS "(wChannel1Field2c - wChannel1)"
+CHANNEL_NOTE_LENGTH EQUS "(wChannel1NoteLength - wChannel1)"
+CHANNEL_FIELD2E EQUS "(wChannel1Field2e - wChannel1)"
+CHANNEL_FIELD2F EQUS "(wChannel1Field2f - wChannel1)"
+CHANNEL_FIELD30 EQUS "(wChannel1Field30 - wChannel1)"
+CHANNEL_STRUCT_LENGTH EQUS "(wChannel2 - wChannel1)"
+
+NOISE_CHAN_F EQU 2 ; bit set in CHAN5-CHAN7
+
; Flags1
-SOUND_CHANNEL_ON EQU 0
-SOUND_SUBROUTINE EQU 1
-SOUND_LOOPING EQU 2
-SOUND_SFX EQU 3
-SOUND_NOISE EQU 4
-SOUND_REST EQU 5
+ const_def
+ const SOUND_CHANNEL_ON ; 0
+ const SOUND_SUBROUTINE ; 1
+ const SOUND_LOOPING ; 2
+ const SOUND_SFX ; 3
+ const SOUND_NOISE ; 4
+ const SOUND_REST ; 5
; Flags2
-
-SOUND_VIBRATO EQU 0
-SOUND_PITCH_WHEEL EQU 1
-SOUND_DUTY EQU 2
-SOUND_UNKN_0B EQU 3
-SOUND_CRY_PITCH EQU 4
-SOUND_UNKN_0D EQU 5
-SOUND_UNKN_0E EQU 6
-SOUND_UNKN_0F EQU 7
+ const_def
+ const SOUND_VIBRATO ; 0
+ const SOUND_PITCH_WHEEL ; 1
+ const SOUND_DUTY ; 2
+ const SOUND_UNKN_0B ; 3
+ const SOUND_CRY_PITCH ; 4
+ const SOUND_UNKN_0D ; 5
+ const SOUND_UNKN_0E ; 6
+ const SOUND_UNKN_0F ; 7
; Flags3
-SOUND_VIBRATO_DIR EQU 0
-SOUND_PITCH_WHEEL_DIR EQU 1
+ const_def
+ const SOUND_VIBRATO_DIR ; 0
+ const SOUND_PITCH_WHEEL_DIR ; 1
; NoteFlags
-NOTE_UNKN_0 EQU 0
-NOTE_UNKN_1 EQU 1
-NOTE_UNKN_3 EQU 3
-NOTE_UNKN_4 EQU 4
-NOTE_REST EQU 5
-NOTE_UNKN_6 EQU 6
+ const_def
+ const NOTE_DUTY_OVERRIDE ; 0
+ const NOTE_FREQ_OVERRIDE ; 1
+ const NOTE_UNUSED ; 2
+ const NOTE_UNKN_3 ; 3
+ const NOTE_NOISE_SAMPLING ; 4
+ const NOTE_REST ; 5
+ const NOTE_VIBRATO_OVERRIDE ; 6
+
+; wVolume
+VOLUME_SO1_F EQU 3
+VOLUME_SO2_F EQU 7
+VOLUME_SO1_LEVEL EQU %00000111
+VOLUME_SO2_LEVEL EQU %01110000
+MAX_VOLUME EQU $77
+
+; wSoundInput
+SOUND_INPUT_CH1_F EQU 0
+SOUND_INPUT_CH2_F EQU 1
+SOUND_INPUT_CH3_F EQU 2
+SOUND_INPUT_CH4_F EQU 3
+SOUND_INPUT_GLOBAL_F EQU 7
+
+; wLowHealthAlarm
+DANGER_PITCH_F EQU 4
+DANGER_ON_F EQU 7
+
+; wMusicFade
+MUSIC_FADE_IN_F EQU 7
diff --git a/data/trainers/encounter_music.asm b/data/trainers/encounter_music.asm
new file mode 100644
index 00000000..a64d160f
--- /dev/null
+++ b/data/trainers/encounter_music.asm
@@ -0,0 +1,75 @@
+; What music plays when a trainer notices you
+
+TrainerEncounterMusic::
+; entries correspond to trainer classes (see constants/trainer_constants.asm)
+ db MUSIC_HIKER_ENCOUNTER ; none
+ db MUSIC_YOUNGSTER_ENCOUNTER ; falkner
+ db MUSIC_LASS_ENCOUNTER ; whitney
+ db MUSIC_YOUNGSTER_ENCOUNTER ; bugsy
+ db MUSIC_OFFICER_ENCOUNTER ; morty
+ db MUSIC_OFFICER_ENCOUNTER ; pryce
+ db MUSIC_LASS_ENCOUNTER ; jasmine
+ db MUSIC_OFFICER_ENCOUNTER ; chuck
+ db MUSIC_BEAUTY_ENCOUNTER ; clair
+ db MUSIC_RIVAL_ENCOUNTER ; rival1
+ db MUSIC_HIKER_ENCOUNTER ; pokemon_prof
+ db MUSIC_HIKER_ENCOUNTER ; will
+ db MUSIC_HIKER_ENCOUNTER ; cal
+ db MUSIC_OFFICER_ENCOUNTER ; bruno
+ db MUSIC_HIKER_ENCOUNTER ; karen
+ db MUSIC_HIKER_ENCOUNTER ; koga
+ db MUSIC_OFFICER_ENCOUNTER ; champion
+ db MUSIC_YOUNGSTER_ENCOUNTER ; brock
+ db MUSIC_LASS_ENCOUNTER ; misty
+ db MUSIC_OFFICER_ENCOUNTER ; lt_surge
+ db MUSIC_ROCKET_ENCOUNTER ; scientist
+ db MUSIC_OFFICER_ENCOUNTER ; erika
+ db MUSIC_YOUNGSTER_ENCOUNTER ; youngster
+ db MUSIC_YOUNGSTER_ENCOUNTER ; schoolboy
+ db MUSIC_YOUNGSTER_ENCOUNTER ; bird_keeper
+ db MUSIC_LASS_ENCOUNTER ; lass
+ db MUSIC_LASS_ENCOUNTER ; janine
+ db MUSIC_HIKER_ENCOUNTER ; cooltrainerm
+ db MUSIC_BEAUTY_ENCOUNTER ; cooltrainerf
+ db MUSIC_BEAUTY_ENCOUNTER ; beauty
+ db MUSIC_POKEMANIAC_ENCOUNTER ; pokemaniac
+ db MUSIC_ROCKET_ENCOUNTER ; gruntm
+ db MUSIC_HIKER_ENCOUNTER ; gentleman
+ db MUSIC_BEAUTY_ENCOUNTER ; skier
+ db MUSIC_BEAUTY_ENCOUNTER ; teacher
+ db MUSIC_BEAUTY_ENCOUNTER ; sabrina
+ db MUSIC_YOUNGSTER_ENCOUNTER ; bug_catcher
+ db MUSIC_HIKER_ENCOUNTER ; fisher
+ db MUSIC_HIKER_ENCOUNTER ; swimmerm
+ db MUSIC_BEAUTY_ENCOUNTER ; swimmerf
+ db MUSIC_HIKER_ENCOUNTER ; sailor
+ db MUSIC_POKEMANIAC_ENCOUNTER ; super_nerd
+ db MUSIC_RIVAL_ENCOUNTER ; rival2
+ db MUSIC_HIKER_ENCOUNTER ; guitarist
+ db MUSIC_HIKER_ENCOUNTER ; hiker
+ db MUSIC_HIKER_ENCOUNTER ; biker
+ db MUSIC_OFFICER_ENCOUNTER ; blaine
+ db MUSIC_POKEMANIAC_ENCOUNTER ; burglar
+ db MUSIC_HIKER_ENCOUNTER ; firebreather
+ db MUSIC_POKEMANIAC_ENCOUNTER ; juggler
+ db MUSIC_HIKER_ENCOUNTER ; blackbelt_t
+ db MUSIC_ROCKET_ENCOUNTER ; executivem
+ db MUSIC_YOUNGSTER_ENCOUNTER ; psychic_t
+ db MUSIC_LASS_ENCOUNTER ; picnicker
+ db MUSIC_YOUNGSTER_ENCOUNTER ; camper
+ db MUSIC_ROCKET_ENCOUNTER ; executivef
+ db MUSIC_SAGE_ENCOUNTER ; sage
+ db MUSIC_SAGE_ENCOUNTER ; medium
+ db MUSIC_HIKER_ENCOUNTER ; boarder
+ db MUSIC_HIKER_ENCOUNTER ; pokefanm
+ db MUSIC_KIMONO_ENCOUNTER ; kimono_girl
+ db MUSIC_LASS_ENCOUNTER ; twins
+ db MUSIC_BEAUTY_ENCOUNTER ; pokefanf
+ db MUSIC_HIKER_ENCOUNTER ; red
+ db MUSIC_RIVAL_ENCOUNTER ; blue
+ db MUSIC_HIKER_ENCOUNTER ; officer
+ db MUSIC_ROCKET_ENCOUNTER ; gruntf
+ db MUSIC_HIKER_ENCOUNTER ; mysticalman
+ db MUSIC_HIKER_ENCOUNTER
+ db MUSIC_HIKER_ENCOUNTER
+ db MUSIC_HIKER_ENCOUNTER
diff --git a/engine/events/overworld.asm b/engine/events/overworld.asm
index 68f7dcc3..82981450 100755
--- a/engine/events/overworld.asm
+++ b/engine/events/overworld.asm
@@ -360,7 +360,7 @@ CheckAbleToSurf:
jr c, .asm_c980
CheckFlagHL ENGINE_ALWAYS_ON_BIKE
jr nz, .asm_c986
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp PLAYER_SURF
jr z, .asm_c983
cp PLAYER_SURF_PIKA
@@ -472,7 +472,7 @@ GetSurfDirection: ; c9ea (3:49ea)
db FACE_RIGHT
TrySurfOW::
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp PLAYER_SURF_PIKA
jr z, .quit
cp PLAYER_SURF
@@ -1389,7 +1389,7 @@ FishingRodFunction: ; cf91
dw Fish_NoFish ; 3:5013
Fish_CheckMap:
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp PLAYER_SURF
jr z, .asm_cfc7
cp PLAYER_SURF_PIKA
@@ -1575,7 +1575,7 @@ BicycleFunction:
Functiond0c9: ; d0c9 (3:50c9)
call CheckBikePermission
jr c, .cant_bike
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp PLAYER_NORMAL
jr z, .get_on_bike
cp PLAYER_BIKE
diff --git a/engine/main_menu.asm b/engine/main_menu.asm
index 9a829be9..ff480e37 100755
--- a/engine/main_menu.asm
+++ b/engine/main_menu.asm
@@ -819,7 +819,7 @@ OakText2:
text_jump _OakText2
start_asm
ld a, MARILL
- call PlayCry
+ call PlayMonCry
call WaitSFX
ld hl, OakText3 ; $606c
ret
diff --git a/engine/overworld/player_movement.asm b/engine/overworld/player_movement.asm
index 61b45a72..1fdec4e2 100755
--- a/engine/overworld/player_movement.asm
+++ b/engine/overworld/player_movement.asm
@@ -24,7 +24,7 @@ Function10017: ; 10017 (4:4017)
ret
Function1002d: ; 1002d (4:402d)
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp PLAYER_NORMAL
jr z, .asm_10044
cp PLAYER_SURF
@@ -236,7 +236,7 @@ Function10147: ; 10147 (4:4147)
ret
Function1016b: ; 1016b (4:416b)
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp $4
jr z, Function101c0
cp $8
@@ -655,7 +655,7 @@ Function103b4: ; 103b4 (4:43b4)
ret
Function103ca: ; 103ca (4:43ca)
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp $1
ret z
cp $2
@@ -699,7 +699,7 @@ Function103ee: ; 103ee (4:43ee)
Function103f9: ; 103f9 (4:43f9)
push bc
ld a, $0
- ld [wPlayerBikeSurfState], a
+ ld [wPlayerState], a
call ReplacePlayerSprite
pop bc
ret
@@ -713,7 +713,7 @@ Function10404: ; 10404 (4:4404)
ld a, [wPlayerStandingTile]
call CheckIceTile
jr nc, .asm_1041e
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp $2
jr nz, .asm_10420
.asm_1041e
diff --git a/engine/specials.asm b/engine/specials.asm
index 6cd4fa91..b26b6bf1 100755
--- a/engine/specials.asm
+++ b/engine/specials.asm
@@ -521,7 +521,7 @@ SnorlaxAwake: ; c5d6 (3:45d6)
PlayCurMonCry: ; c60b (3:460b)
ld a, [wCurPartySpecies]
- jp PlayCry
+ jp PlayMonCry
GameboyCheck: ; c611 (3:4611)
ld a, [hCGB]
diff --git a/engine/variables.asm b/engine/variables.asm
index 4d67c2bf..e2a399f0 100755
--- a/engine/variables.asm
+++ b/engine/variables.asm
@@ -42,7 +42,7 @@ GetVarAction_::
dwb .CountCaughtMons, RETVAR_EXECUTE
dwb .CountSeenMons, RETVAR_EXECUTE
dwb .CountBadges, RETVAR_EXECUTE
- dwb wPlayerBikeSurfState, RETVAR_ADDR_DE
+ dwb wPlayerState, RETVAR_ADDR_DE
dwb .PlayerFacing, RETVAR_EXECUTE
dwb hHours, RETVAR_STRBUF2
dwb .DayOfWeek, RETVAR_EXECUTE
diff --git a/home/audio.asm b/home/audio.asm
index 4e931ab4..bf080550 100644
--- a/home/audio.asm
+++ b/home/audio.asm
@@ -1,14 +1,14 @@
-DisableAudio:: ; 3d4f (0:3d4f)
+MapSetup_Sound_Off:: ; 3d4f (0:3d4f)
push hl
push de
push bc
push af
ld a, [hROMBank]
push af
- ld a, BANK(DisableAudio_)
+ ld a, BANK(_MapSetup_Sound_Off)
ld [hROMBank], a
ld [MBC3RomBank], a
- call DisableAudio_
+ call _MapSetup_Sound_Off
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
@@ -25,10 +25,10 @@ UpdateSound:: ; 3d6b (0:3d6b)
push af
ld a, [hROMBank]
push af
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
ld [hROMBank], a
ld [MBC3RomBank], a
- call UpdateSound_
+ call _UpdateSound
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
@@ -38,13 +38,13 @@ UpdateSound:: ; 3d6b (0:3d6b)
pop hl
ret
-LoadMusicByte_::
+_LoadMusicByte::
ld [hROMBank], a
ld [MBC3RomBank], a
ld a, [de]
ld [wCurMusicByte], a
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
ld [hROMBank], a
ld [MBC3RomBank], a
@@ -57,17 +57,17 @@ PlayMusic:: ; 3d98 (0:3d98)
push af
ld a, [hROMBank]
push af
- ld a, BANK(PlayMusic_)
+ ld a, BANK(_PlayMusic)
ld [hROMBank], a
ld [MBC3RomBank], a
ld a, e
and a
jr z, .asm_3daf
- call PlayMusic_ ; $4b30
+ call _PlayMusic ; $4b30
jr .asm_3db2
.asm_3daf
- call DisableAudio_
+ call _MapSetup_Sound_Off
.asm_3db2
pop af
ld [hROMBank], a
@@ -85,15 +85,15 @@ PlayMusic2::
push af
ld a, [hROMBank]
push af
- ld a, BANK(PlayMusic_)
+ ld a, BANK(_PlayMusic)
ld [hROMBank], a
ld [MBC3RomBank], a
push de
ld de, MUSIC_NONE
- call PlayMusic_
+ call _PlayMusic
call DelayFrame
pop de
- call PlayMusic_
+ call _PlayMusic
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
@@ -103,7 +103,7 @@ PlayMusic2::
pop hl
ret
-PlayCryHeader:: ; 3de4 (0:3de4)
+PlayCry:: ; 3de4 (0:3de4)
push hl
push de
push bc
@@ -132,10 +132,10 @@ PlayCryHeader:: ; 3de4 (0:3de4)
ld [wCryLength], a
ld a, [hl]
ld [wCryLength + 1], a
- ld a, BANK(PlayCryHeader_)
+ ld a, BANK(_PlayCry)
ld [hROMBank], a
ld [MBC3RomBank], a
- call PlayCryHeader_
+ call _PlayCry
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
@@ -158,12 +158,12 @@ PlaySFX:: ; 3e24 (0:3e24)
.asm_3e33
ld a, [hROMBank]
push af
- ld a, BANK(PlaySFX_) ; $3a
+ ld a, BANK(_PlaySFX) ; $3a
ld [hROMBank], a
ld [MBC3RomBank], a
ld a, e
ld [wCurSFX], a
- call PlaySFX_ ; $4c04
+ call _PlaySFX ; $4c04
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
@@ -182,16 +182,16 @@ WaitPlaySFX::
WaitSFX:: ; 3e56 (0:3e56)
push hl
.asm_3e57
- ld hl, wChannel5Flags
+ ld hl, wChannel5Flags1
bit 0, [hl]
jr nz, .asm_3e57
- ld hl, wChannel6Flags
+ ld hl, wChannel6Flags1
bit 0, [hl]
jr nz, .asm_3e57
- ld hl, wChannel7Flags
+ ld hl, wChannel7Flags1
bit 0, [hl]
jr nz, .asm_3e57
- ld hl, wChannel8Flags
+ ld hl, wChannel8Flags1
bit 0, [hl]
jr nz, .asm_3e57
pop hl
@@ -285,7 +285,7 @@ EnterMapMusic::
xor a
ld [wDontPlayMapMusicOnReload], a
ld de, MUSIC_BICYCLE
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp $1
jr z, .asm_3ef6
call GetMapMusic
@@ -336,7 +336,7 @@ RestartMapMusic::
ret
SpecialMapMusic:: ; 3f40 (0:3f40)
- ld a, [wPlayerBikeSurfState]
+ ld a, [wPlayerState]
cp PLAYER_SURF
jr z, .surf
cp PLAYER_SURF_PIKA
@@ -411,16 +411,16 @@ Function3f7d::
ret
CheckSFX:: ; 3fbc (0:3fbc)
- ld a, [wChannel5Flags]
+ ld a, [wChannel5Flags1]
bit 0, a
jr nz, .asm_3fda
- ld a, [wChannel6Flags]
+ ld a, [wChannel6Flags1]
bit 0, a
jr nz, .asm_3fda
- ld a, [wChannel7Flags]
+ ld a, [wChannel7Flags1]
bit 0, a
jr nz, .asm_3fda
- ld a, [wChannel8Flags]
+ ld a, [wChannel8Flags1]
bit 0, a
jr nz, .asm_3fda
and a
@@ -432,7 +432,7 @@ CheckSFX:: ; 3fbc (0:3fbc)
TerminateExpBarSound::
xor a
- ld [wChannel5Flags], a
+ ld [wChannel5Flags1], a
ld [wSoundInput], a
ld [rNR10], a
ld [rNR11], a
diff --git a/home/cry.asm b/home/cry.asm
index 6a6dd561..3fcda0c3 100644
--- a/home/cry.asm
+++ b/home/cry.asm
@@ -3,15 +3,16 @@ PlayStereoCry:: ; 39f0 (0:39f0)
ld a, $1
ld [wStereoPanningMask], a
pop af
- jr continue_cry_fn
+ jr _PlayMonCry
-PlayCry:: ; 39f9 (0:39f9)
+PlayMonCry:: ; 39f9 (0:39f9)
push af
xor a
ld [wStereoPanningMask], a
ld [wCryTracks], a
pop af
-continue_cry_fn
+
+_PlayMonCry::
push hl
push de
push bc
@@ -19,7 +20,7 @@ continue_cry_fn
jr c, .asm_3a12
ld e, c
ld d, b
- call PlayCryHeader
+ call PlayCry
call WaitSFX
.asm_3a12
pop bc
diff --git a/home/init.asm b/home/init.asm
index b340be6b..cf5c18c9 100644
--- a/home/init.asm
+++ b/home/init.asm
@@ -1,5 +1,5 @@
Reset:: ; 5b0 (0:05b0)
- call DisableAudio
+ call MapSetup_Sound_Off
xor a
ld [hMapAnims], a
call ClearPalettes
@@ -136,7 +136,7 @@ Init:: ; 5d1 (0:05d1)
ld a, $30
call Predef
- call DisableAudio
+ call MapSetup_Sound_Off
xor a
ld [wMapMusic], a
jp GameInit
diff --git a/home/text.asm b/home/text.asm
index b689701d..994cc7e5 100644
--- a/home/text.asm
+++ b/home/text.asm
@@ -796,7 +796,7 @@ Text_TX_CRY
ld e, [hl]
inc hl
ld d, [hl]
- call PlayCry
+ call PlayMonCry
pop de
pop hl
pop bc
diff --git a/home/vblank.asm b/home/vblank.asm
index 07113cd3..485b875c 100644
--- a/home/vblank.asm
+++ b/home/vblank.asm
@@ -124,9 +124,9 @@ VBlank0:: ; 180
.ok2
call Joypad
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
rst Bankswitch
- call UpdateSound_
+ call _UpdateSound
ld a, [wROMBankBackup]
rst Bankswitch
ld a, [hSeconds]
@@ -181,9 +181,9 @@ VBlank1:: ; 1f4
ld [rIF], a
ei
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
rst Bankswitch
- call UpdateSound_
+ call _UpdateSound
ld a, [wROMBankBackup]
rst Bankswitch
; enable ints
@@ -230,9 +230,9 @@ VBlank4:: ; 255
call AskSerial
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
rst Bankswitch
- call UpdateSound_
+ call _UpdateSound
ld a, [wROMBankBackup]
rst Bankswitch
@@ -271,9 +271,9 @@ VBlank5:: ; 278
ld [rIF], a
ei
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
rst Bankswitch
- call UpdateSound_
+ call _UpdateSound
ld a, [wROMBankBackup]
rst Bankswitch
di
@@ -291,9 +291,9 @@ VBlank2:: ; 2b0
ld a, [hROMBank]
ld [wROMBankBackup], a
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
rst Bankswitch
- call UpdateSound_
+ call _UpdateSound
ld a, [wROMBankBackup]
rst Bankswitch
@@ -369,9 +369,9 @@ VBlank3:: ; 2c4
ld [rIF], a
ei
- ld a, BANK(UpdateSound_)
+ ld a, BANK(_UpdateSound)
rst Bankswitch
- call UpdateSound_
+ call _UpdateSound
ld a, [wROMBankBackup]
rst Bankswitch
di
diff --git a/items/item_effects.asm b/items/item_effects.asm
index 2e87ed74..51523d62 100755
--- a/items/item_effects.asm
+++ b/items/item_effects.asm
@@ -1417,7 +1417,7 @@ Functionf12c: ; f12c (3:712c)
predef FlagPredef
.asm_f15a
xor a
- ld [wDanger], a
+ ld [wLowHealthAlarm], a
ld a, [wd002]
cp REVIVE
jr z, .asm_f16a
@@ -1451,7 +1451,7 @@ FullRestore: ; f17e (3:717e)
Functionf19a: ; f19a (3:719a)
xor a
- ld [wDanger], a
+ ld [wLowHealthAlarm], a
call Functionf319
ld a, $20
call GetPartyParamLocation
@@ -1528,7 +1528,7 @@ Functionf1ff: ; f1ff (3:71ff)
ld a, $1
ret nc
xor a
- ld [wDanger], a
+ ld [wLowHealthAlarm], a
call Functionf3eb
call Functionf327
call RestoreBattlemonHP
@@ -2060,7 +2060,7 @@ PokeFlute: ; f55c (3:755c)
jp z, PrintText
ld hl, Text_PlayedThePokeFlute ; $75c6
call PrintText
- ld a, [wDanger]
+ ld a, [wLowHealthAlarm]
and $80
jr nz, .asm_f59e
.asm_f59e
diff --git a/macros.asm b/macros.asm
index e8efe5e9..f3070d40 100644
--- a/macros.asm
+++ b/macros.asm
@@ -1,5 +1,6 @@
INCLUDE "macros/enum.asm"
INCLUDE "macros/basestats.asm"
+INCLUDE "macros/code.asm"
INCLUDE "macros/scripts/audio.asm"
INCLUDE "macros/scripts/maps.asm"
@@ -102,14 +103,6 @@ dab: MACRO ; dwb address, bank
endr
ENDM
-lb: MACRO ; r, hi, lo
- ld \1, (\2 & $ff) << 8 + (\3 & $ff)
- ENDM
-
-ln: MACRO ; r, hi, lo
- ld \1, (\2 & $f) << 4 + (\3 & $f)
- ENDM
-
bccoord equs "coord bc,"
decoord equs "coord de,"
hlcoord equs "coord hl,"
@@ -235,17 +228,6 @@ ENDM
palettes EQUS "* 8"
-ldpixel: MACRO
-if _NARG >= 5
- lb \1, \2 * 8 + \4, \3 * 8 + \5
-else
- lb \1, \2 * 8, \3 * 8
-endc
-endm
-
-depixel EQUS "ldpixel de,"
-bcpixel EQUS "ldpixel bc,"
-
dbpixel: MACRO
if _NARG >= 4
db \1 * 8 + \3, \2 * 8 + \4
@@ -287,37 +269,6 @@ menu_coords: MACRO
db \4, \3 ; end coords
ENDM
-jumptable: MACRO
- ld a, [\2]
- ld e, a
- ld d, 0
- ld hl, \1
- add hl, de
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- jp hl
-endm
-
-maskbits: macro
-; returns to x
-; usage in rejection sampling
-; .loop
-; call Random
-; maskbits 30
-; and x
-; cp 30
-; jr nc, .loop
-
-x = 1
-rept 8
-IF \1 > x
-x = (x + 1) * 2 +- 1
-ENDC
-endr
-endm
-
homecall: MACRO
ld a, [hROMBank]
push af
diff --git a/macros/code.asm b/macros/code.asm
new file mode 100644
index 00000000..9429884c
--- /dev/null
+++ b/macros/code.asm
@@ -0,0 +1,106 @@
+; Syntactic sugar macros
+
+lb: MACRO ; r, hi, lo
+ ld \1, ((\2) & $ff) << 8 | ((\3) & $ff)
+ENDM
+
+ln: MACRO ; r, hi, lo
+ ld \1, ((\2) & $f) << 4 | ((\3) & $f)
+ENDM
+
+ldpixel: MACRO
+if _NARG >= 5
+ lb \1, \2 * 8 + \4, \3 * 8 + \5
+else
+ lb \1, \2 * 8, \3 * 8
+endc
+ENDM
+
+depixel EQUS "ldpixel de,"
+bcpixel EQUS "ldpixel bc,"
+
+; Design patterns
+
+jumptable: MACRO
+ ld a, [\2]
+ ld e, a
+ ld d, 0
+ ld hl, \1
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+ENDM
+
+maskbits: MACRO
+; masks just enough bits to cover the first argument
+; the second argument is an optional shift amount
+; e.g. "maskbits 26" becomes "and %00011111" (since 26 - 1 = %00011001)
+; and "maskbits 3, 2" becomes "and %00001100" (since "maskbits 3" becomes %00000011)
+; example usage in rejection sampling:
+; .loop
+; call Random
+; maskbits 26
+; cp 26
+; jr nc, .loop
+x = 1
+rept 8
+if x + 1 < (\1)
+x = x << 1 | 1
+endc
+endr
+if _NARG == 2
+ and x << (\2)
+else
+ and x
+endc
+ENDM
+
+calc_sine_wave: MACRO
+; input: a = a signed 6-bit value
+; output: a = d * sin(a * pi/32)
+ and %111111
+ cp %100000
+ jr nc, .negative\@
+ call .apply\@
+ ld a, h
+ ret
+.negative\@
+ and %011111
+ call .apply\@
+ ld a, h
+ xor $ff
+ inc a
+ ret
+.apply\@
+ ld e, a
+ ld a, d
+ ld d, 0
+if _NARG == 1
+ ld hl, \1
+else
+ ld hl, .sinetable\@
+endc
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, 0
+.multiply\@ ; factor amplitude
+ srl a
+ jr nc, .even\@
+ add hl, de
+.even\@
+ sla e
+ rl d
+ and a
+ jr nz, .multiply\@
+ ret
+if _NARG == 0
+.sinetable\@
+ sine_table 32
+endc
+ENDM
diff --git a/macros/wram.asm b/macros/wram.asm
index d7ba1834..1df2ee28 100755
--- a/macros/wram.asm
+++ b/macros/wram.asm
@@ -119,7 +119,7 @@ channel_struct: MACRO
; Addreses are Channel1 (c101).
\1MusicID:: dw
\1MusicBank:: db
-\1Flags:: db ; 0:on/off 1:subroutine 3:sfx 4:noise 5:rest
+\1Flags1:: db ; 0:on/off 1:subroutine 3:sfx 4:noise 5:rest
\1Flags2:: db ; 0:vibrato on/off 2:duty 4:cry pitch
\1Flags3:: db ; 0:vibrato up/down
\1MusicAddress:: dw
@@ -129,14 +129,12 @@ channel_struct: MACRO
\1Condition:: db ; conditional jumps
\1DutyCycle:: db ; bits 6-7 (0:12.5% 1:25% 2:50% 3:75%)
\1Intensity:: db ; hi:pressure lo:velocity
-\1Frequency:: ; 11 bits
-\1FrequencyLo:: db
-\1FrequencyHi:: db
+\1Frequency:: dw ; 11 bits
\1Pitch:: db ; 0:rest 1-c:note
\1Octave:: db ; 7-0 (0 is highest)
-\1StartingOctave:: db ; raises existing octaves (to repeat phrases)
+\1PitchOffset:: db ; raises existing octaves (to repeat phrases)
\1NoteDuration:: db ; frames remaining for the current note
-\1Field0x16:: ds 1 ; c117
+\1Field16:: ds 1 ; c117
ds 1 ; c118
\1LoopCount:: db
\1Tempo:: dw
@@ -149,16 +147,16 @@ channel_struct: MACRO
\1PitchWheelTarget:: dw ; frequency endpoint for pitch wheel
\1PitchWheelAmount:: db ; c124
\1PitchWheelAmountFraction:: db ; c125
-\1Field0x25:: ds 1 ; c126
+\1Field25:: ds 1 ; c126
ds 1 ; c127
\1CryPitch:: dw
-\1Field0x29:: ds 1
-\1Field0x2a:: ds 2
-\1Field0x2c:: ds 1
+\1Field29:: ds 1
+\1Field2a:: ds 2
+\1Field2c:: ds 1
\1NoteLength:: db ; frames per 16th note
-\1Field0x2e:: ds 1 ; c12f
-\1Field0x2f:: ds 1 ; c130
-\1Field0x30:: ds 1 ; c131
+\1Field2e:: ds 1 ; c12f
+\1Field2f:: ds 1 ; c130
+\1Field30:: ds 1 ; c131
ds 1 ; c132
ENDM
diff --git a/main.asm b/main.asm
index d92f60ae..c62986f7 100644
--- a/main.asm
+++ b/main.asm
@@ -736,7 +736,9 @@ SECTION "bank6", ROMX, BANK[$6]
SECTION "bank7", ROMX, BANK[$7]
LoadMapGroupRoof::
- dr $1c000, $1ffbd
+ dr $1c000, $1f84c
+
+INCLUDE "audio/music/credits.asm"
SECTION "bank8", ROMX, BANK[$8]
dr $20000, $23e3d
@@ -1382,7 +1384,9 @@ PlayBattleAnim::
dr $cc0d7, $cc283
BattleAnimCommands::
- dr $cc283, $d0000
+ dr $cc283, $cfce3
+
+INCLUDE "audio/music/postcredits.asm"
SECTION "bank34", ROMX, BANK[$34]
dr $d0000, $d4000
@@ -1445,21 +1449,12 @@ GoldSilverIntro:
ENDC
SECTION "bank3a", ROMX, BANK[$3a]
-DisableAudio_::
- dr $e8000, $e805c
-
-UpdateSound_::
- dr $e805c, $e8b30
-
-PlayMusic_::
- dr $e8b30, $e8b79
-
-PlayCryHeader_::
- dr $e8b79, $e8c04
-
-PlaySFX_::
-; dr $e8c04, $ec000
- dr $e8c04, $e9492
+INCLUDE "audio/engine.asm"
+INCLUDE "data/trainers/encounter_music.asm"
+INCLUDE "audio/music_pointers.asm"
+INCLUDE "audio/music/nothing.asm"
+INCLUDE "audio/cry_pointers.asm"
+INCLUDE "audio/sfx_pointers.asm"
INCLUDE "audio/music/route36.asm"
INCLUDE "audio/music/rivalbattle.asm"
@@ -1525,7 +1520,43 @@ INCLUDE "data/pokemon/cries.asm"
INCLUDE "audio/cries.asm"
SECTION "bank3d", ROMX, BANK[$3d]
- dr $f4000, $f8000
+INCLUDE "audio/music/viridiancity.asm"
+INCLUDE "audio/music/celadoncity.asm"
+INCLUDE "audio/music/wildpokemonvictory.asm"
+INCLUDE "audio/music/successfulcapture.asm"
+INCLUDE "audio/music/gymleadervictory.asm"
+INCLUDE "audio/music/mtmoonsquare.asm"
+INCLUDE "audio/music/gym.asm"
+INCLUDE "audio/music/pallettown.asm"
+INCLUDE "audio/music/profoakspokemontalk.asm"
+INCLUDE "audio/music/profoak.asm"
+INCLUDE "audio/music/lookrival.asm"
+INCLUDE "audio/music/aftertherivalfight.asm"
+INCLUDE "audio/music/surf.asm"
+INCLUDE "audio/music/nationalpark.asm"
+INCLUDE "audio/music/azaleatown.asm"
+INCLUDE "audio/music/cherrygrovecity.asm"
+INCLUDE "audio/music/unioncave.asm"
+INCLUDE "audio/music/johtowildbattle.asm"
+INCLUDE "audio/music/johtowildbattlenight.asm"
+INCLUDE "audio/music/johtotrainerbattle.asm"
+INCLUDE "audio/music/lookyoungster.asm"
+INCLUDE "audio/music/tintower.asm"
+INCLUDE "audio/music/sprouttower.asm"
+INCLUDE "audio/music/burnedtower.asm"
+INCLUDE "audio/music/mom.asm"
+INCLUDE "audio/music/victoryroad.asm"
+INCLUDE "audio/music/pokemonlullaby.asm"
+INCLUDE "audio/music/pokemonmarch.asm"
+INCLUDE "audio/music/goldsilveropening.asm"
+INCLUDE "audio/music/goldsilveropening2.asm"
+INCLUDE "audio/music/lookhiker.asm"
+INCLUDE "audio/music/lookrocket.asm"
+INCLUDE "audio/music/rockettheme.asm"
+INCLUDE "audio/music/mainmenu.asm"
+INCLUDE "audio/music/lookkimonogirl.asm"
+INCLUDE "audio/music/pokeflutechannel.asm"
+INCLUDE "audio/music/bugcatchingcontest.asm"
SECTION "bank3e", ROMX, BANK[$3e]
Functionf8000::
diff --git a/wram.asm b/wram.asm
index 4d8a3f21..4ff882e2 100644
--- a/wram.asm
+++ b/wram.asm
@@ -73,7 +73,7 @@ wMusicNoiseSampleSet:: ; c1a4
ds 1
wSFXNoiseSampleSet:: ; c1a5
ds 1
-wDanger:: ; c1a6
+wLowHealthAlarm:: ; c1a6
; bit 7: on/off
; bit 4: pitch
; bit 0-3: counter
@@ -98,7 +98,7 @@ wCryLength:: ; c1b2
ds 2
wLastVolume:: ; c1b4
ds 1
-wc1b5:: ds 1 ; c1b5
+wUnusedMusicF9Flag:: ds 1 ; c1b5
wSFXPriority:: ; c1b6
; if nonzero, turn off music when playing sfx
ds 1
@@ -2991,7 +2991,7 @@ wLastDexMode:: ds 1 ; d67e
wWhichRegisteredItem:: ds 1 ; d680
wRegisteredItem:: ds 1 ; d681
-wPlayerBikeSurfState:: ds 1 ; d682
+wPlayerState:: ds 1 ; d682
wd683:: ds 1 ; d683
wd684:: ds 1 ; d684