Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/audio/engine_2.asm
1270 views
1
; The second of three duplicated sound engines.
2
; This copy has a few differences relating to battle sound effects
3
; and the low health alarm that plays in battle
4
5
Audio2_UpdateMusic::
6
ld c, CHAN1
7
.loop
8
ld b, 0
9
ld hl, wChannelSoundIDs
10
add hl, bc
11
ld a, [hl]
12
and a
13
jr z, .nextChannel
14
ld a, c
15
cp CHAN5
16
jr nc, .applyAffects ; if sfx channel
17
ld a, [wMuteAudioAndPauseMusic]
18
and a
19
jr z, .applyAffects
20
bit BIT_MUTE_AUDIO, a
21
jr nz, .nextChannel
22
set BIT_MUTE_AUDIO, a
23
ld [wMuteAudioAndPauseMusic], a
24
xor a ; disable all channels' output
25
ldh [rAUDTERM], a
26
ldh [rAUD3ENA], a
27
ld a, AUD3ENA_ON
28
ldh [rAUD3ENA], a
29
jr .nextChannel
30
.applyAffects
31
call Audio2_ApplyMusicAffects
32
.nextChannel
33
ld a, c
34
inc c ; inc channel number
35
cp CHAN8
36
jr nz, .loop
37
ret
38
39
; this routine checks flags for music effects currently applied
40
; to the channel and calls certain functions based on flags.
41
Audio2_ApplyMusicAffects:
42
ld b, $0
43
ld hl, wChannelNoteDelayCounters ; delay until next note
44
add hl, bc
45
ld a, [hl]
46
cp 1 ; if the delay is 1, play next note
47
jp z, Audio2_PlayNextNote
48
dec a ; otherwise, decrease the delay timer
49
ld [hl], a
50
ld a, c
51
cp CHAN5
52
jr nc, .startChecks ; if a sfx channel
53
ld hl, wChannelSoundIDs + CHAN5
54
add hl, bc
55
ld a, [hl]
56
and a
57
jr z, .startChecks
58
ret
59
.startChecks
60
ld hl, wChannelFlags1
61
add hl, bc
62
bit BIT_ROTATE_DUTY_CYCLE, [hl]
63
jr z, .checkForExecuteMusic
64
call Audio2_ApplyDutyCyclePattern
65
.checkForExecuteMusic
66
ld b, 0
67
ld hl, wChannelFlags2
68
add hl, bc
69
bit BIT_EXECUTE_MUSIC, [hl]
70
jr nz, .checkForPitchSlide
71
ld hl, wChannelFlags1
72
add hl, bc
73
bit BIT_NOISE_OR_SFX, [hl]
74
jr nz, .skipPitchSlideVibrato
75
.checkForPitchSlide
76
ld hl, wChannelFlags1
77
add hl, bc
78
bit BIT_PITCH_SLIDE_ON, [hl]
79
jr z, .checkVibratoDelay
80
jp Audio2_ApplyPitchSlide
81
.checkVibratoDelay
82
ld hl, wChannelVibratoDelayCounters
83
add hl, bc
84
ld a, [hl]
85
and a ; check if delay is over
86
jr z, .checkForVibrato
87
dec [hl] ; otherwise, dec delay
88
.skipPitchSlideVibrato
89
ret
90
.checkForVibrato
91
ld hl, wChannelVibratoExtents
92
add hl, bc
93
ld a, [hl]
94
and a
95
jr nz, .vibrato
96
ret ; no vibrato
97
.vibrato
98
ld d, a
99
ld hl, wChannelVibratoRates
100
add hl, bc
101
ld a, [hl]
102
and $f
103
and a
104
jr z, .applyVibrato
105
dec [hl] ; decrement counter
106
ret
107
.applyVibrato
108
ld a, [hl]
109
swap [hl]
110
or [hl]
111
ld [hl], a ; reload the counter
112
ld hl, wChannelFrequencyLowBytes
113
add hl, bc
114
ld e, [hl] ; get note pitch
115
ld hl, wChannelFlags1
116
add hl, bc
117
; This is the only code that sets/resets the vibrato direction bit, so it
118
; continuously alternates which path it takes.
119
bit BIT_VIBRATO_DIRECTION, [hl]
120
jr z, .unset
121
res BIT_VIBRATO_DIRECTION, [hl]
122
ld a, d
123
and $f
124
ld d, a
125
ld a, e
126
sub d
127
jr nc, .noCarry
128
ld a, 0
129
.noCarry
130
jr .done
131
.unset
132
set BIT_VIBRATO_DIRECTION, [hl]
133
ld a, d
134
and $f0
135
swap a
136
add e
137
jr nc, .done
138
ld a, $ff
139
.done
140
ld d, a
141
ld b, REG_FREQUENCY_LO
142
call Audio2_GetRegisterPointer
143
ld [hl], d
144
ret
145
146
; this routine executes all music commands that take up no time,
147
; like tempo changes, duty cycle changes etc. and doesn't return
148
; until the first note is reached
149
Audio2_PlayNextNote:
150
; reload the vibrato delay counter
151
ld hl, wChannelVibratoDelayCounterReloadValues
152
add hl, bc
153
ld a, [hl]
154
ld hl, wChannelVibratoDelayCounters
155
add hl, bc
156
ld [hl], a
157
158
ld hl, wChannelFlags1
159
add hl, bc
160
res BIT_PITCH_SLIDE_ON, [hl]
161
res BIT_PITCH_SLIDE_DECREASING, [hl]
162
; --- this section is only present in this copy of the sound engine
163
ld a, c
164
cp CHAN5
165
jr nz, .beginChecks
166
ld a, [wLowHealthAlarm]
167
bit BIT_LOW_HEALTH_ALARM, a
168
ret nz
169
.beginChecks
170
; ---
171
call Audio2_sound_ret
172
ret
173
174
Audio2_sound_ret:
175
call Audio2_GetNextMusicByte
176
ld d, a
177
cp sound_ret_cmd
178
jp nz, Audio2_sound_call
179
ld b, 0
180
ld hl, wChannelFlags1
181
add hl, bc
182
bit BIT_SOUND_CALL, [hl]
183
jr nz, .returnFromCall
184
ld a, c
185
cp CHAN4
186
jr nc, .noiseOrSfxChannel
187
jr .disableChannelOutput
188
.noiseOrSfxChannel
189
res BIT_NOISE_OR_SFX, [hl]
190
ld hl, wChannelFlags2
191
add hl, bc
192
res BIT_EXECUTE_MUSIC, [hl]
193
cp CHAN7
194
jr nz, .skipSfxChannel3
195
; restart hardware channel 3 (wave channel) output
196
ld a, AUD3ENA_OFF
197
ldh [rAUD3ENA], a
198
ld a, AUD3ENA_ON
199
ldh [rAUD3ENA], a
200
.skipSfxChannel3
201
jr nz, .dontDisable
202
ld a, [wDisableChannelOutputWhenSfxEnds]
203
and a
204
jr z, .dontDisable
205
xor a
206
ld [wDisableChannelOutputWhenSfxEnds], a
207
jr .disableChannelOutput
208
.dontDisable
209
jr .afterDisable
210
.returnFromCall
211
res BIT_SOUND_CALL, [hl]
212
ld d, $0
213
ld a, c
214
add a
215
ld e, a
216
ld hl, wChannelCommandPointers
217
add hl, de
218
push hl ; store current channel address
219
ld hl, wChannelReturnAddresses
220
add hl, de
221
ld e, l
222
ld d, h
223
pop hl
224
ld a, [de]
225
ld [hli], a
226
inc de
227
ld a, [de]
228
ld [hl], a ; loads channel address to return to
229
jp Audio2_sound_ret
230
.disableChannelOutput
231
ld hl, Audio2_HWChannelDisableMasks
232
add hl, bc
233
ldh a, [rAUDTERM]
234
and [hl]
235
ldh [rAUDTERM], a
236
.afterDisable
237
ld a, [wChannelSoundIDs + CHAN5]
238
cp CRY_SFX_START
239
jr nc, .maybeCry
240
jr .skipCry
241
.maybeCry
242
ld a, [wChannelSoundIDs + CHAN5]
243
cp CRY_SFX_END
244
jr z, .skipCry
245
jr c, .cry
246
jr .skipCry
247
.cry
248
ld a, c
249
cp CHAN5
250
jr z, .skipRewind
251
call Audio2_GoBackOneCommandIfCry
252
ret c
253
.skipRewind
254
ld a, [wSavedVolume]
255
ldh [rAUDVOL], a
256
xor a
257
ld [wSavedVolume], a
258
.skipCry
259
ld hl, wChannelSoundIDs
260
add hl, bc
261
ld [hl], b
262
ret
263
264
Audio2_sound_call:
265
cp sound_call_cmd
266
jp nz, Audio2_sound_loop
267
call Audio2_GetNextMusicByte
268
push af
269
call Audio2_GetNextMusicByte
270
ld d, a
271
pop af
272
ld e, a
273
push de ; store pointer
274
ld d, $0
275
ld a, c
276
add a
277
ld e, a
278
ld hl, wChannelCommandPointers
279
add hl, de
280
push hl
281
ld hl, wChannelReturnAddresses
282
add hl, de
283
ld e, l
284
ld d, h
285
pop hl
286
ld a, [hli]
287
ld [de], a
288
inc de
289
ld a, [hld]
290
ld [de], a ; copy current channel address
291
pop de
292
ld [hl], e
293
inc hl
294
ld [hl], d ; overwrite current address with pointer
295
ld b, $0
296
ld hl, wChannelFlags1
297
add hl, bc
298
set BIT_SOUND_CALL, [hl] ; set the call flag
299
jp Audio2_sound_ret
300
301
Audio2_sound_loop:
302
cp sound_loop_cmd
303
jp nz, Audio2_note_type
304
call Audio2_GetNextMusicByte
305
ld e, a
306
and a
307
jr z, .infiniteLoop
308
ld b, 0
309
ld hl, wChannelLoopCounters
310
add hl, bc
311
ld a, [hl]
312
cp e
313
jr nz, .loopAgain
314
ld a, $1 ; if no more loops to make,
315
ld [hl], a
316
call Audio2_GetNextMusicByte ; skip pointer
317
call Audio2_GetNextMusicByte
318
jp Audio2_sound_ret
319
.loopAgain ; inc loop count
320
inc a
321
ld [hl], a
322
; fall through
323
.infiniteLoop ; overwrite current address with pointer
324
call Audio2_GetNextMusicByte
325
push af
326
call Audio2_GetNextMusicByte
327
ld b, a
328
ld d, $0
329
ld a, c
330
add a
331
ld e, a
332
ld hl, wChannelCommandPointers
333
add hl, de
334
pop af
335
ld [hli], a
336
ld [hl], b
337
jp Audio2_sound_ret
338
339
Audio2_note_type:
340
and $f0
341
cp note_type_cmd
342
jp nz, Audio2_toggle_perfect_pitch
343
ld a, d
344
and $f
345
ld b, $0
346
ld hl, wChannelNoteSpeeds
347
add hl, bc
348
ld [hl], a ; store low nibble as speed
349
ld a, c
350
cp CHAN4
351
jr z, .noiseChannel ; noise channel has 0 params
352
call Audio2_GetNextMusicByte
353
ld d, a
354
ld a, c
355
cp CHAN3
356
jr z, .musicChannel3
357
cp CHAN7
358
jr nz, .skipChannel3
359
ld hl, wSfxWaveInstrument
360
jr .channel3
361
.musicChannel3
362
ld hl, wMusicWaveInstrument
363
.channel3
364
ld a, d
365
and $f
366
ld [hl], a ; store low nibble of param as wave instrument
367
ld a, d
368
and $30
369
sla a
370
ld d, a
371
; fall through
372
373
; if channel 3, store high nibble as volume
374
; else, store volume (high nibble) and fade (low nibble)
375
.skipChannel3
376
ld b, 0
377
ld hl, wChannelVolumes
378
add hl, bc
379
ld [hl], d
380
.noiseChannel
381
jp Audio2_sound_ret
382
383
Audio2_toggle_perfect_pitch:
384
ld a, d
385
cp toggle_perfect_pitch_cmd
386
jr nz, Audio2_vibrato
387
ld b, 0
388
ld hl, wChannelFlags1
389
add hl, bc
390
ld a, [hl]
391
xor 1 << BIT_PERFECT_PITCH
392
ld [hl], a
393
jp Audio2_sound_ret
394
395
Audio2_vibrato:
396
cp vibrato_cmd
397
jr nz, Audio2_pitch_slide
398
call Audio2_GetNextMusicByte
399
ld b, 0
400
ld hl, wChannelVibratoDelayCounters
401
add hl, bc
402
ld [hl], a ; store delay
403
ld hl, wChannelVibratoDelayCounterReloadValues
404
add hl, bc
405
ld [hl], a ; store delay
406
call Audio2_GetNextMusicByte
407
ld d, a
408
409
; The high nybble of the command byte is the extent of the vibrato.
410
; Let n be the extent.
411
; The upper nybble of the channel's byte in the wChannelVibratoExtents
412
; array will store the extent above the note: (n / 2) + (n % 2).
413
; The lower nybble will store the extent below the note: (n / 2).
414
; These two values add to the total extent, n.
415
and $f0
416
swap a
417
ld b, 0
418
ld hl, wChannelVibratoExtents
419
add hl, bc
420
srl a
421
ld e, a
422
adc b
423
swap a
424
or e
425
ld [hl], a
426
427
; The low nybble of the command byte is the rate of the vibrato.
428
; The high and low nybbles of the channel's byte in the wChannelVibratoRates
429
; array are both initialised to this value because the high nybble is the
430
; counter reload value and the low nybble is the counter itself, which should
431
; start at its value upon reload.
432
ld a, d
433
and $f
434
ld d, a
435
ld hl, wChannelVibratoRates
436
add hl, bc
437
swap a
438
or d
439
ld [hl], a
440
441
jp Audio2_sound_ret
442
443
Audio2_pitch_slide:
444
cp pitch_slide_cmd
445
jr nz, Audio2_duty_cycle
446
call Audio2_GetNextMusicByte
447
ld b, 0
448
ld hl, wChannelPitchSlideLengthModifiers
449
add hl, bc
450
ld [hl], a
451
call Audio2_GetNextMusicByte
452
ld d, a
453
and $f0
454
swap a
455
ld b, a
456
ld a, d
457
and $f
458
call Audio2_CalculateFrequency
459
ld b, 0
460
ld hl, wChannelPitchSlideTargetFrequencyHighBytes
461
add hl, bc
462
ld [hl], d
463
ld hl, wChannelPitchSlideTargetFrequencyLowBytes
464
add hl, bc
465
ld [hl], e
466
ld b, 0
467
ld hl, wChannelFlags1
468
add hl, bc
469
set BIT_PITCH_SLIDE_ON, [hl]
470
call Audio2_GetNextMusicByte
471
ld d, a
472
jp Audio2_note_length
473
474
Audio2_duty_cycle:
475
cp duty_cycle_cmd
476
jr nz, Audio2_tempo
477
call Audio2_GetNextMusicByte
478
rrca
479
rrca
480
and $c0
481
ld b, 0
482
ld hl, wChannelDutyCycles
483
add hl, bc
484
ld [hl], a ; store duty cycle
485
jp Audio2_sound_ret
486
487
Audio2_tempo:
488
cp tempo_cmd
489
jr nz, Audio2_stereo_panning
490
ld a, c
491
cp CHAN5
492
jr nc, .sfxChannel
493
call Audio2_GetNextMusicByte
494
ld [wMusicTempo], a ; store first param
495
call Audio2_GetNextMusicByte
496
ld [wMusicTempo + 1], a ; store second param
497
xor a
498
ld [wChannelNoteDelayCountersFractionalPart], a ; clear RAM
499
ld [wChannelNoteDelayCountersFractionalPart + 1], a
500
ld [wChannelNoteDelayCountersFractionalPart + 2], a
501
ld [wChannelNoteDelayCountersFractionalPart + 3], a
502
jr .musicChannelDone
503
.sfxChannel
504
call Audio2_GetNextMusicByte
505
ld [wSfxTempo], a ; store first param
506
call Audio2_GetNextMusicByte
507
ld [wSfxTempo + 1], a ; store second param
508
xor a
509
ld [wChannelNoteDelayCountersFractionalPart + 4], a ; clear RAM
510
ld [wChannelNoteDelayCountersFractionalPart + 5], a
511
ld [wChannelNoteDelayCountersFractionalPart + 6], a
512
ld [wChannelNoteDelayCountersFractionalPart + 7], a
513
.musicChannelDone
514
jp Audio2_sound_ret
515
516
Audio2_stereo_panning:
517
cp stereo_panning_cmd
518
jr nz, Audio2_unknownmusic0xef
519
call Audio2_GetNextMusicByte
520
ld [wStereoPanning], a ; store panning
521
jp Audio2_sound_ret
522
523
; this appears to never be used
524
Audio2_unknownmusic0xef:
525
cp unknownmusic0xef_cmd
526
jr nz, Audio2_duty_cycle_pattern
527
call Audio2_GetNextMusicByte
528
push bc
529
call Audio2_PlaySound
530
pop bc
531
ld a, [wDisableChannelOutputWhenSfxEnds]
532
and a
533
jr nz, .skip
534
ld a, [wChannelSoundIDs + CHAN8]
535
ld [wDisableChannelOutputWhenSfxEnds], a
536
xor a
537
ld [wChannelSoundIDs + CHAN8], a
538
.skip
539
jp Audio2_sound_ret
540
541
Audio2_duty_cycle_pattern:
542
cp duty_cycle_pattern_cmd
543
jr nz, Audio2_volume
544
call Audio2_GetNextMusicByte
545
ld b, 0
546
ld hl, wChannelDutyCyclePatterns
547
add hl, bc
548
ld [hl], a ; store full pattern
549
and %11000000
550
ld hl, wChannelDutyCycles
551
add hl, bc
552
ld [hl], a ; store first duty cycle
553
ld hl, wChannelFlags1
554
add hl, bc
555
set BIT_ROTATE_DUTY_CYCLE, [hl]
556
jp Audio2_sound_ret
557
558
Audio2_volume:
559
cp volume_cmd
560
jr nz, Audio2_execute_music
561
call Audio2_GetNextMusicByte
562
ldh [rAUDVOL], a ; store volume
563
jp Audio2_sound_ret
564
565
Audio2_execute_music:
566
cp execute_music_cmd
567
jr nz, Audio2_octave
568
ld b, $0
569
ld hl, wChannelFlags2
570
add hl, bc
571
set BIT_EXECUTE_MUSIC, [hl]
572
jp Audio2_sound_ret
573
574
Audio2_octave:
575
and $f0
576
cp octave_cmd
577
jr nz, Audio2_sfx_note
578
ld hl, wChannelOctaves
579
ld b, 0
580
add hl, bc
581
ld a, d
582
and $f
583
ld [hl], a ; store low nibble as octave
584
jp Audio2_sound_ret
585
586
; sfx_note is either square_note or noise_note depending on the channel
587
Audio2_sfx_note:
588
cp sfx_note_cmd
589
jr nz, Audio2_pitch_sweep
590
ld a, c
591
cp CHAN4 ; is this a noise or sfx channel?
592
jr c, Audio2_pitch_sweep ; no
593
ld b, 0
594
ld hl, wChannelFlags2
595
add hl, bc
596
bit BIT_EXECUTE_MUSIC, [hl] ; is execute_music being used?
597
jr nz, Audio2_pitch_sweep ; yes
598
call Audio2_note_length
599
600
; This code seems to do the same thing as what Audio2_ApplyDutyCycleAndSoundLength
601
; does below.
602
ld d, a
603
ld b, 0
604
ld hl, wChannelDutyCycles
605
add hl, bc
606
ld a, [hl]
607
or d
608
ld d, a
609
ld b, REG_DUTY_SOUND_LEN
610
call Audio2_GetRegisterPointer
611
ld [hl], d
612
613
call Audio2_GetNextMusicByte
614
ld d, a
615
ld b, REG_VOLUME_ENVELOPE
616
call Audio2_GetRegisterPointer
617
ld [hl], d
618
call Audio2_GetNextMusicByte
619
ld e, a
620
ld a, c
621
cp CHAN8
622
ld a, 0
623
jr z, .skip
624
; Channels 1 through 3 have 2 registers that control frequency, but the noise
625
; channel a single register (the polynomial counter) that controls frequency,
626
; so this command has one less byte on the noise channel.
627
push de
628
call Audio2_GetNextMusicByte
629
pop de
630
.skip
631
ld d, a
632
push de
633
call Audio2_ApplyDutyCycleAndSoundLength
634
call Audio2_EnableChannelOutput
635
pop de
636
call Audio2_ApplyWavePatternAndFrequency
637
ret
638
639
Audio2_pitch_sweep:
640
ld a, c
641
cp CHAN5
642
jr c, Audio2_note ; if not a sfx
643
ld a, d
644
cp pitch_sweep_cmd
645
jr nz, Audio2_note
646
ld b, $0
647
ld hl, wChannelFlags2
648
add hl, bc
649
bit BIT_EXECUTE_MUSIC, [hl]
650
jr nz, Audio2_note ; no
651
call Audio2_GetNextMusicByte
652
ldh [rAUD1SWEEP], a
653
jp Audio2_sound_ret
654
655
Audio2_note:
656
ld a, c
657
cp CHAN4
658
jr nz, Audio2_note_length ; if not noise channel
659
ld a, d
660
and $f0
661
cp drum_note_cmd
662
jr z, .drum_note
663
jr nc, Audio2_note_length
664
665
; this executes when on the noise channel and
666
; the command id is less than drum_note_cmd ($b0)
667
; in this case, the upper nybble is used as the noise instrument ($1-$a)
668
; and the lower nybble is the length minus 1 (0-15)
669
; however, this doesn't work for instrument #2 because the command id
670
; is captured by the noise_note command (command id $2x)
671
; this essentially acts like a drum_note command that is only 1 byte
672
; instead of 2 and can only be used with instruments 1 and 3 through 10
673
; this is unused by the game
674
swap a
675
ld b, a
676
ld a, d
677
and $f
678
ld d, a
679
ld a, b
680
push de
681
push bc
682
jr .playDnote
683
684
.drum_note
685
ld a, d
686
and $f
687
push af
688
push bc
689
call Audio2_GetNextMusicByte ; get drum_note instrument
690
.playDnote
691
ld d, a
692
ld a, [wDisableChannelOutputWhenSfxEnds]
693
and a
694
jr nz, .skipDnote
695
ld a, d
696
call Audio2_PlaySound
697
.skipDnote
698
pop bc
699
pop de
700
701
Audio2_note_length:
702
ld a, d
703
push af
704
and $f
705
inc a
706
ld b, 0
707
ld e, a ; store note length (in 16ths)
708
ld d, b
709
ld hl, wChannelNoteSpeeds
710
add hl, bc
711
ld a, [hl]
712
ld l, b
713
call Audio2_MultiplyAdd
714
ld a, c
715
cp CHAN5
716
jr nc, .sfxChannel
717
ld a, [wMusicTempo]
718
ld d, a
719
ld a, [wMusicTempo + 1]
720
ld e, a
721
jr .skip
722
.sfxChannel
723
ld d, $1
724
ld e, $0
725
cp CHAN8
726
jr z, .skip ; if noise channel
727
call Audio2_SetSfxTempo
728
ld a, [wSfxTempo]
729
ld d, a
730
ld a, [wSfxTempo + 1]
731
ld e, a
732
.skip
733
ld a, l ; a = note_length * note_speed
734
ld b, 0
735
ld hl, wChannelNoteDelayCountersFractionalPart
736
add hl, bc
737
ld l, [hl]
738
call Audio2_MultiplyAdd
739
ld e, l
740
ld d, h ; de = note_delay_frac_part + (note_length * note_speed * tempo)
741
ld hl, wChannelNoteDelayCountersFractionalPart
742
add hl, bc
743
ld [hl], e
744
ld a, d
745
ld hl, wChannelNoteDelayCounters
746
add hl, bc
747
ld [hl], a
748
ld hl, wChannelFlags2
749
add hl, bc
750
bit BIT_EXECUTE_MUSIC, [hl]
751
jr nz, Audio2_note_pitch
752
ld hl, wChannelFlags1
753
add hl, bc
754
bit BIT_NOISE_OR_SFX, [hl]
755
jr z, Audio2_note_pitch
756
pop hl
757
ret
758
759
Audio2_note_pitch:
760
pop af
761
and $f0
762
cp rest_cmd
763
jr nz, .notRest
764
ld a, c
765
cp CHAN5
766
jr nc, .next
767
; If this isn't an SFX channel, try the corresponding SFX channel.
768
ld hl, wChannelSoundIDs + CHAN5
769
add hl, bc
770
ld a, [hl]
771
and a
772
jr nz, .done
773
; fall through
774
.next
775
ld a, c
776
cp CHAN3
777
jr z, .channel3
778
cp CHAN7
779
jr nz, .notChannel3
780
.channel3
781
ld b, 0
782
ld hl, Audio2_HWChannelDisableMasks
783
add hl, bc
784
ldh a, [rAUDTERM]
785
and [hl]
786
ldh [rAUDTERM], a ; disable hardware channel 3's output
787
jr .done
788
.notChannel3
789
ld b, REG_VOLUME_ENVELOPE
790
call Audio2_GetRegisterPointer
791
ld a, $8 ; fade in sound
792
ld [hli], a
793
inc hl
794
ld a, $80 ; restart sound
795
ld [hl], a
796
.done
797
ret
798
.notRest
799
swap a
800
ld b, 0
801
ld hl, wChannelOctaves
802
add hl, bc
803
ld b, [hl]
804
call Audio2_CalculateFrequency
805
ld b, 0
806
ld hl, wChannelFlags1
807
add hl, bc
808
bit BIT_PITCH_SLIDE_ON, [hl]
809
jr z, .skipPitchSlide
810
call Audio2_InitPitchSlideVars
811
.skipPitchSlide
812
push de
813
ld a, c
814
cp CHAN5
815
jr nc, .sfxChannel ; if sfx channel
816
; If this isn't an SFX channel, try the corresponding SFX channel.
817
ld hl, wChannelSoundIDs + CHAN5
818
ld d, 0
819
ld e, a
820
add hl, de
821
ld a, [hl]
822
and a
823
jr nz, .noSfx
824
jr .sfxChannel
825
.noSfx
826
pop de
827
ret
828
.sfxChannel
829
ld b, 0
830
ld hl, wChannelVolumes
831
add hl, bc
832
ld d, [hl]
833
ld b, REG_VOLUME_ENVELOPE
834
call Audio2_GetRegisterPointer
835
ld [hl], d
836
call Audio2_ApplyDutyCycleAndSoundLength
837
call Audio2_EnableChannelOutput
838
pop de
839
ld b, $0
840
ld hl, wChannelFlags1
841
add hl, bc
842
bit BIT_PERFECT_PITCH, [hl] ; has toggle_perfect_pitch been used?
843
jr z, .skipFrequencyInc
844
inc e ; if yes, increment the frequency by 1
845
jr nc, .skipFrequencyInc ; Likely a mistake, because `inc` does not set flag C.
846
; Fortunately this does not seem to affect any notes that actually occur.
847
inc d
848
.skipFrequencyInc
849
ld hl, wChannelFrequencyLowBytes
850
add hl, bc
851
ld [hl], e
852
call Audio2_ApplyWavePatternAndFrequency
853
ret
854
855
Audio2_EnableChannelOutput:
856
ld b, 0
857
ld hl, Audio2_HWChannelEnableMasks
858
add hl, bc
859
ldh a, [rAUDTERM]
860
or [hl] ; set this channel's bits
861
ld d, a
862
ld a, c
863
cp CHAN8
864
jr z, .noiseChannelOrNoSfx
865
cp CHAN5
866
jr nc, .skip ; if sfx channel
867
; If this isn't an SFX channel, try the corresponding SFX channel.
868
ld hl, wChannelSoundIDs + CHAN5
869
add hl, bc
870
ld a, [hl]
871
and a
872
jr nz, .skip
873
.noiseChannelOrNoSfx
874
; If this is the SFX noise channel or a music channel whose corresponding
875
; SFX channel is off, apply stereo panning.
876
ld a, [wStereoPanning]
877
ld hl, Audio2_HWChannelEnableMasks
878
add hl, bc
879
and [hl]
880
ld d, a
881
ldh a, [rAUDTERM]
882
ld hl, Audio2_HWChannelDisableMasks
883
add hl, bc
884
and [hl] ; reset this channel's output bits
885
or d ; set this channel's output bits that enabled in [wStereoPanning]
886
ld d, a
887
.skip
888
ld a, d
889
ldh [rAUDTERM], a
890
ret
891
892
Audio2_ApplyDutyCycleAndSoundLength:
893
ld b, 0
894
ld hl, wChannelNoteDelayCounters ; use the note delay as sound length
895
add hl, bc
896
ld d, [hl]
897
ld a, c
898
cp CHAN3
899
jr z, .skipDuty ; if music channel 3
900
cp CHAN7
901
jr z, .skipDuty ; if sfx channel 3
902
; include duty cycle (except on channel 3 which doesn't have it)
903
ld a, d
904
and $3f
905
ld d, a
906
ld hl, wChannelDutyCycles
907
add hl, bc
908
ld a, [hl]
909
or d
910
ld d, a
911
.skipDuty
912
ld b, REG_DUTY_SOUND_LEN
913
call Audio2_GetRegisterPointer
914
ld [hl], d
915
ret
916
917
Audio2_ApplyWavePatternAndFrequency:
918
ld a, c
919
cp CHAN3
920
jr z, .channel3
921
cp CHAN7
922
jr nz, .notChannel3
923
; fall through
924
.channel3
925
push de
926
ld de, wMusicWaveInstrument
927
cp CHAN3
928
jr z, .next
929
ld de, wSfxWaveInstrument
930
.next
931
ld a, [de]
932
add a
933
ld d, 0
934
ld e, a
935
ld hl, Audio2_WavePointers
936
add hl, de
937
ld e, [hl]
938
inc hl
939
ld d, [hl]
940
ld hl, _AUD3WAVERAM
941
ld b, AUD3WAVE_SIZE - 1
942
ld a, $0 ; stop hardware channel 3
943
ldh [rAUD3ENA], a
944
.loop
945
ld a, [de]
946
inc de
947
ld [hli], a
948
ld a, b
949
dec b
950
and a
951
jr nz, .loop
952
ld a, AUD3ENA_ON ; start hardware channel 3
953
ldh [rAUD3ENA], a
954
pop de
955
.notChannel3
956
ld a, d
957
or $80 ; use counter mode (i.e. disable output when the counter reaches 0)
958
and $c7 ; zero the unused bits in the register
959
ld d, a
960
ld b, REG_FREQUENCY_LO
961
call Audio2_GetRegisterPointer
962
ld [hl], e ; store frequency low byte
963
inc hl
964
ld [hl], d ; store frequency high byte
965
; --- this section is only present in this copy of the sound engine
966
ld a, c
967
cp CHAN5
968
jr c, .musicChannel
969
call Audio2_ApplyFrequencyModifier
970
.musicChannel
971
; ---
972
ret
973
974
; --- this section is only present in this copy of the sound engine
975
; unused
976
Audio2_ResetCryModifiers:
977
ld a, c
978
cp CHAN5
979
jr nz, .skip
980
ld a, [wLowHealthAlarm]
981
bit BIT_LOW_HEALTH_ALARM, a
982
jr z, .skip
983
xor a
984
ld [wFrequencyModifier], a
985
ld a, $80
986
ld [wTempoModifier], a
987
.skip
988
ret
989
; ---
990
991
Audio2_SetSfxTempo:
992
call Audio2_IsCry
993
jr c, .skipCryCheck
994
call Audio2_IsBattleSFX
995
jr nc, .notCry
996
.skipCryCheck
997
ld d, 0
998
ld a, [wTempoModifier]
999
add $80
1000
jr nc, .next
1001
inc d
1002
.next
1003
ld [wSfxTempo + 1], a
1004
ld a, d
1005
ld [wSfxTempo], a
1006
jr .done
1007
.notCry
1008
xor a
1009
ld [wSfxTempo + 1], a
1010
ld a, $1
1011
ld [wSfxTempo], a
1012
.done
1013
ret
1014
1015
Audio2_ApplyFrequencyModifier:
1016
call Audio2_IsCry
1017
jr c, .skipCryCheck
1018
call Audio2_IsBattleSFX
1019
jr nc, .done
1020
.skipCryCheck
1021
; if playing a cry, add the cry's frequency modifier
1022
ld a, [wFrequencyModifier]
1023
add e
1024
jr nc, .noCarry
1025
inc d
1026
.noCarry
1027
dec hl
1028
ld e, a
1029
ld [hl], e
1030
inc hl
1031
ld [hl], d
1032
.done
1033
ret
1034
1035
Audio2_GoBackOneCommandIfCry:
1036
call Audio2_IsCry
1037
jr nc, .done
1038
ld hl, wChannelCommandPointers
1039
ld e, c
1040
ld d, 0
1041
sla e
1042
rl d
1043
add hl, de
1044
ld a, [hl]
1045
sub 1
1046
ld [hl], a
1047
inc hl
1048
ld a, [hl]
1049
sbc 0
1050
ld [hl], a
1051
scf
1052
ret
1053
.done
1054
scf
1055
ccf
1056
ret
1057
1058
Audio2_IsCry:
1059
; Returns whether the currently playing audio is a cry in carry.
1060
ld a, [wChannelSoundIDs + CHAN5]
1061
cp CRY_SFX_START
1062
jr nc, .next
1063
jr .no
1064
.next
1065
cp CRY_SFX_END
1066
jr z, .no
1067
jr c, .yes
1068
.no
1069
scf
1070
ccf
1071
ret
1072
.yes
1073
scf
1074
ret
1075
1076
; --- this section is only present in this copy of the sound engine
1077
Audio2_IsBattleSFX:
1078
; Returns whether the currently playing audio is a battle sfx in carry.
1079
ld a, [wChannelSoundIDs + CHAN8]
1080
ld b, a
1081
ld a, [wChannelSoundIDs + CHAN5]
1082
or b
1083
cp BATTLE_SFX_START
1084
jr nc, .next
1085
jr .no
1086
.next
1087
cp BATTLE_SFX_END
1088
jr z, .no
1089
jr c, .yes
1090
.no
1091
scf
1092
ccf
1093
ret
1094
.yes
1095
scf
1096
ret
1097
; ---
1098
1099
Audio2_ApplyPitchSlide:
1100
ld hl, wChannelFlags1
1101
add hl, bc
1102
bit BIT_PITCH_SLIDE_DECREASING, [hl]
1103
jp nz, .frequencyDecreasing
1104
; frequency increasing
1105
ld hl, wChannelPitchSlideCurrentFrequencyLowBytes
1106
add hl, bc
1107
ld e, [hl]
1108
ld hl, wChannelPitchSlideCurrentFrequencyHighBytes
1109
add hl, bc
1110
ld d, [hl]
1111
ld hl, wChannelPitchSlideFrequencySteps
1112
add hl, bc
1113
ld l, [hl]
1114
ld h, b
1115
add hl, de
1116
ld d, h
1117
ld e, l
1118
ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart
1119
add hl, bc
1120
push hl
1121
ld hl, wChannelPitchSlideFrequencyStepsFractionalPart
1122
add hl, bc
1123
ld a, [hl]
1124
pop hl
1125
add [hl]
1126
ld [hl], a
1127
ld a, 0
1128
adc e
1129
ld e, a
1130
ld a, 0
1131
adc d
1132
ld d, a
1133
ld hl, wChannelPitchSlideTargetFrequencyHighBytes
1134
add hl, bc
1135
ld a, [hl]
1136
cp d
1137
jp c, .reachedTargetFrequency
1138
jr nz, .applyUpdatedFrequency
1139
ld hl, wChannelPitchSlideTargetFrequencyLowBytes
1140
add hl, bc
1141
ld a, [hl]
1142
cp e
1143
jp c, .reachedTargetFrequency
1144
jr .applyUpdatedFrequency
1145
.frequencyDecreasing
1146
ld hl, wChannelPitchSlideCurrentFrequencyLowBytes
1147
add hl, bc
1148
ld a, [hl]
1149
ld hl, wChannelPitchSlideCurrentFrequencyHighBytes
1150
add hl, bc
1151
ld d, [hl]
1152
ld hl, wChannelPitchSlideFrequencySteps
1153
add hl, bc
1154
ld e, [hl]
1155
sub e
1156
ld e, a
1157
ld a, d
1158
sbc b
1159
ld d, a
1160
ld hl, wChannelPitchSlideFrequencyStepsFractionalPart
1161
add hl, bc
1162
ld a, [hl]
1163
add a
1164
ld [hl], a
1165
ld a, e
1166
sbc b
1167
ld e, a
1168
ld a, d
1169
sbc b
1170
ld d, a
1171
ld hl, wChannelPitchSlideTargetFrequencyHighBytes
1172
add hl, bc
1173
ld a, d
1174
cp [hl]
1175
jr c, .reachedTargetFrequency
1176
jr nz, .applyUpdatedFrequency
1177
ld hl, wChannelPitchSlideTargetFrequencyLowBytes
1178
add hl, bc
1179
ld a, e
1180
cp [hl]
1181
jr c, .reachedTargetFrequency
1182
.applyUpdatedFrequency
1183
ld hl, wChannelPitchSlideCurrentFrequencyLowBytes
1184
add hl, bc
1185
ld [hl], e
1186
ld hl, wChannelPitchSlideCurrentFrequencyHighBytes
1187
add hl, bc
1188
ld [hl], d
1189
ld b, REG_FREQUENCY_LO
1190
call Audio2_GetRegisterPointer
1191
ld a, e
1192
ld [hli], a
1193
ld [hl], d
1194
ret
1195
.reachedTargetFrequency
1196
; Turn off pitch slide when the target frequency has been reached.
1197
ld hl, wChannelFlags1
1198
add hl, bc
1199
res BIT_PITCH_SLIDE_ON, [hl]
1200
res BIT_PITCH_SLIDE_DECREASING, [hl]
1201
ret
1202
1203
Audio2_InitPitchSlideVars:
1204
ld hl, wChannelPitchSlideCurrentFrequencyHighBytes
1205
add hl, bc
1206
ld [hl], d
1207
ld hl, wChannelPitchSlideCurrentFrequencyLowBytes
1208
add hl, bc
1209
ld [hl], e
1210
ld hl, wChannelNoteDelayCounters
1211
add hl, bc
1212
ld a, [hl]
1213
ld hl, wChannelPitchSlideLengthModifiers
1214
add hl, bc
1215
sub [hl]
1216
jr nc, .next
1217
ld a, 1
1218
.next
1219
ld [hl], a
1220
ld hl, wChannelPitchSlideTargetFrequencyLowBytes
1221
add hl, bc
1222
ld a, e
1223
sub [hl]
1224
ld e, a
1225
ld a, d
1226
sbc b
1227
ld hl, wChannelPitchSlideTargetFrequencyHighBytes
1228
add hl, bc
1229
sub [hl]
1230
jr c, .targetFrequencyGreater
1231
ld d, a
1232
ld b, 0
1233
ld hl, wChannelFlags1
1234
add hl, bc
1235
set BIT_PITCH_SLIDE_DECREASING, [hl]
1236
jr .next2
1237
.targetFrequencyGreater
1238
; If the target frequency is greater, subtract the current frequency from
1239
; the target frequency to get the absolute difference.
1240
ld hl, wChannelPitchSlideCurrentFrequencyHighBytes
1241
add hl, bc
1242
ld d, [hl]
1243
ld hl, wChannelPitchSlideCurrentFrequencyLowBytes
1244
add hl, bc
1245
ld e, [hl]
1246
ld hl, wChannelPitchSlideTargetFrequencyLowBytes
1247
add hl, bc
1248
ld a, [hl]
1249
sub e
1250
ld e, a
1251
1252
; Bug. Instead of borrowing from the high byte of the target frequency as it
1253
; should, it borrows from the high byte of the current frequency instead.
1254
; This means that the result will be 0x200 greater than it should be if the
1255
; low byte of the current frequency is greater than the low byte of the
1256
; target frequency.
1257
ld a, d
1258
sbc b
1259
ld d, a
1260
1261
ld hl, wChannelPitchSlideTargetFrequencyHighBytes
1262
add hl, bc
1263
ld a, [hl]
1264
sub d
1265
ld d, a
1266
ld b, 0
1267
ld hl, wChannelFlags1
1268
add hl, bc
1269
res BIT_PITCH_SLIDE_DECREASING, [hl]
1270
1271
.next2
1272
ld hl, wChannelPitchSlideLengthModifiers
1273
add hl, bc
1274
.divideLoop
1275
inc b
1276
ld a, e
1277
sub [hl]
1278
ld e, a
1279
jr nc, .divideLoop
1280
ld a, d
1281
and a
1282
jr z, .doneDividing
1283
dec a
1284
ld d, a
1285
jr .divideLoop
1286
.doneDividing
1287
ld a, e ; a = remainder - dividend
1288
add [hl]
1289
ld d, b ; d = quotient + 1
1290
ld b, 0
1291
ld hl, wChannelPitchSlideFrequencySteps
1292
add hl, bc
1293
ld [hl], d ; store quotient + 1
1294
ld hl, wChannelPitchSlideFrequencyStepsFractionalPart
1295
add hl, bc
1296
ld [hl], a ; store remainder - dividend
1297
ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart
1298
add hl, bc
1299
ld [hl], a ; store remainder - dividend
1300
ret
1301
1302
Audio2_ApplyDutyCyclePattern:
1303
ld b, 0
1304
ld hl, wChannelDutyCyclePatterns
1305
add hl, bc
1306
ld a, [hl]
1307
rlca
1308
rlca
1309
ld [hl], a
1310
and $c0
1311
ld d, a
1312
ld b, REG_DUTY_SOUND_LEN
1313
call Audio2_GetRegisterPointer
1314
ld a, [hl]
1315
and $3f
1316
or d
1317
ld [hl], a
1318
ret
1319
1320
Audio2_GetNextMusicByte:
1321
ld d, 0
1322
ld a, c
1323
add a
1324
ld e, a
1325
ld hl, wChannelCommandPointers
1326
add hl, de
1327
ld a, [hli]
1328
ld e, a
1329
ld a, [hld]
1330
ld d, a
1331
ld a, [de] ; get next music command
1332
inc de
1333
ld [hl], e ; store address of next command
1334
inc hl
1335
ld [hl], d
1336
ret
1337
1338
Audio2_GetRegisterPointer:
1339
; hl = address of hardware sound register b for software channel c
1340
ld a, c
1341
ld hl, Audio2_HWChannelBaseAddresses
1342
add l
1343
jr nc, .noCarry
1344
inc h
1345
.noCarry
1346
ld l, a
1347
ld a, [hl]
1348
add b
1349
ld l, a
1350
ld h, $ff
1351
ret
1352
1353
Audio2_MultiplyAdd:
1354
; hl = l + (a * de)
1355
ld h, 0
1356
.loop
1357
srl a
1358
jr nc, .skipAdd
1359
add hl, de
1360
.skipAdd
1361
sla e
1362
rl d
1363
and a
1364
jr z, .done
1365
jr .loop
1366
.done
1367
ret
1368
1369
Audio2_CalculateFrequency:
1370
; return the frequency for note a, octave b in de
1371
ld h, 0
1372
ld l, a
1373
add hl, hl
1374
ld d, h
1375
ld e, l
1376
ld hl, Audio2_Pitches
1377
add hl, de
1378
ld e, [hl]
1379
inc hl
1380
ld d, [hl]
1381
ld a, b
1382
.loop
1383
cp 7
1384
jr z, .done
1385
sra d
1386
rr e
1387
inc a
1388
jr .loop
1389
.done
1390
ld a, 8
1391
add d
1392
ld d, a
1393
ret
1394
1395
Audio2_PlaySound::
1396
ld [wSoundID], a
1397
cp SFX_STOP_ALL_MUSIC
1398
jp z, .stopAllAudio
1399
cp MAX_SFX_ID_2
1400
jp z, .playSfx
1401
jp c, .playSfx
1402
cp $fe
1403
jr z, .playMusic
1404
jp nc, .playSfx
1405
1406
.playMusic
1407
xor a
1408
ld [wUnusedMusicByte], a
1409
ld [wDisableChannelOutputWhenSfxEnds], a
1410
ld [wMusicTempo + 1], a
1411
ld [wMusicWaveInstrument], a
1412
ld [wSfxWaveInstrument], a
1413
ld d, NUM_CHANNELS
1414
ld hl, wChannelReturnAddresses
1415
call .FillMem
1416
ld hl, wChannelCommandPointers
1417
call .FillMem
1418
ld d, NUM_MUSIC_CHANS
1419
ld hl, wChannelSoundIDs
1420
call .FillMem
1421
ld hl, wChannelFlags1
1422
call .FillMem
1423
ld hl, wChannelDutyCycles
1424
call .FillMem
1425
ld hl, wChannelDutyCyclePatterns
1426
call .FillMem
1427
ld hl, wChannelVibratoDelayCounters
1428
call .FillMem
1429
ld hl, wChannelVibratoExtents
1430
call .FillMem
1431
ld hl, wChannelVibratoRates
1432
call .FillMem
1433
ld hl, wChannelFrequencyLowBytes
1434
call .FillMem
1435
ld hl, wChannelVibratoDelayCounterReloadValues
1436
call .FillMem
1437
ld hl, wChannelFlags2
1438
call .FillMem
1439
ld hl, wChannelPitchSlideLengthModifiers
1440
call .FillMem
1441
ld hl, wChannelPitchSlideFrequencySteps
1442
call .FillMem
1443
ld hl, wChannelPitchSlideFrequencyStepsFractionalPart
1444
call .FillMem
1445
ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart
1446
call .FillMem
1447
ld hl, wChannelPitchSlideCurrentFrequencyHighBytes
1448
call .FillMem
1449
ld hl, wChannelPitchSlideCurrentFrequencyLowBytes
1450
call .FillMem
1451
ld hl, wChannelPitchSlideTargetFrequencyHighBytes
1452
call .FillMem
1453
ld hl, wChannelPitchSlideTargetFrequencyLowBytes
1454
call .FillMem
1455
ld a, $1
1456
ld hl, wChannelLoopCounters
1457
call .FillMem
1458
ld hl, wChannelNoteDelayCounters
1459
call .FillMem
1460
ld hl, wChannelNoteSpeeds
1461
call .FillMem
1462
ld [wMusicTempo], a
1463
ld a, $ff
1464
ld [wStereoPanning], a
1465
xor a
1466
ldh [rAUDVOL], a
1467
ld a, AUD1SWEEP_DOWN
1468
ldh [rAUD1SWEEP], a
1469
ld a, 0
1470
ldh [rAUDTERM], a
1471
xor a
1472
ldh [rAUD3ENA], a
1473
ld a, AUD3ENA_ON
1474
ldh [rAUD3ENA], a
1475
ld a, $77
1476
ldh [rAUDVOL], a
1477
jp .playSoundCommon
1478
1479
.playSfx
1480
ld l, a
1481
ld e, a
1482
ld h, 0
1483
ld d, h
1484
add hl, hl
1485
add hl, de
1486
ld de, SFX_Headers_2
1487
add hl, de
1488
ld a, h
1489
ld [wSfxHeaderPointer], a
1490
ld a, l
1491
ld [wSfxHeaderPointer + 1], a
1492
ld a, [hl]
1493
and $c0
1494
rlca
1495
rlca
1496
ld c, a
1497
.sfxChannelLoop
1498
ld d, c
1499
ld a, c
1500
add a
1501
add c
1502
ld c, a
1503
ld b, 0
1504
ld a, [wSfxHeaderPointer]
1505
ld h, a
1506
ld a, [wSfxHeaderPointer + 1]
1507
ld l, a
1508
add hl, bc
1509
ld c, d
1510
ld a, [hl]
1511
and $f
1512
ld e, a ; software channel ID
1513
ld d, 0
1514
ld hl, wChannelSoundIDs
1515
add hl, de
1516
ld a, [hl]
1517
and a
1518
jr z, .playChannel
1519
ld a, e
1520
cp CHAN8
1521
jr nz, .notNoiseChannel
1522
ld a, [wSoundID]
1523
cp NOISE_INSTRUMENTS_END
1524
jr nc, .notNoiseInstrument
1525
ret
1526
.notNoiseInstrument
1527
ld a, [hl]
1528
cp NOISE_INSTRUMENTS_END
1529
jr z, .playChannel
1530
jr c, .playChannel
1531
.notNoiseChannel
1532
ld a, [wSoundID]
1533
cp [hl]
1534
jr z, .playChannel
1535
jr c, .playChannel
1536
ret
1537
.playChannel
1538
xor a
1539
push de
1540
ld h, d
1541
ld l, e
1542
add hl, hl
1543
ld d, h
1544
ld e, l
1545
ld hl, wChannelReturnAddresses
1546
add hl, de
1547
ld [hli], a
1548
ld [hl], a
1549
ld hl, wChannelCommandPointers
1550
add hl, de
1551
ld [hli], a
1552
ld [hl], a
1553
pop de
1554
ld hl, wChannelSoundIDs
1555
add hl, de
1556
ld [hl], a
1557
ld hl, wChannelFlags1
1558
add hl, de
1559
ld [hl], a
1560
ld hl, wChannelDutyCycles
1561
add hl, de
1562
ld [hl], a
1563
ld hl, wChannelDutyCyclePatterns
1564
add hl, de
1565
ld [hl], a
1566
ld hl, wChannelVibratoDelayCounters
1567
add hl, de
1568
ld [hl], a
1569
ld hl, wChannelVibratoExtents
1570
add hl, de
1571
ld [hl], a
1572
ld hl, wChannelVibratoRates
1573
add hl, de
1574
ld [hl], a
1575
ld hl, wChannelFrequencyLowBytes
1576
add hl, de
1577
ld [hl], a
1578
ld hl, wChannelVibratoDelayCounterReloadValues
1579
add hl, de
1580
ld [hl], a
1581
ld hl, wChannelPitchSlideLengthModifiers
1582
add hl, de
1583
ld [hl], a
1584
ld hl, wChannelPitchSlideFrequencySteps
1585
add hl, de
1586
ld [hl], a
1587
ld hl, wChannelPitchSlideFrequencyStepsFractionalPart
1588
add hl, de
1589
ld [hl], a
1590
ld hl, wChannelPitchSlideCurrentFrequencyFractionalPart
1591
add hl, de
1592
ld [hl], a
1593
ld hl, wChannelPitchSlideCurrentFrequencyHighBytes
1594
add hl, de
1595
ld [hl], a
1596
ld hl, wChannelPitchSlideCurrentFrequencyLowBytes
1597
add hl, de
1598
ld [hl], a
1599
ld hl, wChannelPitchSlideTargetFrequencyHighBytes
1600
add hl, de
1601
ld [hl], a
1602
ld hl, wChannelPitchSlideTargetFrequencyLowBytes
1603
add hl, de
1604
ld [hl], a
1605
ld hl, wChannelFlags2
1606
add hl, de
1607
ld [hl], a
1608
ld a, $1
1609
ld hl, wChannelLoopCounters
1610
add hl, de
1611
ld [hl], a
1612
ld hl, wChannelNoteDelayCounters
1613
add hl, de
1614
ld [hl], a
1615
ld hl, wChannelNoteSpeeds
1616
add hl, de
1617
ld [hl], a
1618
ld a, e
1619
cp CHAN5
1620
jr nz, .skipSweepDisable
1621
ld a, AUD1SWEEP_DOWN
1622
ldh [rAUD1SWEEP], a ; sweep off
1623
.skipSweepDisable
1624
ld a, c
1625
and a
1626
jp z, .playSoundCommon
1627
dec c
1628
jp .sfxChannelLoop
1629
1630
.stopAllAudio
1631
ld a, AUDENA_ON
1632
ldh [rAUDENA], a ; sound hardware on
1633
ldh [rAUD3ENA], a ; wave playback on
1634
xor a
1635
ldh [rAUDTERM], a ; no sound output
1636
ldh [rAUD3LEVEL], a ; mute channel 3 (wave channel)
1637
ld a, AUD1SWEEP_DOWN
1638
ldh [rAUD1SWEEP], a ; sweep off
1639
ldh [rAUD1ENV], a ; mute channel 1 (pulse channel 1)
1640
ldh [rAUD2ENV], a ; mute channel 2 (pulse channel 2)
1641
ldh [rAUD4ENV], a ; mute channel 4 (noise channel)
1642
ld a, AUD1HIGH_LENGTH_ON
1643
ldh [rAUD1HIGH], a ; counter mode
1644
ldh [rAUD2HIGH], a
1645
ldh [rAUD4GO], a
1646
ld a, $77
1647
ldh [rAUDVOL], a ; full volume
1648
xor a
1649
ld [wUnusedMusicByte], a
1650
ld [wDisableChannelOutputWhenSfxEnds], a
1651
ld [wMuteAudioAndPauseMusic], a
1652
ld [wMusicTempo + 1], a
1653
ld [wSfxTempo + 1], a
1654
ld [wMusicWaveInstrument], a
1655
ld [wSfxWaveInstrument], a
1656
ld d, $a0
1657
ld hl, wChannelCommandPointers
1658
call .FillMem
1659
ld a, $1
1660
ld d, $18
1661
ld hl, wChannelNoteDelayCounters
1662
call .FillMem
1663
ld [wMusicTempo], a
1664
ld [wSfxTempo], a
1665
ld a, $ff
1666
ld [wStereoPanning], a
1667
ret
1668
1669
; fills d bytes at hl with a
1670
.FillMem
1671
ld b, d
1672
.loop
1673
ld [hli], a
1674
dec b
1675
jr nz, .loop
1676
ret
1677
1678
.playSoundCommon
1679
ld a, [wSoundID]
1680
ld l, a
1681
ld e, a
1682
ld h, 0
1683
ld d, h
1684
add hl, hl
1685
add hl, de
1686
ld de, SFX_Headers_2
1687
add hl, de
1688
ld e, l
1689
ld d, h
1690
ld hl, wChannelCommandPointers
1691
ld a, [de] ; get channel number
1692
ld b, a
1693
rlca
1694
rlca
1695
and $3
1696
ld c, a
1697
ld a, b
1698
and $f
1699
ld b, c
1700
inc b
1701
inc de
1702
ld c, 0
1703
.commandPointerLoop
1704
cp c
1705
jr z, .next
1706
inc c
1707
inc hl
1708
inc hl
1709
jr .commandPointerLoop
1710
.next
1711
push hl
1712
push bc
1713
push af
1714
ld b, 0
1715
ld c, a
1716
ld hl, wChannelSoundIDs
1717
add hl, bc
1718
ld a, [wSoundID]
1719
ld [hl], a
1720
pop af
1721
cp CHAN4
1722
jr c, .skipSettingFlag
1723
ld hl, wChannelFlags1
1724
add hl, bc
1725
set BIT_NOISE_OR_SFX, [hl]
1726
.skipSettingFlag
1727
pop bc
1728
pop hl
1729
ld a, [de] ; get channel pointer
1730
ld [hli], a
1731
inc de
1732
ld a, [de]
1733
ld [hli], a
1734
inc de
1735
inc c
1736
dec b
1737
ld a, b
1738
and a
1739
ld a, [de]
1740
inc de
1741
jr nz, .commandPointerLoop
1742
ld a, [wSoundID]
1743
cp CRY_SFX_START
1744
jr nc, .maybeCry
1745
jr .done
1746
.maybeCry
1747
ld a, [wSoundID]
1748
cp CRY_SFX_END
1749
jr z, .done
1750
jr c, .cry
1751
jr .done
1752
.cry
1753
ld hl, wChannelSoundIDs + CHAN5
1754
ld [hli], a
1755
ld [hli], a
1756
ld [hli], a
1757
ld [hl], a
1758
ld hl, wChannelCommandPointers + CHAN7 * 2 ; sfx wave channel pointer
1759
ld de, Audio2_CryRet
1760
ld [hl], e
1761
inc hl
1762
ld [hl], d ; overwrite pointer to point to sound_ret
1763
ld a, [wSavedVolume]
1764
and a
1765
jr nz, .done
1766
ldh a, [rAUDVOL]
1767
ld [wSavedVolume], a
1768
ld a, $77
1769
ldh [rAUDVOL], a ; full volume
1770
.done
1771
ret
1772
1773
Audio2_CryRet:
1774
sound_ret
1775
1776
Audio2_HWChannelBaseAddresses:
1777
; the low bytes of each HW channel's base address
1778
db HW_CH1_BASE, HW_CH2_BASE, HW_CH3_BASE, HW_CH4_BASE ; channels 0-3
1779
db HW_CH1_BASE, HW_CH2_BASE, HW_CH3_BASE, HW_CH4_BASE ; channels 4-7
1780
1781
Audio2_HWChannelDisableMasks:
1782
db HW_CH1_DISABLE_MASK, HW_CH2_DISABLE_MASK, HW_CH3_DISABLE_MASK, HW_CH4_DISABLE_MASK ; channels 0-3
1783
db HW_CH1_DISABLE_MASK, HW_CH2_DISABLE_MASK, HW_CH3_DISABLE_MASK, HW_CH4_DISABLE_MASK ; channels 4-7
1784
1785
Audio2_HWChannelEnableMasks:
1786
db HW_CH1_ENABLE_MASK, HW_CH2_ENABLE_MASK, HW_CH3_ENABLE_MASK, HW_CH4_ENABLE_MASK ; channels 0-3
1787
db HW_CH1_ENABLE_MASK, HW_CH2_ENABLE_MASK, HW_CH3_ENABLE_MASK, HW_CH4_ENABLE_MASK ; channels 4-7
1788
1789
Audio2_Pitches:
1790
INCLUDE "audio/notes.asm"
1791
1792