--- deliantra/Deliantra-Client/DC/Audio.pm 2012/01/18 00:51:23 1.1 +++ deliantra/Deliantra-Client/DC/Audio.pm 2013/05/01 20:38:50 1.3 @@ -19,14 +19,14 @@ our $SDL_MIXER; -sub init { +sub init() { unless ($::SDL_MIXER) { if (length $::CFG->{audio_driver}) { local $ENV{SDL_AUDIODRIVER} = $::CFG->{audio_driver}; - DC::SDL_Init DC::SDL_INIT_AUDIO + DC::SDL_InitSubSystem DC::SDL_INIT_AUDIO and die "SDL::Init failed!\n"; } else { - DC::SDL_Init DC::SDL_INIT_AUDIO + DC::SDL_InitSubSystem DC::SDL_INIT_AUDIO and die "SDL::Init failed!\n"; } @@ -42,6 +42,42 @@ } } +sub _probe { + my $pid = fork; + + return 1 unless defined $pid; + + unless ($pid) { + eval { + DC::SDL_Init DC::SDL_INIT_NOPARACHUTE; + init; + }; + DC::_exit $@ ? 1 : 0; + } + + waitpid $pid, 0 + and !$? +} + +sub probe { + return unless $^O eq "linux"; + + # on linux, both alsa and pulse (especially the latter) + # are prone to segfaults, while the other interfaces are + # simply unreliable. + + # let's check whether the default config and a few others segfault, + # then decide + + return if _probe; # user selected config + $::CFG->{audio_driver} = "" ; return if _probe; # default sdl config + $::CFG->{audio_driver} = "pulse"; return if _probe; + $::CFG->{audio_driver} = "alsa" ; return if _probe; + $::CFG->{audio_driver} = "esd" ; return if _probe; + $::CFG->{audio_driver} = "dsp" ; return if _probe; + $::CFG->{audio_driver} = "none" ; +} + 1; =back