… | |
… | |
71 | unshift @INC, $ENV{PAR_TEMP} |
71 | unshift @INC, $ENV{PAR_TEMP} |
72 | if %PAR::LibCache; |
72 | if %PAR::LibCache; |
73 | |
73 | |
74 | use Time::HiRes 'time'; |
74 | use Time::HiRes 'time'; |
75 | use Event; |
75 | use Event; |
|
|
76 | use List::Util qw(max min); |
76 | |
77 | |
77 | use Crossfire; |
78 | use Crossfire; |
78 | use Crossfire::Protocol::Constants; |
79 | use Crossfire::Protocol::Constants; |
79 | |
80 | |
80 | use Compress::LZF; |
81 | use Compress::LZF; |
… | |
… | |
459 | mapmap => $MAPMAP, |
460 | mapmap => $MAPMAP, |
460 | query => \&server_query, |
461 | query => \&server_query, |
461 | |
462 | |
462 | setup_req => { |
463 | setup_req => { |
463 | smoothing => $CFG->{map_smoothing}*1, |
464 | smoothing => $CFG->{map_smoothing}*1, |
464 | }, |
|
|
465 | |
|
|
466 | sound_play => sub { |
|
|
467 | my ($x, $y, $soundnum, $type) = @_; |
|
|
468 | |
|
|
469 | $SDL_MIXER |
|
|
470 | or return; |
|
|
471 | |
|
|
472 | my $chunk = $AUDIO_CHUNKS{$SOUNDS[$soundnum]} |
|
|
473 | or return; |
|
|
474 | |
|
|
475 | $chunk->play; |
|
|
476 | }, |
465 | }, |
477 | }; |
466 | }; |
478 | |
467 | |
479 | if ($CONN) { |
468 | if ($CONN) { |
480 | CFPlus::lowdelay fileno $CONN->{fh}; |
469 | CFPlus::lowdelay fileno $CONN->{fh}; |
… | |
… | |
1800 | } |
1789 | } |
1801 | |
1790 | |
1802 | sub audio_channel_finished { |
1791 | sub audio_channel_finished { |
1803 | my ($channel) = @_; |
1792 | my ($channel) = @_; |
1804 | |
1793 | |
1805 | #warn "channel $channel finished\n";#d# |
1794 | # warn "channel $channel finished\n";#d# |
|
|
1795 | } |
|
|
1796 | |
|
|
1797 | our %AUDIO_PLAY; |
|
|
1798 | our %AUDIO_CHUNK; |
|
|
1799 | |
|
|
1800 | sub audio_sound_push($) { |
|
|
1801 | my ($face) = @_; |
|
|
1802 | |
|
|
1803 | if (my $chunk = $AUDIO_CHUNK{$face}) { |
|
|
1804 | for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) { |
|
|
1805 | my (undef, $dx, $dy, $vol) = @$_; |
|
|
1806 | |
|
|
1807 | my $channel = $chunk->play |
|
|
1808 | or return; |
|
|
1809 | |
|
|
1810 | $channel->volume (128 + $vol); |
|
|
1811 | $dx = $dx / 10 * 255; |
|
|
1812 | $channel->set_panning ((min 255, 255 - $dx), (min 255, 255 + $dx)); |
|
|
1813 | # my $angle = $dx ? : $dx < 0 ? |
|
|
1814 | # my $distance = -$vol; |
|
|
1815 | # $channel->set_position ($angle, $distance); |
|
|
1816 | } |
|
|
1817 | } else { |
|
|
1818 | # sound_meta not set means data is in flight either way |
|
|
1819 | my $meta = $CONN->{sound_meta}{$face} |
|
|
1820 | or return; |
|
|
1821 | |
|
|
1822 | # fetch from database |
|
|
1823 | CFPlus::DB::get res_data => $meta->{name}, sub { |
|
|
1824 | my $vol = $meta->{meta}{volume} || 100; |
|
|
1825 | my $rwops = new CFPlus::RW $_[0]; |
|
|
1826 | my $chunk = new CFPlus::MixChunk $rwops; |
|
|
1827 | $chunk->volume ($vol * 128 / 100); |
|
|
1828 | $AUDIO_CHUNK{$face} = $chunk; |
|
|
1829 | |
|
|
1830 | audio_sound_push ($face); |
|
|
1831 | }; |
|
|
1832 | } |
|
|
1833 | } |
|
|
1834 | |
|
|
1835 | sub audio_sound_play { |
|
|
1836 | my ($face, $dx, $dy, $vol) = @_; |
|
|
1837 | |
|
|
1838 | $SDL_MIXER |
|
|
1839 | or return; |
|
|
1840 | |
|
|
1841 | my $queue = $AUDIO_PLAY{$face} ||= []; |
|
|
1842 | push @$queue, [Event::time + 0.2, $dx, $dy, $vol]; # delay sound by max. 0.2s |
|
|
1843 | audio_sound_push $face |
|
|
1844 | unless @$queue > 1; |
1806 | } |
1845 | } |
1807 | |
1846 | |
1808 | sub audio_music_set { |
1847 | sub audio_music_set { |
1809 | my ($songs) = @_; |
1848 | my ($songs) = @_; |
1810 | |
1849 | |
… | |
… | |
1894 | audio_music_changed; |
1933 | audio_music_changed; |
1895 | } |
1934 | } |
1896 | |
1935 | |
1897 | sub audio_init { |
1936 | sub audio_init { |
1898 | if ($CFG->{audio_enable}) { |
1937 | if ($CFG->{audio_enable}) { |
1899 | if (open my $fh, "<", CFPlus::find_rcfile "sounds/config") { |
|
|
1900 | $ENV{MIX_EFFECTSMAXSPEED} = 1; |
1938 | $ENV{MIX_EFFECTSMAXSPEED} = 1; |
1901 | $SDL_MIXER = !CFPlus::Mix_OpenAudio; |
1939 | $SDL_MIXER = !CFPlus::Mix_OpenAudio; |
1902 | |
1940 | |
1903 | unless ($SDL_MIXER) { |
1941 | unless ($SDL_MIXER) { |
1904 | status "Unable to open sound device: there will be no sound"; |
1942 | status "Unable to open sound device: there will be no sound"; |
1905 | return; |
1943 | return; |
1906 | } |
|
|
1907 | |
|
|
1908 | CFPlus::Mix_AllocateChannels 8; |
|
|
1909 | CFPlus::MixMusic::volume $CFG->{bgm_volume} * 128; |
|
|
1910 | |
|
|
1911 | audio_music_finished; |
|
|
1912 | |
|
|
1913 | local $_; |
|
|
1914 | while (<$fh>) { |
|
|
1915 | next if /^\s*#/; |
|
|
1916 | next if /^\s*$/; |
|
|
1917 | |
|
|
1918 | my ($file, $volume, $event) = split /\s+/, $_, 3; |
|
|
1919 | |
|
|
1920 | push @SOUNDS, "$volume,$file"; |
|
|
1921 | |
|
|
1922 | $AUDIO_CHUNKS{"$volume,$file"} ||= do { |
|
|
1923 | my $rwops = new_from_file CFPlus::RW CFPlus::find_rcfile "sounds/$file"; |
|
|
1924 | my $chunk = new CFPlus::MixChunk $rwops; |
|
|
1925 | $chunk->volume ($volume * 128 / 100); |
|
|
1926 | $chunk |
|
|
1927 | }; |
|
|
1928 | } |
|
|
1929 | } else { |
|
|
1930 | status "unable to open sound config: $!"; |
|
|
1931 | } |
1944 | } |
|
|
1945 | |
|
|
1946 | CFPlus::Mix_AllocateChannels 16; |
|
|
1947 | CFPlus::MixMusic::volume $CFG->{bgm_volume} * 128; |
|
|
1948 | |
|
|
1949 | audio_music_finished; |
1932 | } else { |
1950 | } else { |
1933 | undef $SDL_MIXER; |
1951 | undef $SDL_MIXER; |
1934 | } |
1952 | } |
1935 | } |
1953 | } |
1936 | |
1954 | |