… | |
… | |
113 | our $CONN; |
113 | our $CONN; |
114 | our $PROFILE; # current profile |
114 | our $PROFILE; # current profile |
115 | our $FAST; # fast, low-quality mode, possibly useful for software-rendering |
115 | our $FAST; # fast, low-quality mode, possibly useful for software-rendering |
116 | |
116 | |
117 | our $WANT_REFRESH; |
117 | our $WANT_REFRESH; |
118 | our $CAN_REFRESH; |
|
|
119 | |
118 | |
120 | our @SDL_MODES; |
119 | our @SDL_MODES; |
121 | our $WIDTH; |
120 | our $WIDTH; |
122 | our $HEIGHT; |
121 | our $HEIGHT; |
123 | our $FULLSCREEN; |
122 | our $FULLSCREEN; |
… | |
… | |
217 | my ($face) = @_; |
216 | my ($face) = @_; |
218 | |
217 | |
219 | $CFG->{effects_enable} |
218 | $CFG->{effects_enable} |
220 | or return; |
219 | or return; |
221 | |
220 | |
|
|
221 | $AUDIO_PLAY{$face} |
|
|
222 | or return; |
|
|
223 | |
222 | if (my $chunk = $AUDIO_CHUNK{$face}) { |
224 | if (my $chunk = $AUDIO_CHUNK{$face}) { |
223 | for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) { |
225 | for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) { |
224 | my (undef, $dx, $dy, $vol) = @$_; |
226 | my (undef, $dx, $dy, $vol) = @$_; |
225 | |
227 | |
226 | my $channel = CFPlus::Channel::find; |
228 | my $channel = CFPlus::Channel::find; |
227 | $channel->volume ($vol * $CFG->{effects_volume} * 128 / 255); |
229 | $channel->volume ($vol * $CFG->{effects_volume} * 128 / 255); |
228 | $dx = $dx / 10 * 255; |
|
|
229 | $channel->set_panning (255 - $dx, 255 + $dx); |
|
|
230 | |
|
|
231 | # my $angle = $dx ? : $dx < 0 ? |
|
|
232 | # my $distance = -$vol; |
|
|
233 | # $channel->set_position ($angle, $distance); |
230 | $channel->set_position_r ($dx, $dy, 20); |
234 | |
|
|
235 | $chunk->play ($channel); |
231 | $chunk->play ($channel); |
236 | } |
232 | } |
237 | } else { |
233 | } else { |
238 | # sound_meta not set means data is in flight either way |
234 | # sound_meta not set means data is in flight either way |
239 | my $meta = $CONN->{sound_meta}{$face} |
235 | my $meta = $CONN->{sound_meta}{$face} |
… | |
… | |
248 | } else { |
244 | } else { |
249 | # fetch from database |
245 | # fetch from database |
250 | CFPlus::DB::get res_data => $meta->{name}, sub { |
246 | CFPlus::DB::get res_data => $meta->{name}, sub { |
251 | my $rwops = new CFPlus::RW $_[0]; |
247 | my $rwops = new CFPlus::RW $_[0]; |
252 | my $chunk = new CFPlus::MixChunk $rwops |
248 | my $chunk = new CFPlus::MixChunk $rwops |
253 | or Carp::confess "sound face $meta->{face} unloadable: " . CFPlus::Mix_GetError; |
249 | or Carp::confess "sound face " . (JSON::XS::to_json $meta) . " unloadable: " . CFPlus::Mix_GetError; |
254 | $chunk->volume (($meta->{meta}{volume} || 1) * 128); |
250 | $chunk->volume (($meta->{meta}{volume} || 1) * 128); |
255 | $AUDIO_CHUNK{$face} = $chunk; |
251 | $AUDIO_CHUNK{$face} = $chunk; |
256 | |
252 | |
257 | audio_sound_push ($face); |
253 | audio_sound_push ($face); |
258 | }; |
254 | }; |
… | |
… | |
877 | # $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Effects Volume"); |
873 | # $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Effects Volume"); |
878 | # $table->add_at (1, 8, new CFPlus::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub { |
874 | # $table->add_at (1, 8, new CFPlus::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub { |
879 | # $CFG->{effects_volume} = $_[1]; |
875 | # $CFG->{effects_volume} = $_[1]; |
880 | # }); |
876 | # }); |
881 | |
877 | |
882 | $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Effects Volume"); |
878 | $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Sound Effects"); |
883 | $table->add_at (1, $row, new CFPlus::UI::CheckBox |
879 | $table->add_at (1, $row, new CFPlus::UI::CheckBox |
884 | expand => 1, state => $CFG->{effects_enable}, |
880 | expand => 1, state => $CFG->{effects_enable}, |
885 | tooltip => "If enabled, sound effects are enabled. If disabled, no sound effects will be played.", |
881 | tooltip => "If enabled, sound effects are enabled. If disabled, no sound effects will be played.", |
|
|
882 | on_changed => sub { |
886 | on_changed => sub { $CFG->{effects_enable} = $_[1]; 0 } |
883 | $CFG->{effects_enable} = $_[1]; |
|
|
884 | $CONN->update_fx_want if $CONN; |
|
|
885 | 0 |
|
|
886 | } |
887 | ); |
887 | ); |
888 | $table->add_at (2, $row++, new CFPlus::UI::Slider |
888 | $table->add_at (2, $row++, new CFPlus::UI::Slider |
889 | expand => 1, range => [$CFG->{effects_volume}, 0, 1, 0, 1/128], |
889 | expand => 1, range => [$CFG->{effects_volume}, 0, 1, 0, 1/128], |
890 | tooltip => "The relative volume of sound effects. Best audio quality is achieved if this " |
890 | tooltip => "The relative volume of sound effects. Best audio quality is achieved if this " |
891 | . "is set highest and you use your operating system volume setting. Changes are instant.", |
891 | . "is set highest (rightmost) and you use your operating system volume setting. Changes are instant.", |
892 | on_changed => sub { $CFG->{effects_volume} = $_[1]; 0 } |
892 | on_changed => sub { $CFG->{effects_volume} = $_[1]; 0 } |
893 | ); |
893 | ); |
894 | |
894 | |
895 | $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Background Music"); |
895 | $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Background Music"); |
896 | $table->add_at (1, $row, new CFPlus::UI::CheckBox |
896 | $table->add_at (1, $row, new CFPlus::UI::CheckBox |
897 | expand => 1, state => $CFG->{bgm_enable}, |
897 | expand => 1, state => $CFG->{bgm_enable}, |
898 | tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.", |
898 | tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.", |
899 | on_changed => sub { $CFG->{bgm_enable} = $_[1]; 0 } |
899 | on_changed => sub { |
|
|
900 | $CFG->{bgm_enable} = $_[1]; |
|
|
901 | $CONN->update_fx_want if $CONN; |
|
|
902 | 0 |
|
|
903 | } |
900 | ); |
904 | ); |
901 | $table->add_at (2, $row++, new CFPlus::UI::Slider |
905 | $table->add_at (2, $row++, new CFPlus::UI::Slider |
902 | expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128], |
906 | expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128], |
903 | tooltip => "The volume of the background music. Changes are instant.", |
907 | tooltip => "The volume of the background music. Changes are instant.", |
904 | on_changed => sub { $CFG->{bgm_volume} = $_[1]; audio_music_update_volume; 0 } |
908 | on_changed => sub { $CFG->{bgm_volume} = $_[1]; audio_music_update_volume; 0 } |
… | |
… | |
2087 | my $animate_timer; |
2091 | my $animate_timer; |
2088 | |
2092 | |
2089 | my $fps = 9; |
2093 | my $fps = 9; |
2090 | |
2094 | |
2091 | sub force_refresh { |
2095 | sub force_refresh { |
|
|
2096 | if ($ENV{CFPLUS_DEBUG} & 4) { |
2092 | $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05; |
2097 | $fps = $fps * 0.98 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.02; |
2093 | debug sprintf "%3.2f", $fps if $ENV{CFPLUS_DEBUG} & 4; |
2098 | debug sprintf "%3.2f", $fps; |
|
|
2099 | } |
2094 | |
2100 | |
2095 | $CFPlus::UI::ROOT->draw; |
2101 | $CFPlus::UI::ROOT->draw; |
2096 | |
2102 | CFPlus::SDL_GL_SwapBuffers; |
2097 | $WANT_REFRESH = 0; |
|
|
2098 | $CAN_REFRESH = 0; |
|
|
2099 | $LAST_REFRESH = $NOW; |
2103 | $LAST_REFRESH = $NOW; |
2100 | |
2104 | $WANT_REFRESH->stop; |
2101 | CFPlus::SDL_GL_SwapBuffers; |
|
|
2102 | } |
2105 | } |
2103 | |
2106 | |
|
|
2107 | $WANT_REFRESH = Event->idle (min => 0.001, max => 0.06, parked => 1, cb => \&force_refresh); |
|
|
2108 | |
2104 | my $refresh_watcher = Event->timer (after => 0, hard => 0, interval => 1 / $MAX_FPS, cb => sub { |
2109 | my $input = Event->timer (after => 0, hard => 0, interval => 1 / 50, cb => sub { |
2105 | $NOW = time; |
2110 | $NOW = time; |
2106 | |
2111 | |
2107 | ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_) |
2112 | ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_) |
2108 | for CFPlus::poll_events; |
2113 | for CFPlus::poll_events; |
2109 | |
2114 | |
2110 | if (%animate_object) { |
2115 | if (%animate_object) { |
2111 | $_->animate ($LAST_REFRESH - $NOW) for values %animate_object; |
2116 | $_->animate ($LAST_REFRESH - $NOW) for values %animate_object; |
2112 | ++$WANT_REFRESH; |
2117 | $WANT_REFRESH->start; |
2113 | } |
|
|
2114 | |
|
|
2115 | if ($WANT_REFRESH) { |
|
|
2116 | force_refresh; |
|
|
2117 | } else { |
|
|
2118 | $CAN_REFRESH = 1; |
|
|
2119 | } |
2118 | } |
2120 | }); |
2119 | }); |
2121 | |
2120 | |
2122 | sub animation_start { |
2121 | sub animation_start { |
2123 | my ($widget) = @_; |
2122 | my ($widget) = @_; |