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.187 by elmex, Fri Jul 27 18:04:43 2007 UTC vs.
Revision 1.214 by elmex, Tue Aug 14 14:12:46 2007 UTC

71unshift @INC, $ENV{PAR_TEMP} 71unshift @INC, $ENV{PAR_TEMP}
72 if %PAR::LibCache; 72 if %PAR::LibCache;
73 73
74use Time::HiRes 'time'; 74use Time::HiRes 'time';
75use Event; 75use Event;
76use List::Util qw(max min);
76 77
77use Crossfire; 78use Crossfire;
78use Crossfire::Protocol::Constants; 79use Crossfire::Protocol::Constants;
79 80
80use Compress::LZF; 81use Compress::LZF;
112our $CONN; 113our $CONN;
113our $PROFILE; # current profile 114our $PROFILE; # current profile
114our $FAST; # fast, low-quality mode, possibly useful for software-rendering 115our $FAST; # fast, low-quality mode, possibly useful for software-rendering
115 116
116our $WANT_REFRESH; 117our $WANT_REFRESH;
117our $CAN_REFRESH;
118 118
119our @SDL_MODES; 119our @SDL_MODES;
120our $WIDTH; 120our $WIDTH;
121our $HEIGHT; 121our $HEIGHT;
122our $FULLSCREEN; 122our $FULLSCREEN;
143our $SETUP_KEYBOARD; 143our $SETUP_KEYBOARD;
144 144
145our $PL_NOTEBOOK; 145our $PL_NOTEBOOK;
146our $PL_WINDOW; 146our $PL_WINDOW;
147 147
148our $MUSIC_PLAYING_WIDGET;
149our $LICENSE_WIDGET;
150
148our $INVENTORY_PAGE; 151our $INVENTORY_PAGE;
149our $STATS_PAGE; 152our $STATS_PAGE;
150our $SKILL_PAGE; 153our $SKILL_PAGE;
151our $SPELL_PAGE; 154our $SPELL_PAGE;
152our $SPELL_LIST; 155our $SPELL_LIST;
158our $STATWIDS; 161our $STATWIDS;
159 162
160our $SDL_ACTIVE; 163our $SDL_ACTIVE;
161our %SDL_CB; 164our %SDL_CB;
162 165
163our $SDL_MIXER;
164our $MUSIC_DEFAULT = "in_a_heartbeat.ogg";
165our @MUSIC_WANT;
166our $MUSIC_START;
167our $MUSIC_PLAYING;
168our $MUSIC_PLAYER;
169our $MUSIC_RESUME = 30; # resume music when players less than these many seconds before
170our @SOUNDS; # event => file mapping
171our %AUDIO_CHUNKS; # audio files
172
173our $ALT_ENTER_MESSAGE; 166our $ALT_ENTER_MESSAGE;
174our $STATUSBOX; 167our $STATUSBOX;
175our $DEBUG_STATUS; 168our $DEBUG_STATUS;
176 169
177our $INV; 170our $INV;
178our $INVR; 171our $INVR;
179our $INV_RIGHT_HB; 172our $INV_RIGHT_HB;
180 173
181our $PICKUP_CFG; 174our $PICKUP_CFG;
182 175
176#############################################################################
177
183sub status { 178sub status {
184 $STATUSBOX->add (CFPlus::asxml $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]); 179 $STATUSBOX->add (CFPlus::asxml $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]);
185} 180}
186 181
187sub debug { 182sub debug {
190 185
191sub message { 186sub message {
192 my ($para) = @_; 187 my ($para) = @_;
193 $MESSAGE_WINDOW->message ($para); 188 $MESSAGE_WINDOW->message ($para);
194} 189}
190
191#############################################################################
192#TODO: maybe move into own audio module...
193
194our $SDL_MIXER;
195
196our $MUSIC_DEFAULT = "in_a_heartbeat.ogg";
197our $MUSIC_WANT; # arryref of ambient music we want to play
198our @MUSIC_HAVE; # ambient music we have on disk
199our $MUSIC_START;
200our @MUSIC_JINGLE; # which jingles to play next
201our $MUSIC_PLAYING_DATA;
202our $MUSIC_PLAYING_META;
203our $MUSIC_PLAYER;
204our $MUSIC_RESUME = 30; # resume music when played less than these many seconds before
205
206our %AUDIO_CHUNK; # audio "files"
207our %AUDIO_PLAY; # which audio faces should be played
208
209sub audio_channel_finished {
210 my ($channel) = @_;
211
212# warn "channel $channel finished\n";#d#
213}
214
215sub audio_sound_push($) {
216 my ($face) = @_;
217
218 $CFG->{effects_enable}
219 or return;
220
221 $AUDIO_PLAY{$face}
222 or return;
223
224 if (my $chunk = $AUDIO_CHUNK{$face}) {
225 for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) {
226 my (undef, $dx, $dy, $vol) = @$_;
227
228 my $channel = CFPlus::Channel::find;
229 $channel->volume ($vol * $CFG->{effects_volume} * 128 / 255);
230 $channel->set_position_r ($dx, $dy, 20);
231 $chunk->play ($channel);
232 }
233 } else {
234 # sound_meta not set means data is in flight either way
235 my $meta = $CONN->{sound_meta}{$face}
236 or return;
237
238 # if its a jingle, play it as ambient music
239 if ($meta->{meta}{jingle}) {
240 if (delete $AUDIO_PLAY{$face}) { # take the jingle out of the sound queue
241 push @MUSIC_JINGLE, $meta; # push it oto the music/jingle queue
242 &audio_music_push ($face);
243 }
244 } else {
245 # fetch from database
246 CFPlus::DB::get res_data => $meta->{name}, sub {
247 my $rwops = new CFPlus::RW $_[0];
248 my $chunk = new CFPlus::MixChunk $rwops
249 or Carp::confess "sound face " . (JSON::XS::to_json $meta) . " unloadable: " . CFPlus::Mix_GetError;
250 $chunk->volume (($meta->{meta}{volume} || 1) * 128);
251 $AUDIO_CHUNK{$face} = $chunk;
252
253 audio_sound_push ($face);
254 };
255 }
256 }
257}
258
259sub audio_sound_play {
260 my ($face, $dx, $dy, $vol) = @_;
261
262 $SDL_MIXER
263 or return;
264 $CFG->{effects_enable}
265 or return;
266
267 my $queue = $AUDIO_PLAY{$face} ||= [];
268 push @$queue, [Event::time + 0.6, $dx, $dy, $vol]; # do not play sound for outdated events
269 audio_sound_push $face
270 unless @$queue > 1;
271}
272
273sub audio_music_set_meta {
274 my ($meta) = @_;
275
276 $MUSIC_PLAYING_META = $meta;
277 $MUSIC_PLAYING_WIDGET->set_markup (
278 "<b>Name</b>: " . (CFPlus::asxml $meta->{meta}{name}) . "\n"
279 . "<b>Author</b>: " . (CFPlus::asxml $meta->{meta}{author}) . "\n"
280 . "<b>Source</b>: " . (CFPlus::asxml $meta->{meta}{source}) . "\n"
281 . "<b>License</b>: " . (CFPlus::asxml $meta->{meta}{license})
282 );
283}
284
285sub audio_music_update_volume {
286 return unless $MUSIC_PLAYING_META;
287 my $volume = $MUSIC_PLAYING_META->{meta}{volume} || 1;
288 my $base = $MUSIC_PLAYING_META->{meta}{jingle} ? 1 : $CFG->{bgm_volume};
289 CFPlus::MixMusic::volume $base * $volume * 128;
290}
291
292sub audio_music_start {
293 my $meta = $MUSIC_PLAYING_META;
294
295 CFPlus::DB::get res_data => $meta->{name}, sub {
296 return unless $SDL_MIXER;
297
298 # music might have changed...
299 $meta eq $MUSIC_PLAYING_META
300 or return &audio_music_start ();
301
302 audio_music_update_volume;
303
304 $MUSIC_PLAYING_DATA = \$_[0];
305
306 my $rwops = $meta->{path}
307 ? new_from_file CFPlus::RW $meta->{path}
308 : new CFPlus::RW $$MUSIC_PLAYING_DATA;
309
310 $MUSIC_PLAYER = new CFPlus::MixMusic $rwops
311 or Carp::confess "music face $meta->{face} unloadable: " . CFPlus::Mix_GetError;
312
313 my $NOW = time;
314
315 if ($MUSIC_PLAYING_META->{stop_time} > $NOW - $MUSIC_RESUME) {
316 my $pos = $MUSIC_PLAYING_META->{stop_pos};
317 $MUSIC_PLAYER->fade_in_pos (0, 1000, $pos);
318 $MUSIC_START = time - $pos;
319 } else {
320 $MUSIC_PLAYER->play (0);
321 $MUSIC_START = time;
322 }
323
324 delete $meta->{stop_time};
325 delete $meta->{stop_pos};
326 }
327}
328
329sub audio_music_push {
330 return unless $SDL_MIXER;
331
332 my $fade_out;
333
334 if (@MUSIC_JINGLE) {
335 @MUSIC_HAVE = $MUSIC_JINGLE[0];
336 $fade_out = 333;
337 } else {
338 return unless $CFG->{bgm_enable};
339
340 my @have =
341 grep $_,
342 map $CONN->{music_meta}{$_},
343 @$MUSIC_WANT;
344
345 @MUSIC_HAVE = @have
346 if @have;
347
348 # default MUSIC_HAVE == MUSIC_DEFAULT
349 @MUSIC_HAVE = { path => CFPlus::find_rcfile "music/$MUSIC_DEFAULT" } unless @MUSIC_HAVE;
350 $fade_out = 1000;
351 }
352
353 # if the currently playing song is acceptable, let it continue
354 return if grep $MUSIC_PLAYING_META == $_, @MUSIC_HAVE;
355
356 my $NOW = time;
357
358 if ($MUSIC_PLAYING_META) {
359 $MUSIC_PLAYING_META->{stop_time} = $NOW;
360 $MUSIC_PLAYING_META->{stop_pos} = $NOW - $MUSIC_START;
361 CFPlus::MixMusic::fade_out $fade_out;
362 } else {
363 # sort by stop time, oldest first
364 @MUSIC_HAVE = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_HAVE;
365
366 # if the most recently-played piece played very recently,
367 # resume it, else choose the oldest piece for rotation.
368 audio_music_set_meta
369 $MUSIC_HAVE[-1]{stop_time} > $NOW - $MUSIC_RESUME
370 ? $MUSIC_HAVE[-1]
371 : $MUSIC_HAVE[0];
372
373 audio_music_start;
374 }
375}
376
377sub audio_music_set_ambient {
378 my ($songs) = @_;
379
380 $MUSIC_WANT = $songs;
381 audio_music_push;
382}
383
384sub audio_music_finished {
385 # we compress multiple jingles of the same type
386 shift @MUSIC_JINGLE
387 while @MUSIC_JINGLE && $MUSIC_PLAYING_META == $MUSIC_JINGLE[0];
388
389 $MUSIC_PLAYING_WIDGET->clear;
390
391 undef $MUSIC_PLAYER;
392 undef $MUSIC_PLAYING_META;
393 undef $MUSIC_PLAYING_DATA;
394
395 audio_music_push;
396}
397
398sub audio_init {
399 if ($CFG->{audio_enable}) {
400 $ENV{MIX_EFFECTSMAXSPEED} = 1;
401 $SDL_MIXER = !CFPlus::Mix_OpenAudio;
402
403 unless ($SDL_MIXER) {
404 status "Unable to open sound device: there will be no sound";
405 return;
406 }
407
408 CFPlus::Mix_AllocateChannels 16;
409
410 audio_music_finished;
411 } else {
412 undef $SDL_MIXER;
413 }
414}
415
416sub audio_shutdown {
417 undef $MUSIC_PLAYER;
418 undef $MUSIC_PLAYING_META;
419 undef $MUSIC_PLAYING_DATA;
420
421 $MUSIC_WANT = [];
422 @MUSIC_JINGLE = ();
423 %AUDIO_PLAY = ();
424 %AUDIO_CHUNK = ();
425
426 CFPlus::Mix_CloseAudio if $SDL_MIXER;
427 undef $SDL_MIXER;
428}
429
430#############################################################################
195 431
196sub destroy_query_dialog { 432sub destroy_query_dialog {
197 (delete $_[0]{query_dialog})->destroy 433 (delete $_[0]{query_dialog})->destroy
198 if $_[0]{query_dialog}; 434 if $_[0]{query_dialog};
199} 435}
459 query => \&server_query, 695 query => \&server_query,
460 696
461 setup_req => { 697 setup_req => {
462 smoothing => $CFG->{map_smoothing}*1, 698 smoothing => $CFG->{map_smoothing}*1,
463 }, 699 },
464
465 sound_play => sub {
466 my ($x, $y, $soundnum, $type) = @_;
467
468 $SDL_MIXER
469 or return;
470
471 my $chunk = $AUDIO_CHUNKS{$SOUNDS[$soundnum]}
472 or return;
473
474 $chunk->play;
475 },
476 }; 700 };
477 701
478 if ($CONN) { 702 if ($CONN) {
479 CFPlus::lowdelay fileno $CONN->{fh}; 703 CFPlus::lowdelay fileno $CONN->{fh};
480 704
491 $SETUP_DIALOG->show; 715 $SETUP_DIALOG->show;
492 $PL_WINDOW->hide; 716 $PL_WINDOW->hide;
493 $SPELL_LIST->clear_spells; 717 $SPELL_LIST->clear_spells;
494 $CFPlus::UI::ROOT->emit (stop_game => ! ! $CONN); 718 $CFPlus::UI::ROOT->emit (stop_game => ! ! $CONN);
495 719
496 &audio_music_set ([]); 720 &audio_music_set_ambient ([]);
497 721
498 return unless $CONN; 722 return unless $CONN;
499 723
500 status "connection closed"; 724 status "connection closed";
501 725
543 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Fullscreen"); 767 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Fullscreen");
544 $table->add_at (1, $row++, $FULLSCREEN_ENABLE = new CFPlus::UI::CheckBox 768 $table->add_at (1, $row++, $FULLSCREEN_ENABLE = new CFPlus::UI::CheckBox
545 state => $CFG->{fullscreen}, 769 state => $CFG->{fullscreen},
546 tooltip => "Bring the client into fullscreen mode.", 770 tooltip => "Bring the client into fullscreen mode.",
547 on_changed => sub { my ($self, $value) = @_; $CFG->{fullscreen} = $value; 0 } 771 on_changed => sub { my ($self, $value) = @_; $CFG->{fullscreen} = $value; 0 }
772 );
773
774 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Force OpenGL 1.1");
775 $table->add_at (1, $row++, new CFPlus::UI::CheckBox
776 state => $CFG->{opengl11},
777 tooltip => "Limit CFPlus to use OpenGL 1.1 features only. This will normally result in "
778 . "higher memory usage and slower performance. It will, however, help tremendously on "
779 . "cards that claim to support a feature but fall back to software rendering. "
780 . "Nvidia Geforce FX cards are known to claim features the hardware doesn't support, "
781 . "but cards and drivers from other vendors (ATI) are often just as bad. <b>If you "
782 . "experience extremely low framerates and your card should do better, try this option.</b>",
783 on_changed => sub { my ($self, $value) = @_; $CFG->{opengl11} = $value; 0 }
548 ); 784 );
549 785
550 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Fast & Ugly"); 786 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Fast & Ugly");
551 $table->add_at (1, $row++, new CFPlus::UI::CheckBox 787 $table->add_at (1, $row++, new CFPlus::UI::CheckBox
552 state => $CFG->{fast}, 788 state => $CFG->{fast},
580 816
581 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Map Smoothing"); 817 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Map Smoothing");
582 $table->add_at (1, $row++, new CFPlus::UI::CheckBox 818 $table->add_at (1, $row++, new CFPlus::UI::CheckBox
583 state => $CFG->{map_smoothing}, 819 state => $CFG->{map_smoothing},
584 tooltip => "<b>Map Smoothing</b> tries to make tile borders less square. " 820 tooltip => "<b>Map Smoothing</b> tries to make tile borders less square. "
585 . "This increases load on the graphics subsystem and works only with 2.x servers. " 821 . "This increases load on the graphics subsystem and works only with TRT servers. "
586 . "Changes take effect at next connection only.", 822 . "Changes take effect at next login only.",
587 on_changed => sub { my ($self, $value) = @_; $CFG->{map_smoothing} = $value; 0 } 823 on_changed => sub { my ($self, $value) = @_; $CFG->{map_smoothing} = $value; 0 }
588 ); 824 );
589 825
590 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Fog of War"); 826 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Fog of War");
591 $table->add_at (1, $row++, new CFPlus::UI::CheckBox 827 $table->add_at (1, $row++, new CFPlus::UI::CheckBox
602 ); 838 );
603 839
604 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Message Fontsize"); 840 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Message Fontsize");
605 $table->add_at (1, $row++, new CFPlus::UI::Slider 841 $table->add_at (1, $row++, new CFPlus::UI::Slider
606 range => [$CFG->{log_fontsize}, 0.5, 2, 0, 0.1], 842 range => [$CFG->{log_fontsize}, 0.5, 2, 0, 0.1],
607 tooltip => "The font size used by the <b>message/server log</b> window only. Changes are instant.", 843 tooltip => "The font size used by the <b>message/server log</b> window only. Changes are instant, "
844 . "but you still need to press apply to correctly re-layout the widget.",
608 on_changed => sub { $MESSAGE_WINDOW->set_fontsize ($CFG->{log_fontsize} = $_[1]); 0 }, 845 on_changed => sub { $MESSAGE_WINDOW->set_fontsize ($CFG->{log_fontsize} = $_[1]); 0 },
609 ); 846 );
610 847
611 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Gauge fontsize"); 848 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Gauge fontsize");
612 $table->add_at (1, $row++, new CFPlus::UI::Slider 849 $table->add_at (1, $row++, new CFPlus::UI::Slider
634} 871}
635 872
636sub audio_setup { 873sub audio_setup {
637 my $vbox = new CFPlus::UI::VBox; 874 my $vbox = new CFPlus::UI::VBox;
638 875
639 $vbox->add (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 1]); 876 $vbox->add (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 0, 1]);
640 877
641 my $row = 0; 878 my $row = 0;
642 879
643 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Audio Enable"); 880 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Audio Enable");
644 $table->add_at (1, $row++, new CFPlus::UI::CheckBox 881 $table->add_at (1, $row++, new CFPlus::UI::CheckBox
648 ); 885 );
649# $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Effects Volume"); 886# $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Effects Volume");
650# $table->add_at (1, 8, new CFPlus::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub { 887# $table->add_at (1, 8, new CFPlus::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub {
651# $CFG->{effects_volume} = $_[1]; 888# $CFG->{effects_volume} = $_[1];
652# }); 889# });
890
891 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Sound Effects");
892 $table->add_at (1, $row, new CFPlus::UI::CheckBox
893 expand => 1, state => $CFG->{effects_enable},
894 tooltip => "If enabled, sound effects are enabled. If disabled, no sound effects will be played.",
895 on_changed => sub {
896 $CFG->{effects_enable} = $_[1];
897 $CONN->update_fx_want if $CONN;
898 0
899 }
900 );
901 $table->add_at (2, $row++, new CFPlus::UI::Slider
902 expand => 1, range => [$CFG->{effects_volume}, 0, 1, 0, 1/128],
903 tooltip => "The relative volume of sound effects. Best audio quality is achieved if this "
904 . "is set highest (rightmost) and you use your operating system volume setting. Changes are instant.",
905 on_changed => sub { $CFG->{effects_volume} = $_[1]; 0 }
906 );
907
653 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Background Music"); 908 $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Background Music");
654 $table->add_at (1, $row++, my $hbox = new CFPlus::UI::HBox); 909 $table->add_at (1, $row, new CFPlus::UI::CheckBox
655 $hbox->add (new CFPlus::UI::CheckBox
656 expand => 1, state => $CFG->{bgm_enable}, 910 expand => 1, state => $CFG->{bgm_enable},
657 tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.", 911 tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.",
658 on_changed => sub { $CFG->{bgm_enable} = $_[1]; 0 } 912 on_changed => sub {
913 $CFG->{bgm_enable} = $_[1];
914 $CONN->update_fx_want if $CONN;
915 0
916 }
659 ); 917 );
660 $hbox->add (new CFPlus::UI::Slider 918 $table->add_at (2, $row++, new CFPlus::UI::Slider
661 expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128], 919 expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128],
662 tooltip => "The volume of the background music. Changes are instant.", 920 tooltip => "The volume of the background music. Changes are instant.",
663 on_changed => sub { $CFG->{bgm_volume} = $_[1]; CFPlus::MixMusic::volume $_[1] * 128; 0 } 921 on_changed => sub { $CFG->{bgm_volume} = $_[1]; audio_music_update_volume; 0 }
664 ); 922 );
665 923
666 $table->add_at (1, $row++, new CFPlus::UI::Button 924 $table->add_at (1, $row++, new CFPlus::UI::Button
667 expand => 1, align => 0, text => "Apply", 925 c_colspan => 2, expand => 1, align => 0, text => "Apply",
668 tooltip => "Apply the audio settings", 926 tooltip => "Apply the audio settings",
669 on_activate => sub { 927 on_activate => sub {
670 audio_shutdown (); 928 audio_shutdown ();
671 audio_init (); 929 audio_init ();
672 0 930 0
743 $table->add_at (0, 4, new CFPlus::UI::Button text => "die on click(tm)", on_activate => sub { &CFPlus::debug() } ); 1001 $table->add_at (0, 4, new CFPlus::UI::Button text => "die on click(tm)", on_activate => sub { &CFPlus::debug() } );
744 1002
745 $table->add_at (0, 5, new CFPlus::UI::TextEdit text => "line1\0152\0153");#d# 1003 $table->add_at (0, 5, new CFPlus::UI::TextEdit text => "line1\0152\0153");#d#
746 1004
747 $table->add_at (7,7, my $t = new CFPlus::UI::Table expand => 0); 1005 $table->add_at (7,7, my $t = new CFPlus::UI::Table expand => 0);
748 $t->add_at (0,0, new CFPlus::UI::Label text => "a a a a", rowspan => 1, colspan => 2); 1006 $t->add_at (0,0, new CFPlus::UI::Label text => "a a a a", c_rowspan => 1, c_colspan => 2);
749 $t->add_at (2,0, new CFPlus::UI::Label text => "b\nb", rowspan => 2, colspan => 1); 1007 $t->add_at (2,0, new CFPlus::UI::Label text => "b\nb", c_rowspan => 2, c_colspan => 1);
750 $t->add_at (1,2, new CFPlus::UI::Label text => "c c c c", rowspan => 1, colspan => 2); 1008 $t->add_at (1,2, new CFPlus::UI::Label text => "c c c c", c_rowspan => 1, c_colspan => 2);
751 $t->add_at (0,1, new CFPlus::UI::Label text => "d\nd", rowspan => 2, colspan => 1); 1009 $t->add_at (0,1, new CFPlus::UI::Label text => "d\nd", c_rowspan => 2, c_colspan => 1);
752 $t->add_at (1,1, new CFPlus::UI::Label text => "e"); 1010 $t->add_at (1,1, new CFPlus::UI::Label text => "e");
753 1011
754 $table->add_at (7, 6, my $c = new CFPlus::UI::Canvas); 1012 $table->add_at (7, 6, my $c = new CFPlus::UI::Canvas);
755 1013
756 $c->add_items ({ 1014 $c->add_items ({
1081 text => $CFG->{profile}{default}{host}, 1339 text => $CFG->{profile}{default}{host},
1082 tooltip => "The hostname or ip address of the Crossfire(+) server to connect to", 1340 tooltip => "The hostname or ip address of the Crossfire(+) server to connect to",
1083 on_changed => sub { 1341 on_changed => sub {
1084 my ($self, $value) = @_; 1342 my ($self, $value) = @_;
1085 $CFG->{profile}{default}{host} = $value; 1343 $CFG->{profile}{default}{host} = $value;
1086 0 1344 1
1087 } 1345 }
1088 ); 1346 );
1089 1347
1090 $vbox->add (new CFPlus::UI::Button 1348 $vbox->add (new CFPlus::UI::Button
1091 expand => 1, 1349 expand => 1,
1092 text => "Server List", 1350 text => "Server List",
1093 other => $METASERVER, 1351 other => $METASERVER,
1094 tooltip => "Show a list of available crossfire servers", 1352 tooltip => "Show a list of available crossfire servers",
1095 on_activate => sub { $METASERVER->toggle_visibility; 0 }, 1353 on_activate => sub { $METASERVER->toggle_visibility; 0 },
1096 on_visibility_change => sub { $METASERVER->hide unless $_[1]; 0 }, 1354 on_visibility_change => sub { $METASERVER->hide unless $_[1]; 1 },
1097 ); 1355 );
1098 } 1356 }
1099 1357
1100 $table->add_at (0, 4, new CFPlus::UI::Label valign => 0, align => 1, text => "Username"); 1358 $table->add_at (0, 4, new CFPlus::UI::Label valign => 0, align => 1, text => "Username");
1101 $table->add_at (1, 4, new CFPlus::UI::Entry 1359 $table->add_at (1, 4, new CFPlus::UI::Entry
1102 text => $CFG->{profile}{default}{user}, 1360 text => $CFG->{profile}{default}{user},
1103 tooltip => "The name of your character on the server", 1361 tooltip => "The name of your character on the server",
1104 on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{user} = $value } 1362 on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{user} = $value; 1 }
1105 ); 1363 );
1106 1364
1107 $table->add_at (0, 5, new CFPlus::UI::Label valign => 0, align => 1, text => "Password"); 1365 $table->add_at (0, 5, new CFPlus::UI::Label valign => 0, align => 1, text => "Password");
1108 $table->add_at (1, 5, new CFPlus::UI::Entry 1366 $table->add_at (1, 5, new CFPlus::UI::Entry
1109 text => $CFG->{profile}{default}{password}, 1367 text => $CFG->{profile}{default}{password},
1110 hidden => 1, 1368 hidden => 1,
1111 tooltip => "The password for your character", 1369 tooltip => "The password for your character",
1112 on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{password} = $value } 1370 on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{password} = $value; 1 }
1113 ); 1371 );
1114 1372
1115 $table->add_at (0, 7, new CFPlus::UI::Label valign => 0, align => 1, text => "Map Size"); 1373 $table->add_at (0, 7, new CFPlus::UI::Label valign => 0, align => 1, text => "Map Size");
1116 $table->add_at (1, 7, new CFPlus::UI::Slider 1374 $table->add_at (1, 7, new CFPlus::UI::Slider
1117 force_w => 100, 1375 force_w => 100,
1118 range => [$CFG->{mapsize}, 10, 100, 0, 1], 1376 range => [$CFG->{mapsize}, 10, 100, 0, 1],
1119 tooltip => "This is the size of the portion of the map update the server sends you. " 1377 tooltip => "This is the size of the portion of the map update the server sends you. "
1120 . "If you set this to a high value you will be able to see further, " 1378 . "If you set this to a high value you will be able to see further, "
1121 . "but you also increase bandwidth requirements and latency. " 1379 . "but you also increase bandwidth requirements and latency. "
1122 . "This option is only used once at log-in.", 1380 . "This option is only used once at log-in.",
1123 on_changed => sub { my ($self, $value) = @_; $CFG->{mapsize} = $self->{range}[0] = $value = int $value; 0 }, 1381 on_changed => sub { my ($self, $value) = @_; $CFG->{mapsize} = $self->{range}[0] = $value = int $value; 1 },
1124 ); 1382 );
1125 1383
1126 $table->add_at (0, 8, new CFPlus::UI::Label valign => 0, align => 1, text => "Face Prefetch");
1127 $table->add_at (1, 8, new CFPlus::UI::CheckBox
1128 state => $CFG->{face_prefetch},
1129 tooltip => "<b>Background Image Prefetch</b>\n\n"
1130 . "If enabled, the client automatically pre-fetches images from the server. "
1131 . "This might increase or create lag, but increases the chances "
1132 . "of faces being ready for display when you encounter them. "
1133 . "It also uses up server bandwidth on every connect, "
1134 . "so only set it if you really need to prefetch images. "
1135 . "This option can be set and unset any time.",
1136 on_changed => sub { $CFG->{face_prefetch} = $_[1]; 0 },
1137 );
1138
1139 $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Rate"); 1384 $table->add_at (0, 8, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Rate");
1385 $table->add_at (1, 8, new CFPlus::UI::Entry
1386 text => $CFG->{output_rate},
1387 tooltip => "The maximum bandwidth in bytes per second that the server should not exceed "
1388 . "when sending data. When 0 or unset, the server "
1389 . "default will be used, which is usually around 100kb/s. Most servers will "
1390 . "dynamically find an optimal rate, so adjust this only when necessary.",
1391 on_changed => sub { $CFG->{output_rate} = $_[1]; 1 },
1392 );
1393
1394 $table->add_at (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Count");
1140 $table->add_at (1, 9, new CFPlus::UI::Entry 1395 $table->add_at (1, 9, new CFPlus::UI::Entry
1141 text => $CFG->{output_rate},
1142 tooltip => "The approximate bandwidth in bytes per second that the server should not exceed "
1143 . "when sending images, to ensure interactiveness. When 0 or unset, the server "
1144 . "default will be used, which is usually around 100kb/s.",
1145 on_changed => sub { $CFG->{output_rate} = $_[1]; 0 },
1146 );
1147
1148 $table->add_at (0, 10, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Count");
1149 $table->add_at (1, 10, new CFPlus::UI::Entry
1150 text => $CFG->{output_count}, 1396 text => $CFG->{output_count},
1151 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.", 1397 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
1152 on_changed => sub { $CFG->{output_count} = $_[1]; 0 }, 1398 on_changed => sub { $CFG->{output_count} = $_[1]; 1 },
1153 ); 1399 );
1154 1400
1155 $table->add_at (0, 11, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Sync"); 1401 $table->add_at (0, 10, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Sync");
1156 $table->add_at (1, 11, new CFPlus::UI::Entry 1402 $table->add_at (1, 10, new CFPlus::UI::Entry
1157 text => $CFG->{output_sync}, 1403 text => $CFG->{output_sync},
1158 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.", 1404 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
1159 on_changed => sub { $CFG->{output_sync} = $_[1]; 0 }, 1405 on_changed => sub { $CFG->{output_sync} = $_[1]; 1 },
1160 ); 1406 );
1161 1407
1162 $table->add_at (1, 12, $LOGIN_BUTTON = new CFPlus::UI::Button 1408 $table->add_at (1, 11, $LOGIN_BUTTON = new CFPlus::UI::Button
1163 expand => 1, 1409 expand => 1,
1164 align => 0, 1410 align => 0,
1165 text => "Login", 1411 text => "Login",
1166 on_activate => sub { 1412 on_activate => sub {
1167 $CONN ? stop_game 1413 $CONN ? stop_game
1168 : start_game; 1414 : start_game;
1169 0 1415 1
1170 }, 1416 },
1171 ); 1417 );
1172 1418
1173 $vbox->add (new CFPlus::UI::FancyFrame 1419 $vbox->add (new CFPlus::UI::FancyFrame
1174 label => "Server Info", 1420 label => "Server Info",
1375 CFPlus::Protocol::set_opencont ($::CONN, 0, "Floor"); 1621 CFPlus::Protocol::set_opencont ($::CONN, 0, "Floor");
1376 1622
1377 $hb 1623 $hb
1378} 1624}
1379 1625
1626sub media_window {
1627 my $vb = new CFPlus::UI::VBox;
1628
1629 $vb->add (new CFPlus::UI::FancyFrame
1630 label => "Currently playing music",
1631 child => new CFPlus::UI::ScrolledWindow scroll_x => 1, scroll_y => 0,
1632 child => ($MUSIC_PLAYING_WIDGET = new CFPlus::UI::Label ellipsise => 0, fontsize => 0.8),
1633 );
1634
1635 $vb->add (new CFPlus::UI::FancyFrame
1636 label => "Other media used in this session",
1637 expand => 1,
1638 child => ($LICENSE_WIDGET = new CFPlus::UI::TextScroller
1639 expand => 1, fontsize => 0.8, padding_x => 4, padding_y => 4),
1640 );
1641
1642 $vb
1643}
1644
1645sub add_license {
1646 my ($meta) = @_;
1647
1648 $meta = $meta->{meta}
1649 or return;
1650
1651 $meta->{license} || $meta->{author} || $meta->{source}
1652 or return;
1653
1654 $LICENSE_WIDGET->add_paragraph ({
1655 fg => [1, 1, 1, 1],
1656 markup => "<small>"
1657 . "<b>Name:</b> " . (CFPlus::asxml $meta->{name}) . "\n"
1658 . "<b>Author:</b> " . (CFPlus::asxml $meta->{author}) . "\n"
1659 . "<b>Source:</b> " . (CFPlus::asxml $meta->{source}) . "\n"
1660 . "<b>License:</b> " . (CFPlus::asxml $meta->{license}) . "\n"
1661 . "</small>",
1662 });
1663 $LICENSE_WIDGET->scroll_to_bottom;
1664}
1665
1380sub toggle_player_page { 1666sub toggle_player_page {
1381 my ($widget) = @_; 1667 my ($widget) = @_;
1382 1668
1383 if ($PL_WINDOW->{visible} && $PL_NOTEBOOK->get_current_page == $widget) { 1669 if ($PL_WINDOW->{visible} && $PL_NOTEBOOK->get_current_page == $widget) {
1384 $PL_WINDOW->hide; 1670 $PL_WINDOW->hide;
1421 $ntb->add_tab ( 1707 $ntb->add_tab (
1422 "Inventory (F5)" => $INVENTORY_PAGE = inventory_widget, 1708 "Inventory (F5)" => $INVENTORY_PAGE = inventory_widget,
1423 "Toggles the inventory window, where you can manage your loot (or treasures :). " 1709 "Toggles the inventory window, where you can manage your loot (or treasures :). "
1424 . "You can also hit the <b>Tab</b>-key to show/hide the Inventory." 1710 . "You can also hit the <b>Tab</b>-key to show/hide the Inventory."
1425 ); 1711 );
1426 $ntb->add_tab (Pickup => autopickup_setup, 1712 $ntb->add_tab (Pickup => autopickup_setup,
1427 "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them."); 1713 "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them.");
1714
1715 $ntb->add_tab (Media => media_window,
1716 "License, Author and Source info for media sent by the server.");
1428 1717
1429 $ntb->set_current_page ($INVENTORY_PAGE); 1718 $ntb->set_current_page ($INVENTORY_PAGE);
1430 1719
1431 $plwin->add ($ntb); 1720 $plwin->add ($ntb);
1432 $plwin 1721 $plwin
1586 on_activate => sub { $QUIT_DIALOG->hide; 0 }, 1875 on_activate => sub { $QUIT_DIALOG->hide; 0 },
1587 ); 1876 );
1588 $hb->add (new CFPlus::UI::Button 1877 $hb->add (new CFPlus::UI::Button
1589 text => "Quit anyway", 1878 text => "Quit anyway",
1590 expand => 1, 1879 expand => 1,
1591 on_activate => sub { exit }, 1880 on_activate => sub { Event::unloop_all },
1592 ); 1881 );
1593 } 1882 }
1594 1883
1595 $QUIT_DIALOG->show; 1884 $QUIT_DIALOG->show;
1596 $QUIT_DIALOG->grab_focus; 1885 $QUIT_DIALOG->grab_focus;
1790 tooltip => "Terminates the program", 2079 tooltip => "Terminates the program",
1791 on_activate => sub { 2080 on_activate => sub {
1792 if ($CONN) { 2081 if ($CONN) {
1793 open_quit_dialog; 2082 open_quit_dialog;
1794 } else { 2083 } else {
1795 exit; 2084 Event::unloop_all;
1796 } 2085 }
1797 0 2086 0
1798 }, 2087 },
1799 ); 2088 );
1800 2089
1801 $BUTTONBAR->show; 2090 $BUTTONBAR->show;
1802 $SETUP_DIALOG->show; 2091 $SETUP_DIALOG->show;
2092 $MESSAGE_WINDOW->show;
1803 } 2093 }
1804 2094
1805 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]); 2095 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
1806} 2096}
1807 2097
1809 CFPlus::OpenGL::shutdown; 2099 CFPlus::OpenGL::shutdown;
1810 2100
1811 undef $SDL_ACTIVE; 2101 undef $SDL_ACTIVE;
1812} 2102}
1813 2103
1814sub audio_channel_finished {
1815 my ($channel) = @_;
1816
1817 #warn "channel $channel finished\n";#d#
1818}
1819
1820sub audio_music_set {
1821 my ($songs) = @_;
1822
1823 my @want =
1824 grep $_,
1825 map $CONN->{music_meta}{$_},
1826 @$songs;
1827
1828 if (@want) {
1829 @MUSIC_WANT = @want;
1830 &audio_music_changed ();
1831 }
1832}
1833
1834sub audio_music_start {
1835 my $path = $MUSIC_PLAYING->{path}
1836 or return;
1837
1838 CFPlus::DB::prefetch_file $path, 1024_000, sub {
1839 return unless $SDL_MIXER;
1840
1841 # music might have changed...
1842 $path eq $MUSIC_PLAYING->{path}
1843 or return &audio_music_start ();
1844
1845 $MUSIC_PLAYER = new_from_file CFPlus::MixMusic $path;
1846
1847 my $NOW = time;
1848
1849 if ($MUSIC_PLAYING->{stop_time} > $NOW - $MUSIC_RESUME) {
1850 my $pos = $MUSIC_PLAYING->{stop_pos};
1851 $MUSIC_PLAYER->fade_in_pos (0, 1000, $pos);
1852 $MUSIC_START = time - $pos;
1853 } else {
1854 $MUSIC_PLAYER->play (0);
1855 $MUSIC_START = time;
1856 }
1857
1858 delete $MUSIC_PLAYING->{stop_time};
1859 delete $MUSIC_PLAYING->{stop_pos};
1860 }
1861}
1862
1863sub audio_music_changed {
1864 return unless $CFG->{bgm_enable};
1865 return unless $SDL_MIXER;
1866
1867 # default MUSIC_WANT == MUSIC_DEFAULT
1868 @MUSIC_WANT = { path => CFPlus::find_rcfile "music/$MUSIC_DEFAULT" } unless @MUSIC_WANT;
1869
1870 # if the currently playing song is acceptable, let it continue
1871 return if $MUSIC_PLAYING
1872 && grep $MUSIC_PLAYING->{path} eq $_->{path}, @MUSIC_WANT;
1873
1874 my $NOW = time;
1875
1876 if ($MUSIC_PLAYING) {
1877 $MUSIC_PLAYING->{stop_time} = $NOW;
1878 $MUSIC_PLAYING->{stop_pos} = $NOW - $MUSIC_START;
1879 CFPlus::MixMusic::fade_out 1000;
1880 } else {
1881 # sort by stop time, oldest first
1882 @MUSIC_WANT = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_WANT;
1883
1884 # if the most recently-played piece played very recently,
1885 # resume it, else choose the oldest piece for rotation.
1886 $MUSIC_PLAYING =
1887 $MUSIC_WANT[-1]{stop_time} > $NOW - $MUSIC_RESUME
1888 ? $MUSIC_WANT[-1]
1889 : $MUSIC_WANT[0];
1890
1891 audio_music_start;
1892 }
1893}
1894
1895sub audio_music_finished {
1896 $MUSIC_PLAYING = undef;
1897 undef $MUSIC_PLAYER;
1898
1899 audio_music_changed;
1900}
1901
1902sub audio_init {
1903 if ($CFG->{audio_enable}) {
1904 if (open my $fh, "<", CFPlus::find_rcfile "sounds/config") {
1905 $SDL_MIXER = !CFPlus::Mix_OpenAudio;
1906
1907 unless ($SDL_MIXER) {
1908 status "Unable to open sound device: there will be no sound";
1909 return;
1910 }
1911
1912 CFPlus::Mix_AllocateChannels 8;
1913 CFPlus::MixMusic::volume $CFG->{bgm_volume} * 128;
1914
1915 audio_music_finished;
1916
1917 local $_;
1918 while (<$fh>) {
1919 next if /^\s*#/;
1920 next if /^\s*$/;
1921
1922 my ($file, $volume, $event) = split /\s+/, $_, 3;
1923
1924 push @SOUNDS, "$volume,$file";
1925
1926 $AUDIO_CHUNKS{"$volume,$file"} ||= do {
1927 my $chunk = new_from_file CFPlus::MixChunk CFPlus::find_rcfile "sounds/$file";
1928 $chunk->volume ($volume * 128 / 100);
1929 $chunk
1930 };
1931 }
1932 } else {
1933 status "unable to open sound config: $!";
1934 }
1935 } else {
1936 undef $SDL_MIXER;
1937 }
1938}
1939
1940sub audio_shutdown {
1941 CFPlus::Mix_CloseAudio if $SDL_MIXER;
1942 undef $SDL_MIXER;
1943 @SOUNDS = ();
1944 %AUDIO_CHUNKS = ();
1945}
1946
1947my %animate_object; 2104my %animate_object;
1948my $animate_timer; 2105my $animate_timer;
1949 2106
1950my $fps = 9; 2107my $fps = 9;
1951 2108
1952my %demo;#d#
1953
1954sub force_refresh { 2109sub force_refresh {
2110 if ($ENV{CFPLUS_DEBUG} & 4) {
1955 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05; 2111 $fps = $fps * 0.98 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.02;
1956 debug sprintf "%3.2f", $fps if $ENV{CFPLUS_DEBUG} & 4; 2112 debug sprintf "%3.2f", $fps;
2113 }
1957 2114
1958 $CFPlus::UI::ROOT->draw; 2115 $CFPlus::UI::ROOT->draw;
1959 2116 CFPlus::SDL_GL_SwapBuffers;
1960 $WANT_REFRESH = 0;
1961 $CAN_REFRESH = 0;
1962 $LAST_REFRESH = $NOW; 2117 $LAST_REFRESH = $NOW;
1963 2118 $WANT_REFRESH->stop;
1964 CFPlus::SDL_GL_SwapBuffers;
1965} 2119}
1966 2120
2121$WANT_REFRESH = Event->idle (min => 0.001, max => 0.06, parked => 1, cb => \&force_refresh);
2122
1967my $refresh_watcher = Event->timer (after => 0, hard => 0, interval => 1 / $MAX_FPS, cb => sub { 2123my $input = Event->timer (after => 0, hard => 0, interval => 1 / 50, cb => sub {
1968 $NOW = time; 2124 $NOW = time;
1969 2125
1970 ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_) 2126 ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_)
1971 for CFPlus::poll_events; 2127 for CFPlus::poll_events;
1972 2128
1973 if (%animate_object) { 2129 if (%animate_object) {
1974 $_->animate ($LAST_REFRESH - $NOW) for values %animate_object; 2130 $_->animate ($LAST_REFRESH - $NOW) for values %animate_object;
1975 ++$WANT_REFRESH; 2131 $WANT_REFRESH->start;
1976 }
1977
1978 if ($WANT_REFRESH) {
1979 force_refresh;
1980 } else {
1981 $CAN_REFRESH = 1;
1982 } 2132 }
1983}); 2133});
1984 2134
1985sub animation_start { 2135sub animation_start {
1986 my ($widget) = @_; 2136 my ($widget) = @_;
1989 2139
1990sub animation_stop { 2140sub animation_stop {
1991 my ($widget) = @_; 2141 my ($widget) = @_;
1992 delete $animate_object{$widget}; 2142 delete $animate_object{$widget};
1993} 2143}
1994
1995# check once/second for faces that need to be prefetched
1996# this should, of course, only run on demand, but
1997# SDL forces worse things on us....
1998
1999Event->timer (after => 1, interval => 0.25, cb => sub {
2000 $CONN->face_prefetch
2001 if $CONN;
2002});
2003 2144
2004%SDL_CB = ( 2145%SDL_CB = (
2005 CFPlus::SDL_QUIT => sub { 2146 CFPlus::SDL_QUIT => sub {
2006 exit; 2147 exit;
2007 }, 2148 },
2051 2192
2052 CFPlus::UI::set_layout ($::CFG->{layout}); 2193 CFPlus::UI::set_layout ($::CFG->{layout});
2053 2194
2054 my %DEF_CFG = ( 2195 my %DEF_CFG = (
2055 sdl_mode => 0, 2196 sdl_mode => 0,
2056 width => 640,
2057 height => 480,
2058 fullscreen => 0, 2197 fullscreen => 0,
2059 fast => 0, 2198 fast => 0,
2199 opengl11 => 0,
2060 map_scale => 1, 2200 map_scale => 1,
2061 fow_enable => 1, 2201 fow_enable => 1,
2062 fow_intensity => 0, 2202 fow_intensity => 0,
2063 map_smoothing => 1, 2203 map_smoothing => 1,
2064 gui_fontsize => 1, 2204 gui_fontsize => 1,
2066 gauge_fontsize => 1, 2206 gauge_fontsize => 1,
2067 gauge_size => 0.35, 2207 gauge_size => 0.35,
2068 stat_fontsize => 0.7, 2208 stat_fontsize => 0.7,
2069 mapsize => 100, 2209 mapsize => 100,
2070 audio_enable => 1, 2210 audio_enable => 1,
2211 effects_enable => 1,
2212 effects_volume => 1,
2071 bgm_enable => 1, 2213 bgm_enable => 1,
2072 bgm_volume => 0.25, 2214 bgm_volume => 0.5,
2073 face_prefetch => 0,
2074 output_sync => 1, 2215 output_sync => 1,
2075 output_count => 1, 2216 output_count => 1,
2076 output_rate => "", 2217 output_rate => "",
2077 pickup => 0, 2218 pickup => 0,
2078 inv_sort => "mtime", 2219 inv_sort => "mtime",
2152} 2293}
2153 2294
2154show_tip_of_the_day if $CFG->{show_tips}; 2295show_tip_of_the_day if $CFG->{show_tips};
2155 2296
2156Event::loop; 2297Event::loop;
2298
2299#video_shutdown;
2300#audio_shutdown;
2157#CFPlus::SDL_Quit; 2301CFPlus::SDL_Quit;
2158#CFPlus::_exit 0;
2159
2160END {
2161 CFPlus::SDL_Quit;
2162 CFPlus::DB::Server::stop; 2302CFPlus::DB::Server::stop;
2163}
2164 2303
2165=head1 NAME 2304=head1 NAME
2166 2305
2167cfplus - A Crossfire+ and Crossfire game client 2306cfplus - A Crossfire TRT and Crossfire game client
2168 2307
2169=head1 SYNOPSIS 2308=head1 SYNOPSIS
2170 2309
2171Just run it - no commandline arguments are supported. 2310Just run it - no commandline arguments are supported.
2172 2311
2173=head1 USAGE 2312=head1 USAGE
2174 2313
2175cfplus utilises OpenGL for all UI elements and the game. It is supposed to be used 2314cfplus utilises OpenGL for all UI elements and the game. It is supposed to
2176fullscreen and interactively. 2315be used in fullscreen mode and interactively.
2177 2316
2178=head1 DEBUGGING 2317=head1 DEBUGGING
2179 2318
2180 2319
2181CFPLUS_DEBUG - environment variable 2320CFPLUS_DEBUG - environment variable

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines