--- deliantra/Deliantra-Client/bin/deliantra 2009/01/12 03:49:35 1.90 +++ deliantra/Deliantra-Client/bin/deliantra 2010/04/08 04:49:32 1.108 @@ -34,8 +34,7 @@ } } -use strict; -use utf8; +use common::sense; use Carp 'verbose'; @@ -58,8 +57,6 @@ # pango is relocatable on win32 } else { # OS X - $ENV{FONTCONFIG_FILE} = "$root/fonts.conf"; # no effect??!?! - $ENV{FONTCONFIG_DIR} = $root; # no effect??!?! $ENV{PANGO_RC_FILE} = "$root/pango.rc"; $ENV{DYLD_LIBRARY_PATH} = $root; chdir $root; # for pango modules, maybe other things @@ -69,7 +66,7 @@ } } -# prepend private library directory +# prepend private library directory and prepare env BEGIN { for (grep !ref, @INC) { my $path = "$_/Deliantra/Client/private"; @@ -138,6 +135,8 @@ my $MAX_FPS = 60; +our $DEFAULT_SERVER = "gameserver.deliantra.net"; + our $META_SERVER = "http://metaserver.schmorp.de/current.json"; our $LAST_REFRESH; @@ -543,6 +542,11 @@ } sub audio_shutdown { + if ($SDL_MIXER) { + DC::MixMusic::halt; + DC::Mix_AllocateChannels 0; + } + undef $MUSIC_PLAYER; undef $MUSIC_PLAYING_META; undef $MUSIC_PLAYING_DATA; @@ -804,7 +808,12 @@ mapw => $mapw, maph => $maph, - client => "$DC::VERSION $] $^O", + version => { + client => "deliantra", + clientver => $DC::VERSION, + gl_vendor => DC::OpenGL::gl_vendor, + gl_version => DC::OpenGL::gl_version, + }, map_widget => $MAPWIDGET, statusbox => $STATUSBOX, @@ -820,7 +829,7 @@ if ($_[0]) { DC::lowdelay fileno $CONN->{fh}; - status "login successful"; + status "successfully connected to the server"; } else { undef $CONN; status "unable to connect: $!"; @@ -832,12 +841,14 @@ sub start_game { status "logging in..."; + + my $server = $PROFILE->{host} || $DEFAULT_SERVER; + my ($host, $port) = AnyEvent::Socket::parse_hostport $server, "deliantra=13327" + or return status "$server: unable to parse server address, try an empty field."; $LOGIN_BUTTON->set_text ("Logout"); $SETUP_DIALOG->hide; - my ($host, $port) = AnyEvent::Socket::parse_hostport $PROFILE->{host}, "deliantra=13327"; - $MAP = new DC::Map; # hack to make SURE we find the IP address all right @@ -845,8 +856,12 @@ if ($host eq "gameserver.deliantra.net") { AnyEvent::DNS::a "dnstest.deliantra.net", sub { if ($_[0] ne "80.101.114.108") { # Perl - status "dns failure, using hardcoded address"; - $host = "129.13.162.95"; + status "dns failure, trying differently"; + $host = eval { Socket::inet_ntoa Socket::inet_aton "gameserver.deliantra.net" }; + unless (defined $host) { + status "dns failure, using hardcoded address"; + $host = "129.13.162.95"; + } } dc_connect $host, $port; @@ -1025,6 +1040,16 @@ on_changed => sub { my ($self, $value) = @_; $CFG->{smooth_movement} = $value; 0 } ); + $table->add_at (0, $row, new DC::UI::Label align => 1, text => "Smooth Transitions"); + $table->add_at (1, $row++, new DC::UI::CheckBox + state => $CFG->{smooth_transitions}, + tooltip => "Smooth Transitions tries to blend the fog of war and lighting smoothly between updates. " + . "If you have a very slow system, non-accelerated drivers or plain dislike smooth scrolling, " + . "then disable this option. Requires Smooth Movement and OpenGL Multitexturing. Changes take effect immdiately.", + on_changed => sub { my ($self, $value) = @_; $CFG->{smooth_transitions} = $value; 0 } + ); + + $table->add_at (0, $row, new DC::UI::Label align => 1, text => "Map Scale"); $table->add_at (1, $row++, new DC::UI::Slider range => [(log $CFG->{map_scale}) / (log 2), -3, 1, 0, 1], @@ -1048,6 +1073,21 @@ on_changed => sub { my ($self, $value) = @_; $CFG->{fow_enable} = $value; 0 } ); + $table->add_at (0, $row, new DC::UI::Label align => 1, text => "FoW Pattern"); + $table->add_at (1, $row++, new DC::UI::ImageButton + tex => $DC::MapWidget::TEX_HIDDEN[$CFG->{fow_texture}], + bg => [0.3, 0.3, 0.2], + force_w => 64, + force_h => 64, + tooltip => "Fog of War Pattern. The pattern that is overlaid over areas hidden from view. Click to cycle through various alternatives. Changes are instant.", + on_activate => sub { + my ($self) = @_; + $CFG->{fow_texture} = ($CFG->{fow_texture} + 1) % @DC::MapWidget::TEX_HIDDEN; + $self->set_texture ($DC::MapWidget::TEX_HIDDEN[$CFG->{fow_texture}]); + $MAPWIDGET->update; + } + ); + $table->add_at (0, $row, new DC::UI::Label align => 1, text => "FoW Intensity"); $table->add_at (1, $row++, new DC::UI::Slider range => [$CFG->{fow_intensity}, 0, 1, 0, 1 / 256], @@ -1107,7 +1147,9 @@ ? "audio is off" : "audio is enabled\n" . "frequency (Hz): $freq\n" - . "channels: $chans"; + . "channels: $chans\n" + . "chunk decoders available: " . (join ", ", DC::MixChunk::decoders) . "\n" + . "music decoders available: " . (join ", ", DC::MixMusic::decoders); $AUDIO_INFO->set_text ($text); } @@ -1637,17 +1679,17 @@ $table->add_at (0, 4, new DC::UI::Label align => 1, text => "Username"); $table->add_at (1, 4, new DC::UI::Entry - text => $CFG->{profile}{default}{user}, + text => $PROFILE->{user}, tooltip => "The name of your character on the server. The name is case-sensitive!", - on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{user} = $value; 1 } + on_changed => sub { my ($self, $value) = @_; $PROFILE->{user} = $value; 1 } ); $table->add_at (0, 5, new DC::UI::Label align => 1, text => "Password"); $table->add_at (1, 5, new DC::UI::Entry - text => $CFG->{profile}{default}{password}, + text => $PROFILE->{password}, hidden => 1, tooltip => "The password for your character.", - on_changed => sub { my ($self, $value) = @_; $CFG->{profile}{default}{password} = $value; 1 } + on_changed => sub { my ($self, $value) = @_; $PROFILE->{password} = $value; 1 } ); $table->add_at (1, 11, $LOGIN_BUTTON = new DC::UI::Button @@ -1693,11 +1735,11 @@ $vbox->add ( $HOST_ENTRY = new DC::UI::Entry expand => 1, - text => $CFG->{profile}{default}{host}, + text => $PROFILE->{host}, tooltip => "The hostname or ip address of the Deliantra server to connect to (e.g. gameserver.deliantra.net)", on_changed => sub { my ($self, $value) = @_; - $CFG->{profile}{default}{host} = $value; + $PROFILE->{host} = $value; 1 } ); @@ -1906,23 +1948,28 @@ my %SORT_ORDER = ( type => sub { + use sort 'stable'; sort { $a->{type} <=> $b->{type} or $a->{name} cmp $b->{name} } @_ }, mtime => sub { - my $NOW = time; - sort { - my $atime = $a->{mtime} - $NOW; $atime = $atime < 5 * 60 ? int $atime / 60 : 6; - my $btime = $b->{mtime} - $NOW; $btime = $btime < 5 * 60 ? int $btime / 60 : 6; - - ($a->{flags} & F_LOCKED) <=> ($b->{flags} & F_LOCKED) - or $btime <=> $atime - or $a->{type} <=> $b->{type} - } @_ - }, - weight => sub { sort { - $a->{weight} * ($a->{nrof} || 1) <=> $b->{weight} * ($b->{nrof} || 1) - or $a->{type} <=> $b->{type} - } @_ }, + use sort 'stable'; + my $NOW = time; + sort { + my $atime = $a->{mtime} - $NOW; $atime = $atime < 5 * 60 ? int $atime / 60 : 6; + my $btime = $b->{mtime} - $NOW; $btime = $btime < 5 * 60 ? int $btime / 60 : 6; + + ($a->{flags} & F_LOCKED) <=> ($b->{flags} & F_LOCKED) + or $btime <=> $atime + or $a->{type} <=> $b->{type} + } @_ + }, + weight => sub { + use sort 'stable'; + sort { + $a->{weight} * ($a->{nrof} || 1) <=> $b->{weight} * ($b->{nrof} || 1) + or $a->{type} <=> $b->{type} + } @_ + }, ); sub inventory_widget { @@ -2483,7 +2530,7 @@ title => "Minimap", name => "mapmap", x => 0, - y => $FONTSIZE + 8, + y => $::FONTSIZE + 8,#d# hack to move messages window below the menubar border_bg => [1, 1, 1, 192/255], bg => [1, 1, 1, 0], child => ($MAPMAP = new DC::MapWidget::MapMap @@ -2522,6 +2569,7 @@ $MESSAGE_WINDOW = new DC::UI::Dockbar name => "message_window2", title => 'Messages', + y => $::FONTSIZE + 8,#d# hack to move messages window below the menubar force_w => $::WIDTH * 0.6, force_h => $::HEIGHT * 0.25, ; @@ -2562,6 +2610,8 @@ $MODE_SLIDER->emit (changed => $CFG->{sdl_mode}); $CAVEAT_LABEL->set_text ("None :)"); + $CAVEAT_LABEL->set_text ("Apple/NVIDIA Texture bug (slow)") + if $DC::OpenGL::APPLE_NVIDIA_BUG; $CAVEAT_LABEL->set_text ("Software Rendering (very slow)") unless DC::SDL_GL_GetAttribute DC::SDL_GL_ACCELERATED_VISUAL; @@ -2704,10 +2754,12 @@ force_opengl11 => undef, disable_alpha => 0, smooth_movement => 1, + smooth_transitions => 1, texture_compression => 1, map_scale => 1, fow_enable => 1, fow_intensity => 0, + fow_texture => 0, map_smoothing => 1, gui_fontsize => 1, log_fontsize => 0.7, @@ -2732,14 +2784,36 @@ logview_max_par => 1000, shift_fire_stop => 0, uitheme => "wood", + map_shift_x => -24, # arbitrary + map_shift_y => +24, # arbitrary ); - + while (my ($k, $v) = each %DEF_CFG) { $CFG->{$k} = $v unless exists $CFG->{$k}; } - $CFG->{profile}{default}{host} ||= "gameserver.deliantra.net"; - $PROFILE = $CFG->{profile}{default}; + my @args = @ARGV; + + my $profile = 'default'; + + for (my $i = 0; $i < @args; $i++) { + if ($args[$i] =~ /^--?profile$/) { + $profile = $args[$i + 1]; + splice @args, $i, 2, (); + $i = 0; + } elsif ($args[$i] =~ /^--?h/) { + print STDERR "Usage: $0 [--profile name] [host [user [password]]]\n"; + exit 0; + } + } + + $CFG->{profile}{$profile} ||= {}; + $PROFILE = $CFG->{profile}{$profile}; + $PROFILE->{host} ||= "gameserver.deliantra.net"; + + $PROFILE->{host} = $args[0] if @args > 0; + $PROFILE->{user} = $args[1] if @args > 1; + $PROFILE->{password} = $args[2] if @args > 2; # convert old bindings (only default profile matters) if (my $bindings = delete $PROFILE->{bindings}) { @@ -2755,6 +2829,9 @@ sdl_init; + $ENV{FONTCONFIG_FILE} = DC::find_rcfile "fonts/fonts.conf"; + $ENV{FONTCONFIG_DIR} = DC::find_rcfile "fonts"; + { my @fonts = map DC::find_rcfile "fonts/$_", qw( DejaVuSans.ttf @@ -2765,10 +2842,11 @@ DejaVuSansMono-Oblique.ttf DejaVuSans-BoldOblique.ttf DejaVuSansMono-BoldOblique.ttf + mona.ttf ); DC::add_font $_ for @fonts; - + $FONT_PROP = new_from_file DC::Font $fonts[0]; $FONT_FIXED = new_from_file DC::Font $fonts[1]; @@ -2822,16 +2900,16 @@ =head1 SYNOPSIS -Just run it - no commandline arguments are supported. + deliantra [--profile name] [host [user [password]]] + deliantra --help =head1 USAGE -deliantra utilises OpenGL for all UI elements and the game. It is supposed to -be used in fullscreen mode and interactively. +The deliantra client utilises OpenGL for all UI elements and the game. It +is supposed to be used in fullscreen mode and interactively. =head1 DEBUGGING - CFPLUS_DEBUG - environment variable 1 draw borders around widgets