ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/bin/pclient
(Generate patch)

Comparing deliantra/Deliantra-Client/bin/pclient (file contents):
Revision 1.199 by root, Mon May 8 15:12:39 2006 UTC vs.
Revision 1.223 by elmex, Wed May 17 14:55:15 2006 UTC

37use CFClient; 37use CFClient;
38use CFClient::UI; 38use CFClient::UI;
39use CFClient::MapWidget; 39use CFClient::MapWidget;
40 40
41$Event::DIED = sub { 41$Event::DIED = sub {
42 # TODO: display dialog box or so
42 CFClient::error $_[1]; 43 CFClient::error $_[1];
43}; 44};
44 45
45#$SIG{__WARN__} = sub { Carp::cluck $_[0] };#d# 46#$SIG{__WARN__} = sub { Carp::cluck $_[0] };#d#
46 47
59our $NOW; 60our $NOW;
60 61
61our $CFG; 62our $CFG;
62our $CONN; 63our $CONN;
63our $FAST; # fast, low-quality mode, possibly useful for software-rendering 64our $FAST; # fast, low-quality mode, possibly useful for software-rendering
65
66our $WANT_REFRESH;
67our $CAN_REFRESH;
64 68
65our @SDL_MODES; 69our @SDL_MODES;
66our $WIDTH; 70our $WIDTH;
67our $HEIGHT; 71our $HEIGHT;
68our $FULLSCREEN; 72our $FULLSCREEN;
90our $SDL_MIXER; 94our $SDL_MIXER;
91our @SOUNDS; # event => file mapping 95our @SOUNDS; # event => file mapping
92our %AUDIO_CHUNKS; # audio files 96our %AUDIO_CHUNKS; # audio files
93 97
94our $ALT_ENTER_MESSAGE; 98our $ALT_ENTER_MESSAGE;
95our $STATUS_LINE; 99our $STATUSBOX;
96our $DEBUG_STATUS; 100our $DEBUG_STATUS;
97 101
98our $INVWIN; 102our $INVWIN;
99our $INV; 103our $INV;
104our $INVR;
105our $INVR_LBL;
106our $OPENCONT;
100 107
101sub status { 108sub status {
102 $STATUS_LINE->set_text ($_[0]); 109 $STATUSBOX->add ($_[0], pri => -10, group => "status", timeout => 20, fg => [1, 1, 0, 1]);
103 $STATUS_LINE->move (0, $HEIGHT - $ALT_ENTER_MESSAGE->{h} - $STATUS_LINE->{h});
104} 110}
105 111
106sub debug { 112sub debug {
107 $DEBUG_STATUS->set_text ($_[0]); 113 $DEBUG_STATUS->set_text ($_[0]);
108 $DEBUG_STATUS->move ($WIDTH - $DEBUG_STATUS->{w}, 0, $DEBUG_STATUS->{w}, $DEBUG_STATUS->{h}); 114 my ($w, $h) = $DEBUG_STATUS->size_request;
115 $DEBUG_STATUS->move ($WIDTH - $w, 0);
109} 116}
110 117
111sub start_game { 118sub start_game {
112 $LOGIN_BUTTON->set_text ("Logout");
113
114 status "logging in..."; 119 status "logging in...";
115 120
116 my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32; 121 my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32;
117 122
118 $MAPCACHE = CFClient::db_table "mapcache_$CFG->{host}"; 123 $MAPCACHE = CFClient::db_table "mapcache_$CFG->{host}";
119
120 $MAP = new CFClient::Map $mapsize, $mapsize; 124 $MAP = new CFClient::Map $mapsize, $mapsize;
121 125
122 my ($host, $port) = split /:/, $CFG->{host}; 126 my ($host, $port) = split /:/, $CFG->{host};
123 127
124 $CONN = eval { 128 $CONN = eval {
131 maph => $mapsize, 135 maph => $mapsize,
132 ; 136 ;
133 }; 137 };
134 138
135 if ($CONN) { 139 if ($CONN) {
140 $LOGIN_BUTTON->set_text ("Logout");
141
136 status "login successful"; 142 status "login successful";
137 143
138 CFClient::lowdelay fileno $CONN->{fh}; 144 CFClient::lowdelay fileno $CONN->{fh};
139 } else { 145 } else {
140 status "unable to connect"; 146 status "unable to connect";
141 stop_game(); 147 stop_game();
142 } 148 }
143} 149}
144 150
145sub stop_game { 151sub stop_game {
152 return unless $CONN;
153
146 status "connection closed"; 154 status "connection closed";
147 $LOGIN_BUTTON->set_text ("Login"); 155 $LOGIN_BUTTON->set_text ("Login");
156 $CONN->destroy;
157 $CONN = 0; # false, does not autovivify
158
159 undef $MAPCACHE;
148 undef $CONN; 160 undef $MAP;
149} 161}
150 162
151sub client_setup { 163sub client_setup {
152 my $dialog = new CFClient::UI::FancyFrame 164 my $dialog = new CFClient::UI::FancyFrame
153 title => "Client Setup", 165 title => "Client Setup",
155 $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]); 167 $vbox->add (my $table = new CFClient::UI::Table expand => 1, col_expand => [0, 1]);
156 168
157 $table->add (0, 0, new CFClient::UI::Label valign => 0, align => 1, text => "Video Mode"); 169 $table->add (0, 0, new CFClient::UI::Label valign => 0, align => 1, text => "Video Mode");
158 $table->add (1, 0, my $hbox = new CFClient::UI::HBox); 170 $table->add (1, 0, my $hbox = new CFClient::UI::HBox);
159 171
160 $hbox->add (my $mode_slider = new CFClient::UI::Slider expand => 1, req_w => 100, range => [$CFG->{sdl_mode}, 0, scalar @SDL_MODES, 1]); 172 $hbox->add (my $mode_slider = new CFClient::UI::Slider expand => 1, req_w => 100, range => [$CFG->{sdl_mode}, 0, $#SDL_MODES, 1, 1]);
161 $hbox->add (my $mode_label = new CFClient::UI::Label align => 0, valign => 0, height => 0.8, template => "9999x9999"); 173 $hbox->add (my $mode_label = new CFClient::UI::Label align => 0, valign => 0, height => 0.8, template => "9999x9999");
162 174
163 $mode_slider->connect (changed => sub { 175 $mode_slider->connect (changed => sub {
164 my ($self, $value) = @_; 176 my ($self, $value) = @_;
165 177
190 } 202 }
191 ); 203 );
192 204
193 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale"); 205 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Map Scale");
194 $table->add (1, $row++, new CFClient::UI::Slider 206 $table->add (1, $row++, new CFClient::UI::Slider
195 range => [$CFG->{map_scale}, 0.25, 2, 0.05], 207 range => [$CFG->{map_scale}, 0.25, 2, 0.05, 0.05],
196 tooltip => "Enlarge or shrink the displayed map", 208 tooltip => "Enlarge or shrink the displayed map",
197 connect_changed => sub { 209 connect_changed => sub {
198 my ($self, $value) = @_; 210 my ($self, $value) = @_;
199 $CFG->{map_scale} = 0.05 * int $value / 0.05; 211 $CFG->{map_scale} = $value;
200 } 212 }
201 ); 213 );
202 214
203 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War"); 215 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Fog of War");
204 $table->add (1, $row++, new CFClient::UI::CheckBox 216 $table->add (1, $row++, new CFClient::UI::CheckBox
231 } 243 }
232 ); 244 );
233 245
234 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "GUI Fontsize"); 246 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "GUI Fontsize");
235 $table->add (1, $row++, new CFClient::UI::Slider 247 $table->add (1, $row++, new CFClient::UI::Slider
236 range => [$CFG->{gui_fontsize}, 0.5, 2, 0.1], 248 range => [$CFG->{gui_fontsize}, 0.5, 2, 0.1, 0.1],
237 tooltip => "The font size used by most GUI elements", 249 tooltip => "The font size used by most GUI elements",
238 connect_changed => sub { 250 connect_changed => sub { $CFG->{gui_fontsize} = $_[1] },
239 $CFG->{gui_fontsize} = 0.1 * int $_[1] * 10;
240# $FONTSIZE = int $HEIGHT / 40 * $CFG->{gui_fontsize};
241 }
242 ); 251 );
243 252
244 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Server Log Fontsize"); 253 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Server Log Fontsize");
245 $table->add (1, $row++, new CFClient::UI::Slider 254 $table->add (1, $row++, new CFClient::UI::Slider
246 range => [$CFG->{log_fontsize}, 0.5, 2, 0.1], 255 range => [$CFG->{log_fontsize}, 0.5, 2, 0.1, 0.1],
247 tooltip => "The font size used by the server log window only", 256 tooltip => "The font size used by the server log window only",
248 connect_changed => sub { 257 connect_changed => sub { $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = $_[1]) },
249 $LOGVIEW->set_fontsize ($CFG->{log_fontsize} = 0.1 * int $_[1] * 10);
250 }
251 ); 258 );
252 259
253 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Stats Fontsize"); 260 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Stats Fontsize");
254 261
255 $table->add (1, $row++, new CFClient::UI::Slider 262 $table->add (1, $row++, new CFClient::UI::Slider
256 range => [$CFG->{stat_fontsize}, 0.5, 2, 0.1], 263 range => [$CFG->{stat_fontsize}, 0.5, 2, 0.1, 0.1],
257 tooltip => "The font size used by the statistics window only", 264 tooltip => "The font size used by the statistics window only",
258 connect_changed => sub { 265 connect_changed => sub {
259 $CFG->{stat_fontsize} = 0.1 * int $_[1] * 10; 266 $CFG->{stat_fontsize} = $_[1];
260 &set_stats_window_fontsize; 267 &set_stats_window_fontsize;
261 } 268 }
262 ); 269 );
263 270
264 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge size"); 271 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge size");
265 $table->add (1, $row++, new CFClient::UI::Slider 272 $table->add (1, $row++, new CFClient::UI::Slider
266 range => [$CFG->{gauge_size}, 0.2, 0.8, 0.02], 273 range => [$CFG->{gauge_size}, 0.2, 0.8, 0.02],
267 tooltip => "Adjust the size of the stats gauges at the bottom right", 274 tooltip => "Adjust the size of the stats gauges at the bottom right",
268 connect_changed => sub { 275 connect_changed => sub {
269 $CFG->{gauge_size} = $_[1]; 276 $CFG->{gauge_size} = $_[1];
270 my $h = int $HEIGHT * $CFG->{gauge_size}; 277 $GAUGES->{win}->set_size ($WIDTH, int $HEIGHT * $CFG->{gauge_size});
271 $GAUGES->{win}->set_size ($WIDTH, $h);
272 $GAUGES->{win}->move (0, $HEIGHT - $h);
273 } 278 }
274 ); 279 );
275 280
276 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge fontsize"); 281 $table->add (0, $row, new CFClient::UI::Label valign => 0, align => 1, text => "Gauge fontsize");
277 $table->add (1, $row++, new CFClient::UI::Slider 282 $table->add (1, $row++, new CFClient::UI::Slider
278 range => [$CFG->{gauge_fontsize}, 0.5, 2.0, 0.1], 283 range => [$CFG->{gauge_fontsize}, 0.5, 2.0, 0.1, 0.1],
279 tooltip => "Adjusts the fontsize of the gauges at the bottom right", 284 tooltip => "Adjusts the fontsize of the gauges at the bottom right",
280 connect_changed => sub { 285 connect_changed => sub {
281 $CFG->{gauge_fontsize} = 0.1 * int $_[1] * 10; 286 $CFG->{gauge_fontsize} = $_[1];
282 &set_gauge_window_fontsize; 287 &set_gauge_window_fontsize;
283 } 288 }
284 ); 289 );
285 290
286 $table->add (1, $row++, new CFClient::UI::Button 291 $table->add (1, $row++, new CFClient::UI::Button
360# local $GAUGES->{win}{parent};#d# 365# local $GAUGES->{win}{parent};#d#
361# use PApp::Util; open D, ">:utf8", "d"; print D PApp::Util::dumpval $GAUGES->{win}; close D; 366# use PApp::Util; open D, ">:utf8", "d"; print D PApp::Util::dumpval $GAUGES->{win}; close D;
362} 367}
363 368
364sub make_gauge_window { 369sub make_gauge_window {
365 my $gh = int ($HEIGHT * $CFG->{gauge_size}); 370 my $gh = int $HEIGHT * $CFG->{gauge_size};
366# my $gw = int ($WIDTH * $CFG->{gauge_w_size});
367 371
368 my $win = new CFClient::UI::Frame ( 372 my $win = new CFClient::UI::Frame (
369 y => $HEIGHT - $gh, x => 0, user_w => $WIDTH, user_h => $gh 373 req_y => -1,
374 user_w => $WIDTH,
375 user_h => $gh,
370 ); 376 );
377
371 $win->add (my $hbox = new CFClient::UI::HBox 378 $win->add (my $hbox = new CFClient::UI::HBox
372 children => [ 379 children => [
373 (new CFClient::UI::HBox expand => 1), 380 (new CFClient::UI::HBox expand => 1),
374 ($FLOORBOX = new CFClient::UI::VBox), 381 (new CFClient::UI::VBox children => [
382 (new CFClient::UI::Empty expand => 1),
383 (new CFClient::UI::Frame bg => [0, 0, 0, 0.4], child => ($FLOORBOX = new CFClient::UI::VBox)),
384 ]),
375 (my $vbox = new CFClient::UI::VBox), 385 (my $vbox = new CFClient::UI::VBox),
376 ], 386 ],
377 ); 387 );
378 388
379 $vbox->add (new CFClient::UI::HBox 389 $vbox->add (new CFClient::UI::HBox
689 699
690 $METASERVER = metaserver_dialog; 700 $METASERVER = metaserver_dialog;
691 701
692 $vbox->add (new CFClient::UI::Flopper 702 $vbox->add (new CFClient::UI::Flopper
693 expand => 1, 703 expand => 1,
694 text => "Metaserver", 704 text => "Server List",
695 other => $METASERVER, 705 other => $METASERVER,
696 tooltip => "Show a list of avaible crossfire servers", 706 tooltip => "Show a list of available crossfire servers",
697 connect_open => sub { 707 connect_open => sub {
698 update_metaserver $HOST; 708 update_metaserver $HOST;
699 } 709 }
700 ); 710 );
701 } 711 }
722 ); 732 );
723 733
724 $table->add (0, 7, new CFClient::UI::Label valign => 0, align => 1, text => "Map Size"); 734 $table->add (0, 7, new CFClient::UI::Label valign => 0, align => 1, text => "Map Size");
725 $table->add (1, 7, new CFClient::UI::Slider 735 $table->add (1, 7, new CFClient::UI::Slider
726 req_w => 100, 736 req_w => 100,
727 range => [$CFG->{mapsize}, 10, 100 + 1, 1], 737 range => [$CFG->{mapsize}, 10, 100 + 1, 1, 1],
728 tooltip => "This is the size of the portion of the map update the server sends you. " 738 tooltip => "This is the size of the portion of the map update the server sends you. "
729 ."If you set this to a high value you will be able to see further for example.", 739 ."If you set this to a high value you will be able to see further for example.",
730 connect_changed => sub { 740 connect_changed => sub {
731 my ($self, $value) = @_; 741 my ($self, $value) = @_;
732 742
800 810
801 $window 811 $window
802} 812}
803 813
804sub make_inventory_window { 814sub make_inventory_window {
805 my $invwin = new CFClient::UI::FancyFrame user_w => 300, user_h => 300, title => "Inventory"; 815 my $invwin = new CFClient::UI::FancyFrame
816 user_w => $WIDTH * (4/5), user_h => $HEIGHT * (4/5), title => "Inventory";
817
818 $invwin->add (my $hb = new CFClient::UI::HBox);
819
820 $hb->add (my $vb1 = new CFClient::UI::VBox expand => 1);
821 $vb1->add (my $lbl = new CFClient::UI::Label);
822 $lbl->set_text ("Player");
806 $invwin->add ($INV = new CFClient::UI::Inventory expand => 1); 823 $vb1->add ($INV = new CFClient::UI::Inventory expand => 1);
824
825 $hb->add (my $vb2 = new CFClient::UI::VBox expand => 1);
826 $vb2->add ($INVR_LBL = new CFClient::UI::Label);
827 $INVR_LBL->set_text ("Floor");
828 $vb2->add ($INVR = new CFClient::UI::Inventory expand => 1);
829
807 $invwin 830 $invwin
808} 831}
809 832
810sub sdl_init { 833sub sdl_init {
811 CFClient::SDL_Init 834 CFClient::SDL_Init
823 846
824 CFClient::SDL_SetVideoMode $WIDTH, $HEIGHT, $FULLSCREEN 847 CFClient::SDL_SetVideoMode $WIDTH, $HEIGHT, $FULLSCREEN
825 or die "SDL_SetVideoMode failed!\n"; 848 or die "SDL_SetVideoMode failed!\n";
826 849
827 $SDL_ACTIVE = 1; 850 $SDL_ACTIVE = 1;
828
829 $LAST_REFRESH = time - 0.01; 851 $LAST_REFRESH = time - 0.01;
830 852
831 CFClient::gl_init; 853 CFClient::gl_init;
832 854
833 $FONTSIZE = int $HEIGHT / 40 * $CFG->{gui_fontsize}; 855 $FONTSIZE = int $HEIGHT / 40 * $CFG->{gui_fontsize};
834 856
857 $CFClient::UI::ROOT->configure (0, 0, $WIDTH, $HEIGHT);#d#
858
835 ############################################################################# 859 #############################################################################
836 860
861 unless ($DEBUG_STATUS) {
862 # create the widgets
863
837 $DEBUG_STATUS = new CFClient::UI::Label padding => 0, z => 100; 864 $DEBUG_STATUS = new CFClient::UI::Label padding => 0, z => 100, req_x => -1;
838 $DEBUG_STATUS->show; 865 $DEBUG_STATUS->show;
839 866
840 $STATUS_LINE = new CFClient::UI::Label 867 $STATUSBOX = new CFClient::UI::Statusbox;
841 padding => 0, 868 $STATUSBOX->add ("Use <b>Alt-Enter</b> to toggle fullscreen mode", pri => -100, color => [1, 1, 1, 0.8]);
842 y => $HEIGHT - $FONTSIZE * 1.8;
843 $STATUS_LINE->show;
844 869
845 $ALT_ENTER_MESSAGE = new CFClient::UI::Label 870 (new CFClient::UI::Frame
846 padding => 0, 871 bg => [0, 0, 0, 0.4],
847 fontsize => 0.8, 872 req_y => -1,
848 markup => "Use <b>Alt-Enter</b> to toggle fullscreen mode"; 873 child => $STATUSBOX,
849 $ALT_ENTER_MESSAGE->show; 874 )->show;
850 $ALT_ENTER_MESSAGE->move (0, $HEIGHT - $ALT_ENTER_MESSAGE->{h});
851 875
852 CFClient::UI::FancyFrame->new ( 876 CFClient::UI::FancyFrame->new (
853 border_bg => [1, 1, 1, 192/255], 877 border_bg => [1, 1, 1, 192/255],
854 bg => [1, 1, 1, 0], 878 bg => [1, 1, 1, 0],
855 child => ($MAPMAP = new CFClient::MapWidget::MapMap), 879 child => ($MAPMAP = new CFClient::MapWidget::MapMap),
856 )->show; 880 )->show;
857 881
858 $MAPWIDGET = new CFClient::MapWidget; 882 $MAPWIDGET = new CFClient::MapWidget;
859 $MAPWIDGET->connect (activate_console => sub { 883 $MAPWIDGET->connect (activate_console => sub {
860 my ($mapwidget, $preset) = @_; 884 my ($mapwidget, $preset) = @_;
861 885
862 if ($CONSOLE) { 886 if ($CONSOLE) {
863 $CONSOLE->{input}->{auto_activated} = 1; 887 $CONSOLE->{input}->{auto_activated} = 1;
864 $CONSOLE->{input}->focus_in; 888 $CONSOLE->{input}->focus_in;
865 889
866 if ($preset && $CONSOLE->{input}->get_text eq '') { 890 if ($preset && $CONSOLE->{input}->get_text eq '') {
867 $CONSOLE->{input}->set_text ($preset); 891 $CONSOLE->{input}->set_text ($preset);
892 }
868 } 893 }
869 } 894 });
870 });
871 $MAPWIDGET->show; 895 $MAPWIDGET->show;
872 $MAPWIDGET->focus_in; 896 $MAPWIDGET->focus_in;
873 897
874 $BUTTONBAR = new CFClient::UI::HBox; 898 $BUTTONBAR = new CFClient::UI::HBox;
875 899
876 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup); 900 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Client Setup", other => client_setup);
877 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup); 901 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Server Setup", other => server_setup);
878 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window); 902 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Message Window", other => message_window);
879 903
880 make_gauge_window->show; # XXX: this has to be set before make_stats_window as make_stats_window calls update_stats_window which updated the gauges also X-D 904 make_gauge_window->show; # XXX: this has to be set before make_stats_window as make_stats_window calls update_stats_window which updated the gauges also X-D
881 905
882 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window); 906 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Stats Window", other => make_stats_window);
883 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => make_inventory_window); 907 $BUTTONBAR->add (new CFClient::UI::Flopper text => "Inventory", other => make_inventory_window);
884 908
885 $BUTTONBAR->add (new CFClient::UI::Button text => "Save Config", connect_activate => sub { 909 $BUTTONBAR->add (new CFClient::UI::Button text => "Save Config", connect_activate => sub {
886 CFClient::write_cfg "$Crossfire::VARDIR/pclientrc"; 910 CFClient::write_cfg "$Crossfire::VARDIR/pclientrc";
887 status "Configuration Saved"; 911 status "Configuration Saved";
888 }); 912 });
889 913
890 $BUTTONBAR->show; 914 $BUTTONBAR->show;
891 915
916 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
917
918 # delay till geometry is constant
919 $CFClient::UI::ROOT->on_post_alloc (startup => sub {
892 $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup 920 $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup
921 my $widget = $GAUGES->{win};
922 $widget->move (0, $HEIGHT - $widget->{h});#d# to in toplevel
923 });
924 force_refresh ();
925 }
893} 926}
894 927
895sub video_shutdown { 928sub video_shutdown {
896 $CFClient::UI::ROOT->{children} = [];
897 undef $CFClient::UI::GRAB;
898 undef $CFClient::UI::HOVER;
899 undef $SDL_ACTIVE; 929 undef $SDL_ACTIVE;
900} 930}
901 931
902my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# 932my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d#
903my $bgmusic;#TODO#hack#d# 933my $bgmusic;#TODO#hack#d#
955} 985}
956 986
957my %animate_object; 987my %animate_object;
958my $animate_timer; 988my $animate_timer;
959 989
960my $want_refresh;
961my $can_refresh;
962
963my $fps = 9; 990my $fps = 9;
964 991
965sub force_refresh { 992sub force_refresh {
966 $fps = $fps * 0.95 + 1 / ($NOW - $LAST_REFRESH) * 0.05; 993 $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05;
967 debug sprintf "%3.2f", $fps; 994 debug sprintf "%3.2f", $fps;
968 995
969 $want_refresh = 0;
970 $can_refresh = 0;
971
972 $CFClient::UI::ROOT->draw; 996 $CFClient::UI::ROOT->draw;
973
974 CFClient::SDL_GL_SwapBuffers; 997 CFClient::SDL_GL_SwapBuffers;
975 998
999 $WANT_REFRESH = 0;
1000 $CAN_REFRESH = 0;
976 $LAST_REFRESH = $NOW; 1001 $LAST_REFRESH = $NOW;
977} 1002}
978 1003
979my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub { 1004my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub {
980 $NOW = time; 1005 $NOW = time;
982 ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_) 1007 ($SDL_CB{$_->{type}} || sub { warn "unhandled event $_->{type}" })->($_)
983 for CFClient::SDL_PollEvent; 1008 for CFClient::SDL_PollEvent;
984 1009
985 if (%animate_object) { 1010 if (%animate_object) {
986 $_->animate ($LAST_REFRESH - $NOW) for values %animate_object; 1011 $_->animate ($LAST_REFRESH - $NOW) for values %animate_object;
987 $want_refresh++; 1012 $WANT_REFRESH++;
988 } 1013 }
989 1014
990 if ($want_refresh) { 1015 if ($WANT_REFRESH) {
991 force_refresh; 1016 force_refresh;
992 } else { 1017 } else {
993 $can_refresh = 1; 1018 $CAN_REFRESH = 1;
994 } 1019 }
995}); 1020});
996
997sub refresh {
998 $want_refresh++;
999}
1000 1021
1001sub animation_start { 1022sub animation_start {
1002 my ($widget) = @_; 1023 my ($widget) = @_;
1003 $animate_object{$widget} = $widget; 1024 $animate_object{$widget} = $widget;
1004} 1025}
1316 [0.55, 0.41, 0.13], 1337 [0.55, 0.41, 0.13],
1317 [0.99, 0.77, 0.26], 1338 [0.99, 0.77, 0.26],
1318 [0.74, 0.65, 0.41], 1339 [0.74, 0.65, 0.41],
1319 ); 1340 );
1320 1341
1342 my $time = sprintf "%02d:%02d:%02d", (localtime time)[2,1,0];
1343
1344 $text = CFClient::UI::Label::escape $text;
1345 $text =~ s/\[b\](.*?)\[\/b\]/<b>\1<\/b>/g;
1346 $text =~ s/\[color=(.*?)\](.*?)\[\/color\]/<span foreground='\1'>\2<\/span>/g;
1347
1321 $LOGVIEW->add_paragraph ($color[$color], $text); 1348 $LOGVIEW->add_paragraph ($color[$color],
1349 join "\n", map "$time $_", split /\n/, $text);
1350
1351 $STATUSBOX->add ($text,
1352 group => $text,
1353 fg => $color[$color],
1354 timeout => 60,
1355 tooltip_font => $::FONT_FIXED,
1356 );
1357}
1358
1359sub conn::drawextinfo {
1360 my ($self, $color, $type, $subtype, $message) = @_;
1361
1362 $self->drawinfo ($color, $message);
1322} 1363}
1323 1364
1324sub conn::spell_add { 1365sub conn::spell_add {
1325 my ($self, $spell) = @_; 1366 my ($self, $spell) = @_;
1326 1367
1335} 1376}
1336 1377
1337sub conn::addme_success { 1378sub conn::addme_success {
1338 my ($self) = @_; 1379 my ($self) = @_;
1339 1380
1381 $MAPWIDGET->clr_commands;
1382
1340 for my $skill (values %{$self->{skill_info}}) { 1383 for my $skill (values %{$self->{skill_info}}) {
1341 $MAPWIDGET->add_command ("ready_skill $skill", "Ready the skill '$skill'"); 1384 $MAPWIDGET->add_command ("ready_skill $skill", "Ready the skill '$skill'");
1342 $MAPWIDGET->add_command ("use_skill $skill", "Immediately use the skill '$skill'"); 1385 $MAPWIDGET->add_command ("use_skill $skill", "Immediately use the skill '$skill'");
1343 } 1386 }
1387
1388 $MAPWIDGET->add_command ("petmode defend", "Tell pets to stay close to you and defend you");
1389 $MAPWIDGET->add_command ("petmode arena", "Same as petmode sad, but also attack other players");
1390 $MAPWIDGET->add_command ("petmode sad", "Search &amp; Destroy - tell pets to roam about and attack enemies");
1391 $MAPWIDGET->add_command ("killpets", "Kill your pets");
1392 $MAPWIDGET->add_command ("chat", "chat TEXT\nChat with all other players");
1393 $MAPWIDGET->add_command ("shout", "shout TEXT\nShout loudly, used for emergencies");
1394 $MAPWIDGET->add_command ("tell", "tell USERNAME TEXT\nPrivately tell a specific player");
1395
1396 # TODO: add documentation on these
1397 for (qw(
1398 afk
1399 apply
1400 body
1401 bowmode
1402 brace
1403 build
1404 disarm
1405 dm
1406 dmhide
1407 drop
1408 dropall
1409 examine
1410 get
1411 gsay
1412 help
1413 hiscore
1414 inventory
1415 invoke
1416 killpets
1417 listen
1418 logs
1419 mapinfo
1420 maps
1421 mark
1422 motd
1423 output-count
1424 output-sync
1425 party
1426 peaceful
1427 petmode
1428 pickup
1429 players
1430 prepare
1431 quests
1432 rename
1433 resistances
1434 rotateshoottype
1435 save
1436 say
1437 search
1438 search-items
1439 showpets
1440 skills
1441 sound
1442 take
1443 throw
1444 time
1445 title
1446 usekeys
1447 version
1448 weather
1449 whereabouts
1450 whereami
1451 who
1452 wimpy
1453 )) {
1454 $MAPWIDGET->add_command ($_, "$_: no help available (yet)");
1455 }
1456
1457 #TODO: add " and ' "aliases" etc.
1458}
1459
1460sub conn::eof {
1461 $MAPWIDGET->clr_commands;
1462
1463 stop_game;
1344} 1464}
1345 1465
1346sub update_floorbox { 1466sub update_floorbox {
1347 $CFClient::UI::ROOT->on_refresh ($FLOORBOX => sub { 1467 $CFClient::UI::ROOT->on_refresh ($FLOORBOX => sub {
1468 return unless $CONN;
1469
1348 $FLOORBOX->clear; 1470 $FLOORBOX->clear;
1349 $FLOORBOX->add (new CFClient::UI::Empty expand => 1); 1471 $FLOORBOX->add (new CFClient::UI::Empty expand => 1);
1350 1472
1351 # we basically have to use the same sorting as everybody else 1473 my $count = 4;
1352 for my $item (@{ $CONN->{container}{0} }) { 1474 for (@{ $CONN->{container}{0} }) {
1475 if (--$count) {
1353 $FLOORBOX->add (new CFClient::UI::InventoryItem item => $item); 1476 $FLOORBOX->add (new CFClient::UI::InventoryItem item => $_);
1477 } else {
1478 $FLOORBOX->add (new CFClient::UI::Label text => "More...");
1479 last;
1480 }
1354 } 1481 }
1355 }); 1482 });
1356 refresh; 1483
1484 $WANT_REFRESH++;
1357} 1485}
1358 1486
1359sub conn::container_add { 1487sub conn::container_add {
1360 my ($self, $id, $items) = @_; 1488 my ($self, $tag, $items) = @_;
1361 1489
1362 update_floorbox if $id == 0; 1490 #d# print "container_add: container $tag ($self->{player}{tag})\n";
1491
1492 if ($tag == 0) {
1493 update_floorbox;
1494 $OPENCONT = 0;
1495 $INVR_LBL->set_text ("Floor");
1496 $INVR->set_items ($self->{container}{0});
1363 if ($self->{player}{tag} == $id) { 1497 } elsif ($tag == $self->{player}{tag}) {
1498 $INVR_LBL->set_text ("Player");
1364 $INV->set_items ($self->{container}{$self->{player}{tag}}); 1499 $INV->set_items ($self->{container}{$self->{player}{tag}})
1500 } else {
1501 $OPENCONT = $tag;
1502 $INVR_LBL->set_text (CFClient::UI::InventoryItem::_item_to_desc ($self->{item}->{$OPENCONT}));
1503 $INVR->set_items ($self->{container}{$tag});
1365 } 1504 }
1505
1366 # $self-<{player}{tag} => player inv 1506 # $self-<{player}{tag} => player inv
1367 #use PApp::Util; warn PApp::Util::dumpval $self->{container}{$self->{player}{tag}}; 1507 #use PApp::Util; warn PApp::Util::dumpval $self->{container}{$self->{player}{tag}};
1368} 1508}
1369 1509
1370sub conn::container_clear { 1510sub conn::container_clear {
1371 my ($self, $id) = @_; 1511 my ($self, $tag) = @_;
1372 1512
1373 update_floorbox if $id == 0; 1513 #d# print "container_clear: container $tag ($self->{player}{tag})\n";
1374 if ($self->{player}{tag} == $id) { 1514
1515 if ($tag == 0) {
1516 update_floorbox;
1517 $OPENCONT = 0;
1518 $INVR_LBL->set_text ("Floor");
1375 $INV->set_items ($self->{container}{$id}); 1519 $INVR->set_items ($self->{container}{0});
1520 } elsif ($tag == $self->{player}{tag}) {
1521 $INVR_LBL->set_text ("Player");
1522 $INV->set_items ($self->{container}{$tag})
1523 } else {
1524 $OPENCONT = $tag;
1525 $INVR_LBL->set_text (CFClient::UI::InventoryItem::_item_to_desc ($self->{item}->{$OPENCONT}));
1526 $INVR->set_items ($self->{container}{$tag});
1376 } 1527 }
1377 1528
1378# use PApp::Util; warn PApp::Util::dumpval $self->{container}{0}; 1529# use PApp::Util; warn PApp::Util::dumpval $self->{container}{0};
1379} 1530}
1380 1531
1381sub conn::item_delete { 1532sub conn::item_delete {
1382 my ($self, @items) = @_; 1533 my ($self, @items) = @_;
1383 1534
1384 for (@items) { 1535 for (@items) {
1385 update_floorbox if $_->{container} == 0; 1536 #d# print "item_delete: $_->{tag} from $_->{container} ($self->{player}{tag})\n";
1386 if ($self->{player}{tag} == $_->{container}) { 1537
1538 if ($_->{container} == 0) {
1539 update_floorbox;
1540 $OPENCONT = 0;
1541 $INVR_LBL->set_text ("Floor");
1542 $INVR->set_items ($self->{container}{0});
1543 } elsif ($_->{container} == $self->{player}{tag}) {
1544 $INVR_LBL->set_text ("Player");
1545 $INV->set_items ($self->{container}{$self->{player}{tag}})
1546 } else {
1547 $OPENCONT = $_->{container};
1548 $INVR_LBL->set_text (CFClient::UI::InventoryItem::_item_to_desc ($self->{item}->{$OPENCONT}));
1387 $INV->set_items ($self->{container}{$_->{container}}); 1549 $INVR->set_items ($self->{container}{$_->{container}});
1388 } 1550 }
1389 } 1551 }
1390} 1552}
1391 1553
1392sub conn::item_update { 1554sub conn::item_update {
1393 my ($self, $item) = @_; 1555 my ($self, $item) = @_;
1394 1556
1395 update_floorbox if $item->{container} == 0; 1557 #d# print "item_update: $item->{tag} in $item->{container} ($self->{player}{tag}) ($OPENCONT)\n";
1396 if ($self->{player}{tag} == $item->{container}) { 1558
1559 if ($item->{tag} == $OPENCONT && not ($item->{flags} & Crossfire::Protocol::F_OPEN)) {
1560 $OPENCONT = 0;
1561 $INVR_LBL->set_text ("Floor");
1562 $INVR->set_items ($self->{container}{0});
1563
1564 $item->{widget}->update_item
1565 if $item->{widget};
1566 } else {
1567 if ($item->{container} == 0) {
1568 update_floorbox;
1569 $OPENCONT = 0;
1570 $INVR_LBL->set_text ("Floor");
1571 $INVR->set_items ($self->{container}{0});
1572 } elsif ($item->{container} == $self->{player}{tag}) {
1397 $INV->set_items ($self->{container}{$item->{container}}); 1573 $INV->set_items ($self->{container}{$item->{container}})
1574 }
1398 } 1575 }
1399} 1576}
1400 1577
1401%SDL_CB = ( 1578%SDL_CB = (
1402 CFClient::SDL_QUIT => sub { 1579 CFClient::SDL_QUIT => sub {
1403 Event::unloop -1; 1580 Event::unloop -1;
1404 }, 1581 },
1405 CFClient::SDL_VIDEORESIZE => sub { 1582 CFClient::SDL_VIDEORESIZE => sub {
1406 }, 1583 },
1407 CFClient::SDL_VIDEOEXPOSE => \&refresh, 1584 CFClient::SDL_VIDEOEXPOSE => sub {
1585 $WANT_REFRESH++;
1586 },
1408 CFClient::SDL_ACTIVEEVENT => sub { 1587 CFClient::SDL_ACTIVEEVENT => sub {
1409# printf "active %x %x\n", $SDL_EV->active_gain, $SDL_EV->active_state;#d# 1588# printf "active %x %x\n", $SDL_EV->active_gain, $SDL_EV->active_state;#d#
1410 }, 1589 },
1411 CFClient::SDL_KEYDOWN => sub { 1590 CFClient::SDL_KEYDOWN => sub {
1412 if ($_[0]{mod} & CFClient::KMOD_ALT && $_[0]{sym} == 13) { 1591 if ($_[0]{mod} & CFClient::KMOD_ALT && $_[0]{sym} == 13) {
1433 1612
1434############################################################################# 1613#############################################################################
1435 1614
1436$SIG{INT} = $SIG{TERM} = sub { exit }; 1615$SIG{INT} = $SIG{TERM} = sub { exit };
1437 1616
1438CFClient::read_cfg "$Crossfire::VARDIR/pclientrc";
1439
1440$TILECACHE = CFClient::db_table "tilecache";
1441$FACEMAP = CFClient::db_table "facemap";
1442
1443my %DEF_CFG = (
1444 sdl_mode => 0,
1445 width => 640,
1446 height => 480,
1447 fullscreen => 0,
1448 fast => 0,
1449 map_scale => 0.5,
1450 fow_enable => 1,
1451 fow_intensity => 0.45,
1452 fow_smooth => 0,
1453 gui_fontsize => 1,
1454 log_fontsize => 1,
1455 gauge_fontsize => 1,
1456 gauge_size => 0.35,
1457 stat_fontsize => 1,
1458 mapsize => 100,
1459 host => "crossfire.schmorp.de",
1460 say_command => 'say',
1461 audio_enable => 1,
1462 bgm_enable => 1,
1463 bgm_volume => 0.25,
1464);
1465
1466while (my ($k, $v) = each %DEF_CFG) {
1467 $CFG->{$k} = $v unless exists $CFG->{$k};
1468}
1469
1470sdl_init;
1471
1472@SDL_MODES = reverse
1473 grep $_->[0] >= 640 && $_->[1] >= 480,
1474 CFClient::SDL_ListModes;
1475
1476@SDL_MODES or CFClient::fatal "Unable to find a usable video mode\n(hardware accelerated opengl fullscreen)";
1477
1478$CFG->{sdl_mode} = 0 if $CFG->{sdl_mode} > @SDL_MODES;
1479
1480{ 1617{
1618 local $SIG{__DIE__} = sub { CFClient::fatal $_[0] };
1619
1620 CFClient::read_cfg "$Crossfire::VARDIR/pclientrc";
1621
1622 $TILECACHE = CFClient::db_table "tilecache";
1623 $FACEMAP = CFClient::db_table "facemap";
1624
1625 my %DEF_CFG = (
1626 sdl_mode => 0,
1627 width => 640,
1628 height => 480,
1629 fullscreen => 0,
1630 fast => 0,
1631 map_scale => 0.5,
1632 fow_enable => 1,
1633 fow_intensity => 0.45,
1634 fow_smooth => 0,
1635 gui_fontsize => 1,
1636 log_fontsize => 1,
1637 gauge_fontsize=> 1,
1638 gauge_size => 0.35,
1639 stat_fontsize => 1,
1640 mapsize => 100,
1641 host => "crossfire.schmorp.de",
1642 say_command => 'say',
1643 audio_enable => 1,
1644 bgm_enable => 1,
1645 bgm_volume => 0.25,
1646 );
1647
1648 while (my ($k, $v) = each %DEF_CFG) {
1649 $CFG->{$k} = $v unless exists $CFG->{$k};
1650 }
1651
1652 sdl_init;
1653
1654 @SDL_MODES = reverse
1655 grep $_->[0] >= 640 && $_->[1] >= 480,
1656 CFClient::SDL_ListModes;
1657
1658 @SDL_MODES or CFClient::fatal "Unable to find a usable video mode\n(hardware accelerated opengl fullscreen)";
1659
1660 $CFG->{sdl_mode} = 0 if $CFG->{sdl_mode} > @SDL_MODES;
1661
1662 {
1481 my @fonts = map CFClient::find_rcfile "fonts/$_", qw( 1663 my @fonts = map CFClient::find_rcfile "fonts/$_", qw(
1482 DejaVuSans.ttf 1664 DejaVuSans.ttf
1483 DejaVuSansMono.ttf 1665 DejaVuSansMono.ttf
1484 DejaVuSans-Bold.ttf 1666 DejaVuSans-Bold.ttf
1485 DejaVuSansMono-Bold.ttf 1667 DejaVuSansMono-Bold.ttf
1486 DejaVuSans-Oblique.ttf 1668 DejaVuSans-Oblique.ttf
1487 DejaVuSansMono-Oblique.ttf 1669 DejaVuSansMono-Oblique.ttf
1488 DejaVuSans-BoldOblique.ttf 1670 DejaVuSans-BoldOblique.ttf
1489 DejaVuSansMono-BoldOblique.ttf 1671 DejaVuSansMono-BoldOblique.ttf
1490 ); 1672 );
1491 1673
1492 CFClient::add_font $_ for @fonts; 1674 CFClient::add_font $_ for @fonts;
1493 1675
1676 CFClient::pango_init;
1677
1494 $FONT_PROP = new_from_file CFClient::Font $fonts[0]; 1678 $FONT_PROP = new_from_file CFClient::Font $fonts[0];
1495 $FONT_FIXED = new_from_file CFClient::Font $fonts[1]; 1679 $FONT_FIXED = new_from_file CFClient::Font $fonts[1];
1496 1680
1497 $FONT_PROP->make_default; 1681 $FONT_PROP->make_default;
1498} 1682 }
1499 1683
1684# compare mono (ft) vs. rgba (cairo)
1685# ft - 1.8s, cairo 3s, even in alpha-only mode
1686# for my $rgba (0..1) {
1687# my $t1 = Time::HiRes::time;
1688# for (1..1000) {
1689# my $layout = CFClient::Layout->new ($rgba);
1690# $layout->set_text ("hallo" x 100);
1691# $layout->render;
1692# }
1693# my $t2 = Time::HiRes::time;
1694# warn $t2-$t1;
1695# }
1696
1500video_init; 1697 video_init;
1501audio_init; 1698 audio_init;
1699}
1502 1700
1503Event::loop; 1701Event::loop;
1504 1702
1505END { CFClient::SDL_Quit } 1703END { CFClient::SDL_Quit }
1506 1704

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines