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