--- deliantra/Deliantra-Client/bin/cfplus 2007/07/12 18:57:45 1.165 +++ deliantra/Deliantra-Client/bin/cfplus 2007/07/15 21:42:02 1.171 @@ -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 @@ -504,6 +506,8 @@ $SPELL_LIST->clear_spells; $CFPlus::UI::ROOT->emit (stop_game => ! ! $CONN); + &audio_music_set ([]); + return unless $CONN; status "connection closed"; @@ -1278,7 +1282,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, @@ -1372,7 +1383,7 @@ 0 }); - $table + $r } my %SORT_ORDER = ( @@ -2017,26 +2028,41 @@ sub audio_music_set { my ($songs) = @_; - my $count = @$songs; - my @meta; + my @want = + grep $_, + map $CONN->{music_meta}{$_}, + @$songs; + + if (@want) { + @MUSIC_WANT = @want; + &audio_music_changed (); + } +} - 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; - } +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; + } - unless (--$count) { - if (@meta) { - @MUSIC_WANT = @meta; - &audio_music_changed (); - } - } - }; + delete $MUSIC_PLAYING->{stop_time}; + delete $MUSIC_PLAYING->{stop_pos}; } } @@ -2050,15 +2076,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; } } @@ -2136,7 +2171,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; @@ -2180,7 +2215,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;