43#define MAX_NUM_PLUGINS 2
44#define SNDSPEC_SUFFIX ".soundspec"
45#define MUSICSPEC_SUFFIX ".musicspec"
47#define SOUNDSPEC_CAPSTR "+Freeciv-3.1-soundset"
48#define MUSICSPEC_CAPSTR "+Freeciv-2.6-musicset"
69 const char *tag,
bool repeat,
70 int exclude,
bool keep_old_style);
81 static struct strvec *plugin_list = NULL;
83 if (NULL == plugin_list) {
103 struct strvec **audio_list)
105 if (NULL == *audio_list) {
117 static struct strvec *sound_list = NULL;
127 static struct strvec *music_list = NULL;
165 log_fatal(
_(
"Plugin '%s' isn't available. Available are %s"),
171 log_error(
"Plugin %s found, but can't be initialized.",
name);
207 const char *audioset_default = music ?
"stdmusic" :
"stdsounds";
208 char *fname =
fc_malloc(strlen(audioset_name) + strlen(suffix) + 1);
211 sprintf(fname,
"%s%s", audioset_name, suffix);
220 if (strcmp(audioset_name, audioset_default) == 0) {
229 log_error(
_(
"Couldn't find audioset \"%s\", trying \"%s\"."),
230 audioset_name, audioset_default);
239 const char *filename,
241 const char *opt_path)
243 const char *file_capstr;
246 if (NULL == file_capstr) {
247 log_fatal(
"Audio spec-file \"%s\" doesn't have capability string.",
252 log_fatal(
"Audio spec-file appears incompatible:");
254 log_fatal(
" file options: %s", file_capstr);
255 log_fatal(
" supported options: %s", our_cap);
259 log_fatal(
"Audio spec-file claims required option(s) "
260 "which we don't support:");
262 log_fatal(
" file options: %s", file_capstr);
263 log_fatal(
" supported options: %s", our_cap);
274 const char *
const musicset_name,
275 const char *
const preferred_plugin_name)
277 const char *ss_filename;
278 const char *ms_filename;
282 if (strcmp(preferred_plugin_name,
"none") == 0) {
284 log_verbose(
"Proceeding with sound support disabled.");
292 log_normal(
_(
"Proceeding with sound support disabled."));
293 log_normal(
_(
"For sound support, install SDL2_mixer"));
294 log_normal(
"https://github.com/libsdl-org/SDL_mixer");
299 if (!soundset_name) {
303 if (!musicset_name) {
307 log_verbose(
"Initializing sound using %s and %s...",
308 soundset_name, musicset_name);
311 if (!ss_filename || !ms_filename) {
312 log_error(
"Cannot find audio spec-file \"%s\" or \"%s\"",
313 soundset_name, musicset_name);
314 log_normal(
_(
"To get sound you need to download a sound set!"));
316 "https://www.freeciv.org/wiki/Sounds");
317 log_normal(
_(
"Proceeding with sound support disabled."));
323 log_fatal(
_(
"Could not load sound spec-file '%s':\n%s"), ss_filename,
328 log_fatal(
_(
"Could not load music spec-file '%s':\n%s"), ms_filename,
334 "soundspec.options");
336 free((
void *) ss_filename);
339 "musicspec.options");
341 free((
void *) ms_filename);
344 static bool atexit_set =
FALSE;
352 if (preferred_plugin_name[0] !=
'\0') {
354 log_normal(
_(
"Proceeding with sound support disabled."));
361 log_normal(
_(
"No real audio subsystem managed to initialize!"));
362 log_normal(
_(
"Perhaps there is some misconfiguration or bad permissions."));
363 log_normal(
_(
"Proceeding with sound support disabled."));
383 bool usage_enabled =
TRUE;
420 const char *tag,
bool repeat,
int exclude,
423 const char *soundfile;
424 const char *fullpath = NULL;
428 if (!tag || strcmp(tag,
"-") == 0) {
434 if (soundfile == NULL) {
445 if (excluded != -1 && j == 0) {
464 soundfile = files[ret];
465 if (excluded != -1 && excluded < ret) {
473 if (!keep_old_style) {
484 if (NULL == soundfile) {
489 log_error(
"Cannot find audio file %s for tag %s", soundfile, tag);
523 const char *pretty_alt_tag = alt_tag ? alt_tag :
"(null)";
528 log_debug(
"audio_play_sound('%s', '%s')", tag, pretty_alt_tag);
533 log_verbose(
"Neither of tags %s or %s found", tag, pretty_alt_tag);
545 char *pretty_alt_tag = alt_tag ? alt_tag :
"(null)";
549 log_debug(
"audio_play_music('%s', '%s')", tag, pretty_alt_tag);
558 log_verbose(
"Neither of tags %s or %s found", tag, pretty_alt_tag);
668 static char buffer[100];
void audio_restart(const char *soundset_name, const char *musicset_name)
static void music_finished_callback(void)
static struct audio_plugin plugins[MAX_NUM_PLUGINS]
void audio_play_track(const char *const tag, char *const alt_tag)
static void real_audio_play_music(const char *const tag, char *const alt_tag, bool keep_old_style)
static bool audio_play_sound_tag(const char *tag, bool repeat)
static enum music_usage current_usage
static int selected_plugin
void audio_play_music(const char *const tag, char *const alt_tag, enum music_usage usage)
static const char * audiospec_fullname(const char *audioset_name, bool music)
void audio_shutdown(bool play_quit_tag)
const char * audio_get_all_plugin_names(void)
void audio_stop_usage(void)
void audio_play_sound(const char *const tag, const char *const alt_tag)
bool audio_select_plugin(const char *const name)
static struct section_file * ss_tagfile
static int audio_play_music_tag(const char *tag, bool repeat, bool keep_old_style)
static const struct strvec * get_audio_speclist(const char *suffix, struct strvec **audio_list)
static bool check_audiofile_capstr(struct section_file *sfile, const char *filename, const char *our_cap, const char *opt_path)
void audio_set_volume(double volume)
const struct strvec * get_musicset_list(const struct option *poption)
static int audio_play_tag(struct section_file *sfile, const char *tag, bool repeat, int exclude, bool keep_old_style)
double audio_get_volume(void)
void audio_add_plugin(struct audio_plugin *p)
const struct strvec * get_soundset_list(const struct option *poption)
static bool let_single_track_play
static struct section_file * ms_tagfile
static void audio_shutdown_atexit(void)
static struct mfcb_data mfcb
static int num_plugins_used
const struct strvec * get_soundplugin_list(const struct option *poption)
static bool switching_usage
void audio_real_init(const char *const soundset_name, const char *const musicset_name, const char *const preferred_plugin_name)
void(* audio_finished_callback)(void)
#define MAX_ALT_AUDIO_FILES
void audio_none_init(void)
void audio_sdl_init(void)
bool has_capabilities(const char *us, const char *them)
char sound_plugin_name[512]
#define fc_assert_ret(condition)
#define log_verbose(message,...)
#define log_fatal(message,...)
#define log_debug(message,...)
#define log_normal(message,...)
#define log_error(message,...)
struct client_options gui_options
struct section_file * secfile_load(const char *filename, bool allow_duplicates)
const char * secfile_error(void)
void secfile_destroy(struct section_file *secfile)
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
const char * fileinfoname(const struct strvec *dirs, const char *filename)
struct strvec * fileinfolist(const struct strvec *dirs, const char *suffix)
const struct strvec * get_data_dirs(void)
bool strvec_set(struct strvec *psv, size_t svindex, const char *string)
void strvec_reserve(struct strvec *psv, size_t reserve)
struct strvec * strvec_new(void)
void(* set_volume)(double volume)
double(* get_volume)(void)
void(* shutdown)(struct audio_plugin *self)
bool sound_enable_menu_music
bool sound_enable_effects
bool sound_enable_game_music
struct section_file * sfile
bool are_support_services_available(void)
#define sz_strlcpy(dest, src)
#define sz_strlcat(dest, src)