removed clang-format and clang_complete files from the repo
[dosdemo] / src / dos / audos.c
1 #include <stdio.h>
2
3 #ifndef NO_SOUND
4 #include <stdlib.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include "audio.h"
8 #include "midasdll.h"
9 #include "util.h"
10
11 #define SET_MUS_VOL(vol) \
12         do { \
13                 int mv = (vol) * vol_master >> 10; \
14                 MIDASsetMusicVolume(modplay, mv ? mv + 1 : 0); \
15         } while(0)
16
17 extern int force_snd_config;
18
19 static MIDASmodulePlayHandle modplay;
20 static struct au_module *curmod;
21
22 static int vol_master, vol_mus, vol_sfx;
23
24 int au_init(void)
25 {
26         modplay = 0;
27         curmod = 0;
28         vol_master = vol_mus = vol_sfx = 255;
29
30         MIDASstartup();
31
32         if(force_snd_config || (!MIDASloadConfig("sound.cfg") && !MIDASdetectSoundCard())) {
33                 if(MIDASconfig()) {
34                         if(!MIDASsaveConfig("sound.cfg")) {
35                                 fprintf(stderr, "failed to save sound card configuration\n");
36                         }
37                 }
38         }
39
40         MIDASinit();
41
42         MIDASstartBackgroundPlay(0);
43         return 0;
44 }
45
46 void au_shutdown(void)
47 {
48         printf("au_shutdown\n");
49         if(curmod) {
50                 au_stop_module(curmod);
51         }
52         MIDASstopBackgroundPlay();
53         MIDASclose();
54 }
55
56 struct au_module *au_load_module(const char *fname)
57 {
58         static MIDASmoduleInfo info;
59         struct au_module *mod;
60         char *name, *end;
61
62         if(!(mod = malloc(sizeof *mod))) {
63                 fprintf(stderr, "au_load_module: failed to allocate module\n");
64                 return 0;
65         }
66
67         if(!(mod->impl = MIDASloadModule((char*)fname))) {
68                 fprintf(stderr, "au_load_module: failed to load module: %s\n", fname);
69                 free(mod);
70                 return 0;
71         }
72
73         name = 0;
74         if(MIDASgetModuleInfo(mod->impl, &info)) {
75                 name = info.songName;
76                 end = name + strlen(name) - 1;
77                 while(end >= name && isspace(*end)) {
78                         *end-- = 0;
79                 }
80                 if(!*name) name = 0;
81         }
82
83         if(!name) {
84                 /* fallback to using the filename */
85                 if((name = strrchr(fname, '/')) || (name = strrchr(fname, '\\'))) {
86                         name++;
87                 } else {
88                         name = (char*)fname;
89                 }
90         }
91
92         if(!(mod->name = malloc(strlen(name) + 1))) {
93                 fprintf(stderr, "au_load_module: mod->name malloc failed\n");
94                 MIDASfreeModule(mod->impl);
95                 return 0;
96         }
97         strcpy(mod->name, name);
98
99         printf("loaded module \"%s\" (%s)\n", name, fname);
100         return mod;
101 }
102
103 void au_free_module(struct au_module *mod)
104 {
105         if(!mod) return;
106
107         if(mod == curmod) {
108                 au_stop_module(curmod);
109         }
110         MIDASfreeModule(mod->impl);
111         free(mod->name);
112         free(mod);
113 }
114
115 int au_play_module(struct au_module *mod)
116 {
117         if(curmod) {
118                 if(curmod == mod) return 0;
119                 au_stop_module(curmod);
120         }
121
122         if(!(modplay = MIDASplayModule(mod->impl, 1))) {
123                 fprintf(stderr, "au_play_module: failed to play module: %s\n", mod->name);
124                 return -1;
125         }
126         SET_MUS_VOL(vol_mus);
127         curmod = mod;
128         return 0;
129 }
130
131 void au_update(void)
132 {
133 }
134
135 int au_stop_module(struct au_module *mod)
136 {
137         if(mod && curmod != mod) return -1;
138         if(!curmod) return -1;
139
140         MIDASstopModule(modplay);
141         curmod = 0;
142         return 0;
143 }
144
145 int au_module_state(struct au_module *mod)
146 {
147         if(mod) {
148                 return curmod == mod ? AU_PLAYING : AU_STOPPED;
149         }
150         return curmod ? AU_PLAYING : AU_STOPPED;
151 }
152
153 int au_volume(int vol)
154 {
155         AU_VOLADJ(vol_master, vol);
156         if(vol != vol_master) {
157                 vol_master = vol;
158
159                 au_sfx_volume(vol_sfx);
160                 au_music_volume(vol_mus);
161         }
162         return vol_master;
163 }
164
165 int au_sfx_volume(int vol)
166 {
167         AU_VOLADJ(vol_sfx, vol);
168         vol_sfx = vol;
169
170         /* TODO set sfx volume */
171         return vol_sfx;
172 }
173
174
175 int au_music_volume(int vol)
176 {
177         AU_VOLADJ(vol_mus, vol);
178         vol_mus = vol;
179
180         if(curmod) {
181                 SET_MUS_VOL(vol);
182         }
183         return vol_mus;
184 }
185
186 /* when using MIDAS, we can't access the PIT directly, so we don't build timer.c
187  * and implement all the timer functions here, using MIDAS callbacks
188  */
189 static volatile unsigned long ticks;
190 static unsigned long tick_interval;
191
192 static void MIDAS_CALL midas_timer(void)
193 {
194         ticks++;
195 }
196
197 /* macro to divide and round to the nearest integer */
198 #define DIV_ROUND(a, b) \
199         ((a) / (b) + ((a) % (b)) / ((b) / 2))
200
201 void init_timer(int res_hz)
202 {
203         MIDASsetTimerCallbacks(res_hz * 1000, 0, midas_timer, 0, 0);
204         tick_interval = DIV_ROUND(1000, res_hz);
205 }
206
207 void reset_timer(void)
208 {
209         ticks = 0;
210 }
211
212 unsigned long get_msec(void)
213 {
214         return ticks * tick_interval;
215 }
216
217 void sleep_msec(unsigned long msec)
218 {
219         unsigned long wakeup_time = ticks + msec / tick_interval;
220         while(ticks < wakeup_time) {
221 #ifdef USE_HLT
222                 halt();
223 #endif
224         }
225 }
226
227 #else   /* NO_SOUND */
228 #include "audio.h"
229
230 static int vol_master, vol_mus, vol_sfx;
231
232 int au_init(void)
233 {
234         vol_master = vol_mus = vol_sfx = 255;
235         return 0;
236 }
237
238 void au_shutdown(void)
239 {
240         printf("au_shutdown\n");
241 }
242
243 struct au_module *au_load_module(const char *fname)
244 {
245         return 0;
246 }
247
248 void au_free_module(struct au_module *mod)
249 {
250 }
251
252 int au_play_module(struct au_module *mod)
253 {
254         return -1;
255 }
256
257 void au_update(void)
258 {
259 }
260
261 int au_stop_module(struct au_module *mod)
262 {
263         return -1;
264 }
265
266 int au_module_state(struct au_module *mod)
267 {
268         return AU_STOPPED;
269 }
270
271 int au_volume(int vol)
272 {
273         AU_VOLADJ(vol_master, vol);
274         return vol_master;
275 }
276
277 int au_sfx_volume(int vol)
278 {
279         AU_VOLADJ(vol_sfx, vol);
280         return vol_sfx;
281 }
282
283
284 int au_music_volume(int vol)
285 {
286         AU_VOLADJ(vol_mus, vol);
287         return vol_mus;
288 }
289 #endif  /* NO_SOUND */