--- deliantra/Deliantra-Client/bin/cfplus 2007/04/24 01:13:15 1.152 +++ deliantra/Deliantra-Client/bin/cfplus 2007/07/15 21:08:40 1.169 @@ -1,6 +1,7 @@ #!/opt/bin/perl my $startup_done = sub { }; +our $PANGO = "1.5.0"; # do splash-screen thingy on win32 BEGIN { @@ -31,17 +32,38 @@ if (%PAR::LibCache) { @INC = grep ref, @INC; # weed out all paths except pars loader refs + my $tmp = $ENV{PAR_TEMP}; + while (my ($filename, $zip) = each %PAR::LibCache) { for ($zip->memberNames) { next unless /^root\/(.*)/; - $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1") - unless -e "$ENV{PAR_TEMP}/$1"; + $zip->extractMember ($_, "$tmp/$1") + unless -e "$tmp/$1"; } } - # TODO: pango-rc file, anybody? + if ($^O eq "MSWin32") { + # relocatable + } else { + # unix, need to patch pango rc file + open my $fh, "<:perlio", "$tmp/usr/lib/pango/$PANGO/module-files.d/libpango1.0-0.modules" + or die "$tmp/usr/lib/$PANGO/module-files.d/libpango1.0-0.modules: $!"; + local $/; + my $rc = <$fh>; + $rc =~ s/^\//$tmp\//gm; # replace abs paths by relative ones + + mkdir "$tmp/pango-modules"; + open my $fh, ">:perlio", "$tmp/pango-modules/pango.modules" + or die "$tmp/pango-modules/pango.modules: $!"; + print $fh $rc; + + $ENV{PANGO_RC_FILE} = "$tmp/pango.rc"; + open my $fh, ">:perlio", $ENV{PANGO_RC_FILE} + or die "$ENV{PANGO_RC_FILE}: $!"; + print $fh "[Pango]\nModuleFiles = $tmp/pango-modules\n"; + } - unshift @INC, $ENV{PAR_TEMP}; + unshift @INC, $tmp; } } @@ -139,6 +161,12 @@ our %SDL_CB; 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 @@ -271,14 +299,12 @@ ; } - if ($conn->{chargen_race_title}) { - unshift @dialog, new CFPlus::UI::Face - face => $conn->{player}{face}, - bg => [.2, .2, .2, 1], - min_w => 64, - min_h => 64, - ; - } + unshift @dialog, new CFPlus::UI::Face + face => $conn->{player}{face}, + bg => [.2, .2, .2, 1], + min_w => 64, + min_h => 64, + ; if ($conn->{chargen_race_title}) { unshift @dialog, new CFPlus::UI::Label @@ -478,6 +504,9 @@ $SETUP_DIALOG->show; $PL_WINDOW->hide; $SPELL_LIST->clear_spells; + $CFPlus::UI::ROOT->emit (stop_game => ! ! $CONN); + + &audio_music_set ([]); return unless $CONN; @@ -728,7 +757,7 @@ $table->add (1, 2, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 4; 0 }); $table->add (0, 3, new CFPlus::UI::Label text => "Suppress Tooltips"); $table->add (1, 3, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 8; 0 }); - $table->add (0, 4, new CFPlus::UI::Button text => "die on click(tm)", on_activate => sub { die "violator" } ); + $table->add (0, 4, new CFPlus::UI::Button text => "die on click(tm)", on_activate => sub { &CFPlus::debug() } ); my @default_smooth = (0.05, 0.13, 0.05, 0.13, 0.30, 0.13, 0.05, 0.13, 0.05); @@ -1436,7 +1465,7 @@ my $ntb = $PL_NOTEBOOK = - new CFPlus::UI::Notebook expand => 1, debug => 1; + new CFPlus::UI::Notebook expand => 1; $ntb->add ( "Statistics (F2)" => $STATS_PAGE = stats_window, @@ -1458,6 +1487,8 @@ "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 (Pickup => autopickup_setup, + "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them."); $ntb->set_current_page ($INVENTORY_PAGE); @@ -1794,8 +1825,6 @@ "Configure the server to play on, your username, password and other server-related options."); $SETUP_NOTEBOOK->add (Client => client_setup, "Configure various client-specific settings."); - $SETUP_NOTEBOOK->add (Pickup => autopickup_setup, - "Configure autopickup settings, i.e. which items you will pick up automatically when walking (or running) over them."); $SETUP_NOTEBOOK->add (Graphics => graphics_setup, "Configure the video mode, performance, fonts and other graphical aspects of the game."); $SETUP_NOTEBOOK->add (Audio => audio_setup, @@ -1983,23 +2012,89 @@ undef $SDL_ACTIVE; } -my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# -my $bgmusic;#TODO#hack#d# - sub audio_channel_finished { my ($channel) = @_; #warn "channel $channel finished\n";#d# } -sub audio_music_finished { +sub audio_music_set { + my ($songs) = @_; + + my @want = + grep $_, + map $CONN->{music_meta}{$_}, + @$songs; + + if (@want) { + @MUSIC_WANT = @want; + &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}; + } +} + +sub audio_music_changed { return unless $CFG->{bgm_enable}; - # TODO: hack, do play loop and mood music - $bgmusic = new_from_file CFPlus::MixMusic CFPlus::find_rcfile "music/$bgmusic[0]"; - $bgmusic->play (0); + # default MUSIC_WANT == MUSIC_DEFAULT + @MUSIC_WANT = { path => CFPlus::find_rcfile "music/$MUSIC_DEFAULT" } unless @MUSIC_WANT; + + # if the currently playing song is acceptable, let it continue + 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 { + # sort by stop time, oldest first + @MUSIC_WANT = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_WANT; + + # 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]; + + audio_music_start; + } +} + +sub audio_music_finished { + $MUSIC_PLAYING = undef; + undef $MUSIC_PLAYER; - push @bgmusic, shift @bgmusic; + audio_music_changed; } sub audio_init { @@ -2069,7 +2164,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;