TempoQuill

engine(rayshade).asm

Mar 17th, 2021 (edited)
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.63 KB | None | 0 0
  1. ; +-----------------------------------------------------------+
  2. ; | |
  3. ; | POKEMON RAY/SHADE/CHAOS: THE MAIN AUDIO ROUTINE |
  4. ; | |
  5. ; +-----------------------------------------------------------+
  6. ; Interfaces are in home ROM.
  7. ; Notable functions:
  8. ; FadeMusic
  9. ; PlayStereoSFX
  10. ; Notable diffs from Gold:
  11. ; unused content funcationality is restored
  12. ; FREQUENCY OVERRIDES work on all pitched channels
  13. ; notoriously missing commands from Red/Yoshi are now present
  14. _InitSound::
  15. ; restart sound operation
  16. ; clear all relevant hardware registers & wram
  17.  
  18. push hl
  19. push de
  20. push bc
  21. push af
  22. call MusicOff
  23. ld hl, rNR50 ; channel control registers
  24. xor a
  25. ld [hli], a ; rNR50 ; volume/vin
  26.  
  27. ld [hli], a ; rNR51 ; sfx channels
  28. ld a, $80 ; all channels on
  29. ld [hli], a ; rNR52 ; music channels
  30.  
  31. ld hl, rNR10 ; sound channel registers
  32. ld e, NUM_MUSIC_CHANS
  33.  
  34. .clearsound
  35. ; sound channel 1 2 3 4
  36. xor a
  37. ld [hli], a ; rNR10, rNR20, rNR30, rNR40 ; sweep = 0
  38.  
  39. ld [hli], a ; rNR11, rNR21, rNR31, rNR41 ; length/wavepattern = 0
  40. ld a, $8
  41. ld [hli], a ; rNR12, rNR22, rNR32, rNR42 ; envelope = 0
  42. xor a
  43. ld [hli], a ; rNR13, rNR23, rNR33, rNR43 ; frequency lo = 0
  44. ld a, $80
  45. ld [hli], a ; rNR14, rNR24, rNR34, rNR44 ; restart sound (freq hi = 0)
  46. dec e
  47. jr nz, .clearsound
  48.  
  49. ld hl, wChannels ; start of channel data
  50. ld de, wChannelsEnd - wChannels ; length of area to clear (entire sound wram area)
  51.  
  52. .clearchannels
  53.  
  54. xor a
  55. ld [hli], a
  56. dec de
  57. ld a, e
  58. or d
  59. jr nz, .clearchannels
  60. ld a, MAX_VOLUME
  61. ld [wVolume], a
  62. call MusicOn
  63. pop af
  64. pop bc
  65. pop de
  66. pop hl
  67. ret
  68.  
  69. MusicFadeRestart:
  70. ; restart but keep the music id to fade in to
  71.  
  72. ld a, [wMusicFadeID + 1]
  73. push af
  74.  
  75. ld a, [wMusicFadeID]
  76. push af
  77.  
  78. call _InitSound
  79.  
  80. pop af
  81. ld [wMusicFadeID], a
  82.  
  83. pop af
  84. ld [wMusicFadeID + 1], a
  85.  
  86. ret
  87.  
  88. MusicOn:
  89. ld a, 1 << MUSIC_ON_F
  90. ld [wMusicPlaying], a
  91. ret
  92.  
  93. MusicOff:
  94. xor a
  95. ld [wMusicPlaying], a
  96. ret
  97.  
  98. _UpdateSound::
  99. ; called once per frame
  100.  
  101. ; no use updating audio if it's not playing
  102. ld a, [wMusicPlaying]
  103. and a
  104. ret z
  105. ; start at ch1
  106. xor a
  107. ld [wCurChannel], a ; just
  108. ld [wSoundOutput], a ; off
  109. ld bc, wChannel1
  110.  
  111. .loop
  112.  
  113. ; is the channel active?
  114. bc_offset CHANNEL_FLAGS1
  115. bit SOUND_CHANNEL_ON, [hl]
  116. jp z, .nextchannel
  117.  
  118. ; check time left in the current note
  119. bc_offset CHANNEL_NOTE_DURATION
  120. ld a, [hl]
  121. cp $2 ; 1 or 0?
  122. jr c, .noteover
  123.  
  124. dec [hl]
  125. jr .continue_sound_update
  126.  
  127. .noteover
  128.  
  129. ; reset vibrato delay
  130. bc_offset CHANNEL_VIBRATO_DELAY
  131. ld a, [hl]
  132. bc_offset CHANNEL_VIBRATO_DELAY_COUNT
  133. ld [hl], a
  134.  
  135. ; turn vibrato off for now
  136. bc_offset CHANNEL_FLAGS2
  137. res SOUND_VIBRATO, [hl]
  138.  
  139. ; get next note
  140. call ParseMusic
  141.  
  142. .continue_sound_update
  143.  
  144. call ApplyPitchSlide
  145.  
  146. ; duty cycle
  147. bc_offset CHANNEL_DUTY_CYCLE
  148. ld a, [hli]
  149. ld [wCurTrackDuty], a
  150.  
  151. ; volume envelope
  152. ld a, [hli]
  153. ld [wCurTrackVolumeEnvelope], a
  154.  
  155. ; frequency
  156. ld a, [hli]
  157. ld [wCurTrackFrequency], a
  158. ld a, [hl]
  159. ld [wCurTrackFrequency + 1], a
  160.  
  161. ; vibrato, envelope, pitch, chorus, etc
  162. call GeneralHandler
  163. ; noise
  164. call HandleNoise
  165.  
  166. ; turn off music when playing sfx?
  167. ld a, [wSFXPriority]
  168. and a
  169. jr z, .next
  170.  
  171. ; are we in a sfx channel right now?
  172. ld a, [wCurChannel]
  173. cp NUM_MUSIC_CHANS
  174. jr nc, .next
  175.  
  176. ; are any sfx channels active?
  177. ; if so, mute
  178. ld hl, wChannel5Flags1
  179. bit SOUND_CHANNEL_ON, [hl]
  180. jr nz, .restnote
  181.  
  182. ld hl, wChannel6Flags1
  183. bit SOUND_CHANNEL_ON, [hl]
  184. jr nz, .restnote
  185.  
  186. ld hl, wChannel7Flags1
  187. bit SOUND_CHANNEL_ON, [hl]
  188. jr nz, .restnote
  189.  
  190. ld hl, wChannel8Flags1
  191. bit SOUND_CHANNEL_ON, [hl]
  192. jr z, .next
  193.  
  194. .restnote
  195.  
  196. bc_offset CHANNEL_NOTE_FLAGS
  197. set NOTE_REST, [hl] ; Rest
  198.  
  199. .next
  200.  
  201. ; are we in a sfx channel right now?
  202. ld a, [wCurChannel]
  203. cp NUM_MUSIC_CHANS
  204. jr nc, .sfx_channel
  205.  
  206. bc_offset CHANNEL_STRUCT_LENGTH * NUM_MUSIC_CHANS + CHANNEL_FLAGS1
  207. bit SOUND_CHANNEL_ON, [hl]
  208. jr nz, .sound_channel_on
  209.  
  210. .sfx_channel
  211.  
  212. call UpdateChannels
  213. bc_offset CHANNEL_TRACKS
  214. ld a, [wSoundOutput]
  215. or [hl]
  216. ld [wSoundOutput], a
  217.  
  218. .sound_channel_on
  219.  
  220. ; clear note flags
  221. bc_offset CHANNEL_NOTE_FLAGS
  222. xor a
  223. ld [hl], a
  224.  
  225. .nextchannel
  226.  
  227. ; next channel
  228. bc_offset CHANNEL_STRUCT_LENGTH
  229. ld c, l
  230. ld b, h
  231. ld a, [wCurChannel]
  232. inc a
  233. ld [wCurChannel], a
  234. cp NUM_CHANNELS ; are we done?
  235. jp nz, .loop ; do it all again
  236.  
  237. call PlayDanger
  238.  
  239. ; fade music in/out
  240. call FadeMusic
  241.  
  242. ; write volume to hardware register
  243. ld a, [wVolume]
  244. ldh [rNR50], a
  245.  
  246. ; write SO on/off to hardware register
  247. ld a, [wSoundOutput]
  248. ldh [rNR51], a
  249. ret
  250.  
  251. UpdateChannels:
  252.  
  253. ld hl, .ChannelFnPtrs
  254. ld a, [wCurChannel]
  255. and $7
  256. add a
  257. ld e, a
  258. ld d, 0
  259. add hl, de
  260. ld a, [hli]
  261. ld h, [hl]
  262. ld l, a
  263. jp hl
  264.  
  265. .ChannelFnPtrs:
  266. dw .Channel1
  267. dw .Channel26
  268. dw .Channel37
  269. dw .Channel48
  270. ; sfx ch ptrs are identical to music chs
  271. ; ..except 5
  272. ; SfxFnPtrs:
  273. dw .Channel5
  274. dw .Channel26
  275. dw .Channel37
  276. dw .Channel48
  277.  
  278. .Channel1:
  279.  
  280. ld a, [wLowHealthAlarm]
  281. bit DANGER_ON_F, a
  282. ret nz
  283.  
  284. .Channel5:
  285.  
  286. bc_offset CHANNEL_NOTE_FLAGS
  287. bit NOTE_PITCH_SWEEP, [hl]
  288. jr z, .noPitchSweep
  289.  
  290. ld a, [wPitchSweep]
  291. ldh [rNR10], a
  292.  
  293. .noPitchSweep
  294.  
  295. bit NOTE_REST, [hl] ; rest
  296. jr nz, .ch1_rest
  297.  
  298. bit NOTE_NOISE_SAMPLING, [hl]
  299. jr nz, .ch1_noise_sampling
  300.  
  301. bit NOTE_FREQ_OVERRIDE, [hl]
  302. jr nz, .ch1_frequency_override
  303.  
  304. bit NOTE_ENV_OVERRIDE, [hl]
  305. jr nz, .ch1_env_override
  306.  
  307. bit NOTE_VIBRATO_OVERRIDE, [hl]
  308. jr nz, .ch1_vibrato_override
  309.  
  310. jr .ch1_check_duty_override
  311.  
  312. .ch1_frequency_override
  313.  
  314. ld a, [wCurTrackFrequency]
  315. ldh [rNR13], a
  316. ld a, [wCurTrackFrequency + 1]
  317. ldh [rNR14], a
  318.  
  319. .ch1_check_duty_override
  320.  
  321. bit NOTE_DUTY_OVERRIDE, [hl]
  322. ret z
  323.  
  324. ld a, [wCurTrackDuty]
  325. ld d, a
  326. ldh a, [rNR11]
  327. and $3f ; sound length
  328. or d
  329. ldh [rNR11], a
  330. ret
  331.  
  332. .ch1_env_override
  333.  
  334. ld a, [wCurTrackVolumeEnvelope]
  335. ldh [rNR12], a
  336. ld a, [wCurTrackFrequency + 1]
  337. or 1 << FREQUENCY_RST
  338. ldh [rNR14], a
  339. ret
  340.  
  341. .ch1_vibrato_override
  342.  
  343. ld a, [wCurTrackDuty]
  344. ld d, a
  345. ldh a, [rNR11]
  346. and $3f ; sound length
  347. or d
  348. ldh [rNR11], a
  349. ld a, [wCurTrackFrequency]
  350. ldh [rNR13], a
  351. ret
  352.  
  353. .ch1_rest
  354.  
  355. ldh a, [rNR52]
  356. and %10001110 ; ch1 off
  357. ldh [rNR52], a
  358. ld hl, rNR10
  359. call ClearChannel
  360. ret
  361.  
  362. .ch1_noise_sampling
  363.  
  364. ld hl, wCurTrackDuty
  365. ld a, $3f ; sound length
  366. or [hl]
  367. ldh [rNR11], a
  368. ld a, [wCurTrackVolumeEnvelope]
  369. ldh [rNR12], a
  370. ld a, [wCurTrackFrequency]
  371. ldh [rNR13], a
  372. ld a, [wCurTrackFrequency + 1]
  373. or $80
  374. ldh [rNR14], a
  375. ret
  376.  
  377.  
  378. .Channel26:
  379.  
  380. bc_offset CHANNEL_NOTE_FLAGS
  381.  
  382. bit NOTE_REST, [hl] ; rest
  383. jr nz, .ch2_rest
  384.  
  385. bit NOTE_NOISE_SAMPLING, [hl]
  386. jr nz, .ch2_noise_sampling
  387.  
  388. bit NOTE_FREQ_OVERRIDE, [hl]
  389. jr nz, .ch2_frequency_override
  390.  
  391. bit NOTE_ENV_OVERRIDE, [hl]
  392. jr nz, .ch2_env_override
  393.  
  394. bit NOTE_VIBRATO_OVERRIDE, [hl]
  395. jr nz, .ch2_vibrato_override
  396.  
  397. bit NOTE_DUTY_OVERRIDE, [hl]
  398. ret z
  399.  
  400. ld a, [wCurTrackDuty]
  401. ld d, a
  402. ldh a, [rNR21]
  403. and $3f ; sound length
  404. or d
  405. ldh [rNR21], a
  406. ret
  407.  
  408. .ch2_frequency_override
  409.  
  410. ld a, [wCurTrackFrequency]
  411. ldh [rNR23], a
  412. ld a, [wCurTrackFrequency + 1]
  413. ldh [rNR24], a
  414. ret
  415.  
  416. .ch2_env_override
  417.  
  418. ld a, [wCurTrackVolumeEnvelope]
  419. ldh [rNR22], a
  420. ld a, [wCurTrackFrequency + 1]
  421. or 1 << FREQUENCY_RST
  422. ldh [rNR24], a
  423. ret
  424.  
  425. .ch2_vibrato_override
  426.  
  427. ld a, [wCurTrackDuty]
  428. ld d, a
  429. ldh a, [rNR21]
  430. and $3f ; sound length
  431. or d
  432. ldh [rNR21], a
  433. ld a, [wCurTrackFrequency]
  434. ldh [rNR23], a
  435. ret
  436.  
  437. .ch2_rest
  438.  
  439. ldh a, [rNR52]
  440. and %10001101 ; ch2 off
  441. ldh [rNR52], a
  442. ld hl, rNR20
  443. call ClearChannel
  444. ret
  445.  
  446. .ch2_noise_sampling
  447.  
  448. ld hl, wCurTrackDuty
  449. ld a, $3f ; sound length
  450. or [hl]
  451. ldh [rNR21], a
  452. ld a, [wCurTrackVolumeEnvelope]
  453. ldh [rNR22], a
  454. ld a, [wCurTrackFrequency]
  455. ldh [rNR23], a
  456. ld a, [wCurTrackFrequency + 1]
  457. or $80 ; initial (restart)
  458. ldh [rNR24], a
  459. ret
  460.  
  461.  
  462. .Channel37:
  463.  
  464. bc_offset CHANNEL_NOTE_FLAGS
  465.  
  466. bit NOTE_REST, [hl]
  467. jr nz, .ch3_rest
  468.  
  469. bit NOTE_NOISE_SAMPLING, [hl]
  470. jr nz, .ch3_noise_sampling
  471.  
  472. bit NOTE_ENV_OVERRIDE, [hl]
  473. jr nz, .ch3_env_override
  474.  
  475. bit NOTE_VIBRATO_OVERRIDE, [hl]
  476. jr nz, .ch3_vibrato_override
  477.  
  478. bit NOTE_FREQ_OVERRIDE, [hl]
  479. ret z
  480.  
  481. ld a, [wCurTrackFrequency]
  482. ldh [rNR33], a
  483. ld a, [wCurTrackFrequency + 1]
  484. ldh [rNR34], a
  485. ret
  486.  
  487. .ch3_vibrato_override
  488.  
  489. ld a, [wCurTrackFrequency]
  490. ldh [rNR33], a
  491. ret
  492.  
  493. .ch3_rest
  494.  
  495. ldh a, [rNR52]
  496. and %10001011 ; ch3 off
  497. ldh [rNR52], a
  498. ld hl, rNR30
  499. call ClearChannel
  500. ret
  501.  
  502. .ch3_noise_sampling
  503.  
  504. ld a, $3f ; sound length
  505. ldh [rNR31], a
  506.  
  507. .ch3_env_override
  508.  
  509. xor a
  510. ldh [rNR30], a
  511.  
  512. call .load_wave_pattern
  513.  
  514. ld a, $80
  515. ldh [rNR30], a
  516. ld a, [wCurTrackFrequency]
  517. ldh [rNR33], a
  518. ld a, [wCurTrackFrequency + 1]
  519. or $80
  520. ldh [rNR34], a
  521. ret
  522.  
  523. .load_wave_pattern:
  524.  
  525. push hl
  526. ld a, [wCurTrackVolumeEnvelope]
  527.  
  528. ; 0-f are technically valid
  529. ; f is filler made of 0's to avoid garbage
  530. and WAVE_TABLE_MASK
  531. swap a
  532. ld e, a
  533. ld d, 0
  534.  
  535. ; hl << 4
  536. ; each wavetable is fixed at 16 bytes
  537. ; so seeking is done in $10s
  538. ld de, WaveSamples
  539. add hl, de
  540.  
  541. ld a, [hli]
  542. ldh [rWave_0], a
  543. ld a, [hli]
  544. ldh [rWave_1], a
  545. ld a, [hli]
  546. ldh [rWave_2], a
  547. ld a, [hli]
  548. ldh [rWave_3], a
  549. ld a, [hli]
  550. ldh [rWave_4], a
  551. ld a, [hli]
  552. ldh [rWave_5], a
  553. ld a, [hli]
  554. ldh [rWave_6], a
  555. ld a, [hli]
  556. ldh [rWave_7], a
  557. ld a, [hli]
  558. ldh [rWave_8], a
  559. ld a, [hli]
  560. ldh [rWave_9], a
  561. ld a, [hli]
  562. ldh [rWave_a], a
  563. ld a, [hli]
  564. ldh [rWave_b], a
  565. ld a, [hli]
  566. ldh [rWave_c], a
  567. ld a, [hli]
  568. ldh [rWave_d], a
  569. ld a, [hli]
  570. ldh [rWave_e], a
  571. ld a, [hli]
  572. ldh [rWave_f], a
  573.  
  574. pop hl
  575. ld a, [wCurTrackVolumeEnvelope]
  576. and WAVE_VOLUME_MASK
  577. sla a
  578. ldh [rNR32], a
  579. ret
  580.  
  581. .Channel48:
  582.  
  583. bc_offset CHANNEL_NOTE_FLAGS
  584.  
  585. bit NOTE_NOISE_SAMPLING, [hl]
  586. jr nz, .ch4_noise_sampling
  587.  
  588. bit NOTE_REST, [hl]
  589. ret z
  590.  
  591. ldh a, [rNR52]
  592. and %10000111 ; ch4 off
  593. ldh [rNR52], a
  594. ld hl, rNR40
  595. call ClearChannel
  596. ret
  597.  
  598. .ch4_noise_sampling
  599.  
  600. ld a, $3f ; sound length
  601. ldh [rNR41], a
  602. ld a, [wCurTrackVolumeEnvelope]
  603. ldh [rNR42], a
  604. ld a, [wCurTrackFrequency]
  605. ldh [rNR43], a
  606. ld a, $80
  607. ldh [rNR44], a
  608. ret
  609.  
  610. _CheckSFX:
  611. ; return carry if any sfx channels are active
  612.  
  613. ld hl, wChannel5Flags1
  614. bit SOUND_CHANNEL_ON, [hl]
  615. jr nz, .sfxon
  616.  
  617. ld hl, wChannel6Flags1
  618. bit SOUND_CHANNEL_ON, [hl]
  619. jr nz, .sfxon
  620.  
  621. ld hl, wChannel7Flags1
  622. bit SOUND_CHANNEL_ON, [hl]
  623. jr nz, .sfxon
  624.  
  625. ld hl, wChannel8Flags1
  626. bit SOUND_CHANNEL_ON, [hl]
  627. jr nz, .sfxon
  628.  
  629. and a
  630. ret
  631.  
  632. .sfxon
  633. scf
  634. ret
  635.  
  636.  
  637. PlayDanger:
  638.  
  639. ld a, [wLowHealthAlarm]
  640. bit DANGER_ON_F, a
  641. ret z
  642.  
  643. ; Don't do anything if SFX is being played
  644. and $ff ^ (1 << DANGER_ON_F)
  645. ld d, a
  646. call _CheckSFX
  647. jr c, .increment
  648.  
  649. ; Play the high tone
  650. and a
  651. jr z, .begin
  652.  
  653. ; Play the low tone
  654. cp 16
  655. jr z, .halfway
  656.  
  657. jr .increment
  658.  
  659. .halfway
  660.  
  661. ld hl, DangerSoundLow
  662. jr .applychannel
  663.  
  664. .begin
  665.  
  666. ld hl, DangerSoundHigh
  667.  
  668. .applychannel
  669.  
  670. xor a
  671. ldh [rNR10], a
  672. ld a, [hli]
  673. ldh [rNR11], a
  674. ld a, [hli]
  675. ldh [rNR12], a
  676. ld a, [hli]
  677. ldh [rNR13], a
  678. ld a, [hli]
  679. ldh [rNR14], a
  680.  
  681. .increment
  682.  
  683. ld a, d
  684. inc a
  685. cp 30 ; Ending frame
  686. jr c, .noreset
  687.  
  688. xor a
  689.  
  690. .noreset
  691.  
  692. ; Make sure the danger sound is kept on
  693. or 1 << DANGER_ON_F
  694. ld [wLowHealthAlarm], a
  695.  
  696. ; Enable channel 1 if it's off
  697. ld a, [wSoundOutput]
  698. and $11
  699. ret nz
  700. ld a, [wSoundOutput]
  701. or $11
  702. ld [wSoundOutput], a
  703. ret
  704.  
  705. DangerSoundHigh:
  706. db %11000000 ; duty
  707. dn 8, 4 ; volume setting
  708. dw $8731 ; pitch/restart
  709.  
  710. DangerSoundLow:
  711. db %11000000 ; duty
  712. dn 7, 4 ; volume setting
  713. dw $86ee ; pitch/restart
  714.  
  715. FadeMusic:
  716. ; fade music if applicable
  717. ; usage:
  718. ; write to wMusicFade
  719. ; song fades out at the given rate
  720. ; load song id in wMusicFadeID
  721. ; fade new song in
  722. ; notes:
  723. ; max # frames per volume level is $3f
  724.  
  725. ; fading?
  726. ld a, [wMusicFade]
  727. and a
  728. ret z
  729.  
  730. ; has the count ended?
  731. ld a, [wMusicFadeCount]
  732. and a
  733. jr z, .update
  734.  
  735. ; count down
  736. dec a
  737. ld [wMusicFadeCount], a
  738. ret
  739.  
  740. .update
  741.  
  742. ld a, [wMusicFade]
  743. ld d, a
  744.  
  745. ; get new count
  746. and $3f
  747. ld [wMusicFadeCount], a
  748.  
  749. ; get SO1 volume
  750. ld a, [wVolume]
  751. and VOLUME_SO1_LEVEL
  752.  
  753. ; which way are we fading?
  754. bit MUSIC_FADE_IN_F, d
  755. jr nz, .fadein
  756.  
  757. ; fading out
  758. and a
  759. jr z, .novolume
  760.  
  761. dec a
  762. jr .updatevolume
  763.  
  764. .novolume
  765.  
  766. ; make sure volume is off
  767. xor a
  768. ld [wVolume], a
  769.  
  770. ; did we just get on a bike?
  771. ld a, [wPlayerState]
  772. cp PLAYER_BIKE
  773. jr z, .bicycle
  774.  
  775. push bc
  776.  
  777. ; restart sound
  778. call MusicFadeRestart
  779.  
  780. ; get new song id
  781. ld a, [wMusicFadeID]
  782. and a
  783. jr z, .quit ; this assumes there are fewer than 256 songs!
  784.  
  785. ld e, a
  786. ld a, [wMusicFadeID + 1]
  787. ld d, a
  788.  
  789. ; load new song
  790. call _PlayMusic
  791.  
  792. .quit
  793.  
  794. ; cleanup
  795. pop bc
  796.  
  797. ; stop fading
  798. xor a
  799. ld [wMusicFade], a
  800. ret
  801.  
  802. .bicycle
  803.  
  804. push bc
  805.  
  806. ; restart sound
  807. call MusicFadeRestart
  808.  
  809. ; this turns the volume up
  810. ; turn it back down
  811. xor a
  812. ld [wVolume], a
  813.  
  814. ; get new song id
  815. ld a, [wMusicFadeID]
  816. ld e, a
  817. ld a, [wMusicFadeID + 1]
  818. ld d, a
  819.  
  820. ; load new song
  821. call _PlayMusic
  822. pop bc
  823.  
  824. ; fade in
  825. ld hl, wMusicFade
  826. set MUSIC_FADE_IN_F, [hl]
  827. ret
  828.  
  829. .fadein
  830.  
  831. ; are we done?
  832. cp MAX_VOLUME & $f
  833. jr nc, .maxvolume
  834.  
  835. ; inc volume
  836. inc a
  837. jr .updatevolume
  838.  
  839. .maxvolume
  840.  
  841. ; we're done
  842. xor a
  843. ld [wMusicFade], a
  844. ret
  845.  
  846. .updatevolume
  847.  
  848. ; hi = lo
  849. ld d, a
  850. swap a
  851. or d
  852. ld [wVolume], a
  853. ret
  854.  
  855.  
  856. LoadNote:
  857. ; wait for pitch slide to finish
  858. bc_offset CHANNEL_FLAGS2
  859. bit SOUND_PITCH_SLIDE, [hl]
  860. jp z, .relative_pitch
  861.  
  862. ; get note duration
  863. bc_offset CHANNEL_NOTE_DURATION
  864. ld a, [hl]
  865. ld hl, wCurNoteDuration
  866. sub [hl]
  867. jr nc, .ok
  868.  
  869. ld a, 1
  870.  
  871. .ok
  872. ld [hl], a
  873.  
  874. ; get frequency
  875. bc_offset CHANNEL_FREQUENCY
  876. ld e, [hl]
  877. inc hl
  878. ld d, [hl]
  879.  
  880. ; get direction of pitch slide
  881. bc_offset CHANNEL_PITCH_SLIDE_TARGET
  882. ld a, e
  883. sub [hl]
  884. ld e, a
  885. ld a, d
  886. sbc 0
  887. ld d, a
  888.  
  889. bc_offset CHANNEL_PITCH_SLIDE_TARGET + 1
  890. sub [hl]
  891. jr nc, .greater_than
  892.  
  893. bc_offset CHANNEL_FLAGS3
  894. set SOUND_PITCH_SLIDE_DIR, [hl]
  895.  
  896. ; get frequency
  897. bc_offset CHANNEL_FREQUENCY
  898. ld e, [hl]
  899. inc hl
  900. ld d, [hl]
  901.  
  902. ; write target
  903. bc_offset CHANNEL_PITCH_SLIDE_TARGET
  904. ld a, [hl]
  905. sub e
  906. ld e, a
  907. ld a, d
  908. sbc 0
  909. ld d, a
  910.  
  911. bc_offset CHANNEL_PITCH_SLIDE_TARGET + 1
  912. ld a, [hl]
  913. sub d
  914. ld d, a
  915. jr .resume
  916.  
  917. .greater_than
  918.  
  919. bc_offset CHANNEL_FLAGS3
  920. res SOUND_PITCH_SLIDE_DIR, [hl]
  921.  
  922. ; get frequency
  923. bc_offset CHANNEL_FREQUENCY
  924. ld e, [hl]
  925. inc hl
  926. ld d, [hl]
  927.  
  928. ; get distance from pitch slide target
  929. bc_offset CHANNEL_PITCH_SLIDE_TARGET
  930. ld a, e
  931. sub [hl]
  932. ld e, a
  933. ld a, d
  934. sbc 0
  935. ld d, a
  936.  
  937. bc_offset CHANNEL_PITCH_SLIDE_TARGET + 1
  938. sub [hl]
  939. ld d, a
  940.  
  941. .resume
  942.  
  943. ; de = x * [wCurNoteDuration] + y
  944. ; x + 1 -> d
  945. ; y -> a
  946. push bc
  947. ld hl, wCurNoteDuration
  948. ld b, 0 ; quotient
  949.  
  950. .loop
  951.  
  952. inc b
  953. ld a, e
  954. sub [hl]
  955. ld e, a
  956. jr nc, .loop
  957.  
  958. ld a, d
  959. and a
  960. jr z, .quit
  961.  
  962. dec d
  963. jr .loop
  964.  
  965. .quit
  966.  
  967. ld a, e ; remainder
  968. add [hl]
  969. ld d, b ; quotient
  970. pop bc
  971.  
  972. bc_offset CHANNEL_PITCH_SLIDE_AMOUNT
  973. ld [hl], d ; quotient
  974.  
  975. bc_offset CHANNEL_PITCH_SLIDE_FRACTION
  976. ld [hl], a ; remainder
  977.  
  978. bc_offset CHANNEL_PITCH_SLIDE_TEMPO
  979. xor a
  980. ld [hl], a
  981.  
  982. .relative_pitch
  983.  
  984. bc_offset CHANNEL_FLAGS2
  985. bit SOUND_RELATIVE_PITCH, [hl]
  986. jr z, .env_ptrn
  987.  
  988. bc_offset CHANNEL_FLAGS3
  989. res SOUND_REL_PITCH_FLAG, [hl]
  990.  
  991. .env_ptrn
  992.  
  993. bc_offset CHANNEL_FLAGS2
  994. bit SOUND_ENV_PTRN, [hl]
  995. jr z, .mute
  996.  
  997. bc_offset CHANNEL_NOTE_FLAGS
  998. res NOTE_ENV_OVERRIDE, [hl]
  999.  
  1000. ; reset offset
  1001. bc_offset CHANNEL_ENVELOPE_GROUP_OFFSET
  1002. xor a
  1003. ld [hl], a
  1004.  
  1005. .mute
  1006.  
  1007. bc_offset CHANNEL_FLAGS2
  1008. bit SOUND_MUTE, [hl]
  1009. ret z
  1010.  
  1011. ; read mute state
  1012. bc_offset CHANNEL_MUTE_ENABLE
  1013. ld a, [hl]
  1014.  
  1015. ; copy to main byte
  1016. bc_offset CHANNEL_MUTE
  1017. ld [hl], a
  1018. ret
  1019.  
  1020.  
  1021. GeneralHandler:
  1022. ; handle duty, pitch, env ptrn, mute, and vibrato
  1023.  
  1024. bc_offset CHANNEL_FLAGS2
  1025. bit SOUND_DUTY_LOOP, [hl] ; duty cycle looping
  1026. jr z, .relative_pitch
  1027.  
  1028. bc_offset CHANNEL_DUTY_CYCLE_PATTERN
  1029. ld a, [hl]
  1030. rlca
  1031. rlca
  1032. ld [hl], a
  1033. and $c0
  1034. ld [wCurTrackDuty], a
  1035.  
  1036. bc_offset CHANNEL_NOTE_FLAGS
  1037. set NOTE_DUTY_OVERRIDE, [hl]
  1038.  
  1039. .relative_pitch
  1040.  
  1041. bc_offset CHANNEL_FLAGS2
  1042. bit SOUND_RELATIVE_PITCH, [hl]
  1043. jr z, .pitch_offset
  1044.  
  1045. ; is relative pitch on?
  1046. bc_offset CHANNEL_FLAGS3
  1047. bit SOUND_REL_PITCH_FLAG, [hl]
  1048. jr nz, .on
  1049.  
  1050. set SOUND_REL_PITCH_FLAG, [hl]
  1051. jr .skip_pitch
  1052.  
  1053. .on
  1054.  
  1055. res SOUND_REL_PITCH_FLAG, [hl]
  1056.  
  1057. ; get pitch
  1058. bc_offset CHANNEL_PITCH
  1059. ld a, [hl]
  1060. and a
  1061. jr z, .skip_pitch
  1062.  
  1063. ; add to pitch value
  1064. bc_offset CHANNEL_RELATIVE_PITCH
  1065. add [hl]
  1066. ld e, a
  1067.  
  1068. ; get octave
  1069. bc_offset CHANNEL_OCTAVE
  1070. ld d, [hl]
  1071.  
  1072. ; get final tone
  1073. call GetFrequency
  1074. ld hl, wCurTrackFrequency
  1075. ld [hl], e
  1076. inc hl
  1077. ld [hl], d
  1078.  
  1079. ; interesting notes:
  1080. ; $d9 and $e7 can stack with each other
  1081. ; $d9 $01 and $e7 $01 together would be the same as $d9/e7 $02
  1082. ; $e7 $f4-ff can trigger the rest pitch due to a lack of carry
  1083.  
  1084. .skip_pitch
  1085.  
  1086. bc_offset CHANNEL_NOTE_FLAGS
  1087. set NOTE_FREQ_OVERRIDE, [hl]
  1088.  
  1089. .pitch_offset
  1090.  
  1091. bc_offset CHANNEL_FLAGS2
  1092. bit SOUND_PITCH_OFFSET, [hl]
  1093. jr z, .pitch_inc
  1094.  
  1095. ; add offset to wCurTrackFrequency
  1096. bc_offset CHANNEL_PITCH_OFFSET
  1097. ld e, [hl]
  1098. inc hl
  1099. ld d, [hl]
  1100. ld hl, wCurTrackFrequency
  1101. ld a, [hli]
  1102. ld h, [hl]
  1103. ld l, a
  1104. add hl, de
  1105. ld e, l
  1106. ld d, h
  1107. ld hl, wCurTrackFrequency
  1108. ld [hl], e
  1109. inc hl
  1110. ld [hl], d
  1111.  
  1112. .pitch_inc
  1113.  
  1114. ; is pitch inc on?
  1115. bc_offset CHANNEL_FLAGS1
  1116. bit SOUND_PITCH_INC_SWITCH, [hl]
  1117. jr z, .vibrato
  1118.  
  1119. bc_offset CHANNEL_PITCH_INC_SWITCH
  1120.  
  1121. ; is the byte active?
  1122. ld a, [hl]
  1123. and a
  1124. jr z, .skip
  1125.  
  1126. ; if so, inc the pitch by 1
  1127. inc e
  1128. jr nc, .skip
  1129.  
  1130. ; inc d if e rolls over
  1131. inc d
  1132.  
  1133. ; incidentally, pitch_inc_switch can stack with pitch_offset
  1134. ; for example, $f1 followed by $e6 $0001 would essentially mean $e6 $0002
  1135. .skip
  1136.  
  1137. ld hl, wCurTrackFrequency
  1138. ld [hl], e
  1139. inc hl
  1140. ld [hl], d
  1141.  
  1142. .vibrato
  1143.  
  1144. ; is vibrato on?
  1145. bc_offset CHANNEL_FLAGS2
  1146. bit SOUND_VIBRATO, [hl] ; vibrato
  1147. jr z, .env_ptrn
  1148.  
  1149. ; is vibrato active for this note yet?
  1150. ; is the delay over?
  1151. bc_offset CHANNEL_VIBRATO_DELAY_COUNT
  1152. ld a, [hl]
  1153. and a
  1154. jr nz, .subexit
  1155.  
  1156. ; is the extent nonzero?
  1157. bc_offset CHANNEL_VIBRATO_EXTENT
  1158. ld a, [hl]
  1159. and a
  1160. jr z, .env_ptrn
  1161.  
  1162. ; save it for later
  1163. ld d, a
  1164.  
  1165. ; is it time to toggle vibrato up/down?
  1166. bc_offset CHANNEL_VIBRATO_RATE
  1167. ld a, [hl]
  1168. and $f ; count
  1169. jr z, .toggle
  1170.  
  1171. .subexit
  1172.  
  1173. dec [hl]
  1174. jr .env_ptrn
  1175.  
  1176. .toggle
  1177.  
  1178. ; refresh count
  1179. ld a, [hl]
  1180. swap [hl]
  1181. or [hl]
  1182. ld [hl], a
  1183.  
  1184. ; get pitch
  1185. ld a, [wCurTrackFrequency]
  1186. ld e, a
  1187.  
  1188. ; toggle vibrato up/down
  1189. bc_offset CHANNEL_FLAGS3
  1190. bit SOUND_VIBRATO_DIR, [hl] ; vibrato up/down
  1191. jr z, .down
  1192.  
  1193. ; up
  1194.  
  1195. ; vibrato down
  1196. res SOUND_VIBRATO_DIR, [hl]
  1197.  
  1198. ; get the delay
  1199. ld a, d
  1200. and $f ; lo
  1201. ld d, a
  1202. ld a, e
  1203. sub d
  1204. jr nc, .no_carry
  1205. ld a, 0
  1206. jr .no_carry
  1207.  
  1208. .down
  1209.  
  1210. ; vibrato up
  1211. set SOUND_VIBRATO_DIR, [hl]
  1212.  
  1213. ; get the delay
  1214. ld a, d
  1215. and $f0 ; hi
  1216. swap a ; move it to lo
  1217. add e
  1218. jr nc, .no_carry
  1219.  
  1220. ld a, $ff
  1221.  
  1222. .no_carry
  1223.  
  1224. ld [wCurTrackFrequency], a
  1225.  
  1226. bc_offset CHANNEL_NOTE_FLAGS
  1227. set NOTE_VIBRATO_OVERRIDE, [hl]
  1228.  
  1229. .env_ptrn
  1230.  
  1231. bc_offset CHANNEL_FLAGS2
  1232. bit SOUND_ENV_PTRN, [hl]
  1233. jr z, .mute
  1234.  
  1235. bc_offset CHANNEL_NOTE_FLAGS
  1236. set NOTE_ENV_OVERRIDE, [hl]
  1237.  
  1238. ; store group in de
  1239. bc_offset CHANNEL_ENVELOPE_GROUP
  1240. ld e, [hl]
  1241. ld d, 0
  1242. ld a, [wCurChannel]
  1243. maskbits NUM_MUSIC_CHANS
  1244. cp CHAN3
  1245. jr nz, .not_ch3
  1246.  
  1247. ; wavetable group
  1248. ld hl, WaveTableGroups
  1249. call GetByteInEnvelopeGroup
  1250. jr c, .pause
  1251.  
  1252. ld d, a
  1253. and WAVE_TABLE_MASK
  1254. ld a, [wCurTrackVolumeEnvelope]
  1255. and WAVE_VOLUME_MASK
  1256. or d
  1257. ld [wCurTrackVolumeEnvelope], a
  1258. call UpdateChannels.load_wave_pattern
  1259. jr .mute
  1260.  
  1261. .not_ch3
  1262.  
  1263. ; envelope group
  1264. ld hl, EnvelopeGroups
  1265. call GetByteInEnvelopeGroup
  1266. jr nc, .set
  1267.  
  1268. .pause
  1269.  
  1270. ; pause during rest
  1271. bc_offset CHANNEL_NOTE_FLAGS
  1272. set NOTE_REST, [hl]
  1273. jr .mute
  1274.  
  1275. .set
  1276.  
  1277. ; store envelope during note
  1278. ld [wCurTrackVolumeEnvelope], a
  1279. bc_offset CHANNEL_NOTE_FLAGS
  1280. set NOTE_NOISE_SAMPLING, [hl]
  1281.  
  1282. .mute
  1283.  
  1284. bc_offset CHANNEL_FLAGS2
  1285. bit SOUND_MUTE, [hl]
  1286. ret z
  1287.  
  1288. ; check for active state
  1289. bc_offset CHANNEL_MUTE_ENABLE
  1290. ld a, [hl]
  1291. and a
  1292. jr z, .enable
  1293.  
  1294. ; disable
  1295. dec [hl]
  1296. ret
  1297.  
  1298. .enable
  1299.  
  1300. bc_offset CHANNEL_NOTE_FLAGS
  1301. set NOTE_REST, [hl]
  1302. ret
  1303.  
  1304.  
  1305. ApplyPitchSlide:
  1306.  
  1307. ; quit if pitch slide inactive
  1308. bc_offset CHANNEL_FLAGS2
  1309. bit SOUND_PITCH_SLIDE, [hl]
  1310. ret z
  1311.  
  1312. ; de = Frequency
  1313. bc_offset CHANNEL_FREQUENCY
  1314. ld e, [hl]
  1315. inc hl
  1316. ld d, [hl]
  1317.  
  1318. ; check whether pitch slide is going up or down
  1319. bc_offset CHANNEL_FLAGS3
  1320. bit SOUND_PITCH_SLIDE_DIR, [hl]
  1321. jr z, .decreasing
  1322.  
  1323. ; frequency += [Channel*PitchSlideAmount]
  1324. bc_offset CHANNEL_PITCH_SLIDE_AMOUNT
  1325. ld l, [hl]
  1326. ld h, 0
  1327. add hl, de
  1328. ld d, h
  1329. ld e, l
  1330.  
  1331. ; [Channel*PitchSlideTempo] += [Channel*PitchSlideAmountFraction]
  1332. ; if rollover: Frequency += 1
  1333. bc_offset CHANNEL_PITCH_SLIDE_FRACTION
  1334. ld a, [hl]
  1335.  
  1336. bc_offset CHANNEL_PITCH_SLIDE_TEMPO
  1337. add [hl]
  1338. ld [hl], a
  1339. ld a, 0
  1340. adc e
  1341. ld e, a
  1342. ld a, 0
  1343. adc d
  1344. ld d, a
  1345.  
  1346. ; Compare the dw at [Channel*PitchSlideTarget] to de.
  1347. ; If frequency is greater, we're finished.
  1348. ; Otherwise, load the frequency and set two flags.
  1349. bc_offset CHANNEL_PITCH_SLIDE_TARGET + 1
  1350. ld a, [hl]
  1351. cp d
  1352. jr c, .finished_pitch_slide
  1353.  
  1354. jr nz, .continue_pitch_slide
  1355.  
  1356. bc_offset CHANNEL_PITCH_SLIDE_TARGET
  1357. ld a, [hl]
  1358. cp e
  1359. jr c, .finished_pitch_slide
  1360.  
  1361. jr .continue_pitch_slide
  1362.  
  1363. .decreasing
  1364.  
  1365. ; frequency -= [Channel*PitchSlideAmount]
  1366. ld a, e
  1367.  
  1368. bc_offset CHANNEL_PITCH_SLIDE_AMOUNT
  1369. ld e, [hl]
  1370. sub e
  1371. ld e, a
  1372. ld a, d
  1373. sbc 0
  1374. ld d, a
  1375.  
  1376. ; [Channel*PitchSlideTempo] *= 2
  1377. ; if rollover: Frequency -= 1
  1378. bc_offset CHANNEL_PITCH_SLIDE_FRACTION
  1379. ld a, [hl]
  1380. add a
  1381. ld [hl], a
  1382. ld a, e
  1383. sbc 0
  1384. ld e, a
  1385. ld a, d
  1386. sbc 0
  1387. ld d, a
  1388.  
  1389. ; Compare the dw at [Channel*PitchSlideTarget] to de.
  1390. ; If frequency is lower, we're finished.
  1391. ; Otherwise, load the frequency and set two flags.
  1392. bc_offset CHANNEL_PITCH_SLIDE_TARGET + 1
  1393. ld a, d
  1394. cp [hl]
  1395. jr c, .finished_pitch_slide
  1396.  
  1397. jr nz, .continue_pitch_slide
  1398.  
  1399. bc_offset CHANNEL_PITCH_SLIDE_TARGET
  1400. ld a, e
  1401. cp [hl]
  1402. jr nc, .continue_pitch_slide
  1403.  
  1404. .finished_pitch_slide
  1405.  
  1406. bc_offset CHANNEL_FLAGS2
  1407. res SOUND_PITCH_SLIDE, [hl]
  1408.  
  1409. bc_offset CHANNEL_FLAGS3
  1410. res SOUND_PITCH_SLIDE_DIR, [hl]
  1411. ret
  1412.  
  1413. .continue_pitch_slide
  1414.  
  1415. bc_offset CHANNEL_FREQUENCY
  1416. ld [hl], e
  1417. inc hl
  1418. ld [hl], d
  1419.  
  1420. bc_offset CHANNEL_NOTE_FLAGS
  1421. set NOTE_FREQ_OVERRIDE, [hl]
  1422. set NOTE_DUTY_OVERRIDE, [hl]
  1423. ret
  1424.  
  1425. HandleNoise:
  1426.  
  1427. ; is noise sampling on?
  1428. bc_offset CHANNEL_FLAGS1
  1429. bit SOUND_NOISE, [hl] ; noise sampling
  1430. ret z
  1431.  
  1432. ; are we in a sfx channel?
  1433. ld a, [wCurChannel]
  1434. bit NOISE_CHAN_F, a
  1435. jr nz, .next
  1436.  
  1437. ; is ch8 on? (noise)
  1438. ld hl, wChannel8Flags1
  1439. bit SOUND_CHANNEL_ON, [hl] ; on?
  1440. jr z, .next
  1441.  
  1442. ; is ch8 playing noise?
  1443. bit SOUND_NOISE, [hl]
  1444. ret nz ; quit if so
  1445.  
  1446. .next
  1447.  
  1448. ld a, [wNoiseSampleDelay]
  1449. and a
  1450. jr z, ReadNoiseSample
  1451.  
  1452. dec a
  1453. ld [wNoiseSampleDelay], a
  1454. ret
  1455.  
  1456. ReadNoiseSample:
  1457. ; sample struct:
  1458. ; [wx] [yy] [zz]
  1459. ; w: does nothing
  1460. ; x: actual duration - 1
  1461. ; 1 = 2 2 = 3 etc
  1462. ; zz: volume envelope
  1463. ; yy: frequency
  1464.  
  1465. ; de = [wNoiseSampleAddress]
  1466. ld hl, wNoiseSampleAddress
  1467. ld e, [hl]
  1468. inc hl
  1469. ld d, [hl]
  1470.  
  1471. ; is it empty?
  1472. ld a, e
  1473. or d
  1474. jr z, .quit
  1475.  
  1476. ld a, [de]
  1477. inc de
  1478.  
  1479. cp sound_ret_cmd
  1480. jr z, .quit
  1481.  
  1482. and $f
  1483. inc a
  1484. ld [wNoiseSampleDelay], a
  1485. ld a, [de]
  1486. inc de
  1487. ld [wCurTrackVolumeEnvelope], a
  1488. ld a, [de]
  1489. inc de
  1490. ld [wCurTrackFrequency], a
  1491. xor a
  1492. ld [wCurTrackFrequency + 1], a
  1493.  
  1494. ld hl, wNoiseSampleAddress
  1495. ld [hl], e
  1496. inc hl
  1497. ld [hl], d
  1498.  
  1499. bc_offset CHANNEL_NOTE_FLAGS
  1500. set NOTE_NOISE_SAMPLING, [hl]
  1501.  
  1502. .quit
  1503. ret
  1504.  
  1505.  
  1506. ParseMusic:
  1507. ; parses until a note is read or the song is ended
  1508.  
  1509. call GetMusicByte ; store next byte in a
  1510. cp sound_ret_cmd
  1511. jr z, .sound_ret
  1512.  
  1513. cp FIRST_MUSIC_CMD
  1514. jr c, .readnote
  1515.  
  1516. ; then it's a command
  1517. .readcommand
  1518.  
  1519. call ParseMusicCommand
  1520. jr ParseMusic ; start over
  1521.  
  1522. .readnote
  1523. ; wCurMusicByte contains current note
  1524. ; special notes
  1525.  
  1526. bc_offset CHANNEL_FLAGS1
  1527. bit SOUND_SFX, [hl]
  1528. jp nz, ParseSFXOrRest
  1529.  
  1530. bit SOUND_REST, [hl] ; rest
  1531. jp nz, ParseSFXOrRest
  1532.  
  1533. bit SOUND_NOISE, [hl] ; noise sample
  1534. jp nz, GetNoiseSample
  1535.  
  1536. ; normal note
  1537.  
  1538. ; set note duration (bottom nybble)
  1539. ld a, [wCurMusicByte]
  1540. and $f
  1541. call SetNoteDuration
  1542.  
  1543. ; get note pitch (top nybble)
  1544. ld a, [wCurMusicByte]
  1545. swap a
  1546. and $f
  1547. jr z, .rest ; pitch 0 -> rest
  1548.  
  1549. ; update pitch
  1550. bc_offset CHANNEL_PITCH
  1551. ld [hl], a
  1552.  
  1553. ; store pitch in e
  1554. ld e, a
  1555.  
  1556. ; store octave in d
  1557. bc_offset CHANNEL_OCTAVE
  1558. ld d, [hl]
  1559.  
  1560. ; update frequency
  1561. call GetFrequency
  1562.  
  1563. bc_offset CHANNEL_FREQUENCY
  1564. ld [hl], e
  1565. inc hl
  1566. ld [hl], d
  1567.  
  1568. ; check if not or rest
  1569. bc_offset CHANNEL_NOTE_FLAGS
  1570. set NOTE_NOISE_SAMPLING, [hl]
  1571. jp LoadNote
  1572.  
  1573. .rest
  1574. ; note = rest
  1575.  
  1576. bc_offset CHANNEL_NOTE_FLAGS
  1577. set NOTE_REST, [hl] ; Rest
  1578. ret
  1579.  
  1580. .sound_ret
  1581. ; $ff is reached in music data
  1582.  
  1583. bc_offset CHANNEL_FLAGS1
  1584. bit SOUND_SUBROUTINE, [hl] ; in a subroutine?
  1585. jr nz, .readcommand ; execute
  1586.  
  1587. ld a, [wCurChannel]
  1588. cp CHAN5
  1589. jr nc, .chan_5to8
  1590.  
  1591. ; check if Channel 5's on
  1592. bc_offset CHANNEL_STRUCT_LENGTH * NUM_MUSIC_CHANS + CHANNEL_FLAGS1
  1593. bit SOUND_CHANNEL_ON, [hl]
  1594. jr nz, .ok
  1595.  
  1596. .chan_5to8
  1597.  
  1598. bc_offset CHANNEL_FLAGS1
  1599. bit SOUND_REST, [hl]
  1600. call nz, RestoreVolume
  1601.  
  1602. ; end music
  1603. ld a, [wCurChannel]
  1604. cp CHAN5
  1605. jr nz, .ok
  1606.  
  1607. ; no sweep
  1608. xor a
  1609. ldh [rNR10], a ; sweep = 0
  1610.  
  1611. .ok
  1612. ; stop playing
  1613.  
  1614. ; turn channel off
  1615. bc_offset CHANNEL_FLAGS1
  1616. res SOUND_CHANNEL_ON, [hl]
  1617.  
  1618. ; note = rest
  1619. bc_offset CHANNEL_NOTE_FLAGS
  1620. set NOTE_REST, [hl]
  1621.  
  1622. ; clear music id & bank
  1623. bc_offset CHANNEL_MUSIC_ID
  1624. xor a
  1625. ld [hli], a ; id hi
  1626. ld [hli], a ; id lo
  1627. ld [hli], a ; bank
  1628. ret
  1629.  
  1630. RestoreVolume:
  1631.  
  1632. ; ch5 only
  1633. ld a, [wCurChannel]
  1634. cp CHAN5
  1635. ret nz
  1636. xor a
  1637.  
  1638. ld hl, wChannel6PitchOffset
  1639. ld [hli], a
  1640. ld [hl], a
  1641.  
  1642. ld hl, wChannel8PitchOffset
  1643. ld [hli], a
  1644. ld [hl], a
  1645.  
  1646. ld a, [wLastVolume]
  1647. ld [wVolume], a
  1648. xor a
  1649. ld [wLastVolume], a
  1650. ld [wSFXPriority], a
  1651. ret
  1652.  
  1653. ParseSFXOrRest:
  1654.  
  1655. ; turn noise sampling on
  1656. bc_offset CHANNEL_NOTE_FLAGS
  1657. set NOTE_NOISE_SAMPLING, [hl] ; noise sample
  1658.  
  1659. ; update note duration
  1660. ld a, [wCurMusicByte]
  1661. call SetNoteDuration ; top nybble doesnt matter?
  1662.  
  1663. ; update volume envelope from next param
  1664. call GetMusicByte
  1665.  
  1666. bc_offset CHANNEL_VOLUME_ENVELOPE
  1667. ld [hl], a
  1668.  
  1669. ; update lo frequency from next param
  1670. call GetMusicByte
  1671. bc_offset CHANNEL_FREQUENCY
  1672. ld [hl], a
  1673.  
  1674. ; are we on the last channel? (noise sampling)
  1675. ld a, [wCurChannel]
  1676. maskbits NUM_MUSIC_CHANS
  1677. cp CHAN4
  1678. ret z
  1679.  
  1680. ; update hi frequency from next param
  1681. call GetMusicByte
  1682. bc_offset CHANNEL_FREQUENCY + 1
  1683. ld [hl], a
  1684. ret
  1685.  
  1686. GetByteInEnvelopeGroup:
  1687.  
  1688. ; get pointer
  1689. add hl, de
  1690. add hl, de
  1691. ld e, [hl]
  1692. inc hl
  1693. ld d, [hl]
  1694.  
  1695. ; store the offset in hl
  1696. ; each group can only be 256 bytes long
  1697. bc_offset CHANNEL_ENVELOPE_GROUP_OFFSET
  1698. push hl
  1699. ld l, [hl]
  1700. ld h, 0
  1701. add hl, de
  1702. ld a, [hl]
  1703. pop hl
  1704.  
  1705. ; check for ff/fe
  1706. cp env_ret_cmd
  1707. jr z, .quit
  1708.  
  1709. cp env_loop_cmd
  1710. jr nz, .next
  1711.  
  1712. ; reset hl when reading fe
  1713. xor a
  1714. ld [hl], a
  1715. ld a, [de]
  1716.  
  1717. .next
  1718. inc [hl]
  1719. and a
  1720. ret
  1721.  
  1722. .quit
  1723. scf
  1724. ret
  1725.  
  1726. GetNoiseSample:
  1727. ; load ptr to sample header in wNoiseSampleAddress
  1728.  
  1729. ; are we on the last channel?
  1730. ld a, [wCurChannel]
  1731. maskbits NUM_MUSIC_CHANS
  1732. cp CHAN4
  1733.  
  1734. ; ret if not
  1735. ret nz
  1736.  
  1737. ; update note duration
  1738. ld a, [wCurMusicByte]
  1739. and $f
  1740. call SetNoteDuration
  1741.  
  1742. ; check current channel
  1743. ld a, [wCurChannel]
  1744. bit NOISE_CHAN_F, a
  1745. jr nz, .sfx
  1746.  
  1747. ld hl, wChannel8Flags1
  1748. bit SOUND_CHANNEL_ON, [hl] ; is ch8 on? (noise)
  1749. ret nz
  1750.  
  1751. ld a, [wMusicNoiseSampleSet]
  1752. jr .next
  1753.  
  1754. .sfx
  1755.  
  1756. ld a, [wSFXNoiseSampleSet]
  1757.  
  1758. .next
  1759.  
  1760. ; load noise sample set id into de
  1761. ld e, a
  1762. ld d, 0
  1763.  
  1764. ; load ptr to noise sample set in hl
  1765. ld hl, Drumkits
  1766. add hl, de
  1767. add hl, de
  1768. ld a, [hli]
  1769. ld h, [hl]
  1770. ld l, a
  1771.  
  1772. ; get pitch
  1773. ld a, [wCurMusicByte]
  1774. swap a
  1775.  
  1776. ; non-rest note?
  1777. and $f
  1778. ret z
  1779.  
  1780. ; use 'pitch' to seek noise sample set
  1781. ld e, a
  1782. ld d, 0
  1783. add hl, de
  1784. add hl, de
  1785.  
  1786. ; load sample pointer into wNoiseSampleAddress
  1787. ld a, [hli]
  1788. ld [wNoiseSampleAddress], a
  1789. ld a, [hl]
  1790. ld [wNoiseSampleAddress + 1], a
  1791.  
  1792. ; clear delay
  1793. xor a
  1794. ld [wNoiseSampleDelay], a
  1795. ret
  1796.  
  1797. ParseMusicCommand:
  1798.  
  1799. ; reload command
  1800. ld a, [wCurMusicByte]
  1801.  
  1802. ; get command #
  1803. sub FIRST_MUSIC_CMD
  1804. ld e, a
  1805. ld d, 0
  1806.  
  1807. ; seek command pointer
  1808. ld hl, MusicCommands
  1809. add hl, de
  1810. add hl, de
  1811.  
  1812. ; jump to the new pointer
  1813. ld a, [hli]
  1814. ld h, [hl]
  1815. ld l, a
  1816. jp hl
  1817.  
  1818. MusicCommands:
  1819. ; entries correspond to audio constants (see macros/scripts/audio.asm)
  1820.  
  1821. dw Music_Octave ; octave 8
  1822. dw Music_Octave ; octave 7
  1823. dw Music_Octave ; octave 6
  1824. dw Music_Octave ; octave 5
  1825. dw Music_Octave ; octave 4
  1826. dw Music_Octave ; octave 3
  1827. dw Music_Octave ; octave 2
  1828. dw Music_Octave ; octave 1
  1829. dw Music_NoteType ; init note params
  1830. dw Music_Transpose ; add octave/pitch
  1831. dw Music_Tempo ; tempo
  1832. dw Music_DutyCycle ; duty cycle
  1833. dw Music_VolumeEnvelope ; volume envelope
  1834. dw Music_PitchSweep ; update pitch sweep
  1835. dw Music_DutyCyclePattern ; duty cycle pattern
  1836. dw Music_ToggleMusic ; music mode on/off
  1837. dw Music_PitchSlide ; pitch slide
  1838. dw Music_Vibrato ; vibrato
  1839. dw Music_SetMute ; mute
  1840. dw Music_ToggleNoise ; music noise sampling
  1841. dw Music_OldPanning ; old panning
  1842. dw Music_Volume ; volume
  1843. dw Music_PitchOffset ; pitch offset
  1844. dw Music_RelativePitch ; add pitch
  1845. dw Music_VolumeEnvelopePattern ; envelope group
  1846. dw Music_TempoRelative ; tempo adjust
  1847. dw Music_RestartChannel ; restart current channel from header
  1848. dw Music_NewSong ; new song
  1849. dw Music_SFXPriorityOn ; sfx priority on
  1850. dw Music_SFXPriorityOff ; sfx priority off
  1851. dw Music_JumpRAM ; jump ram
  1852. dw Music_StereoPanning ; stereo panning
  1853. dw Music_SFXToggleNoise ; sfx noise sampling
  1854. dw Music_PitchIncSwitch ; pitch inc
  1855. dw Music_SoundEventToggle ; frame swap placeholder
  1856. dw Music_SetMusic ; execute music
  1857. dw MusicDummy ; nothing
  1858. dw MusicDummy ; nothing
  1859. dw MusicDummy ; nothing
  1860. dw MusicDummy ; nothing
  1861. dw MusicDummy ; nothing
  1862. dw Music_SetSoundEvent ; set sound event
  1863. dw Music_SetCondition ; set condition
  1864. dw Music_JumpIf ; jumpif
  1865. dw Music_Jump ; jump
  1866. dw Music_Loop ; loop
  1867. dw Music_Call ; call
  1868. dw Music_Ret ; return
  1869.  
  1870. MusicDummy:
  1871. ret
  1872.  
  1873. Music_PitchIncSwitch:
  1874. ; RSC equivalent to toggle_perfect_pitch
  1875.  
  1876. bc_offset CHANNEL_FLAGS1
  1877. set SOUND_PITCH_INC_SWITCH, [hl]
  1878. bc_offset CHANNEL_PITCH_INC_SWITCH
  1879. ld a, [hl]
  1880. xor TRUE
  1881. ld [hl], a ; flip bit 0 of CHANNEL_PITCH_INC_SWITCH
  1882. ret
  1883.  
  1884.  
  1885. Music_SetMusic:
  1886. ; basically execute_music
  1887.  
  1888. bc_offset CHANNEL_FLAGS1
  1889. set SOUND_SFX, [hl]
  1890. ret
  1891.  
  1892. Music_SoundEventToggle:
  1893. ; will be used when porting Yoshi BGM tracks
  1894.  
  1895. ld hl, wSoundEventFlag
  1896. ld a, [hl]
  1897. and a
  1898. jp z, Music_SetSoundEvent
  1899. xor a
  1900. ld [hl], a
  1901. ret
  1902.  
  1903. Music_Ret:
  1904. ; called when $ff is encountered w/(o) subroutine flag set
  1905. ; end music stream
  1906. ; return to source address (if possible)
  1907.  
  1908. ; copy LastMusicAddress to MusicAddress
  1909. bc_offset CHANNEL_LAST_MUSIC_ADDRESS
  1910. xor a
  1911. ld e, [hl]
  1912. ld [hli], a
  1913. ld d, [hl]
  1914. ld [hl], a
  1915.  
  1916. bc_offset CHANNEL_MUSIC_ADDRESS
  1917. ld [hl], e
  1918. inc hl
  1919. ld [hl], d
  1920.  
  1921. bc_offset CHNANEL_DEEP_MUSIC_ADDRESS
  1922. ld a, [hl]
  1923. and a
  1924. jr nz, .skip_flag
  1925.  
  1926. ; reset subroutine flag
  1927. bc_offset CHANNEL_FLAGS1
  1928. res SOUND_SUBROUTINE, [hl]
  1929. jr .skip_deep_move
  1930.  
  1931. .skip_flag
  1932.  
  1933. ld e, [hl]
  1934. ld [hli], a
  1935. ld d, [hl]
  1936. ld [hl], a
  1937.  
  1938.  
  1939. bc_offset CHANNEL_LAST_MUSIC_ADDRESS
  1940. ld [hl], e
  1941. inc hl
  1942. ld [hl], d
  1943.  
  1944. .skip_deep_move
  1945.  
  1946. ret
  1947.  
  1948. Music_Call:
  1949. ; call music stream (subroutine)
  1950. ; parameters: ll hh ; pointer to subroutine
  1951.  
  1952. ; get pointer from next 2 bytes
  1953. call GetMusicByte
  1954. ld e, a
  1955. call GetMusicByte
  1956. ld d, a
  1957. push de
  1958.  
  1959. bc_offset CHANNEL_LAST_MUSIC_ADDRESS
  1960. ld a, [hl]
  1961. and a
  1962. jr z, .next_stack
  1963.  
  1964. ; copy LastMusicAddress to DeepMusicAddress
  1965. ld e, [hl]
  1966. inc hl
  1967. ld d, [hl]
  1968.  
  1969. bc_offset CHNANEL_DEEP_MUSIC_ADDRESS
  1970. ld [hl], e
  1971. inc hl
  1972. ld [hl], d
  1973.  
  1974. .next_stack
  1975. ; copy MusicAddress to LastMusicAddress
  1976. bc_offset CHANNEL_MUSIC_ADDRESS
  1977. ld e, [hl]
  1978. inc hl
  1979. ld d, [hl]
  1980.  
  1981. bc_offset CHANNEL_LAST_MUSIC_ADDRESS
  1982. ld [hl], e
  1983. inc hl
  1984. ld [hl], d
  1985.  
  1986. ; load pointer into MusicAddress
  1987. pop de
  1988.  
  1989. bc_offset CHANNEL_MUSIC_ADDRESS
  1990. ld [hl], e
  1991. inc hl
  1992. ld [hl], d
  1993.  
  1994. ; set subroutine flag
  1995. bc_offset CHANNEL_FLAGS1
  1996. set SOUND_SUBROUTINE, [hl]
  1997. ret
  1998.  
  1999.  
  2000. Music_Jump:
  2001. ; jump
  2002. ; parameters: ll hh ; pointer
  2003.  
  2004. ; get pointer from next 2 bytes
  2005. call GetMusicByte
  2006. ld e, a
  2007. call GetMusicByte
  2008. ld d, a
  2009.  
  2010. bc_offset CHANNEL_MUSIC_ADDRESS
  2011. ld [hl], e
  2012. inc hl
  2013. ld [hl], d
  2014. ret
  2015.  
  2016.  
  2017. Music_Loop:
  2018. ; loops xx - 1 times
  2019. ; 00: infinite
  2020. ; params: 3
  2021. ; xx ll hh
  2022. ; xx : loop count
  2023. ; ll hh : pointer
  2024.  
  2025. ; get loop count
  2026. call GetMusicByte
  2027.  
  2028. bc_offset CHANNEL_FLAGS1
  2029. bit SOUND_LOOPING, [hl] ; has the loop been initiated?
  2030. jr nz, .checkloop
  2031.  
  2032. and a ; loop counter 0 = infinite
  2033. jr z, .loop
  2034.  
  2035. ; initiate loop
  2036. dec a
  2037. set SOUND_LOOPING, [hl] ; set loop flag
  2038.  
  2039. bc_offset CHANNEL_LOOP_COUNT
  2040. ld [hl], a ; store loop counter
  2041.  
  2042. .checkloop
  2043.  
  2044. bc_offset CHANNEL_LOOP_COUNT
  2045. ld a, [hl]
  2046. and a ; are we done?
  2047. jr z, .endloop
  2048.  
  2049. dec [hl]
  2050.  
  2051. .loop
  2052.  
  2053. ; get pointer
  2054. call GetMusicByte
  2055. ld e, a
  2056. call GetMusicByte
  2057. ld d, a
  2058.  
  2059. ; load new pointer into MusicAddress
  2060. bc_offset CHANNEL_MUSIC_ADDRESS
  2061. ld [hl], e
  2062. inc hl
  2063. ld [hl], d
  2064. ret
  2065.  
  2066. .endloop
  2067.  
  2068. ; reset loop flag
  2069. bc_offset CHANNEL_FLAGS1
  2070. res SOUND_LOOPING, [hl]
  2071.  
  2072. ; skip to next command
  2073. bc_offset CHANNEL_MUSIC_ADDRESS
  2074. ld e, [hl]
  2075. inc hl
  2076. ld d, [hl]
  2077. inc de ; skip
  2078. inc de ; pointer
  2079. ld [hl], d
  2080. dec hl
  2081. ld [hl], e
  2082. ret
  2083.  
  2084.  
  2085. Music_SetCondition:
  2086. ; set condition for a jump
  2087. ; stores condition in channel RAM
  2088. ; used with FB
  2089. ; params: 1
  2090. ; xx ; condition
  2091.  
  2092. ; set condition
  2093. call GetMusicByte
  2094.  
  2095. bc_offset CHANNEL_CONDITION
  2096. ld [hl], a
  2097. ret
  2098.  
  2099. Music_JumpIf:
  2100. ; conditional jump
  2101. ; used with FA
  2102. ; checks conditions in channel RAM
  2103. ; params: 3
  2104. ; xx: condition
  2105. ; ll hh: pointer
  2106. ; check condition
  2107.  
  2108. ; a = condition
  2109. call GetMusicByte
  2110.  
  2111. ; if existing condition matches, jump to new address
  2112. bc_offset CHANNEL_CONDITION
  2113. cp [hl]
  2114. jr z, .jump
  2115.  
  2116. ; skip to next command
  2117.  
  2118. ; get address
  2119. bc_offset CHANNEL_MUSIC_ADDRESS
  2120. ld e, [hl]
  2121. inc hl
  2122. ld d, [hl]
  2123.  
  2124. ; skip pointer
  2125. inc de
  2126. inc de
  2127.  
  2128. ; update address
  2129. ld [hl], d
  2130. dec hl
  2131. ld [hl], e
  2132. ret
  2133.  
  2134. .jump
  2135. ; jump to the new address
  2136.  
  2137. ; get pointer
  2138. call GetMusicByte
  2139. ld e, a
  2140. call GetMusicByte
  2141. ld d, a
  2142.  
  2143. ; update pointer in MusicAddress
  2144. bc_offset CHANNEL_MUSIC_ADDRESS
  2145. ld [hl], e
  2146. inc hl
  2147. ld [hl], d
  2148. ret
  2149.  
  2150.  
  2151. Music_JumpRAM:
  2152. ; conditional jump
  2153. ; checks for active condition in exclusive RAM
  2154. ; RAM may've been used to play dynamic music based on in-game events
  2155. ; params: 2
  2156. ; ll hh ; pointer
  2157.  
  2158. ; get channel
  2159. ld a, [wCurChannel]
  2160. maskbits NUM_MUSIC_CHANS
  2161. ld e, a
  2162. ld d, 0
  2163.  
  2164. ; hl = wChannel1JumpCondition + channel id
  2165. ld hl, wChannel1JumpCondition
  2166. add hl, de
  2167.  
  2168. ; if active, jump
  2169. ld a, [hl]
  2170. and a
  2171. jr nz, .jump
  2172.  
  2173. ; skip to next command
  2174.  
  2175. ; get address
  2176. bc_offset CHANNEL_MUSIC_ADDRESS
  2177. ld e, [hl]
  2178. inc hl
  2179. ld d, [hl]
  2180.  
  2181. ; skip pointer
  2182. inc de
  2183. inc de
  2184.  
  2185. ; update address
  2186. ld [hl], d
  2187. dec hl
  2188. ld [hl], e
  2189. ret
  2190.  
  2191. .jump
  2192.  
  2193. ; reset jump flag
  2194. ld [hl], 0
  2195.  
  2196. ; de = pointer
  2197. call GetMusicByte
  2198. ld e, a
  2199. call GetMusicByte
  2200. ld d, a
  2201.  
  2202. ; update address
  2203. bc_offset CHANNEL_MUSIC_ADDRESS
  2204. ld [hl], e
  2205. inc hl
  2206. ld [hl], d
  2207. ret
  2208.  
  2209.  
  2210. Music_SetSoundEvent:
  2211. ; $F9
  2212. ; sets an exclusive flag
  2213. ; may've been used to enable different scripts
  2214. ; params: 0
  2215.  
  2216. ld a, 1 << SOUND_EVENT_F
  2217. ld [wSoundEventFlag], a
  2218. ret
  2219.  
  2220. Music_SetMute:
  2221. ; appears to be a variant of Gen 1's $ef command
  2222. ; params: 1
  2223.  
  2224. call GetMusicByte
  2225.  
  2226. bc_offset CHANNEL_MUTE
  2227. ld [hl], a
  2228. bc_offset CHANNEL_FLAGS2
  2229. set SOUND_MUTE, [hl]
  2230. ret
  2231.  
  2232.  
  2233. Music_Vibrato:
  2234. ; vibrato
  2235. ; params: 2
  2236. ; 1: [xx]
  2237. ; delay in frames
  2238. ; 2: [yz]
  2239. ; y: extent
  2240. ; z: rate (# frames per cycle)
  2241.  
  2242. ; set vibrato flag?
  2243. bc_offset CHANNEL_FLAGS2
  2244. set SOUND_VIBRATO, [hl]
  2245.  
  2246. ; start at lower frequency (extent is positive)
  2247. bc_offset CHANNEL_FLAGS3
  2248. res SOUND_VIBRATO_DIR, [hl]
  2249.  
  2250. ; get delay
  2251. call GetMusicByte
  2252.  
  2253. ; update delay
  2254.  
  2255. bc_offset CHANNEL_VIBRATO_DELAY
  2256. ld [hl], a
  2257.  
  2258. ; update delay count
  2259.  
  2260. bc_offset CHANNEL_VIBRATO_DELAY_COUNT
  2261. ld [hl], a
  2262.  
  2263. ; update extent
  2264. ; this is split into halves only to get added back together at the last second
  2265.  
  2266. ; get extent/rate
  2267. call GetMusicByte
  2268. bc_offset CHANNEL_VIBRATO_EXTENT
  2269. ld d, a
  2270.  
  2271. ; get top nybble
  2272. and $f0
  2273. swap a
  2274. srl a ; halve
  2275. ld e, a
  2276. adc 0 ; round up
  2277. swap a
  2278. or e
  2279. ld [hl], a
  2280.  
  2281. ; update rate
  2282.  
  2283. bc_offset CHANNEL_VIBRATO_RATE
  2284.  
  2285. ; get bottom nybble
  2286. ld a, d
  2287. and $f
  2288. ld d, a
  2289. swap a
  2290. or d
  2291. ld [hl], a
  2292. ret
  2293.  
  2294.  
  2295. Music_PitchSlide:
  2296. ; set the target for pitch slide
  2297. ; params: 2
  2298. ; note duration
  2299. ; target note
  2300.  
  2301. call GetMusicByte
  2302. ld [wCurNoteDuration], a
  2303.  
  2304. call GetMusicByte
  2305.  
  2306. ; pitch in e
  2307. ld d, a
  2308. and $f
  2309. ld e, a
  2310.  
  2311. ; octave in d
  2312. ld a, d
  2313. swap a
  2314. and $f
  2315. ld d, a
  2316. call GetFrequency
  2317.  
  2318. bc_offset CHANNEL_PITCH_SLIDE_TARGET
  2319. ld [hl], e
  2320.  
  2321. bc_offset CHANNEL_PITCH_SLIDE_TARGET + 1
  2322. ld [hl], d
  2323.  
  2324. bc_offset CHANNEL_FLAGS2
  2325. set SOUND_PITCH_SLIDE, [hl]
  2326. ret
  2327.  
  2328.  
  2329. Music_PitchOffset:
  2330. ; tone
  2331. ; params: 1 (bigdw)
  2332. ; offset to add to each note frequency
  2333.  
  2334. bc_offset CHANNEL_FLAGS2
  2335. set SOUND_PITCH_OFFSET, [hl]
  2336.  
  2337. bc_offset CHANNEL_PITCH_OFFSET + 1
  2338. call GetMusicByte
  2339. ld [hld], a
  2340. call GetMusicByte
  2341. ld [hl], a
  2342. ret
  2343.  
  2344.  
  2345. Music_RelativePitch:
  2346. ; set a note medium
  2347. ; operates squarely on FrequencyTable
  2348. ; params: 1
  2349.  
  2350. bc_offset CHANNEL_FLAGS2
  2351. set SOUND_RELATIVE_PITCH, [hl]
  2352. call GetMusicByte
  2353.  
  2354. bc_offset CHANNEL_RELATIVE_PITCH
  2355. ld [hl], a
  2356. ret
  2357.  
  2358.  
  2359. Music_DutyCyclePattern:
  2360. ; sequence of 4 duty cycles to be looped
  2361. ; params: 1 (4 2-bit duty cycle arguments)
  2362.  
  2363. bc_offset CHANNEL_FLAGS2
  2364. set SOUND_DUTY_LOOP, [hl] ; duty cycle looping
  2365.  
  2366. ; sound duty sequence
  2367. call GetMusicByte
  2368. rrca
  2369. rrca
  2370.  
  2371. bc_offset CHANNEL_DUTY_CYCLE_PATTERN
  2372. ld [hl], a
  2373.  
  2374. ; update duty cycle
  2375. and $c0 ; only uses top 2 bits
  2376.  
  2377. bc_offset CHANNEL_DUTY_CYCLE
  2378. ld [hl], a
  2379. ret
  2380.  
  2381.  
  2382. Music_VolumeEnvelopePattern:
  2383. ; envelope group
  2384. ; params: 1
  2385.  
  2386. bc_offset CHANNEL_FLAGS2
  2387. set SOUND_ENV_PTRN, [hl]
  2388. call GetMusicByte
  2389.  
  2390. bc_offset CHANNEL_ENVELOPE_GROUP
  2391. ld [hl], a
  2392. ret
  2393.  
  2394. Music_ToggleMusic:
  2395. ; switch to music mode
  2396. ; params: none
  2397.  
  2398. bc_offset CHANNEL_FLAGS1
  2399. bit SOUND_SFX, [hl]
  2400. jr nz, .clear
  2401.  
  2402. set SOUND_SFX, [hl]
  2403. ret
  2404.  
  2405. .clear
  2406. res SOUND_SFX, [hl]
  2407. ret
  2408.  
  2409.  
  2410. Music_ToggleNoise:
  2411. ; toggle music noise sampling
  2412. ; can't be used as a straight toggle since the param is not read from on->off
  2413. ; params:
  2414. ; noise on: 1
  2415. ; noise off: 0
  2416.  
  2417. ; check if noise sampling is on
  2418. bc_offset CHANNEL_FLAGS1
  2419. bit SOUND_NOISE, [hl]
  2420. jr z, .on
  2421.  
  2422. ; turn noise sampling off
  2423. res SOUND_NOISE, [hl]
  2424. ret
  2425. .on
  2426.  
  2427. ; turn noise sampling on
  2428. set SOUND_NOISE, [hl]
  2429. call GetMusicByte
  2430. ld [wMusicNoiseSampleSet], a
  2431. ret
  2432.  
  2433.  
  2434. Music_SFXToggleNoise:
  2435. ; toggle sfx noise sampling
  2436. ; params:
  2437. ; on: 1
  2438. ; off: 0
  2439.  
  2440. ; check if noise sampling is on
  2441. bc_offset CHANNEL_FLAGS1
  2442. bit SOUND_NOISE, [hl]
  2443. jr z, .on
  2444.  
  2445. ; turn noise sampling off
  2446. res SOUND_NOISE, [hl]
  2447. ret
  2448.  
  2449. .on
  2450.  
  2451. ; turn noise sampling on
  2452. set SOUND_NOISE, [hl]
  2453. call GetMusicByte
  2454. ld [wSFXNoiseSampleSet], a
  2455. ret
  2456.  
  2457. Music_PitchSweep:
  2458. ; update pitch sweep
  2459. ; params: 1
  2460.  
  2461. call GetMusicByte
  2462. ld [wPitchSweep], a
  2463.  
  2464. bc_offset CHANNEL_NOTE_FLAGS
  2465. set NOTE_PITCH_SWEEP, [hl]
  2466. ret
  2467.  
  2468.  
  2469. Music_DutyCycle:
  2470. ; duty cycle
  2471. ; params: 1
  2472.  
  2473. call GetMusicByte
  2474. rrca
  2475. rrca
  2476. and $c0
  2477.  
  2478. bc_offset CHANNEL_DUTY_CYCLE
  2479. ld [hl], a
  2480. ret
  2481.  
  2482.  
  2483. Music_NoteType:
  2484. ; note length
  2485. ; # frames per 16th note
  2486. ; volume envelope: see Music_VolumeEnvelope
  2487. ; params: 2
  2488.  
  2489. ; note length
  2490. call GetMusicByte
  2491.  
  2492. bc_offset CHANNEL_NOTE_LENGTH
  2493. ld [hl], a
  2494. ld a, [wCurChannel]
  2495. maskbits NUM_MUSIC_CHANS
  2496. cp CHAN4
  2497. ret z
  2498.  
  2499.  
  2500. Music_VolumeEnvelope:
  2501. ; volume envelope
  2502. ; params: 1
  2503. ; hi: volume
  2504. ; lo: fade/wavetable id
  2505.  
  2506. call GetMusicByte
  2507.  
  2508. bc_offset CHANNEL_VOLUME_ENVELOPE
  2509. ld [hl], a
  2510. ret
  2511.  
  2512.  
  2513. Music_Tempo:
  2514. ; global tempo
  2515. ; params: 2
  2516. ; de: tempo
  2517.  
  2518. call GetMusicByte
  2519. ld d, a
  2520. call GetMusicByte
  2521. ld e, a
  2522. call SetGlobalTempo
  2523. ret
  2524.  
  2525.  
  2526. Music_Octave:
  2527. ; set octave based on lo nybble of the command
  2528.  
  2529. bc_offset CHANNEL_OCTAVE
  2530. ld a, [wCurMusicByte]
  2531. and 7
  2532. ld [hl], a
  2533. ret
  2534.  
  2535.  
  2536. Music_Transpose:
  2537. ; set starting octave
  2538. ; this forces all notes up by the starting octave
  2539. ; params: 1
  2540.  
  2541. call GetMusicByte
  2542.  
  2543. bc_offset CHANNEL_TRANSPOSITION
  2544. ld [hl], a
  2545. ret
  2546.  
  2547. Music_StereoPanning:
  2548. ; stereo panning
  2549. ; params: 1
  2550.  
  2551. ; stereo on?
  2552. ld a, [wOptions]
  2553. bit STEREO, a
  2554. jr nz, .pan_channel
  2555.  
  2556. ; skip param
  2557. call GetMusicByte
  2558. ret
  2559.  
  2560. .pan_channel
  2561.  
  2562. call SetLRTracks
  2563. call GetMusicByte
  2564.  
  2565. bc_offset CHANNEL_TRACKS
  2566. and [hl]
  2567. ld [hl], a
  2568. ret
  2569.  
  2570.  
  2571. Music_OldPanning:
  2572. ; old panning
  2573. ; present in pokered/yoshi
  2574. ; only used in red
  2575. ; params: 1
  2576.  
  2577. call GetMusicByte
  2578. ld [wStereoPanningMask], a
  2579. ret
  2580.  
  2581.  
  2582. Music_Volume:
  2583. ; set volume
  2584. ; params: 1
  2585. ; see Volume
  2586.  
  2587. ; read param even if it's not used
  2588. call GetMusicByte
  2589.  
  2590. ; is the song fading?
  2591. ld a, [wMusicFade]
  2592. and a
  2593. ret nz
  2594.  
  2595. ; reload param
  2596. ld a, [wCurMusicByte]
  2597.  
  2598. ; set volume
  2599. ld [wVolume], a
  2600. ret
  2601.  
  2602.  
  2603. Music_TempoRelative:
  2604. ; set global tempo to current channel tempo +/- param
  2605. ; params: 1 signed
  2606.  
  2607. call GetMusicByte
  2608. ld e, a
  2609.  
  2610. ; check sign
  2611. cp $80
  2612.  
  2613. ; -128 to 127
  2614.  
  2615. jr nc, .negative
  2616.  
  2617. ;positive
  2618.  
  2619. ld d, 0
  2620. jr .ok
  2621.  
  2622. .negative
  2623.  
  2624. ld d, -1
  2625.  
  2626. .ok
  2627.  
  2628. bc_offset CHANNEL_TEMPO
  2629. ld a, [hli]
  2630. ld h, [hl]
  2631. ld l, a
  2632. add hl, de
  2633. ld e, l
  2634. ld d, h
  2635. call SetGlobalTempo
  2636. ret
  2637.  
  2638.  
  2639. Music_SFXPriorityOn:
  2640. ; turn sfx priority on
  2641. ; params: none
  2642.  
  2643. ld a, 1 << SOUND_PRIORITY_F
  2644. ld [wSFXPriority], a
  2645. ret
  2646.  
  2647.  
  2648. Music_SFXPriorityOff:
  2649. ; turn sfx priority off
  2650. ; params: none
  2651.  
  2652. xor a
  2653. ld [wSFXPriority], a
  2654. ret
  2655.  
  2656.  
  2657. Music_RestartChannel:
  2658. ; restart current channel from channel header (same bank)
  2659. ; params: 2 (5)
  2660. ; ll hh: pointer to new channel header
  2661. ; header format: 0x yy zz
  2662. ; x: channel # (0-3)
  2663. ; zzyy: pointer to new music data
  2664.  
  2665. ; update music id
  2666. bc_offset CHANNEL_MUSIC_ID
  2667. ld a, [hli]
  2668. ld [wMusicID], a
  2669. ld a, [hl]
  2670. ld [wMusicID + 1], a
  2671.  
  2672. ; update music bank
  2673. bc_offset CHANNEL_MUSIC_BANK
  2674. ld a, [hl]
  2675. ld [wMusicBank], a
  2676.  
  2677. ; get pointer to new channel header
  2678. call GetMusicByte
  2679. ld l, a
  2680. call GetMusicByte
  2681. ld h, a
  2682. ld e, [hl]
  2683. inc hl
  2684. ld d, [hl]
  2685. push bc ; save current channel
  2686. call LoadChannel
  2687. call StartChannel
  2688. pop bc ; restore current channel
  2689. ret
  2690.  
  2691.  
  2692. Music_NewSong:
  2693. ; new song
  2694. ; params: 2
  2695. ; de: song id
  2696.  
  2697. call GetMusicByte
  2698. ld e, a
  2699. call GetMusicByte
  2700. ld d, a
  2701. push bc
  2702. call _PlayMusic
  2703. pop bc
  2704. ret
  2705.  
  2706.  
  2707. GetMusicByte:
  2708. ; returns byte from current address in a
  2709. ; advances to next byte in music data
  2710. ; input: bc = start of current channel
  2711.  
  2712. push hl
  2713. push de
  2714.  
  2715. ; load address into de
  2716. bc_offset CHANNEL_MUSIC_ADDRESS
  2717. ld a, [hli]
  2718. ld e, a
  2719. ld d, [hl]
  2720.  
  2721. ; load bank into a
  2722. bc_offset CHANNEL_MUSIC_BANK
  2723. ld a, [hl]
  2724.  
  2725. ; get byte
  2726. call _LoadMusicByte ; load data into wCurMusicByte
  2727. inc de ; advance to next byte for next time this is called
  2728.  
  2729. ; update channeldata address
  2730. bc_offset CHANNEL_MUSIC_ADDRESS
  2731. ld a, e
  2732. ld [hli], a
  2733. ld [hl], d
  2734.  
  2735. ; cleanup
  2736. pop de
  2737. pop hl
  2738.  
  2739. ; store channeldata in a
  2740. ld a, [wCurMusicByte]
  2741. ret
  2742.  
  2743.  
  2744. GetFrequency:
  2745. ; generate frequency
  2746. ; input:
  2747. ; d: octave
  2748. ; e: pitch
  2749. ; output:
  2750. ; de: frequency
  2751. ; get octave
  2752.  
  2753. ; get starting octave
  2754. bc_offset CHANNEL_TRANSPOSITION
  2755. ld a, [hl]
  2756. swap a ; hi nybble
  2757. and $f
  2758.  
  2759. ; add current octave
  2760. add d
  2761. push af ; we'll use this later
  2762.  
  2763. ; get starting octave
  2764. bc_offset CHANNEL_TRANSPOSITION
  2765. ld a, [hl]
  2766. and $f ; lo nybble
  2767. ld l, a ; ok
  2768. ld d, 0
  2769. ld h, d
  2770. add hl, de ; add current pitch
  2771. add hl, hl ; skip 2 bytes for each
  2772. ld de, FrequencyTable
  2773. add hl, de
  2774. ld e, [hl]
  2775. inc hl
  2776. ld d, [hl]
  2777.  
  2778. ; get our octave
  2779. pop af
  2780.  
  2781. ; shift right by [7 - octave] bits
  2782. .loop
  2783.  
  2784. ; [7 - octave] loops
  2785. cp $7
  2786. jr nc, .ok
  2787.  
  2788. ; sra de
  2789. sra d
  2790. rr e
  2791. inc a
  2792. jr .loop
  2793.  
  2794. .ok
  2795.  
  2796. ld a, d
  2797. and $7 ; top 3 bits for frequency (11 total)
  2798. ld d, a
  2799. ret
  2800.  
  2801.  
  2802. SetNoteDuration:
  2803. ; input: a = note duration in 16ths
  2804.  
  2805. ; store delay units in de
  2806. inc a
  2807. ld e, a
  2808. ld d, 0
  2809.  
  2810. ; store NoteLength in a
  2811. bc_offset CHANNEL_NOTE_LENGTH
  2812. ld a, [hl]
  2813.  
  2814. ; multiply NoteLength by delay units
  2815. ld l, 0 ; just multiply
  2816. call .Multiply
  2817. ld a, l ; low
  2818.  
  2819. ; store Tempo in de
  2820. bc_offset CHANNEL_TEMPO
  2821. ld e, [hl]
  2822. inc hl
  2823. ld d, [hl]
  2824.  
  2825. ; add workflow to the next result
  2826. bc_offset CHANNEL_NOTE_FLOW
  2827. ld l, [hl]
  2828.  
  2829. ; multiply Tempo by last result (NoteLength * LOW(delay))
  2830. call .Multiply
  2831.  
  2832. ; copy result to de
  2833. ld e, l
  2834. ld d, h
  2835.  
  2836. ; store result in xNoteFlow
  2837. bc_offset CHANNEL_NOTE_FLOW
  2838. ld [hl], e
  2839.  
  2840. ; store result in NoteDuration
  2841. bc_offset CHANNEL_NOTE_DURATION
  2842. ld [hl], d
  2843. ret
  2844.  
  2845. .Multiply:
  2846. ; multiplies a and de
  2847. ; adds the result to l
  2848. ; stores the result in hl
  2849.  
  2850. ld h, 0
  2851.  
  2852. .loop
  2853.  
  2854. ; halve a
  2855. srl a
  2856.  
  2857. ; is there a remainder?
  2858. jr nc, .skip
  2859.  
  2860. ; add it to the result
  2861. add hl, de
  2862.  
  2863. .skip
  2864.  
  2865. ; add de, de
  2866. sla e
  2867. rl d
  2868.  
  2869. ; are we done?
  2870. and a
  2871. jr nz, .loop
  2872. ret
  2873.  
  2874.  
  2875. SetGlobalTempo:
  2876.  
  2877. push bc ; save current channel
  2878.  
  2879. ; are we dealing with music or sfx?
  2880. ld a, [wCurChannel]
  2881. cp CHAN5
  2882. jr nc, .sfxchannels
  2883.  
  2884. ld bc, wChannel1
  2885. call Tempo
  2886. ld bc, wChannel2
  2887. call Tempo
  2888. ld bc, wChannel3
  2889. call Tempo
  2890. ld bc, wChannel4
  2891. call Tempo
  2892. jr .end
  2893.  
  2894. .sfxchannels
  2895. ld bc, wChannel5
  2896. call Tempo
  2897. ld bc, wChannel6
  2898. call Tempo
  2899. ld bc, wChannel7
  2900. call Tempo
  2901. ld bc, wChannel8
  2902. call Tempo
  2903.  
  2904. .end
  2905. pop bc ; restore current channel
  2906. ret
  2907.  
  2908. Tempo:
  2909. ; input:
  2910. ; de: note length
  2911.  
  2912. ; update Tempo
  2913. bc_offset CHANNEL_TEMPO
  2914. ld [hl], e
  2915. inc hl
  2916. ld [hl], d
  2917.  
  2918. ; clear workflow
  2919. xor a
  2920.  
  2921. bc_offset CHANNEL_NOTE_FLOW
  2922. ld [hl], a
  2923. ret
  2924.  
  2925.  
  2926. StartChannel:
  2927.  
  2928. call SetLRTracks
  2929.  
  2930. bc_offset CHANNEL_FLAGS1
  2931. set SOUND_CHANNEL_ON, [hl] ; turn channel on
  2932. ret
  2933.  
  2934.  
  2935. SetLRTracks:
  2936. ; set tracks for a the current channel to default
  2937. ; seems to be redundant since this is overwritten by stereo data later
  2938.  
  2939. push de
  2940.  
  2941. ; store current channel in de
  2942. ld a, [wCurChannel]
  2943. maskbits NUM_MUSIC_CHANS
  2944. ld e, a
  2945. ld d, 0
  2946.  
  2947. ; get this channel's lr tracks
  2948. ld hl, SpeakerTracks
  2949. add hl, de ; de = channel 0-3
  2950. ld a, [hl]
  2951.  
  2952. ; load lr tracks into Tracks
  2953. bc_offset CHANNEL_TRACKS
  2954. ld [hl], a
  2955. pop de
  2956. ret
  2957.  
  2958.  
  2959. _PlayMusic::
  2960. ; load music
  2961.  
  2962. call MusicOff
  2963. ld hl, wMusicID
  2964. ld [hl], e ; song number
  2965. inc hl
  2966. ld [hl], d ; (always 0)
  2967. ld hl, Music
  2968.  
  2969. ; 3-byte pointers (bank, address)
  2970. add hl, de
  2971. add hl, de
  2972. add hl, de
  2973. ld a, [hli]
  2974. ld [wMusicBank], a
  2975. ld e, [hl]
  2976. inc hl
  2977. ld d, [hl] ; music header address
  2978. call LoadMusicByte ; store first byte of music header in a
  2979. rlca
  2980. rlca
  2981. maskbits NUM_MUSIC_CHANS
  2982. inc a
  2983.  
  2984. .loop
  2985. ; start playing channels
  2986.  
  2987. push af
  2988. call LoadChannel
  2989. call StartChannel
  2990. pop af
  2991. dec a
  2992. jr nz, .loop
  2993. xor a
  2994. ld [wSoundEventFlag], a
  2995. ld [wChannel1JumpCondition], a
  2996. ld [wChannel2JumpCondition], a
  2997. ld [wChannel3JumpCondition], a
  2998. ld [wChannel4JumpCondition], a
  2999. ld [wNoiseSampleAddress], a
  3000. ld [wNoiseSampleAddress + 1], a
  3001. ld [wNoiseSampleDelay], a
  3002. ld [wMusicNoiseSampleSet], a
  3003. call MusicOn
  3004. ret
  3005.  
  3006.  
  3007. _PlayCry::
  3008. ; Play cry de using parameters:
  3009. ; wCryPitch
  3010. ; wCryLength
  3011.  
  3012. call MusicOff
  3013.  
  3014. ; reset sweep
  3015.  
  3016. xor a
  3017. ld [wPitchSweep], a
  3018.  
  3019. ; Overload the music id with the cry id
  3020.  
  3021. ld hl, wMusicID
  3022. ld [hl], e
  3023. inc hl
  3024. ld [hl], d
  3025.  
  3026. ; 3-byte pointers (bank, address)
  3027.  
  3028. ld hl, Cries
  3029. add hl, de
  3030. add hl, de
  3031. add hl, de
  3032.  
  3033. ld a, [hli]
  3034. ld [wMusicBank], a
  3035.  
  3036. ld e, [hl]
  3037. inc hl
  3038. ld d, [hl]
  3039.  
  3040. ; Read the cry's sound header
  3041.  
  3042. call LoadMusicByte
  3043.  
  3044. ; Top 2 bits contain the number of channels
  3045. rlca
  3046. rlca
  3047. maskbits NUM_MUSIC_CHANS
  3048.  
  3049. ; For each channel:
  3050.  
  3051. inc a
  3052.  
  3053. .loop
  3054.  
  3055. push af
  3056. call LoadChannel
  3057.  
  3058. bc_offset CHANNEL_FLAGS1
  3059. set SOUND_REST, [hl]
  3060.  
  3061. bc_offset CHANNEL_FLAGS2
  3062. set SOUND_PITCH_OFFSET, [hl]
  3063.  
  3064. bc_offset CHANNEL_PITCH_OFFSET
  3065. ld a, [wCryPitch]
  3066. ld [hli], a
  3067. ld a, [wCryPitch + 1]
  3068. ld [hl], a
  3069.  
  3070. ; No tempo for channel 4
  3071.  
  3072. ld a, [wCurChannel]
  3073. maskbits NUM_MUSIC_CHANS
  3074. cp CHAN4
  3075. jr nc, .start
  3076.  
  3077. ; Tempo is effectively length
  3078.  
  3079. bc_offset CHANNEL_TEMPO
  3080. ld a, [wCryLength]
  3081. ld [hli], a
  3082. ld a, [wCryLength + 1]
  3083. ld [hl], a
  3084.  
  3085. .start
  3086.  
  3087. call StartChannel
  3088. ld a, [wStereoPanningMask]
  3089. and a
  3090. jr z, .next
  3091.  
  3092. ; Stereo only: Play cry from the monster's side.
  3093. ; This only applies in-battle.
  3094.  
  3095. ld a, [wOptions]
  3096. bit STEREO, a
  3097. jr z, .next
  3098.  
  3099. ; [Tracks] &= [wCryTracks]
  3100.  
  3101. bc_offset CHANNEL_TRACKS
  3102. ld a, [hl]
  3103. ld hl, wCryTracks
  3104. and [hl]
  3105.  
  3106. bc_offset CHANNEL_TRACKS
  3107. ld [hl], a
  3108.  
  3109. .next
  3110.  
  3111. pop af
  3112. dec a
  3113. jr nz, .loop
  3114.  
  3115. ; Cries play at max volume, so we save the current volume for later (not MAX_VOLUME).
  3116.  
  3117. ld a, [wLastVolume]
  3118. and a
  3119. jr nz, .end
  3120.  
  3121. ld a, [wVolume]
  3122.  
  3123. ; edit: cries will only mute music if not playing at MAX_VOLUME
  3124. ; to achieve this, check for non-MAX_VOLUME before muting
  3125.  
  3126. cp MAX_VOLUME
  3127. jr z, .end
  3128.  
  3129. ; stop playing music
  3130. push af
  3131. ld a, 1 << SOUND_PRIORITY_F
  3132. ld [wSFXPriority], a
  3133. pop af
  3134.  
  3135. .end
  3136.  
  3137. ld [wLastVolume], a
  3138. ld a, MAX_VOLUME
  3139. ld [wVolume], a
  3140. call MusicOn
  3141. ret
  3142.  
  3143. _PlaySFX::
  3144. ; clear channels if they aren't already
  3145.  
  3146. call MusicOff
  3147. ld hl, wChannel5Flags1
  3148. bit SOUND_CHANNEL_ON, [hl] ; ch5 on?
  3149. jr z, .ch6
  3150.  
  3151. res SOUND_CHANNEL_ON, [hl] ; turn it off
  3152. xor a
  3153. ldh [rNR11], a ; length/wavepattern = 0
  3154. ld a, $8
  3155. ldh [rNR12], a ; envelope = 0
  3156. xor a
  3157. ldh [rNR13], a ; frequency lo = 0
  3158. ld a, $80
  3159. ldh [rNR14], a ; restart sound (freq hi = 0)
  3160. xor a
  3161. ld [wPitchSweep], a ; pitch sweep off
  3162. ldh [rNR10], a ; pitch sweep off
  3163.  
  3164. .ch6
  3165.  
  3166. ld hl, wChannel6Flags1
  3167. bit SOUND_CHANNEL_ON, [hl]
  3168. jr z, .ch7
  3169.  
  3170. res SOUND_CHANNEL_ON, [hl] ; turn it off
  3171. xor a
  3172. ldh [rNR21], a ; length/wavepattern = 0
  3173. ld a, $8
  3174. ldh [rNR22], a ; envelope = 0
  3175. xor a
  3176. ldh [rNR23], a ; frequency lo = 0
  3177. ld a, $80
  3178. ldh [rNR24], a ; restart sound (freq hi = 0)
  3179.  
  3180. .ch7
  3181.  
  3182. ld hl, wChannel7Flags1
  3183. bit SOUND_CHANNEL_ON, [hl]
  3184. jr z, .ch8
  3185.  
  3186. res SOUND_CHANNEL_ON, [hl] ; turn it off
  3187. xor a
  3188. ldh [rNR30], a ; sound mode #3 off
  3189. ldh [rNR31], a ; length/wavepattern = 0
  3190. ld a, $8
  3191. ldh [rNR32], a ; envelope = 0
  3192. xor a
  3193. ldh [rNR33], a ; frequency lo = 0
  3194. ld a, $80
  3195. ldh [rNR34], a ; restart sound (freq hi = 0)
  3196.  
  3197. .ch8
  3198.  
  3199. ld hl, wChannel8Flags1
  3200. bit SOUND_CHANNEL_ON, [hl]
  3201. jr z, .chscleared
  3202.  
  3203. res SOUND_CHANNEL_ON, [hl] ; turn it off
  3204. xor a
  3205. ldh [rNR41], a ; length/wavepattern = 0
  3206. ld a, $8
  3207. ldh [rNR42], a ; envelope = 0
  3208. xor a
  3209. ldh [rNR43], a ; frequency lo = 0
  3210. ld a, $80
  3211. ldh [rNR44], a ; restart sound (freq hi = 0)
  3212. xor a
  3213. ld [wNoiseSampleAddress], a
  3214. ld [wNoiseSampleAddress + 1], a
  3215.  
  3216. .chscleared
  3217. ; start reading sfx header for # chs
  3218.  
  3219. ld hl, wMusicID
  3220. ld [hl], e
  3221. inc hl
  3222. ld [hl], d
  3223. ld hl, SFX
  3224.  
  3225. ; 3-byte pointers (bank, address)
  3226.  
  3227. add hl, de
  3228. add hl, de
  3229. add hl, de
  3230.  
  3231. ; get bank
  3232. ld a, [hli]
  3233. ld [wMusicBank], a
  3234.  
  3235. ; get address
  3236. ld e, [hl]
  3237. inc hl
  3238. ld d, [hl]
  3239.  
  3240. ; get # channels
  3241. call LoadMusicByte
  3242. rlca ; top 2
  3243. rlca ; bits
  3244. maskbits NUM_MUSIC_CHANS
  3245. inc a ; # channels -> # loops
  3246.  
  3247. .startchannels
  3248.  
  3249. push af
  3250. call LoadChannel ; bc = current channel
  3251.  
  3252. bc_offset CHANNEL_FLAGS1
  3253. set SOUND_SFX, [hl]
  3254. call StartChannel
  3255. pop af
  3256. dec a
  3257. jr nz, .startchannels
  3258.  
  3259. call MusicOn
  3260. xor a
  3261. ld [wSFXPriority], a
  3262. ret
  3263.  
  3264.  
  3265. PlayStereoSFX::
  3266. ; play sfx de
  3267. ; farcalled by BattleAnimCmd_Sound in "engine/battle_anims/anim_commands.asm"
  3268.  
  3269. call MusicOff
  3270.  
  3271. ; standard procedure if stereo's off
  3272.  
  3273. ld a, [wOptions]
  3274. bit STEREO, a
  3275. jp z, _PlaySFX
  3276.  
  3277. ; else, let's go ahead with this
  3278. ; reset sweep
  3279.  
  3280. xor a
  3281. ld [wPitchSweep], a
  3282.  
  3283. ld hl, wMusicID
  3284. ld [hl], e
  3285. inc hl
  3286. ld [hl], d
  3287.  
  3288. ; get sfx ptr
  3289.  
  3290. ld hl, SFX
  3291. add hl, de
  3292. add hl, de
  3293. add hl, de
  3294.  
  3295. ; bank
  3296.  
  3297. ld a, [hli]
  3298. ld [wMusicBank], a
  3299.  
  3300. ; address
  3301.  
  3302. ld e, [hl]
  3303. inc hl
  3304. ld d, [hl]
  3305.  
  3306. ; bit 2-3
  3307.  
  3308. call LoadMusicByte
  3309. rlca
  3310. rlca
  3311. maskbits NUM_MUSIC_CHANS
  3312. inc a
  3313.  
  3314. .loop
  3315.  
  3316. push af
  3317. call LoadChannel
  3318.  
  3319. bc_offset CHANNEL_FLAGS1
  3320. set SOUND_SFX, [hl]
  3321.  
  3322. push de
  3323.  
  3324. ; get tracks for this channel
  3325. ld a, [wCurChannel]
  3326. maskbits NUM_MUSIC_CHANS
  3327. ld e, a
  3328. ld d, 0
  3329. ld hl, SpeakerTracks
  3330. add hl, de
  3331. ld a, [hl]
  3332. ld hl, wStereoPanningMask
  3333. and [hl]
  3334.  
  3335. bc_offset CHANNEL_TRACKS
  3336. ld [hl], a
  3337.  
  3338. bc_offset CHANNEL_BCD_DELAY_COUNTER
  3339. ld [hl], a
  3340.  
  3341. ld a, [wCryTracks]
  3342. cp 2 ; ch 1-2
  3343. jr c, .skip
  3344.  
  3345. ; ch3-4
  3346.  
  3347. ld a, [wSFXDuration]
  3348.  
  3349. bc_offset CHANNEL_TEMPO_OFFSET
  3350. ld [hl], a
  3351.  
  3352. bc_offset CHANNEL_BCD_DELAY
  3353. ld [hl], a
  3354.  
  3355. bc_offset CHANNEL_FLAGS2
  3356. set SOUND_BCD, [hl]
  3357.  
  3358. .skip
  3359.  
  3360. pop de
  3361.  
  3362. ; turn channel on
  3363.  
  3364. bc_offset CHANNEL_FLAGS1
  3365. set SOUND_CHANNEL_ON, [hl] ; on
  3366.  
  3367. ; done?
  3368.  
  3369. pop af
  3370. dec a
  3371. jr nz, .loop
  3372.  
  3373. ; we're done
  3374.  
  3375. call MusicOn
  3376. ret
  3377.  
  3378.  
  3379. LoadChannel:
  3380. ; prep channel for use
  3381. ; input:
  3382. ; de:
  3383.  
  3384. ; get pointer to current channel
  3385. call LoadMusicByte
  3386. inc de
  3387. and $7 ; bit 0-2 (current channel)
  3388. ld [wCurChannel], a
  3389. ld c, a
  3390. ld b, 0
  3391. ld hl, ChannelPointers
  3392. add hl, bc
  3393. add hl, bc
  3394. ld c, [hl]
  3395. inc hl
  3396. ld b, [hl] ; bc = channel pointer
  3397.  
  3398. bc_offset CHANNEL_FLAGS1
  3399. res SOUND_CHANNEL_ON, [hl] ; channel off
  3400.  
  3401. ; make sure channel is cleared
  3402. ; set default tempo and note length in case nothing is loaded
  3403. ; input:
  3404. ; bc = channel struct pointer
  3405.  
  3406. push de
  3407. xor a
  3408. ; get channel struct location and length
  3409.  
  3410. bc_offset CHANNEL_MUSIC_ID ; start
  3411. ld e, CHANNEL_STRUCT_LENGTH ; channel struct length
  3412. ; clear channel
  3413.  
  3414. .loop
  3415.  
  3416. ld [hli], a
  3417. dec e
  3418. jr nz, .loop
  3419.  
  3420. ; set tempo to default ($100)
  3421. bc_offset CHANNEL_TEMPO
  3422. xor a
  3423. ld [hli], a
  3424. inc a
  3425. ld [hl], a
  3426.  
  3427. ; set note length to default ($1) (fast)
  3428. bc_offset CHANNEL_NOTE_LENGTH
  3429. ld [hl], a
  3430. pop de
  3431.  
  3432. ; load music pointer
  3433. bc_offset CHANNEL_MUSIC_ADDRESS
  3434. call LoadMusicByte
  3435. ld [hli], a
  3436. inc de
  3437. call LoadMusicByte
  3438. ld [hl], a
  3439. inc de
  3440.  
  3441. ; load music id
  3442. bc_offset CHANNEL_MUSIC_ID
  3443. ld a, [wMusicID]
  3444. ld [hli], a
  3445. ld a, [wMusicID + 1]
  3446. ld [hl], a
  3447.  
  3448. ; load music bank
  3449. bc_offset CHANNEL_MUSIC_BANK
  3450. ld a, [wMusicBank]
  3451. ld [hl], a
  3452. ret
  3453.  
  3454.  
  3455. LoadMusicByte::
  3456. ; input:
  3457. ; de = current music address
  3458. ; output:
  3459. ; a = wCurMusicByte
  3460.  
  3461. ld a, [wMusicBank]
  3462. call _LoadMusicByte
  3463. ld a, [wCurMusicByte]
  3464. ret
  3465.  
  3466.  
  3467. SpeakerTracks:
  3468. ; bit corresponds to track #
  3469. ; hi: left channel
  3470. ; lo: right channel
  3471. db $11, $22, $44, $88
  3472.  
  3473.  
  3474. ChannelPointers:
  3475. ; music channels
  3476. dw wChannel1
  3477. dw wChannel2
  3478. dw wChannel3
  3479. dw wChannel4
  3480.  
  3481. ; sfx channels
  3482. dw wChannel5
  3483. dw wChannel6
  3484. dw wChannel7
  3485. dw wChannel8
  3486.  
  3487.  
  3488. ClearChannels::
  3489. ; runs ClearChannel for all 4 channels
  3490. ; functionally identical to InitSound
  3491. ; farcalled by Function29fc9, in "engine/link/mystery_gift"
  3492.  
  3493. ld hl, rNR50
  3494. xor a
  3495. ld [hli], a
  3496.  
  3497. ld [hli], a
  3498. ld a, $80
  3499. ld [hli], a
  3500. ld hl, rNR10
  3501. ld e, NUM_MUSIC_CHANS
  3502.  
  3503. .loop
  3504.  
  3505. call ClearChannel
  3506. dec e
  3507. jr nz, .loop
  3508.  
  3509. ret
  3510.  
  3511.  
  3512. ClearChannel:
  3513. ; input: hl = beginning hw sound register (rNR10, rNR20, rNR30, rNR40)
  3514. ; output: 00 00 08 00 80
  3515. ; sound channel 1 2 3 4
  3516.  
  3517. xor a
  3518. ld [hli], a ; rNR10, rNR20, rNR30, rNR40 ; sweep = 0
  3519.  
  3520. ld [hli], a ; rNR11, rNR21, rNR31, rNR41 ; length/wavepattern = 0
  3521. ld a, $8
  3522. ld [hli], a ; rNR12, rNR22, rNR32, rNR42 ; envelope = 0
  3523. xor a
  3524. ld [hli], a ; rNR13, rNR23, rNR33, rNR43 ; frequency lo = 0
  3525. ld a, $80
  3526. ld [hli], a ; rNR14, rNR24, rNR34, rNR44 ; restart sound (freq hi = 0)
  3527. ret
  3528.  
Add Comment
Please, Sign In to add comment