ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/bin/pclient
Revision: 1.29
Committed: Fri Apr 7 23:05:21 2006 UTC (18 years, 1 month ago) by elmex
Branch: MAIN
Changes since 1.28: +15 -2 lines
Log Message:
added some new widgets

File Contents

# User Rev Content
1 root 1.1 #!/opt/bin/perl
2 root 1.25
3 root 1.2 use strict;
4 root 1.25 use utf8;
5 root 1.2
6 root 1.13 use Glib;
7     use Gtk2 -init;
8    
9     use SDL;
10     use SDL::App;
11     use SDL::Event;
12     use SDL::Surface;
13     use SDL::OpenGL;
14     use SDL::OpenGL::Constants;
15    
16 elmex 1.11 use Crossfire;
17 root 1.2 use Crossfire::Client;
18     use Crossfire::Protocol;
19    
20 elmex 1.20 use Crossfire::Client::Util;
21     use Crossfire::Client::Widget;
22 elmex 1.10
23 root 1.19 our $FACECACHE;
24    
25 root 1.13 our $VERSION = '0.1';
26 root 1.2
27 elmex 1.10 our $CFG;
28 root 1.13 our $CONN;
29 root 1.2
30 root 1.25 our $UIFONT;
31 root 1.24
32 root 1.13 our $SDL_TIMER;
33     our $SDL_APP;
34     our $SDL_EV = new SDL::Event;
35     our %SDL_CB;
36 root 1.18
37     our @GL_INIT; # hooks called on every gl init
38 root 1.2
39 root 1.13 sub init_screen {
40     $SDL_APP = new SDL::App
41 root 1.5 -flags => SDL_ANYFORMAT | SDL_HWSURFACE,
42     -title => "Crossfire+ Client",
43 root 1.13 -width => $CFG->{width},
44     -height => $CFG->{height},
45 root 1.5 -opengl => 1,
46     -red_size => 8,
47     -green_size => 8,
48     -blue_size => 8,
49 root 1.2 -double_buffer => 1,
50 root 1.13 -fullscreen => $CFG->{fullscreen},
51 root 1.5 -resizeable => 0;
52 root 1.2
53 root 1.27 $UIFONT = SDL::TTFOpenFont Crossfire::Client::find_rcfile "uifont.ttf", $CFG->{height} / 40
54     or die "TTFOpenFont: $!";
55    
56 root 1.19 glClearColor 0, 0, 0, 0;
57    
58 root 1.2 glEnable GL_TEXTURE_2D;
59     glShadeModel GL_FLAT;
60     glDisable GL_DEPTH_TEST;
61 root 1.9 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
62 root 1.2
63 root 1.9 glMatrixMode GL_PROJECTION;
64 root 1.4 glLoadIdentity;
65 root 1.24 glOrtho 0, $CFG->{width}, $CFG->{height}, 0, -100 , 100;
66 root 1.19
67     glMatrixMode GL_MODELVIEW;
68 root 1.4
69 root 1.17 $_->() for @GL_INIT;
70 root 1.2 }
71    
72 root 1.24 my $label;#d#
73    
74 root 1.13 sub start_game {
75     $SDL_TIMER = add Glib::Timeout 1000/20, sub {
76     while ($SDL_EV->poll) {
77     ($SDL_CB{$SDL_EV->type} || sub { warn "unhandled event ", $SDL_EV->type })->();
78     }
79    
80     1
81     };
82    
83     init_screen;
84    
85 elmex 1.29 my $v = new Crossfire::Client::Widget::Table;
86     $v->add (0, 0, $label = new Crossfire::Client::Widget::Label 500, 10, 1, $UIFONT, "T");
87     $v->add (0, 1, $label = new Crossfire::Client::Widget::Label 500, 10, 1, $UIFONT, "TT");
88     $v->add (0, 2, $label = new Crossfire::Client::Widget::Label 500, 10, 1, $UIFONT, "TTT");
89     $v->add (1, 1, $label = new Crossfire::Client::Widget::Label 500, 10, 1, $UIFONT, "Testü[]");
90     $v->size_request;
91     my $f = new Crossfire::Client::Widget::Frame;
92     $f->add ($v);
93     $f->activate;
94    
95     # $v->add ($label = new Crossfire::Client::Widget::Label 500, 10, 1, $UIFONT, "Testü[]");
96     # $v->add ($label = new Crossfire::Client::Widget::Label 500, 10, 1, $UIFONT, "Testü[]!!");
97     # $v->activate;
98     # $f->add ($v);#$label = new Crossfire::Client::Widget::Label 500, 10, 1, $UIFONT, "Testü[]");
99     # $label->activate;
100 root 1.24
101 root 1.13 $CONN = new conn
102     host => $CFG->{host},
103 root 1.28 port => $CFG->{port},
104     user => $CFG->{user},
105     pass => $CFG->{password};
106 root 1.13 }
107    
108     sub stop_game {
109     remove Glib::Source $SDL_TIMER;
110    
111     undef $SDL_APP;
112     SDL::Quit;
113     }
114    
115 root 1.2 sub refresh {
116 root 1.5 glClear GL_COLOR_BUFFER_BIT;
117 root 1.2
118 elmex 1.26 $_->draw for @Crossfire::Client::Widget::ACTIVE_WIDGETS;
119 root 1.1
120 root 1.2 SDL::GLSwapBuffers;
121 root 1.1 }
122    
123 root 1.13 %SDL_CB = (
124     SDL_QUIT() => sub {
125 root 1.19 main_quit Gtk2;
126 root 1.13 },
127     SDL_VIDEORESIZE() => sub {
128     },
129     SDL_VIDEOEXPOSE() => sub {
130     refresh;
131     },
132     SDL_KEYDOWN() => sub {
133 root 1.18 if ($SDL_EV->key_mod & KMOD_ALT && $SDL_EV->key_sym == SDLK_RETURN) {
134     # alt-enter
135     $CFG->{fullscreen} = !$CFG->{fullscreen};
136     init_screen;
137     } else {
138 root 1.22 Crossfire::Client::Widget::feed_sdl_key_down_event ($SDL_EV);
139 root 1.18 }
140 root 1.13 },
141     SDL_KEYUP() => sub {
142 root 1.22 Crossfire::Client::Widget::feed_sdl_key_up_event ($SDL_EV);
143 root 1.13 },
144     SDL_MOUSEMOTION() => sub {
145     warn "sdl motion\n";#d#
146     },
147     SDL_MOUSEBUTTONDOWN() => sub {
148 root 1.22 Crossfire::Client::Widget::feed_sdl_button_down_event ($SDL_EV);
149 root 1.13 },
150     SDL_MOUSEBUTTONUP() => sub {
151 root 1.22 Crossfire::Client::Widget::feed_sdl_button_up_event ($SDL_EV);
152 root 1.13 },
153     SDL_ACTIVEEVENT() => sub {
154     warn "active\n";#d#
155     },
156     );
157 root 1.1
158 root 1.2 @conn::ISA = Crossfire::Protocol::;
159 root 1.1
160 root 1.2 sub conn::map_update {
161 root 1.1 my ($self, $dirty) = @_;
162    
163 root 1.2 refresh;
164 root 1.1 }
165    
166 root 1.2 sub conn::map_scroll {
167 root 1.1 my ($self, $dx, $dy) = @_;
168    
169 root 1.2 refresh;
170 root 1.1 }
171    
172 root 1.2 sub conn::map_clear {
173 root 1.1 my ($self) = @_;
174    
175 root 1.2 refresh;
176 root 1.1 }
177    
178 root 1.19 sub conn::face_find {
179     my ($self, $face) = @_;
180    
181     $FACECACHE->{"$face->{chksum},$face->{name}"}
182     }
183    
184 root 1.2 sub conn::face_update {
185 root 1.19 my ($self, $face) = @_;
186    
187     $FACECACHE->{"$face->{chksum},$face->{name}"} = $face->{image};
188 root 1.1
189 root 1.18 $face->{texture} = new_from_image Crossfire::Client::Texture delete $face->{image};
190 root 1.1 }
191    
192 elmex 1.23 sub gtk_add_cfg_field {
193     my ($tbl, $cfg, $klbl, $key, $value) = @_;
194     my $i = $cfg->{_i}++;
195     $tbl->attach_defaults (my $lbl = Gtk2::Label->new ($klbl), 0, 1, $i, $i + 1);
196     $tbl->attach_defaults (my $ent = Gtk2::Entry->new, 1, 2, $i, $i + 1);
197     if ($key eq 'password') {
198     $ent->set_invisible_char ("*");
199     $ent->set (visibility => 0)
200     }
201     $ent->set_text ($value);
202     $ent->signal_connect (changed => sub {
203     my ($ent) = @_;
204     $cfg->{$key} = $ent->get_text;
205     });
206     }
207    
208     sub run_config_dialog {
209     my (%events) = @_;
210    
211     my $w = Gtk2::Window->new;
212    
213     my @cfg = (
214     [qw/Host host/],
215     [qw/Port port/],
216     [qw/Username user/],
217     [qw/Password password/],
218     );
219    
220     my $cfg = {};
221    
222     my $a = SDL::ListModes (0, SDL_FULLSCREEN|SDL_HWSURFACE);
223     my @modes = map { [SDL::RectW ($_), SDL::RectH ($_)] } @$a;
224    
225     $w->add (my $vb = Gtk2::VBox->new);
226     $vb->pack_start (my $t = Gtk2::Table->new (2, scalar @cfg), 0, 0, 0);
227     my $selmode = $::CFG->{width} . 'x' . $::CFG->{height};
228     $t->attach_defaults (Gtk2::Label->new ("Modes"), 0, 1, 0, 1);
229     $t->attach_defaults (my $cb = Gtk2::ComboBox->new_text, 1, 2, 0, 1);
230     my $i = 0;
231     my $act = 0;
232     for (map { "$_->[0]x$_->[1]" } reverse @modes) {
233     if ($_ eq $selmode) { $act = $i }
234     $cb->append_text ($_);
235     $i++;
236     }
237     $cb->set_active ($act);
238     $cb->signal_connect (changed => sub {
239     my ($cb) = @_;
240     my $txt = $cb->get_active_text;
241     if ($txt =~ m/(\d+)x(\d+)/) {
242     $::CFG->{width} = $1;
243     $::CFG->{height} = $2;
244     }
245     });
246    
247     $cfg->{_i} = 1;
248     for (@cfg) {
249     gtk_add_cfg_field ($t, $cfg, $_->[0], $_->[1], $::CFG->{$_->[1]});
250     }
251    
252     $vb->pack_start (my $hb = Gtk2::HBox->new, 0, 0, 0);
253     $hb->pack_start (my $cb = Gtk2::Button->new ("save"), 1, 1, 5);
254     $cb->signal_connect (clicked => sub {
255     for (keys %$cfg) {
256     $::CFG->{$_} = $cfg->{$_}
257     if $_ ne '_i';
258     }
259     Crossfire::Client::write_cfg "$Crossfire::VARDIR/pclientrc";
260     });
261     $hb->pack_start (my $cb = Gtk2::Button->new ("login"), 1, 1, 5);
262     $cb->signal_connect (clicked => sub {
263     for (keys %$cfg) {
264     $::CFG->{$_} = $cfg->{$_}
265     if $_ ne '_i';
266     }
267     my $cb = $events{login} || sub {};
268     $cb->($::CFG->{user}, $::CFG->{password});
269     });
270     $hb->pack_start (my $cb = Gtk2::Button->new ("logout"), 1, 1, 5);
271     $cb->signal_connect (clicked => sub {
272     my $cb = $events{login} || sub {};
273     $cb->();
274     });
275     $hb->pack_start (my $cb = Gtk2::Button->new ("quit"), 1, 1, 5);
276     $cb->signal_connect (clicked => sub { $w->destroy });
277    
278     $w->show_all;
279    
280     $w->signal_connect (destroy => sub { Gtk2->main_quit });
281     }
282    
283    
284 root 1.1 #############################################################################
285    
286 root 1.24 SDL::Init SDL_INIT_EVERYTHING;
287 root 1.27 SDL::TTFInit;
288 elmex 1.20
289     my $mapwidget = Crossfire::Client::Widget::MapWidget->new;
290    
291 elmex 1.16 $mapwidget->activate;
292     $mapwidget->focus_in;
293    
294 root 1.22 Crossfire::Client::read_cfg "$Crossfire::VARDIR/pclientrc";
295 elmex 1.10
296 root 1.13 $CFG ||= {
297     width => 640,
298     height => 480,
299     fullscreen => 0,
300     host => "crossfire.schmorp.de",
301     port => 13327,
302     };
303 elmex 1.12
304 root 1.24 $FACECACHE = eval { Crossfire::load_ref "$Crossfire::VARDIR/pclient.faces" } || {};
305    
306 elmex 1.23 run_config_dialog
307 elmex 1.16 login => sub { start_game },
308     logout => sub { stop_game };
309 root 1.1
310 root 1.13 main Gtk2;
311 root 1.19
312     Crossfire::save_ref $FACECACHE, "$Crossfire::VARDIR/pclient.faces";