ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/bin/cfplus
(Generate patch)

Comparing deliantra/Deliantra-Client/bin/cfplus (file contents):
Revision 1.198 by root, Tue Jul 31 02:45:39 2007 UTC vs.
Revision 1.207 by root, Thu Aug 9 11:02:08 2007 UTC

144our $SETUP_KEYBOARD; 144our $SETUP_KEYBOARD;
145 145
146our $PL_NOTEBOOK; 146our $PL_NOTEBOOK;
147our $PL_WINDOW; 147our $PL_WINDOW;
148 148
149our $MUSIC_PLAYING_WIDGET;
150our $LICENSE_WIDGET;
151
149our $INVENTORY_PAGE; 152our $INVENTORY_PAGE;
150our $STATS_PAGE; 153our $STATS_PAGE;
151our $SKILL_PAGE; 154our $SKILL_PAGE;
152our $SPELL_PAGE; 155our $SPELL_PAGE;
153our $SPELL_LIST; 156our $SPELL_LIST;
211} 214}
212 215
213sub audio_sound_push($) { 216sub audio_sound_push($) {
214 my ($face) = @_; 217 my ($face) = @_;
215 218
219 $CFG->{effects_enable}
220 or return;
221
222 $AUDIO_PLAY{$face}
223 or return;
224
216 if (my $chunk = $AUDIO_CHUNK{$face}) { 225 if (my $chunk = $AUDIO_CHUNK{$face}) {
217 for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) { 226 for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) {
218 my (undef, $dx, $dy, $vol) = @$_; 227 my (undef, $dx, $dy, $vol) = @$_;
219 228
220 my $channel = CFPlus::Channel::find; 229 my $channel = CFPlus::Channel::find;
221 $channel->volume ($vol * 128 / 255); 230 $channel->volume ($vol * $CFG->{effects_volume} * 128 / 255);
222 $dx = $dx / 10 * 255;
223 $channel->set_panning (255 - $dx, 255 + $dx);
224
225# my $angle = $dx ? : $dx < 0 ?
226# my $distance = -$vol;
227# $channel->set_position ($angle, $distance); 231 $channel->set_position_r ($dx, $dy, 20);
228
229 $chunk->play ($channel); 232 $chunk->play ($channel);
230 } 233 }
231 } else { 234 } else {
232 # sound_meta not set means data is in flight either way 235 # sound_meta not set means data is in flight either way
233 my $meta = $CONN->{sound_meta}{$face} 236 my $meta = $CONN->{sound_meta}{$face}
234 or return; 237 or return;
235 238
236 # if its a jingle, play it as ambient music 239 # if its a jingle, play it as ambient music
237 if ($meta->{meta}{jingle}) { 240 if ($meta->{meta}{jingle}) {
238 delete $AUDIO_PLAY{$face}; # take the jingle out of the sound queue 241 if (delete $AUDIO_PLAY{$face}) { # take the jingle out of the sound queue
239 push @MUSIC_JINGLE, $meta; # push it oto the music/jingle queue 242 push @MUSIC_JINGLE, $meta; # push it oto the music/jingle queue
240 &audio_music_push ($face); 243 &audio_music_push ($face);
244 }
241 } else { 245 } else {
242 # fetch from database 246 # fetch from database
243 CFPlus::DB::get res_data => $meta->{name}, sub { 247 CFPlus::DB::get res_data => $meta->{name}, sub {
244 my $rwops = new CFPlus::RW $_[0]; 248 my $rwops = new CFPlus::RW $_[0];
245 my $chunk = new CFPlus::MixChunk $rwops; 249 my $chunk = new CFPlus::MixChunk $rwops
250 or Carp::confess "sound face " . (JSON::XS::to_json $meta) . " unloadable: " . CFPlus::Mix_GetError;
246 $chunk->volume (($meta->{meta}{volume} || 1) * 128); 251 $chunk->volume (($meta->{meta}{volume} || 1) * 128);
247 $AUDIO_CHUNK{$face} = $chunk; 252 $AUDIO_CHUNK{$face} = $chunk;
248 253
249 audio_sound_push ($face); 254 audio_sound_push ($face);
250 }; 255 };
254 259
255sub audio_sound_play { 260sub audio_sound_play {
256 my ($face, $dx, $dy, $vol) = @_; 261 my ($face, $dx, $dy, $vol) = @_;
257 262
258 $SDL_MIXER 263 $SDL_MIXER
264 or return;
265 $CFG->{effects_enable}
259 or return; 266 or return;
260 267
261 my $queue = $AUDIO_PLAY{$face} ||= []; 268 my $queue = $AUDIO_PLAY{$face} ||= [];
262 push @$queue, [Event::time + 0.2, $dx, $dy, $vol]; # delay sound by max. 0.2s 269 push @$queue, [Event::time + 0.2, $dx, $dy, $vol]; # delay sound by max. 0.2s
263 audio_sound_push $face 270 audio_sound_push $face
264 unless @$queue > 1; 271 unless @$queue > 1;
272}
273
274sub audio_music_set_meta {
275 my ($meta) = @_;
276
277 $MUSIC_PLAYING_META = $meta;
278 $MUSIC_PLAYING_WIDGET->set_markup (
279 "<b>Name</b>: " . (CFPlus::asxml $meta->{meta}{name}) . "\n"
280 . "<b>Author</b>: " . (CFPlus::asxml $meta->{meta}{author}) . "\n"
281 . "<b>Source</b>: " . (CFPlus::asxml $meta->{meta}{source}) . "\n"
282 . "<b>License</b>: " . (CFPlus::asxml $meta->{meta}{license})
283 );
265} 284}
266 285
267sub audio_music_update_volume { 286sub audio_music_update_volume {
268 return unless $MUSIC_PLAYING_META; 287 return unless $MUSIC_PLAYING_META;
269 my $volume = $MUSIC_PLAYING_META->{meta}{volume} || 1; 288 my $volume = $MUSIC_PLAYING_META->{meta}{volume} || 1;
288 my $rwops = $meta->{path} 307 my $rwops = $meta->{path}
289 ? new_from_file CFPlus::RW $meta->{path} 308 ? new_from_file CFPlus::RW $meta->{path}
290 : new CFPlus::RW $$MUSIC_PLAYING_DATA; 309 : new CFPlus::RW $$MUSIC_PLAYING_DATA;
291 310
292 $MUSIC_PLAYER = new CFPlus::MixMusic $rwops 311 $MUSIC_PLAYER = new CFPlus::MixMusic $rwops
293 or ((warn CFPlus::Mix_GetError), return); # pretty fatal error 312 or Carp::confess "music face $meta->{face} unloadable: " . CFPlus::Mix_GetError;
294 313
295 my $NOW = time; 314 my $NOW = time;
296 315
297 if ($MUSIC_PLAYING_META->{stop_time} > $NOW - $MUSIC_RESUME) { 316 if ($MUSIC_PLAYING_META->{stop_time} > $NOW - $MUSIC_RESUME) {
298 my $pos = $MUSIC_PLAYING_META->{stop_pos}; 317 my $pos = $MUSIC_PLAYING_META->{stop_pos};
301 } else { 320 } else {
302 $MUSIC_PLAYER->play (0); 321 $MUSIC_PLAYER->play (0);
303 $MUSIC_START = time; 322 $MUSIC_START = time;
304 } 323 }
305 324
306 delete $MUSIC_PLAYING_META->{stop_time}; 325 delete $meta->{stop_time};
307 delete $MUSIC_PLAYING_META->{stop_pos}; 326 delete $meta->{stop_pos};
308 } 327 }
309} 328}
310 329
311sub audio_music_push { 330sub audio_music_push {
312 return unless $SDL_MIXER; 331 return unless $SDL_MIXER;
331 @MUSIC_HAVE = { path => CFPlus::find_rcfile "music/$MUSIC_DEFAULT" } unless @MUSIC_HAVE; 350 @MUSIC_HAVE = { path => CFPlus::find_rcfile "music/$MUSIC_DEFAULT" } unless @MUSIC_HAVE;
332 $fade_out = 1000; 351 $fade_out = 1000;
333 } 352 }
334 353
335 # if the currently playing song is acceptable, let it continue 354 # if the currently playing song is acceptable, let it continue
336 return if $MUSIC_PLAYING_META
337 && grep $MUSIC_PLAYING_META == $_, @MUSIC_HAVE; 355 return if grep $MUSIC_PLAYING_META == $_, @MUSIC_HAVE;
338 356
339 my $NOW = time; 357 my $NOW = time;
340 358
341 if ($MUSIC_PLAYING_META) { 359 if ($MUSIC_PLAYING_META) {
342 $MUSIC_PLAYING_META->{stop_time} = $NOW; 360 $MUSIC_PLAYING_META->{stop_time} = $NOW;
346 # sort by stop time, oldest first 364 # sort by stop time, oldest first
347 @MUSIC_HAVE = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_HAVE; 365 @MUSIC_HAVE = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_HAVE;
348 366
349 # if the most recently-played piece played very recently, 367 # if the most recently-played piece played very recently,
350 # resume it, else choose the oldest piece for rotation. 368 # resume it, else choose the oldest piece for rotation.
351 $MUSIC_PLAYING_META = 369 audio_music_set_meta
352 $MUSIC_HAVE[-1]{stop_time} > $NOW - $MUSIC_RESUME 370 $MUSIC_HAVE[-1]{stop_time} > $NOW - $MUSIC_RESUME
353 ? $MUSIC_HAVE[-1] 371 ? $MUSIC_HAVE[-1]
354 : $MUSIC_HAVE[0]; 372 : $MUSIC_HAVE[0];
355 373
356 audio_music_start; 374 audio_music_start;
366 384
367sub audio_music_finished { 385sub audio_music_finished {
368 # we compress multiple jingles of the same type 386 # we compress multiple jingles of the same type
369 shift @MUSIC_JINGLE 387 shift @MUSIC_JINGLE
370 while @MUSIC_JINGLE && $MUSIC_PLAYING_META == $MUSIC_JINGLE[0]; 388 while @MUSIC_JINGLE && $MUSIC_PLAYING_META == $MUSIC_JINGLE[0];
389
390 $MUSIC_PLAYING_WIDGET->clear;
371 391
372 undef $MUSIC_PLAYER; 392 undef $MUSIC_PLAYER;
373 undef $MUSIC_PLAYING_META; 393 undef $MUSIC_PLAYING_META;
374 undef $MUSIC_PLAYING_DATA; 394 undef $MUSIC_PLAYING_DATA;
375 395
839} 859}
840 860
841sub audio_setup { 861sub audio_setup {
842 my $vbox = new CFPlus::UI::VBox; 862 my $vbox = new CFPlus::UI::VBox;
843 863
844 $vbox->add (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 1]); 864 $vbox->add (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 0, 1]);
845 865
846 my $row = 0; 866 my $row = 0;
847 867
848 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Audio Enable"); 868 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Audio Enable");
849 $table->add_at (1, $row++, new CFPlus::UI::CheckBox 869 $table->add_at (1, $row++, new CFPlus::UI::CheckBox
853 ); 873 );
854# $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Effects Volume"); 874# $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Effects Volume");
855# $table->add_at (1, 8, new CFPlus::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub { 875# $table->add_at (1, 8, new CFPlus::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub {
856# $CFG->{effects_volume} = $_[1]; 876# $CFG->{effects_volume} = $_[1];
857# }); 877# });
878
879 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Sound Effects");
880 $table->add_at (1, $row, new CFPlus::UI::CheckBox
881 expand => 1, state => $CFG->{effects_enable},
882 tooltip => "If enabled, sound effects are enabled. If disabled, no sound effects will be played.",
883 on_changed => sub {
884 $CFG->{effects_enable} = $_[1];
885 $CONN->update_fx_want if $CONN;
886 0
887 }
888 );
889 $table->add_at (2, $row++, new CFPlus::UI::Slider
890 expand => 1, range => [$CFG->{effects_volume}, 0, 1, 0, 1/128],
891 tooltip => "The relative volume of sound effects. Best audio quality is achieved if this "
892 . "is set highest (rightmost) and you use your operating system volume setting. Changes are instant.",
893 on_changed => sub { $CFG->{effects_volume} = $_[1]; 0 }
894 );
895
858 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Background Music"); 896 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Background Music");
859 $table->add_at (1, $row++, my $hbox = new CFPlus::UI::HBox); 897 $table->add_at (1, $row, new CFPlus::UI::CheckBox
860 $hbox->add (new CFPlus::UI::CheckBox
861 expand => 1, state => $CFG->{bgm_enable}, 898 expand => 1, state => $CFG->{bgm_enable},
862 tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.", 899 tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.",
863 on_changed => sub { $CFG->{bgm_enable} = $_[1]; 0 } 900 on_changed => sub {
901 $CFG->{bgm_enable} = $_[1];
902 $CONN->update_fx_want if $CONN;
903 0
904 }
864 ); 905 );
865 $hbox->add (new CFPlus::UI::Slider 906 $table->add_at (2, $row++, new CFPlus::UI::Slider
866 expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128], 907 expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128],
867 tooltip => "The volume of the background music. Changes are instant.", 908 tooltip => "The volume of the background music. Changes are instant.",
868 on_changed => sub { $CFG->{bgm_volume} = $_[1]; audio_music_update_volume; 0 } 909 on_changed => sub { $CFG->{bgm_volume} = $_[1]; audio_music_update_volume; 0 }
869 ); 910 );
870 911
871 $table->add_at (1, $row++, new CFPlus::UI::Button 912 $table->add_at (1, $row++, new CFPlus::UI::Button
872 expand => 1, align => 0, text => "Apply", 913 c_colspan => 2, expand => 1, align => 0, text => "Apply",
873 tooltip => "Apply the audio settings", 914 tooltip => "Apply the audio settings",
874 on_activate => sub { 915 on_activate => sub {
875 audio_shutdown (); 916 audio_shutdown ();
876 audio_init (); 917 audio_init ();
877 0 918 0
948 $table->add_at (0, 4, new CFPlus::UI::Button text => "die on click(tm)", on_activate => sub { &CFPlus::debug() } ); 989 $table->add_at (0, 4, new CFPlus::UI::Button text => "die on click(tm)", on_activate => sub { &CFPlus::debug() } );
949 990
950 $table->add_at (0, 5, new CFPlus::UI::TextEdit text => "line1\0152\0153");#d# 991 $table->add_at (0, 5, new CFPlus::UI::TextEdit text => "line1\0152\0153");#d#
951 992
952 $table->add_at (7,7, my $t = new CFPlus::UI::Table expand => 0); 993 $table->add_at (7,7, my $t = new CFPlus::UI::Table expand => 0);
953 $t->add_at (0,0, new CFPlus::UI::Label text => "a a a a", rowspan => 1, colspan => 2); 994 $t->add_at (0,0, new CFPlus::UI::Label text => "a a a a", c_rowspan => 1, c_colspan => 2);
954 $t->add_at (2,0, new CFPlus::UI::Label text => "b\nb", rowspan => 2, colspan => 1); 995 $t->add_at (2,0, new CFPlus::UI::Label text => "b\nb", c_rowspan => 2, c_colspan => 1);
955 $t->add_at (1,2, new CFPlus::UI::Label text => "c c c c", rowspan => 1, colspan => 2); 996 $t->add_at (1,2, new CFPlus::UI::Label text => "c c c c", c_rowspan => 1, c_colspan => 2);
956 $t->add_at (0,1, new CFPlus::UI::Label text => "d\nd", rowspan => 2, colspan => 1); 997 $t->add_at (0,1, new CFPlus::UI::Label text => "d\nd", c_rowspan => 2, c_colspan => 1);
957 $t->add_at (1,1, new CFPlus::UI::Label text => "e"); 998 $t->add_at (1,1, new CFPlus::UI::Label text => "e");
958 999
959 $table->add_at (7, 6, my $c = new CFPlus::UI::Canvas); 1000 $table->add_at (7, 6, my $c = new CFPlus::UI::Canvas);
960 1001
961 $c->add_items ({ 1002 $c->add_items ({
1568 CFPlus::Protocol::set_opencont ($::CONN, 0, "Floor"); 1609 CFPlus::Protocol::set_opencont ($::CONN, 0, "Floor");
1569 1610
1570 $hb 1611 $hb
1571} 1612}
1572 1613
1614sub media_window {
1615 my $vb = new CFPlus::UI::VBox;
1616
1617 $vb->add (new CFPlus::UI::FancyFrame
1618 label => "Currently playing music",
1619 child => new CFPlus::UI::ScrolledWindow scroll_x => 1, scroll_y => 0,
1620 child => ($MUSIC_PLAYING_WIDGET = new CFPlus::UI::Label ellipsise => 0, fontsize => 0.8),
1621 );
1622
1623 $vb->add (new CFPlus::UI::FancyFrame
1624 label => "Other media used in this session",
1625 expand => 1,
1626 child => ($LICENSE_WIDGET = new CFPlus::UI::TextScroller
1627 expand => 1, fontsize => 0.8, padding_x => 4, padding_y => 4),
1628 );
1629
1630 $vb
1631}
1632
1633sub add_license {
1634 my ($meta) = @_;
1635
1636 $meta = $meta->{meta}
1637 or return;
1638
1639 $meta->{license} || $meta->{author} || $meta->{source}
1640 or return;
1641
1642 $LICENSE_WIDGET->add_paragraph ({
1643 fg => [1, 1, 1, 1],
1644 markup => "<small>"
1645 . "<b>Name:</b> " . (CFPlus::asxml $meta->{name}) . "\n"
1646 . "<b>Author:</b> " . (CFPlus::asxml $meta->{author}) . "\n"
1647 . "<b>Source:</b> " . (CFPlus::asxml $meta->{source}) . "\n"
1648 . "<b>License:</b> " . (CFPlus::asxml $meta->{license}) . "\n"
1649 . "</small>",
1650 });
1651 $LICENSE_WIDGET->scroll_to_bottom;
1652}
1653
1573sub toggle_player_page { 1654sub toggle_player_page {
1574 my ($widget) = @_; 1655 my ($widget) = @_;
1575 1656
1576 if ($PL_WINDOW->{visible} && $PL_NOTEBOOK->get_current_page == $widget) { 1657 if ($PL_WINDOW->{visible} && $PL_NOTEBOOK->get_current_page == $widget) {
1577 $PL_WINDOW->hide; 1658 $PL_WINDOW->hide;
1614 $ntb->add_tab ( 1695 $ntb->add_tab (
1615 "Inventory (F5)" => $INVENTORY_PAGE = inventory_widget, 1696 "Inventory (F5)" => $INVENTORY_PAGE = inventory_widget,
1616 "Toggles the inventory window, where you can manage your loot (or treasures :). " 1697 "Toggles the inventory window, where you can manage your loot (or treasures :). "
1617 . "You can also hit the <b>Tab</b>-key to show/hide the Inventory." 1698 . "You can also hit the <b>Tab</b>-key to show/hide the Inventory."
1618 ); 1699 );
1619 $ntb->add_tab (Pickup => autopickup_setup, 1700 $ntb->add_tab (Pickup => autopickup_setup,
1620 "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them."); 1701 "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them.");
1702
1703 $ntb->add_tab (Media => media_window,
1704 "License, Author and Source info for media sent by the server.");
1621 1705
1622 $ntb->set_current_page ($INVENTORY_PAGE); 1706 $ntb->set_current_page ($INVENTORY_PAGE);
1623 1707
1624 $plwin->add ($ntb); 1708 $plwin->add ($ntb);
1625 $plwin 1709 $plwin
2113 gauge_fontsize => 1, 2197 gauge_fontsize => 1,
2114 gauge_size => 0.35, 2198 gauge_size => 0.35,
2115 stat_fontsize => 0.7, 2199 stat_fontsize => 0.7,
2116 mapsize => 100, 2200 mapsize => 100,
2117 audio_enable => 1, 2201 audio_enable => 1,
2202 effects_enable => 1,
2203 effects_volume => 1,
2118 bgm_enable => 1, 2204 bgm_enable => 1,
2119 bgm_volume => 0.25, 2205 bgm_volume => 0.5,
2120 output_sync => 1, 2206 output_sync => 1,
2121 output_count => 1, 2207 output_count => 1,
2122 output_rate => "", 2208 output_rate => "",
2123 pickup => 0, 2209 pickup => 0,
2124 inv_sort => "mtime", 2210 inv_sort => "mtime",
2202Event::loop; 2288Event::loop;
2203#CFPlus::SDL_Quit; 2289#CFPlus::SDL_Quit;
2204#CFPlus::_exit 0; 2290#CFPlus::_exit 0;
2205 2291
2206END { 2292END {
2293 video_shutdown;
2294 audio_shutdown;
2207 CFPlus::SDL_Quit; 2295 CFPlus::SDL_Quit;
2208 CFPlus::DB::Server::stop; 2296 CFPlus::DB::Server::stop;
2209} 2297}
2210 2298
2211=head1 NAME 2299=head1 NAME
2212 2300
2213cfplus - A Crossfire+ and Crossfire game client 2301cfplus - A Crossfire TRT and Crossfire game client
2214 2302
2215=head1 SYNOPSIS 2303=head1 SYNOPSIS
2216 2304
2217Just run it - no commandline arguments are supported. 2305Just run it - no commandline arguments are supported.
2218 2306
2219=head1 USAGE 2307=head1 USAGE
2220 2308
2221cfplus utilises OpenGL for all UI elements and the game. It is supposed to be used 2309cfplus utilises OpenGL for all UI elements and the game. It is supposed to
2222fullscreen and interactively. 2310be used in fullscreen mode and interactively.
2223 2311
2224=head1 DEBUGGING 2312=head1 DEBUGGING
2225 2313
2226 2314
2227CFPLUS_DEBUG - environment variable 2315CFPLUS_DEBUG - environment variable

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines