LIB: pm_cmusic

Background Music (BGM) and sound effects (SFX) playback

Note: IRQ_MUSIC must be included in PM_HEADER IRQ flags list for the mixer to work

pmrom_cmusic.s

Type: Source File

Dependency: pm_init.s

Including Rules: Must be after ROM (PM_HEADER) declaration and inside Bank 0

Functions

Initialize tracker

c_music_init MasterTime, RAMPointer

[CVar] MasterTime: Master time

[CVar] RAMPointer: RAM pointer

No return

Setup Timers 2 and 3 and enable them, master time will be transfered to Timer 2 preset with prescaler 6 (CPU / 1024)

RAMPointer will be the start address to process RAM writes to trigger events or effects, music data can only access between RAMPointer+0 to RAMPointer+255

Set master time

c_music_setmastertime MasterTime

[CVar] MasterTime: Master time

No return

Modify master time (affects both BGM and SFX)

Get master time

c_music_getmastertime

Returns: Master time

Set RAM pointer

c_music_setrampointer RAMPointer

[CVar] MasterTime: RAM pointer

No return

Modify RAM pointer (affects both BGM and SFX)

Get RAM pointer

c_music_getmastertime

Returns: RAM pointer

Set BGM master volume

c_music_setvolbgm vol

[CVar] vol: Volume from 0 to 3

No return

0 (Silence) to 3 (Max), default is 3
If out of range, the call will be ignored

Get BGM master volume

c_music_getvolbgm

Returns: Volume from 0 to 3

Set SFX master volume

c_music_setvolsfx vol

[CVar] vol: Volume from 0 to 3

No return

0 (Silence) to 3 (Max), default is 3
If out of range, the call will be ignored

Get SFX master volume

c_music_getvolsfx

Returns: Volume from 0 to 3

Play BGM

c_music_playbgm pattlist

[CPtr] pattlist: Pattern list address

No return

Stop BGM

c_music_stopbgm

No return

Is playing BGM?

c_music_isplayingbgm

Returns: non-zero if playing, zero if not

Play SFX

c_music_playsfx pattdata

[CPtr] pattdata: Pattern data address

No return

Stop BGM

c_music_stopbgm

No return

Is playing BGM?

c_music_isplayingbgm

Returns: non-zero if playing, zero if not

Macros

Note: Macros names are case insensitive

Macro Description
PMMUSIC_ALIGN Align data for music data, equivalent to ".align 2" but doesn't override assembler's aligment
PMMUSIC_PATTERN pataddr Must be inside BGM
Define pattern, BGM must have at least 1 pattern
pataddr = Label of pattern
PMMUSIC_ROW note_id, pwm_amt, volume, wait_amt Must be inside SFX or Pattern
Define row inside pattern
note_id = N_* definition
pwm_amt = Pulse-Width, 0 to 255, 128 = 50% (Square)
volume = Volume, 0 to 3
wait_amt = Wait ticks, 1 to 255
Set note_id to N____ and pwm_amt to -1 to not update note (saves 4 bytes)
Pulse-width changing require note definition!
PMMUSIC_WRITE_RAM address, value Must be inside SFX or Pattern
Write to RAM
address = Relative adress
pwm_amt = Pulse-Width, 0 to 255, 128 = 50% (Square)
PMMUSIC_MARK loop_id Must be inside SFX or Pattern
Mark position for loop
loop_id = Loop identification, 0 to 3
PMMUSIC_LOOP loop_id, loop_num Must be inside SFX or Pattern
Loop back
loop_id = Loop identification, 0 to 3
loop_num = Number of loops, 0 to 255
PMMUSIC_NEXT Must be inside Pattern
Go to next pattern
PMMUSIC_GOBACK pattnum Must be inside Pattern
Mark position for loop
pattnum = Number of patterns to go back
0 will repeat same pattern over and over
1 will jump to the previous pattern
PMMUSIC_END Must be inside SFX or Pattern
End BGM/SFX playback

Defines

Definition Description
IRQ_MUSIC Interrupt for handling the music, must be defined in PM_HEADER IRQ flags list for the mixer to work. This definition is equivalent to IRQ_TMR2_HI

Notes for PMMUSIC_ROW

Definition Description
N____ Don't change note
N_C_n Play C, n is octave number between 1 and 7
N_CSn Play C#, n is octave number between 1 and 7
N_D_n Play D, n is octave number between 1 and 7
N_DSn Play D#, n is octave number between 1 and 7
N_E_n Play E, n is octave number between 1 and 7
N_F_n Play F, n is octave number between 1 and 7
N_FSn Play F#, n is octave number between 1 and 7
N_G_n Play G, n is octave number between 1 and 7
N_GSn Play G#, n is octave number between 1 and 7
N_A_n Play A, n is octave number between 1 and 7
N_ASn Play A#, n is octave number between 1 and 7
N_B_n Play B, n is octave number between 1 and 7

Example

  .include "pm_libs/pm_init.s"
  .include "pm_libs/pm_cmusic.s"

  ; 1st: Game Title string, must be 12 characters
  ; 2nd: Interrupts to map, OR flags for multiple interrupts
  ; 3rd: Extra flags
  pm_header "PoKe", "PMMusic TsT ", IRQ_KEY_POWER | IRQ_MUSIC, 0

  ; Note! For pm_music to work you MUST define IRQ_MUSIC (or IRQ_TMR2_HI)
  ; in PM_HEADER IRQs flag list!
  .include "pm_libs/pmrom_music.s"

  ; Power button, shutdown PM
irq_key_power:	; Interrupt function (same name as definition but in lowercase)
  cint CINT_SHUTDOWN	; Call shutdown in BIOS

  ; Code starts here
main:
  ; Enable power key interrupt
  enable_irqs IRQ_KEY_POWER

  ; Initialize PM Music
  c_music_init $00FF, 0

  ; Enable interrupts
  enable_mirq

  ; Play PM Intro sound
  c_music_playbgm pm_intro

: halt
  jmp :b

  ; 2 bytes alignment is recommended before any pmmusic data
  ; data can be located anywhere in 2MB range and support bank crossing
  pmmusic_align

  ; PM Intro list of patterns
pm_intro:
  pmmusic_pattern pm_intro_pat

  ; PM Intro pattern
pm_intro_pat:
  ;           Note    Pw  V  Wait
  pmmusic_row N_E_5, $80, 3, 4
  pmmusic_row N____,  -1, 2, 4
  pmmusic_row N_A_5, $80, 3, 4
  pmmusic_row N____,  -1, 2, 4
  pmmusic_row N____,  -1, 0, 9
  pmmusic_row N_D_6, $80, 3, 4
  pmmusic_row N____,  -1, 2, 4
  pmmusic_row N_CS6, $80, 3, 4
  pmmusic_row N____,  -1, 2, 4
  pmmusic_row N_A_5, $80, 3, 4
  pmmusic_row N____,  -1, 2, 4
  pmmusic_row N_E_6, $80, 3, 4
  pmmusic_row N____,  -1, 2, 4
  pmmusic_row N____,  -1, 0, 24
  pmmusic_row N_D_6, $80, 3, 3
  pmmusic_row N_A_6, $80, 3, 3
  pmmusic_row N_E_7, $80, 3, 3
  pmmusic_row N_B_7, $80, 3, 3
  pmmusic_row N_E_7, $80, 3, 3
  pmmusic_row N_B_7, $80, 3, 3
  pmmusic_row N____,  -1, 0, 6
  pmmusic_end

  pm_rominfo	; Optional, report ROM and RAM size