#include #include #include #include "mikmod.h" #include "ubox_sound.h" static uint8_t has_sound = 0; static uint8_t cur = 0; static uint32_t voice = 0; static SAMPLE **effects = NULL; static uint8_t effects_cnt = 0; static MODULE *music = NULL; uint8_t ubox_sound_init(const ubox_sound_data *mus, const ubox_sound_data *efx, uint8_t efx_cnt) { MikMod_InitThreads(); MikMod_RegisterDriver(&drv_sb); MikMod_RegisterLoader(&load_it); md_mode |= DMODE_SOFT_SNDFX | DMODE_SOFT_MUSIC; md_volume = 128; md_sndfxvolume = 128; md_pansep = 0; md_mixfreq = 22050; if (MikMod_Init(NULL)) /* has_sound is 0 */ return 1; if (efx && efx_cnt) { effects = (SAMPLE **)calloc(efx_cnt, sizeof(SAMPLE *)); if (!effects) return 0; for (uint8_t i = 0; i < efx_cnt; i++) { effects[i] = Sample_LoadMem(efx[i].data, efx[i].len); if (!effects[i]) return 0; } /* 1 voice for effects */ if (MikMod_SetNumVoices(-1, 1)) /* has_sound is 0 */ return 1; } /* needs a song playing to get effects; have a "silence" pattern on 0 */ if (mus) { music = Player_LoadMem(mus->data, mus->len, 8, 0); if (!music) return 0; Player_Start(music); } if (MikMod_EnableOutput()) /* has_sound is 0 */ return 1; has_sound = 1; return 1; } volatile static uint8_t divider = 0; void ubox_sound_update() { if (!has_sound) return; if (++divider == UBOX_SOUND_DIVIDER) { divider = 0; MikMod_Update(); } } void ubox_sound_mute() { if (has_sound) MikMod_DisableOutput(); } void ubox_sound_unmute() { if (has_sound) MikMod_EnableOutput(); } void ubox_sound_free() { if (!has_sound) return; MikMod_DisableOutput(); if (music) Player_Free(music); if (effects && effects_cnt) { for (uint8_t i = 0; i < effects_cnt; i++) if (effects[i]) Sample_Free(effects[i]); free(effects); } MikMod_Exit(); } void ubox_sound_music_pattern(uint16_t pat) { if (has_sound && music) Player_SetPosition(pat); } void ubox_sound_play_efx(uint8_t efxno) { if (has_sound && effects) { if (cur > efxno && !Voice_Stopped(voice)) return; cur = efxno; voice = Sample_Play(effects[cur], 0, 0); } }