tsound.c - vaccinewars - be a doctor and try to vaccinate the world
HTML git clone git://src.adamsgaard.dk/vaccinewars
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tsound.c (6512B)
---
1 /************************************************************************
2 * sound.c dopewars sound system *
3 * Copyright (C) 1998-2021 Ben Webb *
4 * Email: benwebb@users.sf.net *
5 * WWW: https://dopewars.sourceforge.io/ *
6 * *
7 * This program is free software; you can redistribute it and/or *
8 * modify it under the terms of the GNU General Public License *
9 * as published by the Free Software Foundation; either version 2 *
10 * of the License, or (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, USA. *
21 ************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <glib.h>
28 #include <string.h>
29
30 #ifdef PLUGINS
31 #include <sys/types.h>
32 #include <dirent.h>
33 #include <dlfcn.h>
34 #else
35 #include "plugins/sound_sdl.h"
36 #include "plugins/sound_esd.h"
37 #include "plugins/sound_winmm.h"
38 #ifdef HAVE_COCOA
39 SoundDriver *sound_cocoa_init(void);
40 #endif
41 #endif
42
43 #include "dopewars.h"
44 #include "log.h"
45 #include "nls.h"
46 #include "sound.h"
47
48 #define NOPLUGIN "none"
49
50 static SoundDriver *driver = NULL;
51 static GSList *driverlist = NULL;
52 typedef SoundDriver *(*InitFunc)(void);
53 static gboolean sound_enabled = TRUE;
54
55 gchar *GetPluginList(void)
56 {
57 GSList *listpt;
58 GString *plugins;
59 gchar *retstr;
60
61 plugins = g_string_new("\""NOPLUGIN"\"");
62 for (listpt = driverlist; listpt; listpt = g_slist_next(listpt)) {
63 SoundDriver *drivpt = (SoundDriver *)listpt->data;
64
65 if (drivpt && drivpt->name) {
66 g_string_append_printf(plugins, ", \"%s\"", drivpt->name);
67 }
68 }
69 retstr = plugins->str;
70 g_string_free(plugins, FALSE);
71 return retstr;
72 }
73
74 static void AddPlugin(InitFunc ifunc, void *module)
75 {
76 SoundDriver *newdriver = (*ifunc)();
77
78 if (newdriver) {
79 dopelog(5, 0, "%s sound plugin init OK", newdriver->name);
80 newdriver->module = module;
81 driverlist = g_slist_append(driverlist, newdriver);
82 }
83 }
84
85 #ifdef PLUGINS
86 static void OpenModule(const gchar *modname, const gchar *fullname)
87 {
88 InitFunc ifunc;
89 gint len = strlen(modname);
90 void *soundmodule;
91
92 if (len > 6 && strncmp(modname, "lib", 3) == 0
93 && strcmp(modname + len - 3, ".so") == 0) {
94 GString *funcname;
95
96 soundmodule = dlopen(fullname, RTLD_NOW);
97 if (!soundmodule) {
98 /* FIXME: using dlerror() here causes a segfault later in the program */
99 dopelog(3, 0, "dlopen of %s failed: %s", fullname, dlerror());
100 return;
101 }
102
103 funcname = g_string_new(modname);
104 g_string_truncate(funcname, len - 3);
105 g_string_erase(funcname, 0, 3);
106 g_string_append(funcname, "_init");
107 ifunc = dlsym(soundmodule, funcname->str);
108 if (ifunc) {
109 AddPlugin(ifunc, soundmodule);
110 } else {
111 dopelog(3, 0, "dlsym (%s) failed: %s", funcname->str, dlerror());
112 dlclose(soundmodule);
113 }
114 g_string_free(funcname, TRUE);
115 }
116 }
117
118 static void ScanPluginDir(const gchar *dirname)
119 {
120 DIR *dir;
121
122 dir = opendir(dirname);
123 if (dir) {
124 struct dirent *fileinfo;
125 GString *modname;
126
127 modname = g_string_new("");
128 do {
129 fileinfo = readdir(dir);
130 if (fileinfo) {
131 g_string_assign(modname, dirname);
132 g_string_append_c(modname, G_DIR_SEPARATOR);
133 g_string_append(modname, fileinfo->d_name);
134 OpenModule(fileinfo->d_name, modname->str);
135 }
136 } while (fileinfo);
137 g_string_free(modname, TRUE);
138 closedir(dir);
139 } else {
140 dopelog(5, 0, "Cannot open dir %s", dirname);
141 }
142 }
143 #endif
144
145 void SoundInit(void)
146 {
147 #ifdef PLUGINS
148 ScanPluginDir(PLUGINDIR);
149 ScanPluginDir("src/plugins/.libs");
150 ScanPluginDir("plugins/.libs");
151 #else
152 #ifdef HAVE_ESD
153 AddPlugin(sound_esd_init, NULL);
154 #endif
155 #ifdef HAVE_SDL_MIXER
156 AddPlugin(sound_sdl_init, NULL);
157 #endif
158 #ifdef HAVE_WINMM
159 AddPlugin(sound_winmm_init, NULL);
160 #endif
161 #ifdef HAVE_COCOA
162 AddPlugin(sound_cocoa_init, NULL);
163 #endif
164 #endif
165 driver = NULL;
166 }
167
168 static SoundDriver *GetPlugin(gchar *drivername)
169 {
170 GSList *listpt;
171
172 for (listpt = driverlist; listpt; listpt = g_slist_next(listpt)) {
173 SoundDriver *drivpt = (SoundDriver *)listpt->data;
174
175 if (drivpt && drivpt->name
176 && (!drivername || strcmp(drivpt->name, drivername) == 0)) {
177 return drivpt;
178 }
179 }
180 return NULL;
181 }
182
183 void SoundOpen(gchar *drivername)
184 {
185 if (!drivername || strcmp(drivername, NOPLUGIN) != 0) {
186 driver = GetPlugin(drivername);
187 if (driver) {
188 if (driver->open) {
189 dopelog(3, 0, "Using plugin %s", driver->name);
190 driver->open();
191 }
192 } else if (drivername) {
193 gchar *plugins, *err;
194
195 plugins = GetPluginList();
196 err = g_strdup_printf(_("Invalid plugin \"%s\" selected.\n"
197 "(%s available; now using \"%s\".)"),
198 drivername, plugins, NOPLUGIN);
199 g_log(NULL, G_LOG_LEVEL_CRITICAL, "%s", err);
200 g_free(plugins);
201 g_free(err);
202 }
203 }
204 sound_enabled = TRUE;
205 }
206
207 void SoundClose(void)
208 {
209 #ifdef PLUGINS
210 GSList *listpt;
211 SoundDriver *listdriv;
212 #endif
213
214 if (driver && driver->close) {
215 driver->close();
216 driver = NULL;
217 }
218 #ifdef PLUGINS
219 for (listpt = driverlist; listpt; listpt = g_slist_next(listpt)) {
220 listdriv = (SoundDriver *)listpt->data;
221 if (listdriv && listdriv->module) {
222 dlclose(listdriv->module);
223 }
224 }
225 #endif
226 g_slist_free(driverlist);
227 driverlist = NULL;
228 }
229
230 void SoundPlay(const gchar *snd)
231 {
232 if (sound_enabled && driver && driver->play && snd && snd[0]) {
233 driver->play(snd);
234 }
235 }
236
237 void SoundEnable(gboolean enable)
238 {
239 sound_enabled = enable;
240 }
241
242 gboolean IsSoundEnabled(void)
243 {
244 return sound_enabled;
245 }