--- deliantra/Deliantra-Client/DC.pm 2006/05/11 23:41:45 1.50 +++ deliantra/Deliantra-Client/DC.pm 2006/05/25 16:24:43 1.62 @@ -21,9 +21,12 @@ XSLoader::load "CFClient", $VERSION; } +use utf8; + use Carp (); -use AnyEvent; +use AnyEvent (); use BerkeleyDB; + use CFClient::OpenGL; our %GL_EXT; @@ -37,11 +40,13 @@ %GL_EXT = map +($_ => 1), split /\s+/, gl_extensions; $GL_NPOT = $GL_EXT{GL_ARB_texture_non_power_of_two} || $GL_VERSION >= 2; + $GL_NPOT = 0 if gl_vendor =~ /ATI Technologies/; # ATI doesn't get it right... glDisable GL_COLOR_MATERIAL; glShadeModel GL_FLAT; glDisable GL_DITHER; glDisable GL_DEPTH_TEST; + glDepthMask 0; glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST; CFClient::Texture::restore_state (); @@ -51,7 +56,8 @@ return unless $GL_DEBUG; if (my $error = glGetError) { - Carp::cluck sprintf "opengl error %x while %s", $error, sprintf @_; + my ($format, @args) = @_; + Carp::cluck sprintf "opengl error %x while $format", $error, @args; } } @@ -106,7 +112,7 @@ -ErrFile => "$Crossfire::VARDIR/pclient/errorlog.txt", # -ErrPrefix => "DATABASE", -Verbose => 1, - -Flags => DB_CREATE | DB_RECOVER_FATAL | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN, + -Flags => DB_CREATE | DB_RECOVER | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN, or die "unable to create/open database home $Crossfire::VARDIR/pclient: $BerkeleyDB::Error"; sub db_table($) { @@ -119,10 +125,78 @@ -Filename => $table, # -Filename => "database", # -Subname => $table, + -Property => DB_CHKSUM, -Flags => DB_CREATE | DB_UPGRADE, or die "unable to create/open database table $_[0]: $BerkeleyDB::Error"; } +sub pod_to_pango($) { + my ($pom) = @_; + + $pom->present ("CFClient::PodToPango") +} + +sub pod_to_pango_list($) { + my ($pom) = @_; + + [ + map s/^(\s*)// && [40 * length $1, length $_ ? $_ : " "], + split /\n/, $pom->present ("CFClient::PodToPango") + ] +} + +package CFClient::PodToPango; + +use base Pod::POM::View::Text; + +our $indent = 0; + +*view_seq_code = +*view_seq_bold = sub { "$_[1]" }; +*view_seq_italic = sub { "$_[1]" }; +*view_seq_space = +*view_seq_link = +*view_seq_index = sub { CFClient::UI::Label::escape ($_[1]) }; + +sub view_seq_text { + my $text = $_[1]; + $text =~ s/\s+/ /g; + CFClient::UI::Label::escape ($text) +} + +sub view_item { + ("\t" x ($indent / 4)) + . $_[1]->title->present ($_[0]) + . "\n" + . $_[1]->content->present ($_[0]) +} + +sub view_verbatim { + (join "", + map +("\t" x ($indent / 2)) . "$_\n", + split /\n/, CFClient::UI::Label::escape ($_[1])) + . "\n" +} + +sub view_textblock { + ("\t" x ($indent / 2)) . "$_[1]\n\n" +} + +sub view_head1 { + "" . $_[1]->title->present ($_[0]) . "\n\n" + . $_[1]->content->present ($_[0]) +}; + +sub view_head2 { + "" . $_[1]->title->present ($_[0]) . "\n\n" + . $_[1]->content->present ($_[0]) +}; + +sub view_over { + local $indent = $indent + $_[1]->indent; + $_[1]->content->present ($_[0]) +} + package CFClient::Database; our @ISA = BerkeleyDB::Btree::; @@ -145,6 +219,77 @@ $db->db_put ($key => $data) } +package CFClient::Item; + +sub desc_string { + my ($self) = @_; + + my $desc = + $self->{nrof} < 2 + ? $self->{name} + : "$self->{nrof} × $self->{name_pl}"; + + $self->{flags} & Crossfire::Protocol::F_OPEN + and $desc .= " (open)"; + $self->{flags} & Crossfire::Protocol::F_APPLIED + and $desc .= " (applied)"; + $self->{flags} & Crossfire::Protocol::F_UNPAID + and $desc .= " (unpaid)"; + $self->{flags} & Crossfire::Protocol::F_MAGIC + and $desc .= " (magic)"; + $self->{flags} & Crossfire::Protocol::F_CURSED + and $desc .= " (cursed)"; + $self->{flags} & Crossfire::Protocol::F_DAMNED + and $desc .= " (damned)"; + $self->{flags} & Crossfire::Protocol::F_LOCKED + and $desc .= " *"; + + $desc +} + +sub weight_string { + my ($self) = @_; + + my $weight = ($self->{nrof} || 1) * $self->{weight}; + + $weight < 0 ? "?" : $weight * 0.001 +} + +sub update_widgets { + my ($self) = @_; + + my $tooltip_std = "" + . "Left click - examine item\n" + . "Shift-Left click - " . ($self->{container} ? "move or drop" : "take") . " item\n" + . "Middle click - apply\n" + . "Right click - further options" + . "\n"; + + $self->{face_widget} ||= new CFClient::UI::Face can_events => 1, can_hover => 1; + $self->{face_widget}{face} = $self->{face}; + $self->{face_widget}{anim} = $self->{anim}; + $self->{face_widget}{animspeed} = $self->{animespeed}; + $self->{face_widget}->set_tooltip ( + "Face/Animation.\n" + . "Item uses face #$self->{face}. " + . ($self->{animspeed} ? "Item uses animation #$self->{anim} at " . (1 / $self->{animspeed}) . "fps. " : "Item is not animated. ") + . "\n\n$tooltip_std" + ); + + $self->{desc_widget} ||= new CFClient::UI::Label ellipsise => 2, can_events => 1, can_hover => 1; + $self->{desc_widget}->set_text (CFClient::Item::desc_string $self); + + $self->{weight_widget} ||= new CFClient::UI::Label ellipsise => 0, can_events => 1, can_hover => 1, align => 0.5; + $self->{weight_widget}->set_text (CFClient::Item::weight_string $self); + + $self->{weight_widget}->set_tooltip ( + "Weight.\n" + . ($self->{weight} >= 0 ? "One item weighs $self->{weight}g. " : "You have no idea how much this weighs. ") + . ($self->{nrof} ? "You have $self->{nrof} of it. " : "Item cannot stack with others of it's kind. ") + . "\n\n$tooltip_std" + ); +} + package CFClient::Texture; use strict; @@ -302,7 +447,7 @@ if (defined $data) { glTexImage2D GL_TEXTURE_2D, 0, $self->{internalformat}, - $tw, $th, # need to pad texture first + $tw, $th, 0, $self->{format}, $self->{type}, @@ -318,6 +463,8 @@ CFClient::gl_check "copying to texture %dx%d if=%x", $tw, $th, $self->{internalformat}; } + + glBindTexture GL_TEXTURE_2D, 0; # just to be on the safe side } sub DESTROY { @@ -329,10 +476,10 @@ if $self->{name}; } -sub restore_state{ +sub restore_state { $_->upload for values %TEXTURES; -}; +} 1;