]> git.lizzy.rs Git - nothing.git/blob - src/game/sound_samples.c
create_lt() -> {0}
[nothing.git] / src / game / sound_samples.c
1 #include <SDL2/SDL.h>
2 #include <SDL2/SDL_mixer.h>
3 #include "system/stacktrace.h"
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include "math/pi.h"
8 #include "sound_samples.h"
9 #include "system/log.h"
10 #include "system/lt.h"
11 #include "system/nth_alloc.h"
12
13 struct Sound_samples
14 {
15     Lt lt;
16     Mix_Chunk **samples;
17     size_t samples_count;
18     int paused;
19 };
20
21 static int mix_get_free_channel(void)
22 {
23     for (int i = 0; i < MIX_CHANNELS; ++i) {
24         if (!Mix_Playing(i)) {
25             return i;
26         }
27     }
28
29     return -1;
30 }
31
32 Sound_samples *create_sound_samples(const char *sample_files[],
33                                       size_t sample_files_count)
34 {
35     trace_assert(sample_files);
36     trace_assert(sample_files_count > 0);
37
38     Lt lt = {0};
39     if (lt == NULL) {
40         return NULL;
41     }
42
43     Sound_samples *sound_samples = PUSH_LT(lt, nth_calloc(1, sizeof(Sound_samples)), free);
44     if (sound_samples == NULL) {
45         RETURN_LT(lt, NULL);
46     }
47
48     sound_samples->samples = PUSH_LT(
49         lt,
50         nth_calloc(1, sizeof(Mix_Chunk*) * sample_files_count),
51         free);
52     if (sound_samples->samples == NULL) {
53         RETURN_LT(lt, NULL);
54     }
55
56     for (size_t i = 0; i < sample_files_count; ++i) {
57         sound_samples->samples[i] = PUSH_LT(
58             lt,
59             Mix_LoadWAV(sample_files[i]),
60             Mix_FreeChunk);
61         if (sound_samples->samples[i] == NULL) {
62             log_fail("Could not load '%s': %s\n", sample_files[i], Mix_GetError());
63             RETURN_LT(lt, NULL);
64         }
65     }
66
67     sound_samples->samples_count = sample_files_count;
68     sound_samples->paused = 0;
69
70     sound_samples->lt = lt;
71
72     return sound_samples;
73 }
74
75 void destroy_sound_samples(Sound_samples *sound_samples)
76 {
77     trace_assert(sound_samples);
78     RETURN_LT0(sound_samples->lt);
79 }
80
81 int sound_samples_play_sound(Sound_samples *sound_samples,
82                             size_t sound_index,
83                             int loops)
84 {
85     trace_assert(sound_samples);
86
87     if (sound_index < sound_samples->samples_count) {
88         const int free_channel = mix_get_free_channel();
89
90         log_info("Found free channel: %d\n", free_channel);
91
92         if (free_channel >= 0) {
93             return Mix_PlayChannel(free_channel, sound_samples->samples[sound_index], loops);
94         }
95     }
96
97     return 0;
98 }
99
100 int sound_samples_toggle_pause(Sound_samples *sound_samples)
101 {
102     trace_assert(sound_samples);
103
104     if (sound_samples->paused) {
105         Mix_Resume(-1);
106     } else {
107         Mix_Pause(-1);
108     }
109
110     sound_samples->paused = !sound_samples->paused;
111
112     return 0;
113 }