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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines