summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--audio/drumkits.inc140
-rw-r--r--audio/engine.asm2345
-rw-r--r--audio/intensity_overrides.inc33
-rw-r--r--audio/notes.inc26
-rw-r--r--audio/wave_overrides.inc11
-rw-r--r--audio/wave_samples.inc27
-rw-r--r--constants/audio_constants.asm17
-rw-r--r--home/cry.asm6
-rw-r--r--layout.link10
-rw-r--r--ram/wram.asm31
-rwxr-xr-xshim.sym13
11 files changed, 2601 insertions, 58 deletions
diff --git a/audio/drumkits.inc b/audio/drumkits.inc
new file mode 100644
index 0000000..642d5fd
--- /dev/null
+++ b/audio/drumkits.inc
@@ -0,0 +1,140 @@
+Drumkits:
+ dw Drumkit0
+ dw Drumkit1
+ dw Drumkit2
+ dw Drum00
+ dw Drum00
+ dw Drum00
+
+Drumkit0:
+ dw Drum00
+ dw Snare1
+ dw Snare2
+ dw Snare3
+ dw Snare4
+ dw Drum05
+ dw Triangle1
+ dw Triangle2
+ dw HiHat1
+ dw Snare5
+ dw Snare6
+ dw Snare7
+ dw HiHat2
+
+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
+
+Drum00:
+ sound_ret
+
+Snare1:
+ noise_note 32, 12, 1, 51
+ sound_ret
+
+Snare2:
+ noise_note 32, 11, 1, 51
+ sound_ret
+
+Snare3:
+ noise_note 32, 10, 1, 51
+ sound_ret
+
+Snare4:
+ noise_note 32, 8, 1, 51
+ sound_ret
+
+Drum05:
+; Reverse cymbal / wooshing sound
+ noise_note 39, 8, 4, 55
+ noise_note 38, 8, 4, 54
+ noise_note 37, 8, 3, 53
+ noise_note 36, 8, 3, 52
+ noise_note 35, 8, 2, 51
+ noise_note 34, 8, 1, 50
+ sound_ret
+
+Triangle1:
+ noise_note 32, 5, 1, 42
+ sound_ret
+
+Triangle2:
+ noise_note 33, 4, 1, 43
+ noise_note 32, 6, 1, 42
+ sound_ret
+
+HiHat1:
+ noise_note 32, 8, 1, 16
+ sound_ret
+
+Snare5:
+ noise_note 32, 8, 2, 35
+ sound_ret
+
+Snare6:
+ noise_note 32, 8, 2, 37
+ sound_ret
+
+Snare7:
+ noise_note 32, 8, 2, 38
+ sound_ret
+
+HiHat2:
+ noise_note 32, 10, 1, 16
+ sound_ret
+
+HiHat3:
+ noise_note 32, 10, 2, 17
+ sound_ret
+
+Snare8:
+ noise_note 32, 10, 2, 80
+ sound_ret
+
+Triangle3:
+ noise_note 32, 10, 1, 24
+ noise_note 32, 3, 1, 51
+ sound_ret
+
+Triangle4:
+ noise_note 34, 9, 1, 40
+ noise_note 32, 7, 1, 24
+ sound_ret
+
+Snare9:
+ noise_note 32, 9, 1, 34
+ sound_ret
+
+Snare10:
+ noise_note 32, 7, 1, 34
+ sound_ret
+
+Snare11:
+ noise_note 32, 6, 1, 34
+ sound_ret
diff --git a/audio/engine.asm b/audio/engine.asm
index 157734c..f722621 100644
--- a/audio/engine.asm
+++ b/audio/engine.asm
@@ -1,6 +1,6 @@
INCLUDE "constants.asm"
-SECTION "audio/engine.asm@Audio", ROMX
+SECTION "audio/engine.asm", ROMX
_DisableAudio::
push hl
@@ -38,7 +38,7 @@ _DisableAudio::
or d
jr nz, .clear
- ld a, $77
+ ld a, MAX_VOLUME
ld [wVolume], a
pop af
@@ -94,7 +94,7 @@ UpdateChannel:
.noteover
call DisablePitchWheel
- call Functione884f
+ call ParseMusic
.continue_sound_update
call Functione80b6
@@ -170,15 +170,15 @@ Functione80b6:
ld [wCurTrackFrequency], a
ld a, [hl]
ld [wCurTrackFrequency + 1], a
- ld a, $3f
- ld [wc195], a
+ ld a, $3F
+ ld [wSoundLength], a
call Functione85d8
- call Functione87f9
- call Functione8839
+ call ReadNoiseSample
+ call HaltMusicWhileSFXPlaying
call IsChannelSFXOn
jr nc, .end
- call Functione80fa
+ call UpdateChannels
ld hl, CHANNEL_TRACKS
add hl, bc
ld a, [wSoundOutput]
@@ -192,7 +192,7 @@ Functione80b6:
ld [hl], a
ret
-Functione80fa:
+UpdateChannels:
ld hl, .jumptable
ld a, [wCurChannel]
maskbits NUM_CHANNELS
@@ -206,9 +206,280 @@ Functione80fa:
jp hl
.jumptable
- ; TODO
+; Music channels
+ dw .Channel1
+ dw .Channel2
+ dw .Channel3
+ dw .Channel4
+; SFX channels
+ dw .Channel5
+ dw .Channel6
+ dw .Channel7
+ dw .Channel8
+
+.Channel1:
+ ld a, [wLowHealthAlarm]
+ bit 7, a
+ ret nz
+
+.Channel5:
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ bit NOTE_PITCH_SWEEP, [hl]
+ jr z, .ch1_no_sweep
+
+ ld a, [wPitchSweep]
+ ldh [rNR10], a
+
+.ch1_no_sweep
+ bit NOTE_REST, [hl]
+ jr nz, .ch1_rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .ch1_noise_sampling
+ bit NOTE_FREQ_OVERRIDE, [hl]
+ call nz, .ch1_freq_override
+ bit NOTE_INTENSITY_OVERRIDE, [hl]
+ call nz, .ch1_intensity_override
+ bit NOTE_DUTY_OVERRIDE, [hl]
+ call nz, .ch1_duty_override
+ ret
+
+.ch1_rest
+ ld a, %1000 ; stop envelope
+ ldh [rNR12], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80 ; restart ch1
+ ldh [rNR14], a
+ ret
+
+.ch1_noise_sampling
+ ld hl, wCurTrackDuty
+ ld a, [wSoundLength]
+ 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
+
+.ch1_duty_override
+ ld a, [wCurTrackDuty]
+ ldh a, [rNR11]
+ and $3f
+ or d
+ ldh [rNR11], a
+ ret
+
+.ch1_intensity_override
+ ld a, [wCurTrackIntensity]
+ ldh [rNR12], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR14], a
+ ret
+
+.ch1_freq_override
+ ld a, [wCurTrackFrequency]
+ ldh [rNR13], a
+ ld a, [wCurTrackFrequency + 1]
+ ldh [rNR14], a
+ ret
+
+.Channel2:
+.Channel6:
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ bit NOTE_REST, [hl]
+ jr nz, .ch2_rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .ch2_noise_sampling
+ bit NOTE_FREQ_OVERRIDE, [hl]
+ call nz, .ch2_freq_override
+ bit NOTE_INTENSITY_OVERRIDE, [hl]
+ call nz, .ch2_intensity_override
+ bit NOTE_DUTY_OVERRIDE, [hl]
+ call nz, .ch2_duty_override
+ ret
+
+.ch2_rest
+ ld a, $08
+ ldh [rNR22], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR24], a
+ ret
+
+.ch2_noise_sampling
+ ld hl, wCurTrackDuty
+ ld a, [wSoundLength]
+ or [hl]
+ ldh [rNR21], a
+ ld a, [wCurTrackIntensity]
+ ldh [rNR22], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR23], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR24], a
+ ret
+
+.ch2_duty_override
+ ld a, [wCurTrackDuty]
+ ld d, a
+ ldh a, [rNR21]
+ and $3f
+ or d
+ ldh [rNR21], a
+ ret
+
+.ch2_intensity_override
+ ld a, [wCurTrackIntensity]
+ ldh [rNR22], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR24], a
+ ret
+
+.ch2_freq_override
+ ld a, [wCurTrackFrequency]
+ ldh [rNR23], a
+ ld a, [wCurTrackFrequency + 1]
+ ldh [rNR24], a
+ ret
+
+.Channel3:
+.Channel7:
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ bit NOTE_REST, [hl]
+ jr nz, .ch3_rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .ch3_noise_sampling
+ bit NOTE_FREQ_OVERRIDE, [hl]
+ call nz, .ch3_freq_override
+ bit NOTE_INTENSITY_OVERRIDE, [hl]
+ call nz, .ch3_intensity_override
+ ret
+
+.ch3_rest
+ xor a
+ ldh [rNR30], a
+ ret
+
+.ch3_noise_sampling
+ ld a, [wSoundLength]
+ ldh [rNR31], a
+ xor a
+ ldh [rNR30], a
+ call .load_wave_pattern
+ ld a, $80
+ ldh [rNR30], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR33], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR34], a
+ ret
+
+.ch3_freq_override
+ ld a, [wCurTrackFrequency]
+ ldh [rNR33], a
+ ld a, [wCurTrackFrequency + 1]
+ ldh [rNR34], a
+ ret
+
+.ch3_intensity_override
+ xor a
+ ldh [rNR30], a
+ call .load_wave_pattern
+ ld a, $80
+ ldh [rNR30], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR33], a
+ ld a, [wCurTrackFrequency + 1]
+ or $80
+ ldh [rNR34], a
+ ret
+
+.load_wave_pattern
+ push hl
+ ld a, [wCurTrackIntensity]
+; only patterns 0 - 9 are valid
+ and $f
+ ld l, a
+ ld h, 0
+; hl << 4 (hl * $10), because each pattern is $f bytes
+rept 4
+ add hl, hl
+endr
+ ld de, WaveSamples
+ add hl, de
+ ld de, rWave_0
+ push bc
+ ld b, $10
+.load_pattern
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .load_pattern
+
+ pop bc
+ 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]
+ jr nz, .ch4_rest
+ bit NOTE_NOISE_SAMPLING, [hl]
+ jr nz, .ch4_noise_sampling
+ bit NOTE_FREQ_OVERRIDE, [hl]
+ call nz, .ch4_freq_override
+ bit NOTE_INTENSITY_OVERRIDE, [hl]
+ call nz, .ch4_intensity_override
+ ret
+
+.ch4_rest
+ ld a, $08
+ ldh [rNR42], a
+ ld a, $80
+ ldh [rNR44], a
+ ret
+
+.ch4_noise_sampling
+ ld a, [wSoundLength]
+ ldh [rNR41], a
+ ld a, [wCurTrackIntensity]
+ ldh [rNR42], a
+ ld a, [wCurTrackFrequency]
+ ldh [rNR43], a
+ ld a, $80
+ ldh [rNR44], a
+ ret
+
+.ch4_freq_override
+ ld a, [wCurTrackFrequency]
+ ldh [rNR43], a
+ ret
+
+.ch4_intensity_override
+ ld a, [wCurTrackIntensity]
+ ldh [rNR42], a
+ ld a, $80
+ ldh [rNR44], a
+ ret
-SECTION "audio/engine.asm@IsChannelSFXOn", ROMX
IsChannelSFXOn:
; If it's not a valid channel, return
ld a, [wCurChannel]
@@ -249,12 +520,11 @@ IsAnySFXOn:
scf
ret
-SECTION "audio/engine.asm@Functione82f0", ROMX
Functione82f0:
call IncrementTempo
call PlayDanger
call FadeMusic
- call Functione841d
+ call DoSweepingFade
ld a, [wVolume]
ld [rNR50], a
ld a, [wSoundOutput]
@@ -502,7 +772,1676 @@ FadeMusic:
ld [wVolume], a
ret
-SECTION "audio/engine.asm@Audio engine, part 2", ROMX
+DoSweepingFade::
+; performs a sweeping fade effect starting from the
+; left channel, then the right, then repeats
+
+ ld a, [wSweepingFadeIndex]
+ and a
+ ret z
+
+; first nybble of wSweepingFadeIndex is the subroutine index
+; second is the fade length
+
+ swap a
+ and 7
+ ld e, a
+ ld d, 0
+ ld hl, .jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.jumptable
+ dw .DoFade1
+ dw .DoFade2
+ dw .DoFade3
+ dw .DoFade4
+ dw .DoFade5
+ dw .DoFade6
+ dw .DoFade1
+ dw .DoFade1
+
+.DoFade1:
+ ld a, 1
+ call .SetIndex
+ xor a
+ ld [wSweepingFadeCounter], a
+ ld [wVolume], a
+
+.DoFade2:
+ call .LeftChannel
+ call .DecrementCounter
+ ret nc
+ call .IncreaseVolume
+ ret nc
+ ld a, 2
+ call .SetIndex
+
+.DoFade3:
+ call .LeftChannel
+ call .DecrementCounter
+ ret nc
+ call .DecreaseVolume
+ ret nc
+ ld a, 3
+ call .SetIndex
+
+.DoFade4:
+ call .RightChannel
+ call .DecrementCounter
+ ret nc
+ call .IncreaseVolume
+ ret nc
+ ld a, 4
+ call .SetIndex
+
+.DoFade5:
+ call .RightChannel
+ call .DecrementCounter
+ ret nc
+ call .DecreaseVolume
+ ret nc
+ ld a, 0
+ call .SetIndex
+ ret
+
+.DoFade6:
+ xor a
+ ld [wSweepingFadeIndex], a
+ ld a, MAX_VOLUME
+ ld [wVolume], a
+ ret
+
+.SetIndex:
+ swap a
+ ld d, a
+ ld a, [wSweepingFadeIndex]
+ and $f
+ or d
+ ld [wSweepingFadeIndex], a
+ ret
+
+.DecrementCounter:
+ ld a, [wSweepingFadeCounter]
+ and a
+ jr z, .reset_counter
+ dec a
+ ld [wSweepingFadeCounter], a
+ and a
+ ret
+ .reset_counter
+ ld a, [wSweepingFadeIndex]
+ and $f
+ ld [wSweepingFadeCounter], a
+ scf
+ ret
+
+.IncreaseVolume:
+ ld a, [wVolume]
+ and 7
+ cp 7
+ jr nc, .max_volume
+ inc a
+ ld d, a
+ swap a
+ or d
+ ld [wVolume], a
+ and a
+ ret
+.max_volume
+ scf
+ ret
+
+.DecreaseVolume:
+ ld a, [wVolume]
+ and $f
+ jr z, .min_volume
+ dec a
+ ld d, a
+ swap a
+ or d
+ ld [wVolume], a
+ and a
+ ret
+.min_volume
+ scf
+ ret
+
+.LeftChannel:
+ call IsAnySFXOn
+ ret c
+ ld a, [wSoundOutput]
+ and $f0
+ ld [wSoundOutput], a
+ ret
+
+.RightChannel:
+ call IsAnySFXOn
+ ret c
+ ld a, [wSoundOutput]
+ and $0f
+ ld [wSoundOutput], a
+ ret
+
+LoadNote:
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ bit SOUND_PITCH_WHEEL, [hl]
+ call nz, .get_note
+ bit SOUND_VIBRATO, [hl]
+ call nz, .vibrato
+ bit SOUND_UNKN_0E, [hl]
+ call nz, .flag_0e
+ bit SOUND_UNKN_0D, [hl]
+ call nz, .flag_0d
+ bit SOUND_UNKN_0B, [hl]
+ call nz, .flag_0b
+ ret
+
+.get_note
+ push hl
+ 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
+ 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, 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]
+ 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]
+ 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, 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
+ push bc
+ ld hl, wCurNoteDuration
+ ld b, 0
+
+.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
+ add [hl]
+ ld d, b
+ pop bc
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT
+ add hl, bc
+ ld [hl], d
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT_FRACTION
+ add hl, bc
+ ld [hl], a
+ ld hl, CHANNEL_FIELD25
+ add hl, bc
+ xor a
+ ld [hl], a
+ pop hl
+ ret
+
+.vibrato
+ push hl
+ ld hl, CHANNEL_VIBRATO_DELAY
+ add hl, bc
+ ld a, [hl]
+ ld hl, CHANNEL_VIBRATO_DELAY_COUNT
+ add hl, bc
+ ld [hl], a
+ pop hl
+ ret
+
+.flag_0e
+ push hl
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ res NOTE_INTENSITY_OVERRIDE, [hl]
+ pop hl
+ ret
+
+.flag_0d
+ push hl
+ ld hl, CHANNEL_FIELD2A + 1
+ add hl, bc
+ xor a
+ ld [hl], a
+ pop hl
+ ret
+
+.flag_0b
+ push hl
+ ld hl, CHANNEL_FIELD2C
+ add hl, bc
+ ld a, [hl]
+ ld hl, CHANNEL_FIELD25 + 1
+ add hl, bc
+ ld [hl], a
+ pop hl
+ ret
+
+Functione85d8::
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ bit SOUND_DUTY, [hl]
+ call nz, HandleDuty
+ bit SOUND_UNKN_0E, [hl]
+ call nz, Handle_0e
+ bit SOUND_CRY_PITCH, [hl]
+ call nz, Handle_crypitch
+ bit SOUND_PITCH_WHEEL, [hl]
+ call nz, ApplyPitchSlide
+ bit SOUND_VIBRATO, [hl]
+ call nz, HandleVibrato
+ bit SOUND_UNKN_0D, [hl]
+ call nz, Handle_0d
+ bit SOUND_UNKN_0B, [hl]
+ call nz, Handle_0b
+ bit SOUND_UNKN_0F, [hl]
+ call nz, HandleNoise
+ ret
+
+HandleDuty:
+ push hl
+ 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 0, [hl]
+ pop hl
+ ret
+
+ApplyPitchSlide:
+ push hl
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ bit SOUND_PITCH_WHEEL_DIR, [hl]
+ jr z, .decreasing
+
+ ld hl, CHANNEL_PITCH_WHEEL_AMOUNT
+ add hl, bc
+ ld l, [hl]
+ ld h, 0
+ add hl, de
+ ld d, h
+ ld e, l
+ 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
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ ld a, [hl]
+ cp d
+ jp c, .finished_pitch_slide
+ jr nz, .continue_pitch_slide
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld a, [hl]
+ cp e
+ jp c, .finished_pitch_slide
+ jr .continue_pitch_slide
+
+.decreasing
+ 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
+ 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
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ ld a, d
+ cp [hl]
+ jr c, .finished_pitch_slide
+ jr nz, .continue_pitch_slide
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET
+ add hl, bc
+ ld a, e
+ cp [hl]
+ jr nc, .continue_pitch_slide
+
+.finished_pitch_slide
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ res 1, [hl]
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ res 1, [hl]
+ ld hl, CHANNEL_PITCH_WHEEL_TARGET + 1
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+.continue_pitch_slide
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set 1, [hl]
+ pop hl
+ ret
+
+
+HandleVibrato:
+ push hl
+ ld hl, CHANNEL_VIBRATO_DELAY_COUNT
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr nz, .subexit
+
+ ld hl, CHANNEL_VIBRATO_RATE
+ add hl, bc
+ ld a, [hl]
+ and $0f
+ jr z, .toggle
+
+.subexit
+ dec [hl]
+ jr .quit
+
+.toggle
+ ld a, [hl]
+ swap [hl]
+ or [hl]
+ ld [hl], a
+ ld hl, CHANNEL_VIBRATO_EXTENT
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .quit
+
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ bit SOUND_VIBRATO_DIR, [hl]
+ jr z, .down
+
+ res SOUND_VIBRATO_DIR, [hl]
+ and $0f
+ ld d, a
+ ld a, [wCurTrackFrequency]
+ sub d
+ jr nc, .no_carry
+
+ xor a
+ jr .no_carry
+
+.down
+ set SOUND_VIBRATO_DIR, [hl]
+ and $f0
+ swap a
+ ld d, a
+ ld a, [wCurTrackFrequency]
+ add d
+ jr nc, .no_carry
+
+ ld a, $ff
+
+.no_carry
+ ld [wCurTrackFrequency], a
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_FREQ_OVERRIDE, [hl]
+
+.quit
+ pop hl
+ ret
+
+
+Handle_0b:
+ push hl
+ ld hl, CHANNEL_FIELD25 + 1
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .set_rest
+
+ dec [hl]
+ jr .done
+
+.set_rest
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_REST, [hl]
+
+.done
+ pop hl
+ ret
+
+
+Handle_crypitch:
+ push hl
+ ld hl, CHANNEL_CRY_PITCH
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, wCurTrackFrequency
+ push hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ add hl, de
+ ld e, l
+ ld d, h
+ pop hl
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ pop hl
+ ret
+
+
+Handle_0e:
+ push hl
+ ld hl, CHANNEL_FLAGS3
+ add hl, bc
+ bit SOUND_UNKN_12, [hl]
+ jr nz, .skip
+
+ set SOUND_UNKN_12, [hl]
+ jr .done
+
+.skip
+ res SOUND_UNKN_12, [hl]
+ ld hl, CHANNEL_PITCH
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .done
+
+ ld hl, CHANNEL_FIELD29
+ add hl, bc
+ add [hl]
+ ld e, a
+ ld hl, CHANNEL_OCTAVE
+ add hl, bc
+ ld d, [hl]
+ call GetFrequency
+ ld hl, wCurTrackFrequency
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+.done
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set SOUND_PITCH_WHEEL_DIR, [hl]
+ pop hl
+ ret
+
+
+Handle_0d:
+ push hl
+ ld hl, CHANNEL_FIELD2A
+ add hl, bc
+ ld e, [hl]
+ ld d, 0
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ cp CHAN3
+ jr nz, .not_ch3
+
+ ld hl, WaveOverrides
+ call GetFromTable
+ jr c, .rest_done
+
+ ld d, a
+ ld a, [wCurTrackIntensity]
+ and $c0
+ or d
+ jr .intensity_done
+
+.not_ch3
+ ld hl, IntensityOverrides
+ call GetFromTable
+ jr nc, .intensity_done
+
+.rest_done
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_REST, [hl]
+ pop hl
+ ret
+
+
+.intensity_done
+ ld [wCurTrackIntensity], a
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_INTENSITY_OVERRIDE, [hl]
+ pop hl
+ ret
+
+
+GetFromTable:
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, CHANNEL_FIELD2A + 1
+ add hl, bc
+ push hl
+ ld l, [hl]
+ ld h, 0
+ add hl, de
+ ld a, [hl]
+ pop hl
+ cp $ff
+ jr z, .carry
+
+ cp $fe
+ jr nz, .done_nocarry
+
+ xor a
+ ld [hl], a
+ ld a, [de]
+
+.done_nocarry
+ inc [hl]
+ and a
+ ret
+.carry
+ scf
+ ret
+
+
+HandleNoise:
+ ld hl, CHANNEL_FIELD2E
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .skip
+
+ dec [hl]
+ ld hl, CHANNEL_FIELD30
+ add hl, bc
+ ld a, [hl]
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld [hl], a
+ ret
+
+.skip
+ ld hl, CHANNEL_FIELD2F
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .skip2
+
+ dec [hl]
+ ld hl, CHANNEL_FIELD30
+ add hl, bc
+ ld a, [hl]
+ swap a
+ or [hl]
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld [hl], a
+ ret
+
+.skip2
+ ld hl, CHANNEL_FIELD30
+ add hl, bc
+ ld a, [hl]
+ swap a
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ ld [hl], a
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ res SOUND_UNKN_0F, [hl]
+ ret
+
+
+ReadNoiseSample::
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_NOISE, [hl]
+ ret z
+
+ ld a, [wNoiseSampleDelay]
+ and a
+ jr z, .get_new_sample
+
+ dec a
+ ld [wNoiseSampleDelay], a
+ ret
+
+.get_new_sample
+ ld hl, wNoiseSampleAddress
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld a, [de]
+ inc de
+ cp $ff
+ jr z, .done
+
+ and $0f
+ 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
+
+.done
+ ret
+
+
+HaltMusicWhileSFXPlaying::
+ ld a, [wSFXPriority]
+ and a
+ ret z
+
+ ld a, [wCurChannel]
+ cp CHAN5
+ ret nc
+
+ call IsAnySFXOn
+ ret nc
+
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_REST, [hl]
+ ret
+
+
+ParseMusic::
+ call GetMusicByte
+ cp sound_ret_cmd
+ jr z, .end_music
+
+ cp FIRST_MUSIC_CMD
+ jr nc, .parse_commands
+
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_SFX, [hl]
+ jr nz, .parse_sfx_or_rest
+
+ bit SOUND_REST, [hl]
+ jr nz, .parse_sfx_or_rest
+
+ bit SOUND_NOISE, [hl]
+ jr nz, .parse_noise
+
+ call _ParseMusic
+ ret
+
+.parse_sfx_or_rest
+ call ParseSFXOrRest
+ ret
+
+.parse_noise
+ call GetNoiseSample
+ ret
+
+.end_music
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_SUBROUTINE, [hl]
+ jr nz, .parse_commands
+
+ call IsChannelSFXOn
+ jr nc, .ok
+
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_REST, [hl]
+ call nz, RestoreVolume
+ ld a, [wCurChannel]
+ cp CHAN5
+ jr nz, .ok
+
+ xor a
+ ldh [rNR10], a
+
+.ok
+ call StopChannel
+ ret
+
+.parse_commands
+ call ParseMusicCommand
+ jr ParseMusic
+
+RestoreVolume:
+ 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
+
+
+_ParseMusic:
+ ld a, [wCurMusicByte]
+ and $f
+ call SetNoteDuration
+ ld a, [wCurMusicByte]
+ swap a
+ and $f
+ jr z, .rest
+
+ ld hl, CHANNEL_PITCH
+ add hl, bc
+ ld [hl], a
+ ld e, a
+ ld hl, CHANNEL_OCTAVE
+ add hl, bc
+ ld d, [hl]
+ 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]
+ call LoadNote
+ ret
+
+
+.rest
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_REST, [hl]
+ ret
+
+
+ParseSFXOrRest:
+; turn noise sampling on
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set NOTE_NOISE_SAMPLING, [hl]
+ ld a, [wCurMusicByte]
+ call SetNoteDuration
+
+; update volume envelope from next param
+ call GetMusicByte
+ ld hl, CHANNEL_INTENSITY
+ add hl, bc
+ ld [hl], a
+
+; update lo frequence from next param
+ call GetMusicByte
+ ld hl, CHANNEL_FREQUENCY
+ add hl, bc
+ ld [hl], a
+
+; on noise channel?
+ 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:
+ ld a, [wCurChannel]
+ cp CHAN4
+ ret nz
+
+ ld a, [wCurMusicByte]
+ and $f
+ call SetNoteDuration
+
+ ld a, [wNoiseSampleSet]
+ ld e, a
+ ld d, 0
+ ld hl, Drumkits
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ ld a, [wCurMusicByte]
+ swap a
+ and $f
+ ret z
+
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld [wNoiseSampleAddress], a
+ ld a, [hl]
+ ld [wNoiseSampleAddress + 1], a
+ xor a
+ ld [wNoiseSampleDelay], a
+ ret
+
+
+ParseMusicCommand:
+ ld a, [wCurMusicByte]
+ sub FIRST_MUSIC_CMD
+ ld e, a
+ ld d, 0
+ ld hl, MusicCommands
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+MusicCommands:
+ dw Music_Octave8
+ dw Music_Octave7
+ dw Music_Octave6
+ dw Music_Octave5
+ dw Music_Octave4
+ dw Music_Octave3
+ dw Music_Octave2
+ dw Music_Octave1
+ dw Music_NoteType
+ dw Music_Transpose
+ dw Music_Tempo
+ dw Music_DutyCycle
+ dw Music_VolumeEnvelope
+ dw Music_PitchSweep
+ dw Music_DutyCyclePattern
+ dw Music_ToggleSFX
+ dw Music_PitchSlide
+ dw Music_Vibrato
+ dw MusicE2
+ dw Music_ToggleNoise
+ dw Music_ForceStereoPanning
+ dw Music_Volume
+ dw Music_PitchOffset
+ dw MusicE7
+ dw MusicE8
+ dw Music_TempoRelative
+ dw Music_RestartChannel
+ dw Music_NewSong
+ dw Music_SFXPriorityOn
+ dw Music_SFXPriorityOff
+ dw MusicEE
+ dw Music_StereoPanning
+ dw MusicF0
+ dw MusicF1
+ dw MusicF2
+ dw MusicF3
+ dw MusicF4
+ dw MusicF5
+ dw MusicF6
+ dw MusicF7
+ dw MusicF8
+ dw MusicF9
+ dw Music_SetCondition
+ dw Music_JumpIf
+ dw Music_Jump
+ dw Music_Loop
+ dw Music_Call
+ dw Music_Ret
+
+MusicF0:
+MusicF1:
+MusicF2:
+MusicF3:
+MusicF4:
+MusicF5:
+MusicF6:
+MusicF7:
+MusicF8:
+ ret
+
+Music_Ret:
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ res SOUND_SUBROUTINE, [hl]
+ 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_Call:
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ push de
+ 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
+ pop de
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_SUBROUTINE, [hl]
+ ret
+
+Music_Jump:
+ 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_Loop:
+ call GetMusicByte
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_LOOPING, [hl]
+ jr nz, .checkloop
+
+ and a
+ jr z, .loop
+
+ dec a
+ set SOUND_LOOPING, [hl]
+ ld hl, CHANNEL_LOOP_COUNT
+ add hl, bc
+ ld [hl], a
+
+.checkloop
+ ld hl, CHANNEL_LOOP_COUNT
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .endloop
+ dec [hl]
+
+.loop
+ 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
+
+.endloop
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ res SOUND_LOOPING, [hl]
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc de
+ inc de
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ ret
+
+Music_SetCondition:
+ call GetMusicByte
+ ld hl, CHANNEL_CONDITION
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_JumpIf:
+ call GetMusicByte
+ ld hl, CHANNEL_CONDITION
+ add hl, bc
+ cp [hl]
+ jr z, .jump
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc de
+ inc de
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ ret
+
+.jump
+ 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
+
+MusicEE:
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ ld e, a
+ ld d, 0
+ ld hl, wChannel1JumpCondition
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .jump
+
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc de
+ inc de
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ ret
+
+.jump
+ ld [hl], 0
+ 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
+
+MusicF9:
+ ld a, 1
+ ld [wc1b3], a
+ ret
+
+MusicE2:
+ 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:
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_VIBRATO, [hl]
+ res SOUND_VIBRATO, [hl]
+ call GetMusicByte
+ ld hl, CHANNEL_VIBRATO_DELAY
+ add hl, bc
+ ld [hl], a
+ call GetMusicByte
+ ld hl, CHANNEL_VIBRATO_EXTENT
+ add hl, bc
+ ld d, a
+ and $f0
+ swap a
+ srl a
+ ld e, a
+ adc 0
+ swap a
+ or e
+ ld [hl], a
+ ld hl, CHANNEL_VIBRATO_RATE
+ add hl, bc
+ ld a, d
+ and $0f
+ ld d, a
+ swap a
+ or d
+ ld [hl], a
+ ret
+
+Music_PitchSlide:
+ call GetMusicByte
+ ld [wCurNoteDuration], a
+ call GetMusicByte
+ ld d, a
+ and $f
+ ld e, a
+ 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_PitchOffset:
+ 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:
+ 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_DutyCyclePattern:
+ ld hl, CHANNEL_FLAGS2
+ add hl, bc
+ set SOUND_DUTY, [hl]
+ call GetMusicByte
+ rrca
+ rrca
+ ld hl, CHANNEL_SFX_DUTY_LOOP
+ add hl, bc
+ ld [hl], a
+ and $c0
+ ld hl, CHANNEL_DUTY_CYCLE
+ add hl, bc
+ ld [hl], a
+ ret
+
+MusicE8:
+ 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:
+ 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:
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ bit SOUND_NOISE, [hl]
+ jr z, .on
+ res SOUND_NOISE, [hl]
+ ret
+.on
+ set SOUND_NOISE, [hl]
+ call GetMusicByte
+ ld [wNoiseSampleSet], a
+ ret
+
+Music_NoteType:
+ call GetMusicByte
+ ld hl, CHANNEL_NOTE_LENGTH
+ add hl, bc
+ ld [hl], a
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ cp CHAN4
+ ret z
+ call Music_VolumeEnvelope
+ ret
+
+Music_PitchSweep:
+ call GetMusicByte
+ ld [wPitchSweep], a
+ ld hl, CHANNEL_NOTE_FLAGS
+ add hl, bc
+ set 3, [hl]
+ ret
+
+Music_DutyCycle:
+ call GetMusicByte
+ rrca
+ rrca
+ and $c0
+ ld hl, CHANNEL_DUTY_CYCLE
+ add hl, bc
+ ld [hl], a
+ ret
+
+
+Music_VolumeEnvelope:
+ call GetMusicByte
+ ld hl, CHANNEL_INTENSITY
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_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:
+ ld hl, CHANNEL_OCTAVE
+ add hl, bc
+ ld a, [wCurMusicByte]
+ and 7
+ ld [hl], a
+ ret
+
+Music_Transpose:
+ call GetMusicByte
+ ld hl, CHANNEL_PITCH_OFFSET
+ add hl, bc
+ ld [hl], a
+ ret
+
+Music_StereoPanning:
+ ld a, [wce5f]
+ bit 5, a
+ ret z
+
+Music_ForceStereoPanning:
+ call SetLRTracks
+ call GetMusicByte
+ ld hl, CHANNEL_TRACKS
+ add hl, bc
+ and [hl]
+ ld [hl], a
+ ret
+
+Music_Volume:
+ call GetMusicByte
+ ld a, [wMusicFade]
+ and a
+ ret nz
+ ld a, [wCurMusicByte]
+ ld [wVolume], a
+ ret
+
+Music_TempoRelative:
+ 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:
+ ld a, 1
+ ld [wSFXPriority], a
+ ret
+
+Music_SFXPriorityOff:
+ xor a
+ ld [wSFXPriority], a
+ ret
+
+Music_RestartChannel:
+ ld hl, CHANNEL_MUSIC_ID
+ add hl, bc
+ ld a, [hli]
+ ld [wMusicID], a
+ ld a, [hl]
+ ld [wMusicID + 1], a
+ ld hl, CHANNEL_MUSIC_BANK
+ add hl, bc
+ ld a, [hl]
+ ld [wMusicBank], a
+ call GetMusicByte
+ ld l, a
+ call GetMusicByte
+ ld h, a
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ push bc
+ call LoadChannel
+ call StartChannel
+ pop bc
+ ret
+
+Music_NewSong:
+ call GetMusicByte
+ ld e, a
+ call GetMusicByte
+ ld d, a
+ push bc
+ call _PlayMusic
+ pop bc
+ ret
+
+GetMusicByte:
+ push hl
+ push de
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, CHANNEL_MUSIC_BANK
+ add hl, bc
+ ld a, [hl]
+ call _LoadMusicByte
+ ld [wCurMusicByte], a
+ inc de
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ pop de
+ pop hl
+ ret
+
+
+GetFrequency:
+; generate frequency
+; input:
+; d: octave
+; e: pitch
+; output:
+; de: frequency
+
+; get octave
+ ld hl, CHANNEL_PITCH_OFFSET
+ add hl, bc
+ ld a, [hl]
+ swap a
+ and $f
+ add d
+
+ push af
+
+ ld hl, CHANNEL_PITCH_OFFSET
+ add hl, bc
+ ld a, [hl]
+ and $f
+ ld l, a
+ ld d, 0
+ ld h, d
+ add hl, de
+ add hl, hl
+
+ ld de, FrequencyTable
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+ pop af
+
+.loop
+; [7 - octave] loops
+ cp 7
+ jr nc, .ok
+
+ sra d
+ rr e
+ inc a
+ jr .loop
+
+.ok
+ ld a, d
+ and $07
+ ld d, a
+ ret
+
+
+SetNoteDuration:
+; input: a = note duration in 16ths
+
+ inc a
+ ld e, a
+ ld d, 0
+ ld hl, CHANNEL_NOTE_LENGTH
+ add hl, bc
+ ld a, [hl]
+ ld l, 0
+ call .Multiply
+ ld a, l
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld hl, CHANNEL_FIELD16
+ add hl, bc
+ ld l, [hl]
+ call .Multiply
+ ld e, l
+ ld d, h
+ ld hl, CHANNEL_FIELD16
+ add hl, bc
+ ld [hl], e
+ 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
+ jr nc, .skip
+
+; add the remainder to the result
+ add hl, de
+
+.skip
+; de * 2
+ sla e
+ rl d
+
+; done multiplying?
+ and a
+ jr nz, .loop
+ ret
SetGlobalTempo:
push bc
@@ -573,7 +2512,7 @@ SetLRTracks:
maskbits NUM_MUSIC_CHANS
ld e, a
ld d, 0
- ld hl, $52B3 ; FIXME
+ ld hl, LRTracks
add hl, de
ld a, [hl]
ld hl, CHANNEL_TRACKS
@@ -588,29 +2527,399 @@ _PlayMusic::
ld [hl], e
inc hl
ld [hl], d
- ld hl, Music
+ ld hl, SongHeaderPointers
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld [wMusicBank], a
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ call LoadMusicByte
+ rlca
+ rlca
+ maskbits NUM_MUSIC_CHANS
+ inc a
+.loop
+ push af
+ call LoadChannel
+ call StartChannel
+ pop af
+ dec a
+ jr nz, .loop
+ xor a
+ ld [wc1b3], a
+ ld [wChannel1JumpCondition], a
+ ld [wChannel2JumpCondition], a
+ ld [wChannel3JumpCondition], a
+ ld [wChannel4JumpCondition], a
+ ret
+
+
+_PlayCryHeader::
+ ld hl, wMusicID
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+ ld hl, CryHeaderPointers
+ add hl, de
+ add hl, de
+ add hl, de
+
+ ld a, [hli]
+ ld [wMusicBank], a
+
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+ call LoadMusicByte
+ rlca
+ rlca
+ maskbits NUM_MUSIC_CHANS
+ 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
+
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ cp 3
+ jr nc, .start
+
+; no tempo for ch4
+ 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
+
+ ld a, [wce5f]
+ bit 5, a
+ jr z, .next
+
+ 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
+
+ ld a, [wLastVolume]
+ and a
+ jr nz, .end
+
+ ld a, [wVolume]
+ ld [wLastVolume], a
+ ld a, MAX_VOLUME
+ ld [wVolume], a
+
+.end
+; stop playing music
+ ld a, 1
+ ld [wSFXPriority], a
+ ret
+
+
+_PlaySFX::
+ ld hl, wMusicID
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, SFXPointers
+; three byte pointers
+ add hl, de
+ add hl, de
+ add hl, de
+; get bank
+ ld a, [hli]
+ ld [wMusicBank], a
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ call LoadMusicByte
+ rlca
+ rlca
+ maskbits NUM_MUSIC_CHANS
+ inc a
+
+.start_channels
+ push af
+ call LoadChannel
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_SFX, [hl]
+ call StartChannel
+ pop af
+ dec a
+ jr nz, .start_channels
+ ret
+
+ ld a, [wce5f]
+ bit 5, a ; Stereo flag?
+ jr z, _PlaySFX
+
+ ld hl, wMusicID
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+ ld hl, SFXPointers
add hl, de
add hl, de
add hl, de
+
ld a, [hli]
ld [wMusicBank], a
ld e, [hl]
inc hl
ld d, [hl]
+
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
+
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ ld e, a
+ ld d, 0
+ ld hl, LRTracks
+ 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
+ jr c, .skip
+
+ 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
+
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_CHANNEL_ON, [hl]
+
+ pop af
+ dec a
+ jr nz, .loop
+
+ ret
+
+ ld hl, wMusicID
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, SFXPointers
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld [wMusicBank], a
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ call LoadMusicByte
+ rlca
+ rlca
+ maskbits NUM_MUSIC_CHANS
+ inc a
+
+.cry_channels
+ push af
+ call LoadChannel
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ set SOUND_SFX, [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
+ ld a, [wCurChannel]
+ maskbits NUM_MUSIC_CHANS
+ cp 3
+ jr nc, .cry_ok
+
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
+ ld a, [wCryLength]
+ ld [hli], a
+ ld a, [wCryLength + 1]
+ ld [hl], a
+
+.cry_ok
call StartChannel
pop af
dec a
+ jr nz, .cry_channels
+
+ ret
+
+
+LoadChannel::
+ call LoadMusicByte
+ inc de
+ and 7
+ 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]
+ ld hl, CHANNEL_FLAGS1
+ add hl, bc
+ res SOUND_CHANNEL_ON, [hl]
+ call ChannelInit
+ ld hl, CHANNEL_MUSIC_ADDRESS
+ add hl, bc
+ call LoadMusicByte
+ ld [hli], a
+ inc de
+ call LoadMusicByte
+ ld [hl], a
+ inc de
+ ld hl, CHANNEL_MUSIC_ID
+ add hl, bc
+ ld a, [wMusicID]
+ ld [hli], a
+ ld a, [wMusicID + 1]
+ ld [hl], a
+ ld hl, CHANNEL_MUSIC_BANK
+ add hl, bc
+ ld a, [wMusicBank]
+ ld [hl], a
+ ret
+
+
+ChannelInit:
+ push de
+ xor a
+ ld hl, CHANNEL_MUSIC_ID
+ add hl, bc
+ ld e, CHANNEL_STRUCT_LENGTH
+
+.loop
+ ld [hli], a
+ dec e
jr nz, .loop
+
+ ld hl, CHANNEL_TEMPO
+ add hl, bc
xor a
- ; TODO
+ ld [hli], a
+ inc a
+ ld [hl], a
+ ld hl, CHANNEL_NOTE_LENGTH
+ add hl, bc
+ ld [hl], a
+ pop de
+ ret
+
+
+LoadMusicByte::
+ ld a, [wMusicBank]
+ call _LoadMusicByte
+ ret
+
+INCLUDE "audio/notes.inc"
+
+INCLUDE "audio/wave_samples.inc"
+
+INCLUDE "audio/wave_overrides.inc"
+
+INCLUDE "audio/intensity_overrides.inc"
+
+INCLUDE "audio/drumkits.inc"
+
+LRTracks:
+; bit corresponds to track #
+; hi: left channel
+; lo: right channel
+ 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
-SECTION "audio/engine.asm@Song Header Pointers", ROMX
INCLUDE "audio/song_header_pointers.inc"
diff --git a/audio/intensity_overrides.inc b/audio/intensity_overrides.inc
new file mode 100644
index 0000000..3740427
--- /dev/null
+++ b/audio/intensity_overrides.inc
@@ -0,0 +1,33 @@
+IntensityOverrides:
+ dw .override1
+ dw .override2
+ dw .override3
+ dw .override4
+ dw Drumkits
+ dw Drumkits
+
+.override1
+ db $11, $21, $31, $41, $51, $61, $71, $81, $91, $A1, $B1, $C1, $D1, $E1
+ db $F1, $F1, $F1, $F1, $F1, $F1, $E1, $E1, $E1, $E1, $D1, $D1, $D1, $D1
+ db $C1, $C1, $C1, $C1, $B1, $B1, $B1, $B1, $A1, $A1, $A1, $A1, $91, $91
+ db $91, $91, $81, $81, $81, $81, $71, $71, $71, $71, $61, $61, $61, $61
+ db $51, $51, $51, $51, $41, $41, $41, $41, $31, $31, $31, $31, $21, $21
+ db $21, $21, $11, $11, $11, $11
+ db -1
+
+.override2
+ db $11, $91, $D1, $F1, $F1, $F1, $F1, $F1, $D1, $D1, $D1, $D1, $A1, $A1
+ db $A1, $A1, $81, $81, $81, $81, $61, $61, $61, $61, $41, $41, $41, $41
+ db $21, $21, $21, $21
+ db -1
+
+.override3
+ db $31, $51, $A1, $51, $F1, $51, $F1, $51, $F1, $51, $F1, $51, $D1, $51
+ db $D1, $51, $B1, $51, $B1, $51, $91, $51, $91, $51, $71, $51, $71, $51
+ db $51, $51, $51, $51, $31, $51, $31, $51, $11, $51, $11, $51
+ db -1
+
+.override4
+ db $F0, $E0, $D0, $C0, $B0, $A0, $90, $80, $70, $60, $50, $40, $30, $20
+ db $10, $00
+ db -1
diff --git a/audio/notes.inc b/audio/notes.inc
new file mode 100644
index 0000000..eeb8495
--- /dev/null
+++ b/audio/notes.inc
@@ -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/wave_overrides.inc b/audio/wave_overrides.inc
new file mode 100644
index 0000000..8876dc6
--- /dev/null
+++ b/audio/wave_overrides.inc
@@ -0,0 +1,11 @@
+WaveOverrides:
+ dw .override
+ dw .override
+ dw .override
+ dw .override
+ dw .override
+ dw .override
+
+.override
+ db $0A, $0B, $0C, $0D, $0E, $0F, $10, $11, $12, $13, $14, $15, $16, $17
+ db -1
diff --git a/audio/wave_samples.inc b/audio/wave_samples.inc
new file mode 100644
index 0000000..bc40b9d
--- /dev/null
+++ b/audio/wave_samples.inc
@@ -0,0 +1,27 @@
+WaveSamples:
+ 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 ; 0
+ 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 ; 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 ; 2
+ 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 ; 3
+ 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 ; 4
+ dn 0, 0, 2, 3, 4, 5, 6, 7, 8, 10, 12, 7, 14, 14, 15, 7, 7, 15, 14, 14, 13, 7, 10, 8, 7, 6, 5, 4, 3, 2, 1, 4 ; 5
+ dn 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 15 ; 6
+ dn 0, 15, 0, 15, 0, 14, 0, 14, 0, 13, 0, 13, 0, 12, 0, 12, 0, 11, 0, 11, 0, 10, 0, 10, 0, 9, 0, 9, 0, 8, 0, 8 ; 7
+ dn 0, 7, 0, 7, 0, 6, 0, 6, 0, 5, 0, 5, 0, 4, 0, 4, 0, 3, 0, 3, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0, 0, 0 ; 8
+ dn 15, 15, 15, 15, 15, 15, 15, 15, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8 ; 9
+ dn 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; a
+ dn 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; b
+ dn 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; c
+ dn 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; d
+ dn 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; e
+ dn 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; f
+
+; inaccessible beyond this point?
+ dn 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
+ dn 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
+ dn 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
+ dn 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
+ dn 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
+ dn 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
+ dn 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
+ dn 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
diff --git a/constants/audio_constants.asm b/constants/audio_constants.asm
index 51dc36f..39a99f6 100644
--- a/constants/audio_constants.asm
+++ b/constants/audio_constants.asm
@@ -42,7 +42,7 @@ 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_PITCH_OFFSET EQUS "(wChannel1StartingOctave - wChannel1)"
CHANNEL_NOTE_DURATION EQUS "(wChannel1NoteDuration - wChannel1)"
CHANNEL_FIELD16 EQUS "(wChannel1Field16 - wChannel1)"
CHANNEL_LOOP_COUNT EQUS "(wChannel1LoopCount - wChannel1)"
@@ -93,16 +93,17 @@ NOISE_CHAN_F EQU 2 ; bit set in CHAN5-CHAN7
const_def
const SOUND_VIBRATO_DIR ; 0
const SOUND_PITCH_WHEEL_DIR ; 1
+ const SOUND_UNKN_12 ; 2
; NoteFlags
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
+ const NOTE_DUTY_OVERRIDE ; 0
+ const NOTE_FREQ_OVERRIDE ; 1
+ const NOTE_INTENSITY_OVERRIDE ; 2
+ const NOTE_PITCH_SWEEP ; 3
+ const NOTE_NOISE_SAMPLING ; 4
+ const NOTE_REST ; 5
+ const NOTE_VIBRATO_OVERRIDE ; 6
; wVolume
VOLUME_SO1_F EQU 3
diff --git a/home/cry.asm b/home/cry.asm
index 3dbe63f..994bc29 100644
--- a/home/cry.asm
+++ b/home/cry.asm
@@ -5,15 +5,15 @@ SECTION "home/cry.asm", ROM0
PlayStereoCry::
push af
ld a, $1
- ld [wc1b9], a
+ ld [wStereoPanningMask], a
pop af
jr _PlayCry
PlayCry::
push af
xor a
- ld [wc1b9], a
- ld [wc1ba], a
+ ld [wStereoPanningMask], a
+ ld [wCryTracks], a
pop af
_PlayCry:
push hl
diff --git a/layout.link b/layout.link
index a52e750..ab1e182 100644
--- a/layout.link
+++ b/layout.link
@@ -906,15 +906,7 @@ ROMX $39
ROMX $3a
org $4000
- "audio/engine.asm@Audio"
- org $42bd
- "audio/engine.asm@IsChannelSFXOn"
- "audio/engine.asm@Functione82f0"
- org $4cee
- "audio/engine.asm@Audio engine, part 2"
- org $52c7
- "audio/engine.asm@Song Header Pointers"
- org $52ee
+ "audio/engine.asm"
"audio/songs/none.asm"
ROMX $3b
diff --git a/ram/wram.asm b/ram/wram.asm
index 56e87b8..6b7fa0f 100644
--- a/ram/wram.asm
+++ b/ram/wram.asm
@@ -22,9 +22,9 @@ wChannel8:: channel_struct wChannel8
wCurTrackDuty:: db
wCurTrackIntensity:: db
wCurTrackFrequency:: dw
-wc195:: db
-
- ds 2 ; TODO
+wSoundLength:: db
+wCurNoteDuration:: db
+wCurMusicByte:: db
wCurChannel:: db
wVolume:: db
@@ -34,12 +34,15 @@ wSoundOutput::
; bit 0-3: ch1-4 so1 on/off
db
- ds 1 ; TODO
+wPitchSweep:: db
wMusicID:: dw
wMusicBank:: db
- ds 5 ; TODO
+wNoiseSampleAddress:: dw
+wNoiseSampleDelay:: db
+wc1a2:: db
+wNoiseSampleSet:: db
wLowHealthAlarm::
; bit 7: on/off
@@ -58,19 +61,27 @@ wMusicFadeID::
wMusicFadeIDLow:: db
wMusicFadeIDHigh:: db
- ds 2 ; TODO
+wSweepingFadeIndex:: db
+wSweepingFadeCounter:: db
wIncrementTempo: dw
wMapMusic:: db
wCryPitch:: dw
wCryLength:: dw
- ds 7 ; TODO
+wLastVolume:: db
+wc1b3:: db
+wSFXPriority:: db
+wChannel1JumpCondition:: db
+wChannel2JumpCondition:: db
+wChannel3JumpCondition:: db
+wChannel4JumpCondition:: db
+
+wStereoPanningMask:: db
-wc1b9:: db
-wc1ba:: db
+wCryTracks:: db
; either wChannelsEnd or wMusicEnd, unsure
- ds 1 ; TODO
+wSFXDuration:: db
wMusicInitEnd::
diff --git a/shim.sym b/shim.sym
index 7b68e54..5b3b000 100755
--- a/shim.sym
+++ b/shim.sym
@@ -151,22 +151,15 @@
33:625D BattleAnim_Sine_e
33:6263 BattleAnim_Cosine_e
-3A:441D Functione841d
-3A:45D8 Functione85d8
-3A:47F9 Functione87f9
-3A:4839 Functione8839
-3A:484F Functione884f
-3A:4D9D _PlayCryHeader
-3A:4E22 _PlaySFX
-3A:4F11 LoadChannel
-3A:4F6C LoadMusicByte
-3A:52C7 Music
+3A:536D SFXPointers
+3A:52FB CryHeaderPointers
3F:40E9 InGameDebugMenu
3F:4305 TrainerGear
3F:4C24 Functionfcc24
3F:4E3E Functionfce3e
3F:5B66 Functionfdb66
+3F:6255 Functionfe255
3F:64CE MonsterTest
3F:654E PicTest
3F:6750 PicTestMenu