aboutsummaryrefslogtreecommitdiff
path: root/src/sound.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-08-28 15:16:12 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-08-28 15:30:25 +0100
commite35cff6d299a07d9b34f303717083a9299a37e82 (patch)
tree7204099ad4978dfc67e04bc11df29d0f366af851 /src/sound.c
downloaduboxlib-dos-e35cff6d299a07d9b34f303717083a9299a37e82.tar.gz
uboxlib-dos-e35cff6d299a07d9b34f303717083a9299a37e82.zip
Initial import
Diffstat (limited to 'src/sound.c')
-rw-r--r--src/sound.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/sound.c b/src/sound.c
new file mode 100644
index 0000000..3ff9fa4
--- /dev/null
+++ b/src/sound.c
@@ -0,0 +1,134 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <dos.h>
+
+#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);
+ }
+}