--- deliantra/Deliantra-Client/DC.pm 2006/05/25 21:18:09 1.65
+++ deliantra/Deliantra-Client/DC.pm 2006/05/30 14:35:08 1.81
@@ -27,40 +27,6 @@
use AnyEvent ();
use BerkeleyDB;
-use CFClient::OpenGL;
-
-our %GL_EXT;
-our $GL_VERSION;
-
-our $GL_NPOT;
-our $GL_DEBUG = 1;
-
-sub gl_init {
- $GL_VERSION = gl_version * 1;
- %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 ();
-}
-
-sub gl_check {
- return unless $GL_DEBUG;
-
- if (my $error = glGetError) {
- my ($format, @args) = @_;
- Carp::cluck sprintf "opengl error %x while $format", $error, @args;
- }
-}
-
sub find_rcfile($) {
my $path;
@@ -104,22 +70,33 @@
close CFG;
}
-mkdir "$Crossfire::VARDIR/pclient", 0777;
+mkdir "$Crossfire::VARDIR/cfplus", 0777;
+
+our $DB_ENV;
+
+{
+ use strict;
+
+ my $recover = $BerkeleyDB::db_version >= 4.4
+ ? eval "DB_REGISTER | DB_RECOVER"
+ : 0;
-our $DB_ENV = new BerkeleyDB::Env
- -Home => "$Crossfire::VARDIR/pclient",
- -Cachesize => 1_000_000,
- -ErrFile => "$Crossfire::VARDIR/pclient/errorlog.txt",
+ $DB_ENV = new BerkeleyDB::Env
+ -Home => "$Crossfire::VARDIR/cfplus",
+ -Cachesize => 1_000_000,
+ -ErrFile => "$Crossfire::VARDIR/cfplus/errorlog.txt",
# -ErrPrefix => "DATABASE",
- -Verbose => 1,
- -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";
+ -Verbose => 1,
+ -Flags => DB_CREATE | DB_RECOVER | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | $recover,
+ -SetFlags => DB_AUTO_COMMIT | DB_LOG_AUTOREMOVE,
+ or die "unable to create/open database home $Crossfire::VARDIR/cfplus: $BerkeleyDB::Error";
+}
sub db_table($) {
my ($table) = @_;
$table =~ s/([^a-zA-Z0-9_\-])/sprintf "=%x=", ord $1/ge;
-
+
new CFClient::Database
-Env => $DB_ENV,
-Filename => $table,
@@ -127,7 +104,7 @@
# -Subname => $table,
-Property => DB_CHKSUM,
-Flags => DB_CREATE | DB_UPGRADE,
- or die "unable to create/open database table $_[0]: $BerkeleyDB::Error";
+ or die "unable to create/open database table $_[0]: $BerkeleyDB::Error"
}
sub pod_to_pango($) {
@@ -173,7 +150,7 @@
sub view_verbatim {
(join "",
- map +("\t" x ($indent / 2)) . "$_\n",
+ map +("\t" x ($indent / 2)) . "$_\n",
split /\n/, CFClient::UI::Label::escape ($_[1]))
. "\n"
}
@@ -183,12 +160,17 @@
}
sub view_head1 {
- "" . $_[1]->title->present ($_[0]) . "\n\n"
+ "\n\n" . $_[1]->title->present ($_[0]) . "\n\n"
. $_[1]->content->present ($_[0])
};
sub view_head2 {
- "" . $_[1]->title->present ($_[0]) . "\n\n"
+ "\n" . $_[1]->title->present ($_[0]) . "\n\n"
+ . $_[1]->content->present ($_[0])
+};
+
+sub view_head3 {
+ "\n" . $_[1]->title->present ($_[0]) . "\n\n"
. $_[1]->content->present ($_[0])
};
@@ -221,6 +203,9 @@
package CFClient::Item;
+use strict;
+use Crossfire::Protocol::Constants;
+
sub desc_string {
my ($self) = @_;
@@ -229,19 +214,19 @@
? $self->{name}
: "$self->{nrof} × $self->{name_pl}";
- $self->{flags} & Crossfire::Protocol::F_OPEN
+ $self->{flags} & F_OPEN
and $desc .= " (open)";
- $self->{flags} & Crossfire::Protocol::F_APPLIED
+ $self->{flags} & F_APPLIED
and $desc .= " (applied)";
- $self->{flags} & Crossfire::Protocol::F_UNPAID
+ $self->{flags} & F_UNPAID
and $desc .= " (unpaid)";
- $self->{flags} & Crossfire::Protocol::F_MAGIC
+ $self->{flags} & F_MAGIC
and $desc .= " (magic)";
- $self->{flags} & Crossfire::Protocol::F_CURSED
+ $self->{flags} & F_CURSED
and $desc .= " (cursed)";
- $self->{flags} & Crossfire::Protocol::F_DAMNED
+ $self->{flags} & F_DAMNED
and $desc .= " (damned)";
- $self->{flags} & Crossfire::Protocol::F_LOCKED
+ $self->{flags} & F_LOCKED
and $desc .= " *";
$desc
@@ -268,7 +253,8 @@
$targ = $::CONN->{open_container};
}
- $::CONN->send ("move $targ $self->{tag} 0");
+ $::CONN->send ("move $targ $self->{tag} 0")
+ if $targ || !($self->{flags} & F_LOCKED);
} elsif ($ev->{button} == 1) {
$::CONN->send ("examine $self->{tag}");
} elsif ($ev->{button} == 2) {
@@ -279,7 +265,7 @@
["mark", sub { $::CONN->send ("mark ". pack "N", $self->{tag}) }],
["apply", sub { $::CONN->send ("apply $self->{tag}") }],
(
- $self->{flags} & Crossfire::Protocol::F_LOCKED
+ $self->{flags} & F_LOCKED
? (
["unlock", sub { $::CONN->send ("lock " . pack "CN", 0, $self->{tag}) }],
)
@@ -306,7 +292,9 @@
$self->{face_widget} ||= new CFClient::UI::Face
can_events => 1,
can_hover => 1,
- connect_button_down => $button_cb,
+ anim => $self->{anim},
+ animspeed => $self->{animspeed}, # TODO# must be set at creation time
+ on_button_down => $button_cb,
;
$self->{face_widget}{face} = $self->{face};
$self->{face_widget}{anim} = $self->{anim};
@@ -322,8 +310,8 @@
can_events => 1,
can_hover => 1,
ellipsise => 2,
- xalign => 0,
- connect_button_down => $button_cb,
+ align => -1,
+ on_button_down => $button_cb,
;
my $desc = CFClient::Item::desc_string $self;
$self->{desc_widget}->set_text ($desc);
@@ -333,8 +321,8 @@
can_events => 1,
can_hover => 1,
ellipsise => 0,
- xalign => 0.5,
- connect_button_down => $button_cb,
+ align => 0,
+ on_button_down => $button_cb,
;
$self->{weight_widget}->set_text (CFClient::Item::weight_string $self);
@@ -346,195 +334,111 @@
);
}
-package CFClient::Texture;
-
-use strict;
-
-use Scalar::Util;
-
-use CFClient::OpenGL;
-
-my %TEXTURES;
-
-sub new {
- my ($class, %data) = @_;
-
- my $self = bless {
- internalformat => GL_RGBA,
- format => GL_RGBA,
- type => GL_UNSIGNED_BYTE,
- %data,
- }, $class;
-
- Scalar::Util::weaken ($TEXTURES{$self+0} = $self);
-
- $self->upload;
-
- $self
-}
-
-sub new_from_image {
- my ($class, $image, %arg) = @_;
-
- $class->new (image => $image, %arg)
-}
-
-sub new_from_file {
- my ($class, $path, %arg) = @_;
+package CFClient::Binder;
- open my $fh, "<:raw", $path
- or die "$path: $!";
-
- local $/;
- $class->new_from_image (<$fh>, %arg)
-}
-
-#sub new_from_surface {
-# my ($class, $surface) = @_;
-#
-# $surface->rgba;
-#
-# $class->new (
-# data => $surface->pixels,
-# w => $surface->width,
-# h => $surface->height,
-# )
-#}
-
-sub new_from_layout {
- my ($class, $layout, %arg) = @_;
-
- my ($w, $h, $data, $format, $internalformat) = $layout->render;
-
- $class->new (
- w => $w,
- h => $h,
- data => $data,
- format => $format,
- internalformat => $format,
- type => GL_UNSIGNED_BYTE,
- %arg,
- )
-}
-
-sub new_from_opengl {
- my ($class, $w, $h, $cb) = @_;
-
- $class->new (w => $w || 1, h => $h || 1, render_cb => $cb)
-}
-
-sub topot {
- (grep $_ >= $_[0], 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)[0]
-}
-
-sub upload {
- my ($self) = @_;
-
- return unless $GL_VERSION;
-
- my $data;
-
- if (exists $self->{data}) {
- $data = $self->{data};
-
- } elsif (exists $self->{render_cb}) {
- glViewport 0, 0, $self->{w}, $self->{h};
- glMatrixMode GL_PROJECTION;
- glLoadIdentity;
- glOrtho 0, $self->{w}, 0, $self->{h}, -10000, 10000;
- glMatrixMode GL_MODELVIEW;
- glLoadIdentity;
- $self->{render_cb}->($self, $self->{w}, $self->{h});
-
- } else {
- ($self->{w}, $self->{h}, $data, $self->{internalformat}, $self->{format}, $self->{type})
- = CFClient::load_image_inline $self->{image};
- }
-
- my ($tw, $th) = @$self{qw(w h)};
-
- unless ($tw > 0 && $th > 0) {
- $tw = $th = 1;
- $data = "\x00" x 64;
- }
-
- $self->{minified} = [CFClient::average $tw, $th, $data]
- if $self->{minify};
-
- unless ($GL_NPOT) {
- # TODO: does not work for zero-sized textures
- $tw = topot $tw;
- $th = topot $th;
-
- if (($tw != $self->{w} || $th != $self->{h}) && defined $data) {
- my $bpp = (length $data) / ($self->{w} * $self->{h});
- $data = pack "(a" . ($tw * $bpp) . ")*",
- unpack "(a" . ($self->{w} * $bpp) . ")*", $data;
- $data .= ("\x00" x ($tw * $bpp)) x ($th - $self->{h});
- }
- }
-
- $self->{s} = $self->{w} / $tw;
- $self->{t} = $self->{h} / $th;
+my @ALLOWED_MODIFIER_KEYS = (
+ (CFClient::SDLK_LSHIFT),
+ (CFClient::SDLK_LCTRL ),
+ (CFClient::SDLK_LALT ),
+ (CFClient::SDLK_LMETA ),
+
+ (CFClient::SDLK_RSHIFT),
+ (CFClient::SDLK_RCTRL ),
+ (CFClient::SDLK_RALT ),
+ (CFClient::SDLK_RMETA ),
+);
+
+my %ALLOWED_MODIFIERS = (
+ (CFClient::KMOD_LSHIFT) => "LSHIFT",
+ (CFClient::KMOD_LCTRL ) => "LCTRL",
+ (CFClient::KMOD_LALT ) => "LALT",
+ (CFClient::KMOD_LMETA ) => "LMETA",
+
+ (CFClient::KMOD_RSHIFT) => "RSHIFT",
+ (CFClient::KMOD_RCTRL ) => "RCTRL",
+ (CFClient::KMOD_RALT ) => "RALT",
+ (CFClient::KMOD_RMETA ) => "RMETA",
+);
+
+my %DIRECT_BIND_CHARS = map { $_ => 1 } qw/0 1 2 3 4 5 6 7 8 9/;
+my @DIRECT_BIND_KEYS = (
+ CFClient::SDLK_F1,
+ CFClient::SDLK_F2,
+ CFClient::SDLK_F3,
+ CFClient::SDLK_F4,
+ CFClient::SDLK_F5,
+ CFClient::SDLK_F6,
+ CFClient::SDLK_F7,
+ CFClient::SDLK_F8,
+ CFClient::SDLK_F9,
+ CFClient::SDLK_F10,
+ CFClient::SDLK_F11,
+ CFClient::SDLK_F12,
+ CFClient::SDLK_F13,
+ CFClient::SDLK_F14,
+ CFClient::SDLK_F15,
+);
+
+# this binding dialog asks for a key-combo to be pressed
+# and if successful it calls the $cb with $mod and $sym as args.
+sub open_binding_dialog {
+ my ($cb) = @_;
+
+ my $w = new CFClient::UI::FancyFrame
+ title => "Bind Action",
+ x => "center",
+ y => "center";
+
+ $w->add (my $vb = new CFClient::UI::VBox);
+ $vb->add (new CFClient::UI::Label
+ text => "Press a modifier (CTRL, ALT and/or SHIFT) and a key."
+ ."You can only bind 0-9 and F1-F15 without modifiers."
+ );
+ $vb->add (my $entry = new CFClient::UI::Entry
+ text => "",
+ on_key_down => sub {
+ my ($entry, $ev) = @_;
+
+ my $mod = $ev->{mod};
+ my $sym = $ev->{sym};
+
+ # XXX: This seems a little bit hackisch to me, but i have to ignore them
+ if (grep { $_ == $sym } @ALLOWED_MODIFIER_KEYS) {
+ return;
+ }
- $self->{name} ||= glGenTexture;
+ if ($mod == CFClient::KMOD_NONE
+ and not $DIRECT_BIND_CHARS{chr ($ev->{unicode})}
+ and not grep { $sym == $_ } @DIRECT_BIND_KEYS)
+ {
+ $::STATUSBOX->add (
+ "Can't bind key ".CFClient::SDL_GetKeyName ($sym)
+ ." directly without modifier! It would damage the completer handling."
+ );
+ return;
+ }
- glBindTexture GL_TEXTURE_2D, $self->{name};
+ $entry->focus_out;
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP;
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP;
-
- if ($::FAST) {
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST;
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST;
- } elsif ($self->{mipmap} && $GL_VERSION >= 1.4) {
- # alternatively check for 0x8191
- glTexParameter GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1;
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR;
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR;
- } else {
- glTexParameter GL_TEXTURE_2D, GL_GENERATE_MIPMAP, $self->{mipmap};
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR;
- glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR;
- }
-
- glGetError;
+ $cb->($mod, $sym);
- if (defined $data) {
- glTexImage2D GL_TEXTURE_2D, 0,
- $self->{internalformat},
- $tw, $th,
- 0,
- $self->{format},
- $self->{type},
- $data;
- CFClient::gl_check "uploading texture %dx%d if=%x f=%x t=%x",
- $tw, $th, $self->{internalformat}, $self->{format}, $self->{type};
- } else {
- glCopyTexImage2D GL_TEXTURE_2D, 0,
- $self->{internalformat},
- 0, 0,
- $tw, $th,
- 0;
- CFClient::gl_check "copying to texture %dx%d if=%x",
- $tw, $th, $self->{internalformat};
- }
+ $w->destroy
+ });
- glBindTexture GL_TEXTURE_2D, 0; # just to be on the safe side
+ $entry->focus_in;
+ $w->show;
}
-sub DESTROY {
- my ($self) = @_;
-
- delete $TEXTURES{$self+0};
+sub keycombo_to_name {
+ my ($mod, $sym) = @_;
- glDeleteTexture delete $self->{name}
- if $self->{name};
-}
+ my $mods = join '+',
+ map { $ALLOWED_MODIFIERS{$_} }
+ grep { ($_ + 0) & ($mod + 0) }
+ keys %ALLOWED_MODIFIERS;
+ $mods .= "+" if $mods ne '';
-sub restore_state {
- $_->upload
- for values %TEXTURES;
+ return $mods . CFClient::SDL_GetKeyName ($sym);
}
1;