--- deliantra/Deliantra-Client/bin/cfplus 2007/07/12 19:13:20 1.166 +++ deliantra/Deliantra-Client/bin/cfplus 2007/07/17 16:02:14 1.172 @@ -163,8 +163,10 @@ our $SDL_MIXER; our $MUSIC_DEFAULT = "in_a_heartbeat.ogg"; our @MUSIC_WANT; +our $MUSIC_START; our $MUSIC_PLAYING; our $MUSIC_PLAYER; +our $MUSIC_RESUME = 30; # resume music when players less than these many seconds before our @SOUNDS; # event => file mapping our %AUDIO_CHUNKS; # audio files @@ -529,17 +531,25 @@ can_events => 1, tooltip => "" . (CFPlus::OpenGL::gl_extensions) . ""); + my $vidmode_tooltip = + "Video Mode. The video mode to use for fullscreen (and the window size for windowed operation). " + . "The format is width x height \@ depth-per-channel + alpha-channel."; + $table->add (0, $row, new CFPlus::UI::Label valign => 0, align => 1, text => "Video Mode"); $table->add (1, $row++, my $hbox = new CFPlus::UI::HBox); - $hbox->add (my $mode_slider = new CFPlus::UI::Slider force_w => $WIDTH * 0.1, expand => 1, range => [$CFG->{sdl_mode}, 0, $#SDL_MODES, 0, 1]); - $hbox->add (my $mode_label = new CFPlus::UI::Label align => 0, valign => 0, height => 0.8, template => "9999x9999"); + $hbox->add (my $mode_slider = new CFPlus::UI::Slider + force_w => $WIDTH * 0.1, expand => 1, range => [$CFG->{sdl_mode}, 0, $#SDL_MODES, 0, 1], + tooltip => $vidmode_tooltip); + $hbox->add (my $mode_label = new CFPlus::UI::Label + align => 0, valign => 0, height => 0.8, template => "9999x9999@9+9", + can_events => 1, tooltip => $vidmode_tooltip); $mode_slider->connect (changed => sub { my ($self, $value) = @_; $CFG->{sdl_mode} = $self->{range}[0] = $value = int $value; - $mode_label->set_text (sprintf "%dx%d", @{$SDL_MODES[$value]}); + $mode_label->set_text (sprintf '%dx%d@%d+%d', @{$SDL_MODES[$value]}); }); $mode_slider->emit (changed => $mode_slider->{range}[0]); @@ -1280,7 +1290,14 @@ } sub autopickup_setup { - my $table = new CFPlus::UI::Table; + my $r = new CFPlus::UI::ScrolledWindow ( + expand => 1, + scroll_y => 1 + ); + $r->add (my $table = new CFPlus::UI::Table + row_expand => [0], + col_expand => [0, 1, 0, 1], + ); for ( ["General", 0, 0, @@ -1374,7 +1391,7 @@ 0 }); - $table + $r } my %SORT_ORDER = ( @@ -1718,17 +1735,15 @@ } sub video_init { - sdl_init; - $CFG->{sdl_mode} = 0 if $CFG->{sdl_mode} >= @SDL_MODES; my ($old_w, $old_h) = ($WIDTH, $HEIGHT); - ($WIDTH, $HEIGHT) = @{ $SDL_MODES[$CFG->{sdl_mode}] }; + ($WIDTH, $HEIGHT, my ($rgb, $alpha)) = @{ $SDL_MODES[$CFG->{sdl_mode}] }; $FULLSCREEN = $CFG->{fullscreen}; $FAST = $CFG->{fast}; - CFPlus::SDL_SetVideoMode $WIDTH, $HEIGHT, $FULLSCREEN + CFPlus::SDL_SetVideoMode $WIDTH, $HEIGHT, $rgb, $alpha, $FULLSCREEN or die "SDL_SetVideoMode failed: " . (CFPlus::SDL_GetError) . "\n"; $SDL_ACTIVE = 1; @@ -2019,26 +2034,41 @@ sub audio_music_set { my ($songs) = @_; - my $count = @$songs; - my @meta; + my @want = + grep $_, + map $CONN->{music_meta}{$_}, + @$songs; - for my $name (@$songs) { - CFPlus::DB::get resmap => $name, sub { - my ($data) = @_; - - if ($data) { - $data = JSON::XS->new->utf8->decode ($data); - $data->{path} = CFPlus::DB::path_of $name; - push @meta, $data; - } + if (@want) { + @MUSIC_WANT = @want; + &audio_music_changed (); + } +} - unless (--$count) { - if (@meta) { - @MUSIC_WANT = @meta; - &audio_music_changed (); - } - } - }; +sub audio_music_start { + my $path = $MUSIC_PLAYING->{path} + or return; + + CFPlus::DB::prefetch_file $path, 1024_000, sub { + # music might have changed... + $path eq $MUSIC_PLAYING->{path} + or return &audio_music_start (); + + $MUSIC_PLAYER = new_from_file CFPlus::MixMusic $path; + + my $NOW = time; + + if ($MUSIC_PLAYING->{stop_time} > $NOW - $MUSIC_RESUME) { + my $pos = $MUSIC_PLAYING->{stop_pos}; + $MUSIC_PLAYER->fade_in_pos (0, 1000, $pos); + $MUSIC_START = time - $pos; + } else { + $MUSIC_PLAYER->play (0); + $MUSIC_START = time; + } + + delete $MUSIC_PLAYING->{stop_time}; + delete $MUSIC_PLAYING->{stop_pos}; } } @@ -2052,15 +2082,24 @@ return if $MUSIC_PLAYING && grep $MUSIC_PLAYING->{path} eq $_->{path}, @MUSIC_WANT; + my $NOW = time; + if ($MUSIC_PLAYING) { + $MUSIC_PLAYING->{stop_time} = $NOW; + $MUSIC_PLAYING->{stop_pos} = $NOW - $MUSIC_START; CFPlus::MixMusic::fade_out 1000; } else { - my $music = $MUSIC_WANT [rand @MUSIC_WANT]; + # sort by stop time, oldest first + @MUSIC_WANT = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_WANT; - $MUSIC_PLAYING = $music; + # if the most recently-played piece played very recently, + # resume it, else choose the oldest piece for rotation. + $MUSIC_PLAYING = + $MUSIC_WANT[-1]{stop_time} > $NOW - $MUSIC_RESUME + ? $MUSIC_WANT[-1] + : $MUSIC_WANT[0]; - $MUSIC_PLAYER = new_from_file CFPlus::MixMusic $music->{path}; - $MUSIC_PLAYER->play (0); + audio_music_start; } } @@ -2138,7 +2177,7 @@ $NOW = time; ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_) - for CFPlus::SDL_PollEvent; + for CFPlus::poll_events; if (%animate_object) { $_->animate ($LAST_REFRESH - $NOW) for values %animate_object; @@ -2182,7 +2221,8 @@ }, CFPlus::SDL_ACTIVEEVENT => sub { # not useful, as APPACTIVE include sonly iconified state, not unmapped -# printf "active %x %x\n", $_[0]{gain}, $_[0]{state};#d# +# printf "active %x %x %x\n", $_[0]{gain}, $_[0]{state}, CFPlus::SDL_GetAppState;#d# +# printf "a %x\n", CFPlus::SDL_GetAppState & CFPlus::SDL_APPACTIVE;#d# # printf "A\n" if $_[0]{state} & CFPlus::SDL_APPACTIVE; # printf "K\n" if $_[0]{state} & CFPlus::SDL_APPINPUTFOCUS; # printf "M\n" if $_[0]{state} & CFPlus::SDL_APPMOUSEFOCUS; @@ -2273,10 +2313,8 @@ sdl_init; - @SDL_MODES = reverse - grep $_->[0] >= 640 && $_->[1] >= 480, - CFPlus::SDL_ListModes; - + @SDL_MODES = CFPlus::SDL_ListModes 8, 8; + @SDL_MODES = CFPlus::SDL_ListModes 5, 0 unless @SDL_MODES; @SDL_MODES or CFPlus::fatal "Unable to find a usable video mode\n(hardware accelerated opengl fullscreen)"; $CFG->{sdl_mode} = 0 if $CFG->{sdl_mode} > @SDL_MODES;