--- deliantra/Deliantra-Client/bin/cfplus 2007/07/31 02:45:39 1.198
+++ deliantra/Deliantra-Client/bin/cfplus 2007/08/11 14:41:38 1.209
@@ -115,7 +115,6 @@
our $FAST; # fast, low-quality mode, possibly useful for software-rendering
our $WANT_REFRESH;
-our $CAN_REFRESH;
our @SDL_MODES;
our $WIDTH;
@@ -146,6 +145,9 @@
our $PL_NOTEBOOK;
our $PL_WINDOW;
+our $MUSIC_PLAYING_WIDGET;
+our $LICENSE_WIDGET;
+
our $INVENTORY_PAGE;
our $STATS_PAGE;
our $SKILL_PAGE;
@@ -213,19 +215,19 @@
sub audio_sound_push($) {
my ($face) = @_;
+ $CFG->{effects_enable}
+ or return;
+
+ $AUDIO_PLAY{$face}
+ or return;
+
if (my $chunk = $AUDIO_CHUNK{$face}) {
for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) {
my (undef, $dx, $dy, $vol) = @$_;
my $channel = CFPlus::Channel::find;
- $channel->volume ($vol * 128 / 255);
- $dx = $dx / 10 * 255;
- $channel->set_panning (255 - $dx, 255 + $dx);
-
-# my $angle = $dx ? : $dx < 0 ?
-# my $distance = -$vol;
-# $channel->set_position ($angle, $distance);
-
+ $channel->volume ($vol * $CFG->{effects_volume} * 128 / 255);
+ $channel->set_position_r ($dx, $dy, 20);
$chunk->play ($channel);
}
} else {
@@ -235,14 +237,16 @@
# if its a jingle, play it as ambient music
if ($meta->{meta}{jingle}) {
- delete $AUDIO_PLAY{$face}; # take the jingle out of the sound queue
- push @MUSIC_JINGLE, $meta; # push it oto the music/jingle queue
- &audio_music_push ($face);
+ if (delete $AUDIO_PLAY{$face}) { # take the jingle out of the sound queue
+ push @MUSIC_JINGLE, $meta; # push it oto the music/jingle queue
+ &audio_music_push ($face);
+ }
} else {
# fetch from database
CFPlus::DB::get res_data => $meta->{name}, sub {
my $rwops = new CFPlus::RW $_[0];
- my $chunk = new CFPlus::MixChunk $rwops;
+ my $chunk = new CFPlus::MixChunk $rwops
+ or Carp::confess "sound face " . (JSON::XS::to_json $meta) . " unloadable: " . CFPlus::Mix_GetError;
$chunk->volume (($meta->{meta}{volume} || 1) * 128);
$AUDIO_CHUNK{$face} = $chunk;
@@ -257,6 +261,8 @@
$SDL_MIXER
or return;
+ $CFG->{effects_enable}
+ or return;
my $queue = $AUDIO_PLAY{$face} ||= [];
push @$queue, [Event::time + 0.2, $dx, $dy, $vol]; # delay sound by max. 0.2s
@@ -264,6 +270,18 @@
unless @$queue > 1;
}
+sub audio_music_set_meta {
+ my ($meta) = @_;
+
+ $MUSIC_PLAYING_META = $meta;
+ $MUSIC_PLAYING_WIDGET->set_markup (
+ "Name: " . (CFPlus::asxml $meta->{meta}{name}) . "\n"
+ . "Author: " . (CFPlus::asxml $meta->{meta}{author}) . "\n"
+ . "Source: " . (CFPlus::asxml $meta->{meta}{source}) . "\n"
+ . "License: " . (CFPlus::asxml $meta->{meta}{license})
+ );
+}
+
sub audio_music_update_volume {
return unless $MUSIC_PLAYING_META;
my $volume = $MUSIC_PLAYING_META->{meta}{volume} || 1;
@@ -290,7 +308,7 @@
: new CFPlus::RW $$MUSIC_PLAYING_DATA;
$MUSIC_PLAYER = new CFPlus::MixMusic $rwops
- or ((warn CFPlus::Mix_GetError), return); # pretty fatal error
+ or Carp::confess "music face $meta->{face} unloadable: " . CFPlus::Mix_GetError;
my $NOW = time;
@@ -303,8 +321,8 @@
$MUSIC_START = time;
}
- delete $MUSIC_PLAYING_META->{stop_time};
- delete $MUSIC_PLAYING_META->{stop_pos};
+ delete $meta->{stop_time};
+ delete $meta->{stop_pos};
}
}
@@ -333,8 +351,7 @@
}
# if the currently playing song is acceptable, let it continue
- return if $MUSIC_PLAYING_META
- && grep $MUSIC_PLAYING_META == $_, @MUSIC_HAVE;
+ return if grep $MUSIC_PLAYING_META == $_, @MUSIC_HAVE;
my $NOW = time;
@@ -348,7 +365,7 @@
# if the most recently-played piece played very recently,
# resume it, else choose the oldest piece for rotation.
- $MUSIC_PLAYING_META =
+ audio_music_set_meta
$MUSIC_HAVE[-1]{stop_time} > $NOW - $MUSIC_RESUME
? $MUSIC_HAVE[-1]
: $MUSIC_HAVE[0];
@@ -369,6 +386,8 @@
shift @MUSIC_JINGLE
while @MUSIC_JINGLE && $MUSIC_PLAYING_META == $MUSIC_JINGLE[0];
+ $MUSIC_PLAYING_WIDGET->clear;
+
undef $MUSIC_PLAYER;
undef $MUSIC_PLAYING_META;
undef $MUSIC_PLAYING_DATA;
@@ -787,7 +806,7 @@
$table->add_at (1, $row++, new CFPlus::UI::CheckBox
state => $CFG->{map_smoothing},
tooltip => "Map Smoothing tries to make tile borders less square. "
- . "This increases load on the graphics subsystem and works only with 2.x servers. "
+ . "This increases load on the graphics subsystem and works only with TRT servers. "
. "Changes take effect at next connection only.",
on_changed => sub { my ($self, $value) = @_; $CFG->{map_smoothing} = $value; 0 }
);
@@ -841,7 +860,7 @@
sub audio_setup {
my $vbox = new CFPlus::UI::VBox;
- $vbox->add (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 1]);
+ $vbox->add (my $table = new CFPlus::UI::Table expand => 1, col_expand => [0, 0, 1]);
my $row = 0;
@@ -855,21 +874,42 @@
# $table->add_at (1, 8, new CFPlus::UI::Slider range => [$CFG->{effects_volume}, 0, 128, 1], on_changed => sub {
# $CFG->{effects_volume} = $_[1];
# });
+
+ $table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Sound Effects");
+ $table->add_at (1, $row, new CFPlus::UI::CheckBox
+ expand => 1, state => $CFG->{effects_enable},
+ tooltip => "If enabled, sound effects are enabled. If disabled, no sound effects will be played.",
+ on_changed => sub {
+ $CFG->{effects_enable} = $_[1];
+ $CONN->update_fx_want if $CONN;
+ 0
+ }
+ );
+ $table->add_at (2, $row++, new CFPlus::UI::Slider
+ expand => 1, range => [$CFG->{effects_volume}, 0, 1, 0, 1/128],
+ tooltip => "The relative volume of sound effects. Best audio quality is achieved if this "
+ . "is set highest (rightmost) and you use your operating system volume setting. Changes are instant.",
+ on_changed => sub { $CFG->{effects_volume} = $_[1]; 0 }
+ );
+
$table->add_at (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Background Music");
- $table->add_at (1, $row++, my $hbox = new CFPlus::UI::HBox);
- $hbox->add (new CFPlus::UI::CheckBox
+ $table->add_at (1, $row, new CFPlus::UI::CheckBox
expand => 1, state => $CFG->{bgm_enable},
tooltip => "If enabled, playing of background music is enabled. If disabled, no background music will be played.",
- on_changed => sub { $CFG->{bgm_enable} = $_[1]; 0 }
+ on_changed => sub {
+ $CFG->{bgm_enable} = $_[1];
+ $CONN->update_fx_want if $CONN;
+ 0
+ }
);
- $hbox->add (new CFPlus::UI::Slider
+ $table->add_at (2, $row++, new CFPlus::UI::Slider
expand => 1, range => [$CFG->{bgm_volume}, 0, 1, 0, 1/128],
tooltip => "The volume of the background music. Changes are instant.",
on_changed => sub { $CFG->{bgm_volume} = $_[1]; audio_music_update_volume; 0 }
);
$table->add_at (1, $row++, new CFPlus::UI::Button
- expand => 1, align => 0, text => "Apply",
+ c_colspan => 2, expand => 1, align => 0, text => "Apply",
tooltip => "Apply the audio settings",
on_activate => sub {
audio_shutdown ();
@@ -950,10 +990,10 @@
$table->add_at (0, 5, new CFPlus::UI::TextEdit text => "line1\0152\0153");#d#
$table->add_at (7,7, my $t = new CFPlus::UI::Table expand => 0);
- $t->add_at (0,0, new CFPlus::UI::Label text => "a a a a", rowspan => 1, colspan => 2);
- $t->add_at (2,0, new CFPlus::UI::Label text => "b\nb", rowspan => 2, colspan => 1);
- $t->add_at (1,2, new CFPlus::UI::Label text => "c c c c", rowspan => 1, colspan => 2);
- $t->add_at (0,1, new CFPlus::UI::Label text => "d\nd", rowspan => 2, colspan => 1);
+ $t->add_at (0,0, new CFPlus::UI::Label text => "a a a a", c_rowspan => 1, c_colspan => 2);
+ $t->add_at (2,0, new CFPlus::UI::Label text => "b\nb", c_rowspan => 2, c_colspan => 1);
+ $t->add_at (1,2, new CFPlus::UI::Label text => "c c c c", c_rowspan => 1, c_colspan => 2);
+ $t->add_at (0,1, new CFPlus::UI::Label text => "d\nd", c_rowspan => 2, c_colspan => 1);
$t->add_at (1,1, new CFPlus::UI::Label text => "e");
$table->add_at (7, 6, my $c = new CFPlus::UI::Canvas);
@@ -1570,6 +1610,46 @@
$hb
}
+sub media_window {
+ my $vb = new CFPlus::UI::VBox;
+
+ $vb->add (new CFPlus::UI::FancyFrame
+ label => "Currently playing music",
+ child => new CFPlus::UI::ScrolledWindow scroll_x => 1, scroll_y => 0,
+ child => ($MUSIC_PLAYING_WIDGET = new CFPlus::UI::Label ellipsise => 0, fontsize => 0.8),
+ );
+
+ $vb->add (new CFPlus::UI::FancyFrame
+ label => "Other media used in this session",
+ expand => 1,
+ child => ($LICENSE_WIDGET = new CFPlus::UI::TextScroller
+ expand => 1, fontsize => 0.8, padding_x => 4, padding_y => 4),
+ );
+
+ $vb
+}
+
+sub add_license {
+ my ($meta) = @_;
+
+ $meta = $meta->{meta}
+ or return;
+
+ $meta->{license} || $meta->{author} || $meta->{source}
+ or return;
+
+ $LICENSE_WIDGET->add_paragraph ({
+ fg => [1, 1, 1, 1],
+ markup => ""
+ . "Name: " . (CFPlus::asxml $meta->{name}) . "\n"
+ . "Author: " . (CFPlus::asxml $meta->{author}) . "\n"
+ . "Source: " . (CFPlus::asxml $meta->{source}) . "\n"
+ . "License: " . (CFPlus::asxml $meta->{license}) . "\n"
+ . "",
+ });
+ $LICENSE_WIDGET->scroll_to_bottom;
+}
+
sub toggle_player_page {
my ($widget) = @_;
@@ -1616,9 +1696,12 @@
"Toggles the inventory window, where you can manage your loot (or treasures :). "
. "You can also hit the Tab-key to show/hide the Inventory."
);
- $ntb->add_tab (Pickup => autopickup_setup,
+ $ntb->add_tab (Pickup => autopickup_setup,
"Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them.");
+ $ntb->add_tab (Media => media_window,
+ "License, Author and Source info for media sent by the server.");
+
$ntb->set_current_page ($INVENTORY_PAGE);
$plwin->add ($ntb);
@@ -2010,19 +2093,20 @@
my $fps = 9;
sub force_refresh {
- $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05;
- debug sprintf "%3.2f", $fps if $ENV{CFPLUS_DEBUG} & 4;
+ if ($ENV{CFPLUS_DEBUG} & 4) {
+ $fps = $fps * 0.98 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.02;
+ debug sprintf "%3.2f", $fps;
+ }
$CFPlus::UI::ROOT->draw;
-
- $WANT_REFRESH = 0;
- $CAN_REFRESH = 0;
- $LAST_REFRESH = $NOW;
-
CFPlus::SDL_GL_SwapBuffers;
+ $LAST_REFRESH = $NOW;
+ $WANT_REFRESH->stop;
}
-my $refresh_watcher = Event->timer (after => 0, hard => 0, interval => 1 / $MAX_FPS, cb => sub {
+$WANT_REFRESH = Event->idle (min => 0.001, max => 0.06, parked => 1, cb => \&force_refresh);
+
+my $input = Event->timer (after => 0, hard => 0, interval => 1 / 50, cb => sub {
$NOW = time;
($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_)
@@ -2030,13 +2114,7 @@
if (%animate_object) {
$_->animate ($LAST_REFRESH - $NOW) for values %animate_object;
- ++$WANT_REFRESH;
- }
-
- if ($WANT_REFRESH) {
- force_refresh;
- } else {
- $CAN_REFRESH = 1;
+ $WANT_REFRESH->start;
}
});
@@ -2115,8 +2193,10 @@
stat_fontsize => 0.7,
mapsize => 100,
audio_enable => 1,
+ effects_enable => 1,
+ effects_volume => 1,
bgm_enable => 1,
- bgm_volume => 0.25,
+ bgm_volume => 0.5,
output_sync => 1,
output_count => 1,
output_rate => "",
@@ -2204,13 +2284,15 @@
#CFPlus::_exit 0;
END {
+ video_shutdown;
+ audio_shutdown;
CFPlus::SDL_Quit;
CFPlus::DB::Server::stop;
}
=head1 NAME
-cfplus - A Crossfire+ and Crossfire game client
+cfplus - A Crossfire TRT and Crossfire game client
=head1 SYNOPSIS
@@ -2218,8 +2300,8 @@
=head1 USAGE
-cfplus utilises OpenGL for all UI elements and the game. It is supposed to be used
-fullscreen and interactively.
+cfplus utilises OpenGL for all UI elements and the game. It is supposed to
+be used in fullscreen mode and interactively.
=head1 DEBUGGING