aboutsummaryrefslogtreecommitdiff
path: root/src/sound.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-07-02 21:31:19 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-07-02 21:31:19 +0100
commita88810c8a70c8e3a7533a266774ab61a84a9adf4 (patch)
tree9ec78cd5e20f06a6cbcbd0251e215f2ecaae71c4 /src/sound.c
parent6e03fe85b19bc533888a4689572aab0ccf68edc4 (diff)
downloadgold-mine-run-a88810c8a70c8e3a7533a266774ab61a84a9adf4.tar.gz
gold-mine-run-a88810c8a70c8e3a7533a266774ab61a84a9adf4.zip
Add sound support
Diffstat (limited to 'src/sound.c')
-rw-r--r--src/sound.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/sound.c b/src/sound.c
new file mode 100644
index 0000000..f57c133
--- /dev/null
+++ b/src/sound.c
@@ -0,0 +1,116 @@
+#include <stdint.h>
+
+#include "data.h"
+
+#include "mikmod.h"
+
+typedef struct
+{
+ SAMPLE *s;
+ const char *data;
+ size_t len;
+} Efx;
+
+#define EFX_CNT 7
+
+static Efx efx[EFX_CNT] =
+{
+ { NULL, (const char *)binary_gold_efx_start, (size_t)&binary_gold_efx_size},
+ { NULL, (const char *)binary_jump_efx_start, (size_t)&binary_jump_efx_size},
+ { NULL, (const char *)binary_pickup_efx_start, (size_t)&binary_pickup_efx_size},
+ { NULL, (const char *)binary_warp_efx_start, (size_t)&binary_warp_efx_size},
+ { NULL, (const char *)binary_time_efx_start, (size_t)&binary_time_efx_size},
+ { NULL, (const char *)binary_hit_efx_start, (size_t)&binary_hit_efx_size},
+ { NULL, (const char *)binary_death_efx_start, (size_t)&binary_death_efx_size},
+};
+
+static uint8_t cur = 0;
+static uint32_t voice = 0;
+
+static MODULE *music = NULL;
+
+uint8_t sound_init()
+{
+ MikMod_RegisterAllDrivers();
+ 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))
+ return 0;
+
+ for (uint8_t i = 0; i < EFX_CNT; i++)
+ {
+ efx[i].s = Sample_LoadMem(efx[i].data, efx[i].len);
+ if (!efx[i].s)
+ return 0;
+ }
+
+ /* 1 voice for effects */
+ MikMod_SetNumVoices(-1, 1);
+
+ /* needs a song playing to get effects; have a "silence" pattern on 0 */
+ music = Player_LoadMem((const char *)binary_music_start, (size_t)&binary_music_size, 8, 0);
+ if (!music)
+ return 0;
+
+ Player_Start(music);
+ MikMod_EnableOutput();
+
+ return 1;
+}
+
+volatile static uint8_t divider = 0;
+
+/* To be called from the timer int, so we update every 540ms approx by using a
+ * counter and updating 1 in 10 interrupts */
+void sound_update()
+{
+ if (++divider == 10)
+ {
+ divider = 0;
+ MikMod_Update();
+ }
+}
+
+void sound_mute()
+{
+ MikMod_DisableOutput();
+}
+
+void sound_unmute()
+{
+ MikMod_EnableOutput();
+}
+
+void sound_free()
+{
+ MikMod_DisableOutput();
+
+ if (music)
+ Player_Free(music);
+
+ for (uint8_t i = 0; i < EFX_CNT; i++)
+ if (!efx[i].s)
+ Sample_Free(efx[i].s);
+
+ MikMod_Exit();
+}
+
+void sound_music_pattern(uint16_t pat)
+{
+ Player_SetPosition(pat);
+}
+
+void sound_play_efx(uint8_t efxno)
+{
+ if (cur > efxno && !Voice_Stopped(voice))
+ return;
+
+ cur = efxno;
+ voice = Sample_Play(efx[cur].s, 0, 0);
+}