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