Freeciv-3.3: /fast/freeciv/nightly/main/client/audio.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
audio.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Team
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22/* utility */
23#include "capability.h"
24#include "fcintl.h"
25#include "log.h"
26#include "mem.h"
27#include "rand.h"
28#include "registry.h"
29#include "shared.h"
30#include "string_vector.h"
31#include "support.h"
32
33/* client */
34#include "audio_none.h"
35#ifdef AUDIO_SDL
36#include "audio_sdl.h"
37#endif /* AUDIO_SDL */
38#include "client_main.h"
39#include "music.h"
40#include "options.h"
41
42#include "audio.h"
43
44#define MAX_NUM_PLUGINS 2
45#define SNDSPEC_SUFFIX ".soundspec"
46#define MUSICSPEC_SUFFIX ".musicspec"
47
48#define SOUNDSPEC_CAPSTR "+Freeciv-soundset-Devel-2022-07-03"
49#define MUSICSPEC_CAPSTR "+Freeciv-musicspec-3.2-Devel-2023-Jun-03"
50
51/* Keep them open throughout */
52 static struct section_file *ss_tagfile = NULL;
53 static struct section_file *ms_tagfile = NULL;
54
55 static struct audio_plugin plugins[MAX_NUM_PLUGINS];
56 static int num_plugins_used = 0;
57 static int selected_plugin = -1;
58 static int current_track = -1;
59 static enum music_usage current_usage;
60 static bool switching_usage = FALSE;
61 static bool let_single_track_play = FALSE;
62
63 static struct mfcb_data
64{
65 struct section_file *sfile;
66 const char *tag;
67} mfcb;
68
69static int audio_play_tag(struct section_file *sfile,
70 const char *tag, bool repeat,
71 int exclude, bool keep_old_style);
72
73static void audio_shutdown_atexit(void);
74
75/**********************************************************************/
80 const struct strvec *get_soundplugin_list(const struct option *poption)
81{
82 static struct strvec *plugin_list = NULL;
83
84 if (NULL == plugin_list) {
85 int i;
86
87 plugin_list = strvec_new();
88 strvec_reserve(plugin_list, num_plugins_used);
89 for (i = 0; i < num_plugins_used; i++) {
90 strvec_set(plugin_list, i, plugins[i].name);
91 }
92 }
93
94 return plugin_list;
95}
96
97/**********************************************************************/
103 static const struct strvec *get_audio_speclist(const char *suffix,
104 struct strvec **audio_list)
105{
106 if (NULL == *audio_list) {
107 *audio_list = fileinfolist(get_data_dirs(), suffix);
108 }
109
110 return *audio_list;
111}
112
113/**********************************************************************/
116 const struct strvec *get_soundset_list(const struct option *poption)
117{
118 static struct strvec *sound_list = NULL;
119
120 return get_audio_speclist(SNDSPEC_SUFFIX, &sound_list);
121}
122
123/**********************************************************************/
126 const struct strvec *get_musicset_list(const struct option *poption)
127{
128 static struct strvec *music_list = NULL;
129
130 return get_audio_speclist(MUSICSPEC_SUFFIX, &music_list);
131}
132
133/**********************************************************************/
136 void audio_add_plugin(struct audio_plugin *p)
137{
138 fc_assert_ret(num_plugins_used < MAX_NUM_PLUGINS);
139 memcpy(&plugins[num_plugins_used], p, sizeof(struct audio_plugin));
140 num_plugins_used++;
141}
142
143/**********************************************************************/
146 bool audio_select_plugin(const char *const name)
147{
148 int i;
149 bool found = FALSE;
150
151 for (i = 0; i < num_plugins_used; i++) {
152 if (strcmp(plugins[i].name, name) == 0) {
153 found = TRUE;
154 break;
155 }
156 }
157
158 if (found && i != selected_plugin) {
159 log_debug("Shutting down %s", plugins[selected_plugin].name);
160 plugins[selected_plugin].stop();
161 plugins[selected_plugin].wait();
162 plugins[selected_plugin].shutdown(&(plugins[selected_plugin]));
163 }
164
165 if (!found) {
166 log_fatal(_("Plugin '%s' isn't available. Available are %s"),
167 name, audio_get_all_plugin_names());
168 exit(EXIT_FAILURE);
169 }
170
171 if (!plugins[i].init(&(plugins[i]))) {
172 log_error("Plugin %s found, but can't be initialized.", name);
173 return FALSE;
174 }
175
176 selected_plugin = i;
177 log_verbose("Plugin '%s' is now selected", plugins[selected_plugin].name);
178
179 plugins[selected_plugin].set_volume(gui_options.sound_effects_volume / 100.0);
180
181 return TRUE;
182}
183
184/**********************************************************************/
188 void audio_init(void)
189{
190#ifdef AUDIO_SDL
191 audio_sdl_init();
192#endif
193
194 /* Initialize dummy plugin last, as lowest priority plugin. This
195 * affects which plugin gets selected as default in new installations. */
196 audio_none_init();
197 selected_plugin = 0;
198}
199
200/**********************************************************************/
204 static const char *audiospec_fullname(const char *audioset_name,
205 bool music)
206{
207 const char *suffix = music ? MUSICSPEC_SUFFIX : SNDSPEC_SUFFIX;
208 const char *audioset_default = music ? "stdmusic" : "stdsounds";/* Do not i18n! */
209 char *fname = fc_malloc(strlen(audioset_name) + strlen(suffix) + 1);
210 const char *dname;
211
212 sprintf(fname, "%s%s", audioset_name, suffix);
213
214 dname = fileinfoname(get_data_dirs(), fname);
215 free(fname);
216
217 if (dname) {
218 return fc_strdup(dname);
219 }
220
221 if (strcmp(audioset_name, audioset_default) == 0) {
222 /* avoid endless recursion */
223 return NULL;
224 }
225
226 /* Marked for translation, as user may see this when
227 * their client configuration from older version has
228 * a musicset that they have not yet installed for the
229 * new version. */
230 log_error(_("Couldn't find audioset \"%s\", trying \"%s\"."),
231 audioset_name, audioset_default);
232
233 return audiospec_fullname(audioset_default, music);
234}
235
236/**********************************************************************/
239 static bool check_audiofile_capstr(struct section_file *sfile,
240 const char *filename,
241 const char *our_cap,
242 const char *opt_path)
243{
244 const char *file_capstr;
245
246 file_capstr = secfile_lookup_str(sfile, "%s", opt_path);
247 if (NULL == file_capstr) {
248 log_fatal("Audio spec-file \"%s\" doesn't have capability string.",
249 filename);
250 exit(EXIT_FAILURE);
251 }
252 if (!has_capabilities(our_cap, file_capstr)) {
253 log_fatal("Audio spec-file appears incompatible:");
254 log_fatal(" file: \"%s\"", filename);
255 log_fatal(" file options: %s", file_capstr);
256 log_fatal(" supported options: %s", our_cap);
257 exit(EXIT_FAILURE);
258 }
259 if (!has_capabilities(file_capstr, our_cap)) {
260 log_fatal("Audio spec-file claims required option(s) "
261 "which we don't support:");
262 log_fatal(" file: \"%s\"", filename);
263 log_fatal(" file options: %s", file_capstr);
264 log_fatal(" supported options: %s", our_cap);
265 exit(EXIT_FAILURE);
266 }
267
268 return TRUE;
269}
270
271/**********************************************************************/
274 void audio_real_init(const char *const soundset_name,
275 const char *const musicset_name,
276 const char *const preferred_plugin_name)
277{
278 const char *ss_filename;
279 const char *ms_filename;
280 char us_ss_capstr[] = SOUNDSPEC_CAPSTR;
281 char us_ms_capstr[] = MUSICSPEC_CAPSTR;
282
283 if (strcmp(preferred_plugin_name, "none") == 0) {
284 /* We explicitly choose none plugin, silently skip the code below */
285 log_verbose("Proceeding with sound support disabled.");
286 ss_tagfile = NULL;
287 musicspec_close(ms_tagfile);
288 ms_tagfile = NULL;
289
290 return;
291 }
292 if (num_plugins_used == 1) {
293 /* We only have the dummy plugin, skip the code but issue an advertise */
294 log_normal(_("No real audio plugin present."));
295 log_normal(_("Proceeding with sound support disabled."));
296 log_normal(_("For sound support, install SDL2_mixer"));
297 log_normal("https://github.com/libsdl-org/SDL_mixer");
298 ss_tagfile = NULL;
299 musicspec_close(ms_tagfile);
300 ms_tagfile = NULL;
301
302 return;
303 }
304 if (!soundset_name) {
305 log_fatal("No sound spec-file given!");
306 exit(EXIT_FAILURE);
307 }
308 if (!musicset_name) {
309 log_fatal("No music spec-file given!");
310 exit(EXIT_FAILURE);
311 }
312 log_verbose("Initializing sound using %s and %s...",
313 soundset_name, musicset_name);
314 ss_filename = audiospec_fullname(soundset_name, FALSE);
315 ms_filename = audiospec_fullname(musicset_name, TRUE);
316 if (!ss_filename || !ms_filename) {
317 log_error("Cannot find audio spec-file \"%s\" or \"%s\"",
318 soundset_name, musicset_name);
319 log_normal(_("To get sound you need to download a sound set!"));
320 log_normal(_("Get sound sets from <%s>."),
321 "https://www.freeciv.org/wiki/Sounds");
322 log_normal(_("Proceeding with sound support disabled."));
323 ss_tagfile = NULL;
324 musicspec_close(ms_tagfile);
325 ms_tagfile = NULL;
326
327 return;
328 }
329 if (!(ss_tagfile = secfile_load(ss_filename, TRUE))) {
330 log_fatal(_("Could not load sound spec-file '%s':\n%s"), ss_filename,
331 secfile_error());
332 exit(EXIT_FAILURE);
333 }
334 if (!(ms_tagfile = musicspec_load(ms_filename))) {
335 log_fatal(_("Could not load music spec-file '%s':\n%s"), ms_filename,
336 secfile_error());
337 exit(EXIT_FAILURE);
338 }
339
340 check_audiofile_capstr(ss_tagfile, ss_filename, us_ss_capstr,
341 "soundspec.options");
342
343 free((void *) ss_filename);
344
345 check_audiofile_capstr(ms_tagfile, ms_filename, us_ms_capstr,
346 "musicspec.options");
347
348 free((void *) ms_filename);
349
350 {
351 static bool atexit_set = FALSE;
352
353 if (!atexit_set) {
354 atexit(audio_shutdown_atexit);
355 atexit_set = TRUE;
356 }
357 }
358
359 if (preferred_plugin_name[0] != '\0') {
360 if (!audio_select_plugin(preferred_plugin_name))
361 log_normal(_("Proceeding with sound support disabled."));
362 return;
363 }
364
365#ifdef AUDIO_SDL
366 if (audio_select_plugin("sdl")) return;
367#endif
368 log_normal(_("No real audio subsystem managed to initialize!"));
369 log_normal(_("Perhaps there is some misconfiguration or bad permissions."));
370 log_normal(_("Proceeding with sound support disabled."));
371}
372
373/**********************************************************************/
376 void audio_restart(const char *soundset_name, const char *musicset_name)
377{
378 audio_stop(); /* Fade down old one */
379
380 sz_strlcpy(sound_set_name, soundset_name);
381 sz_strlcpy(music_set_name, musicset_name);
382 audio_real_init(sound_set_name, music_set_name, sound_plugin_name);
383}
384
385/**********************************************************************/
388 static void music_finished_callback(void)
389{
390 bool usage_enabled = TRUE;
391
392 if (switching_usage) {
393 switching_usage = FALSE;
394
395 return;
396 }
397
398 if (let_single_track_play) {
399 /* This call is style music ending before single track plays.
400 * Do not restart style music now.
401 * Make sure style music restarts when single track itself finishes. */
402 let_single_track_play = FALSE;
403
404 return;
405 }
406
407 switch (current_usage) {
408 case MU_MENU:
409 usage_enabled = gui_options.sound_enable_menu_music;
410 break;
411 case MU_INGAME:
412 usage_enabled = gui_options.sound_enable_game_music;
413 break;
414 }
415
416 if (usage_enabled) {
417 current_track = audio_play_tag(mfcb.sfile, mfcb.tag, TRUE, current_track,
418 FALSE);
419 }
420}
421
422/**********************************************************************/
426 static int audio_play_tag(struct section_file *sfile,
427 const char *tag, bool repeat, int exclude,
428 bool keep_old_style)
429{
430 const char *soundfile;
431 const char *fullpath = NULL;
432 audio_finished_callback cb = NULL;
433 int ret = 0;
434
435 if (!tag || strcmp(tag, "-") == 0) {
436 return -1;
437 }
438
439 if (sfile) {
440 soundfile = secfile_lookup_str(sfile, "files.%s", tag);
441 if (soundfile == NULL) {
442 const char *files[MAX_ALT_AUDIO_FILES];
443 int excluded = -1;
444 int i;
445 int j;
446
447 j = 0;
448 for (i = 0; i < MAX_ALT_AUDIO_FILES; i++) {
449 const char *ftmp = secfile_lookup_str(sfile, "files.%s_%d", tag, i);
450
451 if (ftmp == NULL) {
452 if (excluded != -1 && j == 0) {
453 /* Cannot exclude the only track */
454 excluded = -1;
455 j++;
456 }
457 files[j] = NULL;
458 break;
459 }
460 files[j] = ftmp;
461 if (i != exclude) {
462 j++;
463 } else {
464 excluded = j;
465 }
466 }
467
468 if (j > 0) {
469 ret = fc_rand(j);
470
471 soundfile = files[ret];
472 if (excluded != -1 && excluded < ret) {
473 /* Exclude track was skipped earlier, include it to track number to return */
474 ret++;
475 }
476 }
477 }
478
479 if (repeat) {
480 if (!keep_old_style) {
481 mfcb.sfile = sfile;
482 mfcb.tag = tag;
483 }
484
485 /* Callback is needed even when there's no alternative tracks -
486 * we may be running single track now, and want to switch
487 * (by the callback) back to style music when it ends. */
488 cb = music_finished_callback;
489 }
490
491 if (NULL == soundfile) {
492 log_verbose("No sound file for tag %s", tag);
493 } else {
494 fullpath = fileinfoname(get_data_dirs(), soundfile);
495 if (!fullpath) {
496 log_error("Cannot find audio file %s for tag %s", soundfile, tag);
497 }
498 }
499 }
500
501 if (!plugins[selected_plugin].play(tag, fullpath, repeat, cb)) {
502 return -1;
503 }
504
505 return ret;
506}
507
508/**********************************************************************/
511 static bool audio_play_sound_tag(const char *tag, bool repeat)
512{
513 return (audio_play_tag(ss_tagfile, tag, repeat, -1, FALSE) >= 0);
514}
515
516/**********************************************************************/
519 static int audio_play_music_tag(const char *tag, bool repeat,
520 bool keep_old_style)
521{
522 return audio_play_tag(ms_tagfile, tag, repeat, -1, keep_old_style);
523}
524
525/**********************************************************************/
528 void audio_play_sound(const char *const tag, const char *const alt_tag,
529 const char *const alt_tag2)
530{
531 const char *pretty_alt_tag = alt_tag ? alt_tag : "(null)";
532 const char *pretty_alt2_tag = alt_tag2 ? alt_tag2 : "(null)";
533
534 if (gui_options.sound_enable_effects) {
535 fc_assert_ret(tag != NULL);
536
537 log_debug("audio_play_sound('%s', '%s', '%s')",
538 tag, pretty_alt_tag, pretty_alt2_tag);
539
540 /* Try playing primary tag first, if not go to alternative tags */
541 if (!audio_play_sound_tag(tag, FALSE)
542 && !audio_play_sound_tag(alt_tag, FALSE)
543 && !audio_play_sound_tag(alt_tag2, FALSE)) {
544 log_verbose( "None of tags %s, %s, or %s found",
545 tag, pretty_alt_tag, pretty_alt2_tag);
546 }
547 }
548}
549
550/**********************************************************************/
554 static void real_audio_play_music(const char *const tag, char *const alt_tag,
555 bool keep_old_style)
556{
557 char *pretty_alt_tag = alt_tag ? alt_tag : "(null)";
558
559 fc_assert_ret(tag != NULL);
560
561 log_debug("audio_play_music('%s', '%s')", tag, pretty_alt_tag);
562
563 /* try playing primary tag first, if not go to alternative tag */
564 current_track = audio_play_music_tag(tag, TRUE, keep_old_style);
565
566 if (current_track < 0) {
567 current_track = audio_play_music_tag(alt_tag, TRUE, keep_old_style);
568
569 if (current_track < 0) {
570 log_verbose("Neither of tags %s or %s found", tag, pretty_alt_tag);
571 }
572 }
573}
574
575/**********************************************************************/
578 void audio_play_music(const char *const tag, char *const alt_tag,
579 enum music_usage usage)
580{
581 current_usage = usage;
582
583 real_audio_play_music(tag, alt_tag, FALSE);
584}
585
586/**********************************************************************/
589 void audio_play_track(const char *const tag, char *const alt_tag)
590{
591 if (current_track >= 0) {
592 /* Only set let_single_track_play when there's music playing that will
593 * result in calling the music_finished_callback */
594 let_single_track_play = TRUE;
595
596 /* Stop old music. */
597 audio_stop();
598 }
599
600 real_audio_play_music(tag, alt_tag, TRUE);
601}
602
603/**********************************************************************/
606 void audio_pause(void)
607{
608 plugins[selected_plugin].pause();
609}
610
611/**********************************************************************/
614 void audio_resume(void)
615{
616 plugins[selected_plugin].resume();
617}
618
619/**********************************************************************/
622 void audio_stop(void)
623{
624 plugins[selected_plugin].stop();
625}
626
627/**********************************************************************/
630 void audio_stop_usage(void)
631{
632 switching_usage = TRUE;
633 plugins[selected_plugin].stop();
634}
635
636/**********************************************************************/
639 double audio_get_volume(void)
640{
641 return plugins[selected_plugin].get_volume();
642}
643
644/**********************************************************************/
647 void audio_set_volume(double volume)
648{
649 plugins[selected_plugin].set_volume(volume);
650}
651
652/**********************************************************************/
657 void audio_shutdown(bool play_quit_tag)
658{
659 /* Avoid infinite loop at end of game */
660 audio_stop();
661
662 if (play_quit_tag) {
663 audio_play_sound("e_client_quit", NULL, NULL);
664 }
665
666 if (plugins[selected_plugin].initialized) {
667 plugins[selected_plugin].wait();
668 plugins[selected_plugin].shutdown(&(plugins[selected_plugin]));
669 }
670
671 if (NULL != ss_tagfile) {
672 secfile_destroy(ss_tagfile);
673 ss_tagfile = NULL;
674 }
675 if (NULL != ms_tagfile) {
676 musicspec_close(ms_tagfile);
677 ms_tagfile = NULL;
678 }
679}
680
681/**********************************************************************/
684 static void audio_shutdown_atexit(void)
685{
686 /* If support has already been shut down, can't handle audio tags. */
687 audio_shutdown(are_support_services_available());
688}
689
690/**********************************************************************/
694 const char *audio_get_all_plugin_names(void)
695{
696 static char buffer[100];
697 int i;
698
699 sz_strlcpy(buffer, "[");
700
701 for (i = 0; i < num_plugins_used; i++) {
702 sz_strlcat(buffer, plugins[i].name);
703 if (i != num_plugins_used - 1) {
704 sz_strlcat(buffer, ", ");
705 }
706 }
707 sz_strlcat(buffer, "]");
708 return buffer;
709}
audio_restart
void audio_restart(const char *soundset_name, const char *musicset_name)
Definition audio.c:376
music_finished_callback
static void music_finished_callback(void)
Definition audio.c:388
audio_pause
void audio_pause(void)
Definition audio.c:606
plugins
static struct audio_plugin plugins[MAX_NUM_PLUGINS]
Definition audio.c:55
audio_play_track
void audio_play_track(const char *const tag, char *const alt_tag)
Definition audio.c:589
real_audio_play_music
static void real_audio_play_music(const char *const tag, char *const alt_tag, bool keep_old_style)
Definition audio.c:554
SNDSPEC_SUFFIX
#define SNDSPEC_SUFFIX
Definition audio.c:45
audio_play_sound_tag
static bool audio_play_sound_tag(const char *tag, bool repeat)
Definition audio.c:511
current_usage
static enum music_usage current_usage
Definition audio.c:59
audio_resume
void audio_resume(void)
Definition audio.c:614
MUSICSPEC_CAPSTR
#define MUSICSPEC_CAPSTR
Definition audio.c:49
selected_plugin
static int selected_plugin
Definition audio.c:57
audio_play_music
void audio_play_music(const char *const tag, char *const alt_tag, enum music_usage usage)
Definition audio.c:578
audiospec_fullname
static const char * audiospec_fullname(const char *audioset_name, bool music)
Definition audio.c:204
audio_shutdown
void audio_shutdown(bool play_quit_tag)
Definition audio.c:657
audio_get_all_plugin_names
const char * audio_get_all_plugin_names(void)
Definition audio.c:694
audio_stop
void audio_stop(void)
Definition audio.c:622
audio_stop_usage
void audio_stop_usage(void)
Definition audio.c:630
audio_init
void audio_init(void)
Definition audio.c:188
current_track
static int current_track
Definition audio.c:58
audio_select_plugin
bool audio_select_plugin(const char *const name)
Definition audio.c:146
SOUNDSPEC_CAPSTR
#define SOUNDSPEC_CAPSTR
Definition audio.c:48
ss_tagfile
static struct section_file * ss_tagfile
Definition audio.c:52
audio_play_music_tag
static int audio_play_music_tag(const char *tag, bool repeat, bool keep_old_style)
Definition audio.c:519
get_audio_speclist
static const struct strvec * get_audio_speclist(const char *suffix, struct strvec **audio_list)
Definition audio.c:103
check_audiofile_capstr
static bool check_audiofile_capstr(struct section_file *sfile, const char *filename, const char *our_cap, const char *opt_path)
Definition audio.c:239
audio_set_volume
void audio_set_volume(double volume)
Definition audio.c:647
get_musicset_list
const struct strvec * get_musicset_list(const struct option *poption)
Definition audio.c:126
audio_play_sound
void audio_play_sound(const char *const tag, const char *const alt_tag, const char *const alt_tag2)
Definition audio.c:528
audio_play_tag
static int audio_play_tag(struct section_file *sfile, const char *tag, bool repeat, int exclude, bool keep_old_style)
Definition audio.c:426
audio_get_volume
double audio_get_volume(void)
Definition audio.c:639
audio_add_plugin
void audio_add_plugin(struct audio_plugin *p)
Definition audio.c:136
get_soundset_list
const struct strvec * get_soundset_list(const struct option *poption)
Definition audio.c:116
let_single_track_play
static bool let_single_track_play
Definition audio.c:61
ms_tagfile
static struct section_file * ms_tagfile
Definition audio.c:53
audio_shutdown_atexit
static void audio_shutdown_atexit(void)
Definition audio.c:684
mfcb
static struct mfcb_data mfcb
num_plugins_used
static int num_plugins_used
Definition audio.c:56
get_soundplugin_list
const struct strvec * get_soundplugin_list(const struct option *poption)
Definition audio.c:80
MUSICSPEC_SUFFIX
#define MUSICSPEC_SUFFIX
Definition audio.c:46
MAX_NUM_PLUGINS
#define MAX_NUM_PLUGINS
Definition audio.c:44
switching_usage
static bool switching_usage
Definition audio.c:60
audio_real_init
void audio_real_init(const char *const soundset_name, const char *const musicset_name, const char *const preferred_plugin_name)
Definition audio.c:274
audio.h
music_usage
music_usage
Definition audio.h:46
MU_INGAME
@ MU_INGAME
Definition audio.h:46
MU_MENU
@ MU_MENU
Definition audio.h:46
audio_finished_callback
void(* audio_finished_callback)(void)
Definition audio.h:28
MAX_ALT_AUDIO_FILES
#define MAX_ALT_AUDIO_FILES
Definition audio.h:26
audio_none_init
void audio_none_init(void)
Definition audio_none.c:91
audio_none.h
audio_sdl_init
void audio_sdl_init(void)
Definition audio_sdl.c:295
audio_sdl.h
has_capabilities
bool has_capabilities(const char *us, const char *them)
Definition capability.c:86
capability.h
music_set_name
char music_set_name[512]
Definition client_main.c:140
sound_plugin_name
char sound_plugin_name[512]
Definition client_main.c:138
sound_set_name
char sound_set_name[512]
Definition client_main.c:139
client_main.h
incite_cost
char * incite_cost
Definition comments.c:74
initialized
static bool initialized
Definition effects.c:42
fcintl.h
_
#define _(String)
Definition fcintl.h:67
name
const char * name
Definition inputfile.c:127
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
log_fatal
#define log_fatal(message,...)
Definition log.h:100
log_debug
#define log_debug(message,...)
Definition log.h:115
log_normal
#define log_normal(message,...)
Definition log.h:107
log_error
#define log_error(message,...)
Definition log.h:103
init
bool init
Definition mapimg.c:483
mem.h
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
musicspec_load
struct section_file * musicspec_load(const char *ms_filename)
Definition music.c:148
musicspec_close
void musicspec_close(struct section_file *tagfile)
Definition music.c:219
music.h
gui_options
struct client_options gui_options
Definition options.c:71
options.h
rand.h
fc_rand
#define fc_rand(_size)
Definition rand.h:56
secfile_load
struct section_file * secfile_load(const char *filename, bool allow_duplicates)
Definition registry.c:50
registry.h
secfile_error
const char * secfile_error(void)
Definition section_file.c:36
secfile_destroy
void secfile_destroy(struct section_file *secfile)
Definition section_file.c:95
secfile_lookup_str
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Definition registry_ini.c:2175
fileinfoname
const char * fileinfoname(const struct strvec *dirs, const char *filename)
Definition shared.c:1101
fileinfolist
struct strvec * fileinfolist(const struct strvec *dirs, const char *suffix)
Definition shared.c:1027
get_data_dirs
const struct strvec * get_data_dirs(void)
Definition shared.c:893
shared.h
strvec_set
bool strvec_set(struct strvec *psv, size_t svindex, const char *string)
Definition string_vector.c:306
strvec_reserve
void strvec_reserve(struct strvec *psv, size_t reserve)
Definition string_vector.c:81
strvec_new
struct strvec * strvec_new(void)
Definition string_vector.c:59
string_vector.h
audio_plugin
Definition audio.h:30
audio_plugin::resume
void(* resume)(void)
Definition audio.h:43
audio_plugin::stop
void(* stop)(void)
Definition audio.h:36
audio_plugin::wait
void(* wait)(void)
Definition audio.h:37
audio_plugin::set_volume
void(* set_volume)(double volume)
Definition audio.h:39
audio_plugin::get_volume
double(* get_volume)(void)
Definition audio.h:38
audio_plugin::shutdown
void(* shutdown)(struct audio_plugin *self)
Definition audio.h:35
audio_plugin::pause
void(* pause)(void)
Definition audio.h:42
client_options::sound_enable_menu_music
bool sound_enable_menu_music
Definition options.h:189
client_options::sound_effects_volume
int sound_effects_volume
Definition options.h:191
client_options::sound_enable_effects
bool sound_enable_effects
Definition options.h:188
client_options::sound_enable_game_music
bool sound_enable_game_music
Definition options.h:190
mfcb_data
Definition audio.c:64
mfcb_data::sfile
struct section_file * sfile
Definition audio.c:65
mfcb_data::tag
const char * tag
Definition audio.c:66
option
Definition options.c:514
section_file
Definition section_file.h:36
strvec
Definition string_vector.c:29
are_support_services_available
bool are_support_services_available(void)
Definition support.c:1369
support.h
sz_strlcpy
#define sz_strlcpy(dest, src)
Definition support.h:189
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
sz_strlcat
#define sz_strlcat(dest, src)
Definition support.h:190