mirror of
https://github.com/pret/pokegold-spaceworld.git
synced 2026-04-25 07:22:04 -05:00
* Began decompiling Bank $33 * Decompiled battle anim functions * Decompiled battle anim OAM and AnimObjGFX, split up and labelled battle animation graphics, other minor changes * Deleted useless files I forgot to delete * Decompiled framesets * Decompiled battle anim objects * Partially started decompiling animations * Finished decompiling and labelling bank 32 in its entirety * Replaced gfx.c with latest version * Labelled all sound effects, properly constantified * Fixed up bg_effects.asm, other minor LYOverrides-related changes
2927 lines
38 KiB
NASM
2927 lines
38 KiB
NASM
INCLUDE "constants.asm"
|
|
|
|
SECTION "audio/engine.asm", ROMX
|
|
|
|
_DisableAudio::
|
|
push hl
|
|
push de
|
|
push bc
|
|
push af
|
|
ld hl, rNR50
|
|
xor a
|
|
ld [hli], a
|
|
ld [hli], a
|
|
ld a, $80
|
|
ld [hli], a
|
|
ld hl, rNR10
|
|
ld e, 4
|
|
.init_channel
|
|
xor a
|
|
ld [hli], a
|
|
ld [hli], a
|
|
ld a, 8
|
|
ld [hli], a
|
|
xor a
|
|
ld [hli], a
|
|
ld a, $80
|
|
ld [hli], a
|
|
dec e
|
|
jr nz, .init_channel
|
|
|
|
ld hl, wMusic
|
|
ld de, wMusicInitEnd - wMusic
|
|
.clear
|
|
xor a
|
|
ld [hli], a
|
|
dec de
|
|
ld a, e
|
|
or d
|
|
jr nz, .clear
|
|
|
|
ld a, MAX_VOLUME
|
|
ld [wVolume], a
|
|
|
|
pop af
|
|
pop bc
|
|
pop de
|
|
pop hl
|
|
ret
|
|
|
|
_UpdateSound::
|
|
; Called once per frame
|
|
xor a
|
|
ld [wCurChannel], a
|
|
ld [wSoundOutput], a
|
|
ld bc, wChannel1
|
|
|
|
.loop
|
|
ld hl, CHANNEL_FLAGS1
|
|
add hl, bc
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr z, .nextchannel
|
|
|
|
call UpdateChannel
|
|
|
|
.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
|
|
jr nz, .loop
|
|
|
|
call Functione82f0
|
|
ret
|
|
|
|
UpdateChannel:
|
|
; Get the note's duration
|
|
ld hl, CHANNEL_NOTE_DURATION
|
|
add hl, bc
|
|
ld a, [hl]
|
|
|
|
; Check if this is the last frame
|
|
cp 1
|
|
jr z, .noteover
|
|
and a
|
|
jr z, .noteover
|
|
|
|
dec [hl]
|
|
jr .continue_sound_update
|
|
|
|
.noteover
|
|
call DisablePitchWheel
|
|
call ParseMusic
|
|
|
|
.continue_sound_update
|
|
call Functione80b6
|
|
ret
|
|
|
|
DisablePitchWheel:
|
|
ld hl, CHANNEL_FLAGS2
|
|
add hl, bc
|
|
res SOUND_PITCH_WHEEL, [hl]
|
|
ret
|
|
|
|
Unreferenced_Functione8081:
|
|
ld a, [wMapMusic]
|
|
bit 0, a
|
|
jr nz, .disable_music
|
|
|
|
bit 1, a
|
|
jr nz, .disable_sfx
|
|
|
|
.fail
|
|
and a
|
|
ret
|
|
|
|
.disable_music
|
|
call _DisableAudio
|
|
jr .done
|
|
|
|
.disable_sfx
|
|
call IsChannelSFXOn
|
|
jr c, .fail
|
|
|
|
; Clear the registers of the channel
|
|
call GetChannelRegisters
|
|
ld e, rNR20 - rNR10
|
|
xor a
|
|
|
|
.clear_loop
|
|
ld [hli], a
|
|
dec e
|
|
jr nz, .clear_loop
|
|
|
|
.done
|
|
scf
|
|
ret
|
|
|
|
GetChannelRegisters:
|
|
ld a, [wCurChannel]
|
|
ld e, a
|
|
ld d, $00
|
|
ld hl, .registers
|
|
add hl, de
|
|
ld l, [hl]
|
|
ld h, $ff ; HIGH(rNR10, rNR20, rNR30, rNR40)
|
|
ret
|
|
|
|
.registers
|
|
db LOW(rNR10), LOW(rNR20), LOW(rNR30), LOW(rNR40)
|
|
|
|
Functione80b6:
|
|
ld hl, CHANNEL_DUTY_CYCLE
|
|
add hl, bc
|
|
ld a, [hl]
|
|
ld [wCurTrackDuty], a
|
|
|
|
ld hl, CHANNEL_INTENSITY
|
|
add hl, bc
|
|
ld a, [hl]
|
|
ld [wCurTrackIntensity], a
|
|
|
|
ld hl, CHANNEL_FREQUENCY
|
|
add hl, bc
|
|
ld a, [hli]
|
|
ld [wCurTrackFrequency], a
|
|
ld a, [hl]
|
|
ld [wCurTrackFrequency + 1], a
|
|
ld a, $3F
|
|
ld [wSoundLength], a
|
|
call Functione85d8
|
|
call ReadNoiseSample
|
|
call HaltMusicWhileSFXPlaying
|
|
call IsChannelSFXOn
|
|
jr nc, .end
|
|
|
|
call UpdateChannels
|
|
ld hl, CHANNEL_TRACKS
|
|
add hl, bc
|
|
ld a, [wSoundOutput]
|
|
or [hl]
|
|
ld [wSoundOutput], a
|
|
|
|
.end
|
|
ld hl, CHANNEL_NOTE_FLAGS
|
|
add hl, bc
|
|
xor a
|
|
ld [hl], a
|
|
ret
|
|
|
|
UpdateChannels:
|
|
ld hl, .jumptable
|
|
ld a, [wCurChannel]
|
|
maskbits NUM_CHANNELS
|
|
add a
|
|
ld e, a
|
|
ld d, 0
|
|
add hl, de
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
jp hl
|
|
|
|
.jumptable
|
|
; 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
|
|
|
|
IsChannelSFXOn:
|
|
; If it's not a valid channel, return
|
|
ld a, [wCurChannel]
|
|
cp NUM_MUSIC_CHANS
|
|
jr nc, .off
|
|
|
|
; Check if the corresponding SFX channel is on
|
|
ld hl, CHANNEL_STRUCT_LENGTH * NUM_MUSIC_CHANS + CHANNEL_FLAGS1
|
|
add hl, bc
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr z, .off
|
|
|
|
and a
|
|
ret
|
|
|
|
.off
|
|
scf
|
|
ret
|
|
|
|
IsAnySFXOn:
|
|
ld hl, wChannel5Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr nz, .on
|
|
ld hl, wChannel6Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr nz, .on
|
|
ld hl, wChannel7Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr nz, .on
|
|
ld hl, wChannel8Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr nz, .on
|
|
|
|
and a
|
|
ret
|
|
|
|
.on
|
|
scf
|
|
ret
|
|
|
|
Functione82f0:
|
|
call IncrementTempo
|
|
call PlayDanger
|
|
call FadeMusic
|
|
call DoSweepingFade
|
|
ld a, [wVolume]
|
|
ldh [rNR50], a
|
|
ld a, [wSoundOutput]
|
|
ldh [rNR51], a
|
|
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 IsAnySFXOn
|
|
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
|
|
|
|
; Make sure channel 1 is on
|
|
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
|
|
|
|
IncrementTempo:
|
|
call IsAnyChannelOn
|
|
ret c
|
|
|
|
ld a, [wIncrementTempo]
|
|
ld e, a
|
|
ld a, [wIncrementTempo + 1]
|
|
ld d, a
|
|
or e
|
|
ret z
|
|
|
|
ld hl, wChannel1Tempo
|
|
call .addtempo
|
|
ld hl, wChannel2Tempo
|
|
call .addtempo
|
|
ld hl, wChannel3Tempo
|
|
call .addtempo
|
|
ld hl, wChannel4Tempo
|
|
call .addtempo
|
|
xor a
|
|
ld [wIncrementTempo], a
|
|
ld [wIncrementTempo + 1], a
|
|
ret
|
|
|
|
.addtempo
|
|
; (int16)[hl] += de
|
|
push de
|
|
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 de
|
|
ret
|
|
|
|
IsAnyChannelOn:
|
|
; Check if any music channel is on and isn't on the last frame
|
|
|
|
ld hl, wChannel1Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr z, .check_channel2
|
|
|
|
ld hl, wChannel1NoteDuration
|
|
ld a, [hl]
|
|
cp 1
|
|
jr nz, .on
|
|
|
|
.check_channel2
|
|
ld hl, wChannel2Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr z, .check_channel3
|
|
|
|
ld hl, wChannel2NoteDuration
|
|
ld a, [hl]
|
|
cp 1
|
|
jr nz, .on
|
|
|
|
.check_channel3
|
|
ld hl, wChannel3Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr z, .check_channel4
|
|
|
|
ld hl, wChannel3NoteDuration
|
|
ld a, [hl]
|
|
cp 1
|
|
jr nz, .on
|
|
|
|
.check_channel4
|
|
ld hl, wChannel4Flags1
|
|
bit SOUND_CHANNEL_ON, [hl]
|
|
jr z, .off
|
|
|
|
ld hl, wChannel4NoteDuration
|
|
ld a, [hl]
|
|
cp 1
|
|
jr nz, .on
|
|
|
|
.off
|
|
and a
|
|
ret
|
|
|
|
.on
|
|
scf
|
|
ret
|
|
|
|
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 $7f
|
|
|
|
; Exit early if not fading
|
|
ld a, [wMusicFade]
|
|
and a
|
|
ret z
|
|
|
|
; If it doesn't have a count, assign it
|
|
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 $7f
|
|
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
|
|
|
|
; Decrement volume
|
|
and a
|
|
jr z, .novolume
|
|
dec a
|
|
jr .updatevolume
|
|
|
|
.novolume
|
|
; Fade in new song
|
|
ld a, [wMusicFadeID]
|
|
ld e, a
|
|
ld a, [wMusicFadeID + 1]
|
|
ld d, a
|
|
push bc
|
|
call _PlayMusic
|
|
pop bc
|
|
ld hl, wMusicFade
|
|
set 7, [hl]
|
|
ret
|
|
|
|
.fadein
|
|
; Increment volume
|
|
cp MAX_VOLUME & $f
|
|
jr nc, .maxvolume
|
|
inc a
|
|
jr .updatevolume
|
|
|
|
.maxvolume
|
|
; Clear wMusicFade
|
|
xor a
|
|
ld [wMusicFade], a
|
|
ret
|
|
|
|
.updatevolume
|
|
; Set the current volume for both speakers
|
|
ld d, a
|
|
swap a
|
|
or d
|
|
ld [wVolume], a
|
|
ret
|
|
|
|
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
|
|
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
|
|
ret
|
|
|
|
Tempo:
|
|
ld hl, CHANNEL_TEMPO
|
|
add hl, bc
|
|
ld [hl], e
|
|
inc hl
|
|
ld [hl], d
|
|
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]
|
|
ret
|
|
|
|
|
|
StopChannel:
|
|
ld hl, CHANNEL_FLAGS1
|
|
add hl, bc
|
|
res SOUND_CHANNEL_ON, [hl]
|
|
ld hl, CHANNEL_MUSIC_ID
|
|
add hl, bc
|
|
xor a
|
|
ld [hli], a
|
|
ld [hli], a
|
|
ld [hli], a
|
|
ret
|
|
|
|
|
|
SetLRTracks:
|
|
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, CHANNEL_TRACKS
|
|
add hl, bc
|
|
ld [hl], a
|
|
pop de
|
|
ret
|
|
|
|
|
|
_PlayMusic::
|
|
ld hl, wMusicID
|
|
ld [hl], e
|
|
inc hl
|
|
ld [hl], d
|
|
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, Cries
|
|
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, SFX
|
|
; 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
|
|
|
|
PlayStereoSFX::
|
|
ld a, [wce5f]
|
|
bit 5, a ; Stereo flag?
|
|
jr z, _PlaySFX
|
|
|
|
ld hl, wMusicID
|
|
ld [hl], e
|
|
inc hl
|
|
ld [hl], d
|
|
|
|
ld hl, SFX
|
|
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, SFX
|
|
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
|
|
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
|
|
|
|
INCLUDE "audio/song_header_pointers.inc"
|