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

Comparing deliantra/Deliantra-Client/bin/cfplus (file contents):
Revision 1.117 by elmex, Tue Aug 15 06:30:05 2006 UTC vs.
Revision 1.143 by root, Fri Mar 16 02:33:50 2007 UTC

1#!/opt/bin/perl 1#!/opt/bin/perl
2
3my $startup_done = sub { };
4
5# do splash-screen thingy on win32
6BEGIN {
7 if (%PAR::LibCache && $^O eq "MSWin32") {
8 while (my ($filename, $zip) = each %PAR::LibCache) {
9 $zip->extractMember ("SPLASH.bmp", "$ENV{PAR_TEMP}/SPLASH.bmp");
10 }
11
12 require Win32::GUI::SplashScreen;
13
14 Win32::GUI::SplashScreen::Show (
15 -file => "$ENV{PAR_TEMP}/SPLASH.bmp",
16 );
17
18 $startup_done = sub {
19 Win32::GUI::SplashScreen::Done (1);
20 };
21 }
22}
2 23
3use strict; 24use strict;
4use utf8; 25use utf8;
26
27use Carp 'verbose';
5 28
6# do things only needed for single-binary version (par) 29# do things only needed for single-binary version (par)
7BEGIN { 30BEGIN {
8 if (%PAR::LibCache) { 31 if (%PAR::LibCache) {
9 @INC = grep ref, @INC; # weed out all paths except pars loader refs 32 @INC = grep ref, @INC; # weed out all paths except pars loader refs
10 33
11 while (my ($filename, $zip) = each %PAR::LibCache) { 34 while (my ($filename, $zip) = each %PAR::LibCache) {
12 for ($zip->memberNames) { 35 for ($zip->memberNames) {
13 next unless /^\/root\/(.*)/; 36 next unless /^root\/(.*)/;
14 $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1") 37 $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1")
15 unless -e "$ENV{PAR_TEMP}/$1"; 38 unless -e "$ENV{PAR_TEMP}/$1";
16 } 39 }
17 } 40 }
18 41
36 59
37use CFPlus; 60use CFPlus;
38use CFPlus::OpenGL (); 61use CFPlus::OpenGL ();
39use CFPlus::Protocol; 62use CFPlus::Protocol;
40use CFPlus::UI; 63use CFPlus::UI;
64use CFPlus::UI::Inventory;
65use CFPlus::UI::SpellList;
41use CFPlus::Pod; 66use CFPlus::Pod;
42use CFPlus::BindingEditor;
43use CFPlus::MapWidget; 67use CFPlus::MapWidget;
68use CFPlus::Macro;
44 69
45$SIG{QUIT} = sub { Carp::cluck "QUIT" }; 70$SIG{QUIT} = sub { Carp::cluck "QUIT" };
46$SIG{PIPE} = 'IGNORE'; 71$SIG{PIPE} = 'IGNORE';
47 72
48$Event::Eval = 0; 73$Event::Eval = 1;
49$Event::DIED = sub { 74$Event::DIED = sub {
50 # TODO: display dialog box or so 75 CFPlus::fatal Carp::longmess $_[1]
51 Carp::cluck $_[1];#d#TODO: remove when stable
52 CFPlus::error $_[1];
53}; 76};
54
55$SIG{__DIE__} = sub {
56 return if CFPlus::in_destruct;
57 Carp::cluck $_[0];
58 CFPlus::error $_[0];
59 return;#d#
60 #return unless defined $^S && !$^S;
61 $Event::DIED->(undef, $_[0]);
62};
63
64our $VERSION = '0.1';
65 77
66my $MAX_FPS = 60; 78my $MAX_FPS = 60;
67my $MIN_FPS = 5; # unused as of yet 79my $MIN_FPS = 5; # unused as of yet
68 80
69our $META_SERVER = "crossfire.real-time.com:13326"; 81our $META_SERVER = "http://metaserver.schmorp.de/current.json";
70 82
71our $LAST_REFRESH; 83our $LAST_REFRESH;
72our $NOW; 84our $NOW;
73 85
74our $CFG; 86our $CFG;
75our $CONN; 87our $CONN;
88our $PROFILE; # current profile
76our $FAST; # fast, low-quality mode, possibly useful for software-rendering 89our $FAST; # fast, low-quality mode, possibly useful for software-rendering
77 90
78our $WANT_REFRESH; 91our $WANT_REFRESH;
79our $CAN_REFRESH; 92our $CAN_REFRESH;
80 93
111 124
112our $INVENTORY_PAGE; 125our $INVENTORY_PAGE;
113our $STATS_PAGE; 126our $STATS_PAGE;
114our $SKILL_PAGE; 127our $SKILL_PAGE;
115our $SPELL_PAGE; 128our $SPELL_PAGE;
129our $SPELL_LIST;
116 130
117our $HELP_WINDOW; 131our $HELP_WINDOW;
118our $MESSAGE_WINDOW; 132our $MESSAGE_WINDOW;
119our $FLOORBOX; 133our $FLOORBOX;
120our $GAUGES; 134our $GAUGES;
133 147
134our $INV; 148our $INV;
135our $INVR; 149our $INVR;
136our $INV_RIGHT_HB; 150our $INV_RIGHT_HB;
137 151
138our $BIND_EDITOR;
139our $BIND_UPD_CB;
140
141our $PICKUP_CFG; 152our $PICKUP_CFG;
153
154our $IN_BUILD_MODE;
155our $BUILD_BUTTON;
142 156
143sub status { 157sub status {
144 $STATUSBOX->add (CFPlus::asxml $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]); 158 $STATUSBOX->add (CFPlus::asxml $_[0], pri => -10, group => "status", timeout => 10, fg => [1, 1, 0, 1]);
145} 159}
146 160
147sub debug { 161sub debug {
148 $DEBUG_STATUS->set_text ($_[0]); 162 $DEBUG_STATUS->set_text ($_[0]);
163}
164
165sub message {
166 my ($para) = @_;
167
168 my $time = sprintf "%02d:%02d:%02d", (localtime time)[2,1,0];
169
170 $para->{markup} = "<span foreground='#ffffff'>$time</span> $para->{markup}";
171
172 $LOGVIEW->add_paragraph ($para);
173 $LOGVIEW->scroll_to_bottom;
149} 174}
150 175
151sub destroy_query_dialog { 176sub destroy_query_dialog {
152 (delete $_[0]{query_dialog})->destroy 177 (delete $_[0]{query_dialog})->destroy
153 if $_[0]{query_dialog}; 178 if $_[0]{query_dialog};
154} 179}
155 180
181# FIXME: a very ugly hack to wait for stat update look below! #d#
182our $QUERY_TIMER; #d#
183
156# server query dialog 184# server query dialog
157sub server_query { 185sub server_query {
158 my ($conn, $flags, $prompt) = @_; 186 my ($conn, $flags, $prompt) = @_;
187
188 # FIXME: a very ugly hack to wait for stat update #d#
189 if ($prompt =~ /roll new stats/ and not $conn->{stat_change_with}) {
190 unless ($QUERY_TIMER) {
191 $QUERY_TIMER =
192 Event->timer (
193 after => 1,
194 cb => sub {
195 server_query ($conn, $flags, $prompt, 1);
196 $QUERY_TIMER = undef
197 }
198 );
199 return;
200 }
201 }
159 202
160 $conn->{query_dialog} = my $dialog = new CFPlus::UI::Toplevel 203 $conn->{query_dialog} = my $dialog = new CFPlus::UI::Toplevel
161 x => "center", 204 x => "center",
162 y => "center", 205 y => "center",
163 title => "Server Query", 206 title => "Server Query",
354 $LOGIN_BUTTON->set_text ("Logout"); 397 $LOGIN_BUTTON->set_text ("Logout");
355 $SETUP_DIALOG->hide; 398 $SETUP_DIALOG->hide;
356 399
357 my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32; 400 my $mapsize = List::Util::min 32, List::Util::max 11, int $WIDTH * $CFG->{mapsize} * 0.01 / 32;
358 401
359 my ($host, $port) = split /:/, $CFG->{profile}{default}{host}; 402 my ($host, $port) = split /:/, $PROFILE->{host};
360 403
361 $MAP = new CFPlus::Map $mapsize, $mapsize; 404 $MAP = new CFPlus::Map;
362 405
363 $CONN = eval { 406 $CONN = eval {
364 new CFPlus::Protocol 407 new CFPlus::Protocol
365 host => $host, 408 host => $host,
366 port => $port || 13327, 409 port => $port || 13327,
367 user => $CFG->{profile}{default}{user}, 410 user => $PROFILE->{user},
368 pass => $CFG->{profile}{default}{password}, 411 pass => $PROFILE->{password},
369 mapw => $mapsize, 412 mapw => $mapsize,
370 maph => $mapsize, 413 maph => $mapsize,
414
415 client => "cfplus $CFPlus::VERSION $] $^O",
371 416
372 map_widget => $MAPWIDGET, 417 map_widget => $MAPWIDGET,
373 logview => $LOGVIEW, 418 logview => $LOGVIEW,
374 statusbox => $STATUSBOX, 419 statusbox => $STATUSBOX,
375 map => $MAP, 420 map => $MAP,
402sub stop_game { 447sub stop_game {
403 $LOGIN_BUTTON->set_text ("Login"); 448 $LOGIN_BUTTON->set_text ("Login");
404 $SETUP_NOTEBOOK->set_current_page ($SETUP_SERVER); 449 $SETUP_NOTEBOOK->set_current_page ($SETUP_SERVER);
405 $SETUP_DIALOG->show; 450 $SETUP_DIALOG->show;
406 $PL_WINDOW->hide; 451 $PL_WINDOW->hide;
407 $SPELL_PAGE->clear_spells; 452 $SPELL_LIST->clear_spells;
408 453
409 return unless $CONN; 454 return unless $CONN;
410 455
411 status "connection closed"; 456 status "connection closed";
412 457
639 $table->add (1, 1, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 2; 0 }); 684 $table->add (1, 1, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 2; 0 });
640 $table->add (0, 2, new CFPlus::UI::Label text => "Show FPS"); 685 $table->add (0, 2, new CFPlus::UI::Label text => "Show FPS");
641 $table->add (1, 2, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 4; 0 }); 686 $table->add (1, 2, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 4; 0 });
642 $table->add (0, 3, new CFPlus::UI::Label text => "Suppress Tooltips"); 687 $table->add (0, 3, new CFPlus::UI::Label text => "Suppress Tooltips");
643 $table->add (1, 3, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 8; 0 }); 688 $table->add (1, 3, new CFPlus::UI::CheckBox on_changed => sub { $ENV{CFPLUS_DEBUG} ^= 8; 0 });
689 $table->add (0, 4, new CFPlus::UI::Button text => "die on click(tm)", on_activate => sub { die "violator" } );
644 690
645 my @default_smooth = (0.05, 0.13, 0.05, 0.13, 0.30, 0.13, 0.05, 0.13, 0.05); 691 my @default_smooth = (0.05, 0.13, 0.05, 0.13, 0.30, 0.13, 0.05, 0.13, 0.05);
646 692
647 for my $x (0..2) { 693 for my $x (0..2) {
648 for my $y (0 .. 2) { 694 for my $y (0 .. 2) {
652 on_changed => sub { $MAP->{smooth_matrix}[$x * 3 + $y] = $_[1] if $MAP; 0 }, 698 on_changed => sub { $MAP->{smooth_matrix}[$x * 3 + $y] = $_[1] if $MAP; 0 },
653 ); 699 );
654 } 700 }
655 } 701 }
656 702
703 $table->add (0, 5, new CFPlus::UI::TextEdit text => "line1\0152\0153");#d#
657 704
658 $table 705 $table
659} 706}
660 707
661sub stats_window { 708sub stats_window {
830 877
831 my $table = $METASERVER->{table}; 878 my $table = $METASERVER->{table};
832 $table->clear; 879 $table->clear;
833 $table->add (0, 0, my $label = new CFPlus::UI::Label max_w => $WIDTH * 0.8, text => "fetching server list..."); 880 $table->add (0, 0, my $label = new CFPlus::UI::Label max_w => $WIDTH * 0.8, text => "fetching server list...");
834 881
835 my $buf; 882 my $ok = 0;
836 883
837 my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0; 884 CFPlus::background {
885 my $ua = CFPlus::lwp_useragent;
838 886
839 unless ($fh) { 887 CFPlus::background_msg CFPlus::from_json +(CFPlus::lwp_check $ua->get ($META_SERVER))->decoded_content;
840 $label->set_text ("unable to contact metaserver: $!"); 888 } sub {
841 return; 889 my ($msg) = @_;
842 } 890 if ($msg) {
843
844 Event->io (fd => $fh, poll => 'r', cb => sub {
845 my $res = sysread $fh, $buf, 8192, length $buf;
846
847 if (!defined $res) {
848 $_[0]->w->cancel;
849 $label->set_text ("error while retrieving server list: $!");
850 } elsif ($res == 0) {
851 $_[0]->w->cancel;
852 status "server list retrieved";
853
854 utf8::decode $buf if utf8::valid $buf;
855
856 $table->clear; 891 $table->clear;
857 892
858 my @tip = ( 893 my @tip = (
859 "The current number of users logged in on the server.", 894 "The current number of users logged in on the server.",
860 "The hostname of the server.", 895 "The hostname of the server.",
870 for 0 .. $#col; 905 for 0 .. $#col;
871 906
872 my @align = qw(1 0 1 1 -1); 907 my @align = qw(1 0 1 1 -1);
873 908
874 my $y = 0; 909 my $y = 0;
875 for my $m (sort { $b->[3] <=> $a->[3] } map [split /\|/], split /\015?\012/, $buf) { 910 for my $m (@{ $msg->{servers} }) {
876 my ($ip, $last, $host, $users, $version, $desc, $ibytes, $obytes, $uptime) = @$m; 911 my ($ip, $last, $host, $users, $version, $desc, $ibytes, $obytes, $uptime, $highlight) =
912 @$m{qw(ip age hostname users version description ibytes obytes uptime highlight)};
877 913
878 for ($desc) { 914 for ($desc) {
879 s/<br>/\n/gi; 915 s/<br>/\n/gi;
880 s/<li>/\n· /gi; 916 s/<li>/\n· /gi;
881 s/<.*?>//sgi; 917 s/<.*?>//sgi;
882 s/&/&amp;/g; 918 s/&amp;/&/g;
883 s/</&lt;/g; 919 s/&lt;/</g;
884 s/>/&gt;/g; 920 s/&gt;/>/g;
885 } 921 }
886 922
887 $uptime = sprintf "%dd %02d:%02d:%02d", 923 $uptime = sprintf "%dd %02d:%02d:%02d",
888 (int $m->[8] / 86400), 924 (int $uptime / 86400),
889 (int $m->[8] / 3600) % 24, 925 (int $uptime / 3600) % 24,
890 (int $m->[8] / 60) % 60, 926 (int $uptime / 60) % 60,
891 $m->[8] % 60; 927 $uptime % 60;
892 928
893 $m = [$users, $host, $uptime, $version, $desc]; 929 $m = [$users, $host, $uptime, $version, $desc];
894 930
895 $y++; 931 $y++;
896 932
906 ), 942 ),
907 (new CFPlus::UI::Empty expand => 1), 943 (new CFPlus::UI::Empty expand => 1),
908 ]); 944 ]);
909 945
910 $table->add ($_, $y, new CFPlus::UI::Label 946 $table->add ($_, $y, new CFPlus::UI::Label
947 max_w => $::WIDTH * 0.4,
911 ellipsise => 0, 948 ellipsise => 0,
912 align => $align[$_], 949 align => $align[$_],
913 text => $m->[$_], 950 text => $m->[$_],
914 tooltip => $tip[$_], 951 tooltip => $tip[$_],
952 fg => ($highlight ? [1, 1, 1] : [.7, .7, .7]),
915 can_hover => 1, 953 can_hover => 1,
916 can_events => 1, 954 can_events => 1,
917 fontsize => 0.8) 955 fontsize => 0.8)
918 for 0 .. $#$m; 956 for 0 .. $#$m;
919 } 957 }
958 } else {
959 $ok or $label->set_text ("error while contacting metaserver");
920 } 960 }
921 }); 961 };
962
922} 963}
923 964
924sub metaserver_dialog { 965sub metaserver_dialog {
925 my $vbox = new CFPlus::UI::VBox; 966 my $vbox = new CFPlus::UI::VBox;
926 my $table = new CFPlus::UI::Table; 967 my $table = new CFPlus::UI::Table;
930 title => "Server List", 971 title => "Server List",
931 name => 'metaserver_dialog', 972 name => 'metaserver_dialog',
932 x => 'center', 973 x => 'center',
933 y => 'center', 974 y => 'center',
934 z => 3, 975 z => 3,
976 force_w => $::WIDTH * 0.9,
935 force_h => $::HEIGHT * 0.4, 977 force_h => $::HEIGHT * 0.7,
936 child => $vbox, 978 child => $vbox,
937 has_close_button => 1, 979 has_close_button => 1,
938 table => $table, 980 table => $table,
939 on_visibility_change => sub { 981 on_visibility_change => sub {
940 update_metaserver ($_[0]) if $_[1]; 982 update_metaserver ($_[0]) if $_[1];
1016 . "so only set it if you really need to prefetch images. " 1058 . "so only set it if you really need to prefetch images. "
1017 . "This option can be set and unset any time.", 1059 . "This option can be set and unset any time.",
1018 on_changed => sub { $CFG->{face_prefetch} = $_[1]; 0 }, 1060 on_changed => sub { $CFG->{face_prefetch} = $_[1]; 0 },
1019 ); 1061 );
1020 1062
1021 $table->add (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Count"); 1063 $table->add (0, 9, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Rate");
1022 $table->add (1, 9, new CFPlus::UI::Entry 1064 $table->add (1, 9, new CFPlus::UI::Entry
1065 text => $CFG->{output_rate},
1066 tooltip => "The approximate bandwidth in bytes per second that the server should not exceed "
1067 . "when sending images, to ensure interactiveness. When 0 or unset, the server "
1068 . "default will be used, which is usually around 100kb/s.",
1069 on_changed => sub { $CFG->{output_rate} = $_[1]; 0 },
1070 );
1071
1072 $table->add (0, 10, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Count");
1073 $table->add (1, 10, new CFPlus::UI::Entry
1023 text => $CFG->{output_count}, 1074 text => $CFG->{output_count},
1024 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.", 1075 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
1025 on_changed => sub { $CFG->{output_count} = $_[1]; 0 }, 1076 on_changed => sub { $CFG->{output_count} = $_[1]; 0 },
1026 ); 1077 );
1027 1078
1028 $table->add (0, 10, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Sync"); 1079 $table->add (0, 11, new CFPlus::UI::Label valign => 0, align => 1, text => "Output-Sync");
1029 $table->add (1, 10, new CFPlus::UI::Entry 1080 $table->add (1, 11, new CFPlus::UI::Entry
1030 text => $CFG->{output_sync}, 1081 text => $CFG->{output_sync},
1031 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.", 1082 tooltip => "Should be set to 1 unless you know what you are doing. This option is only used once at log-in.",
1032 on_changed => sub { $CFG->{output_sync} = $_[1]; 0 }, 1083 on_changed => sub { $CFG->{output_sync} = $_[1]; 0 },
1033 ); 1084 );
1034 1085
1035 $table->add (1, 11, $LOGIN_BUTTON = new CFPlus::UI::Button 1086 $table->add (1, 12, $LOGIN_BUTTON = new CFPlus::UI::Button
1036 expand => 1, 1087 expand => 1,
1037 align => 0, 1088 align => 0,
1038 text => "Login", 1089 text => "Login",
1039 on_activate => sub { 1090 on_activate => sub {
1040 $CONN ? stop_game 1091 $CONN ? stop_game
1041 : start_game; 1092 : start_game;
1042 0 1093 0
1043 }, 1094 },
1044 ); 1095 );
1045 1096
1046 $table->add (0, 12, new CFPlus::UI::Label valign => 0, align => 1, text => "Chat Command"); 1097 $table->add (0, 13, new CFPlus::UI::Label valign => 0, align => 1, text => "Chat Command");
1047 $table->add (1, 12, my $saycmd = new CFPlus::UI::Entry 1098 $table->add (1, 13, my $saycmd = new CFPlus::UI::Entry
1048 text => $CFG->{say_command}, 1099 text => $CFG->{say_command},
1049 tooltip => "This is the command that will be used if you write a line in the message window entry or press <b>\"</b> in the map window. " 1100 tooltip => "This is the command that will be used if you write a line in the message window entry or press <b>\"</b> in the map window. "
1050 . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. " 1101 . "Usually you want to enter something like 'say' or 'shout' or 'gsay' here. "
1051 . "But you could also set it to <b>tell <i>playername</i></b> to only chat with that user.", 1102 . "But you could also set it to <b>tell <i>playername</i></b> to only chat with that user.",
1052 on_changed => sub { 1103 on_changed => sub {
1053 my ($self, $value) = @_; 1104 my ($self, $value) = @_;
1054 $CFG->{say_command} = $value; 1105 $CFG->{say_command} = $value;
1106 0
1107 }
1108 );
1109
1110 $table->add (0, 14, new CFPlus::UI::Label valign => 0, align => 1, text => "Tip of the day");
1111 $table->add (1, 14, my $saycmd = new CFPlus::UI::CheckBox
1112 state => $CFG->{show_tips},
1113 tooltip => "Show the <b>Tip of the day</b> window at startup?",
1114 on_changed => sub {
1115 my ($self, $value) = @_;
1116 $CFG->{show_tips} = $value;
1055 0 1117 0
1056 } 1118 }
1057 ); 1119 );
1058 1120
1059 $vbox->add (new CFPlus::UI::FancyFrame 1121 $vbox->add (new CFPlus::UI::FancyFrame
1123 window => $window, 1185 window => $window,
1124 input => $input, 1186 input => $input,
1125 }; 1187 };
1126 1188
1127 $window 1189 $window
1128}
1129
1130sub open_string_query {
1131 my ($title, $cb, $txt, $tooltip) = @_;
1132 my $dialog = new CFPlus::UI::Toplevel
1133 x => "center",
1134 y => "center",
1135 z => 50,
1136 force_w => $WIDTH * 4/5,
1137 title => $title;
1138
1139 $dialog->add (
1140 my $e = new CFPlus::UI::Entry
1141 on_activate => sub { $cb->(@_); $dialog->hide; 0 },
1142 on_key_down => sub { $_[1]->{sym} == 27 and $dialog->hide; 0 },
1143 tooltip => $tooltip
1144 );
1145
1146 $e->grab_focus;
1147 $e->set_text ($txt) if $txt;
1148 $dialog->show;
1149}
1150
1151sub open_quit_dialog {
1152 unless ($QUIT_DIALOG) {
1153 $QUIT_DIALOG = new CFPlus::UI::Toplevel
1154 x => "center",
1155 y => "center",
1156 z => 50,
1157 title => "Really Quit?",
1158 on_key_down => sub {
1159 my ($dialog, $ev) = @_;
1160 $ev->{sym} == 27 and $dialog->hide;
1161 }
1162 ;
1163
1164 $QUIT_DIALOG->add (my $vb = new CFPlus::UI::VBox expand => 1);
1165
1166 $vb->add (new CFPlus::UI::Label
1167 text => "You should find a savebed and apply it first!",
1168 max_w => $WIDTH * 0.25,
1169 ellipsize => 0,
1170 );
1171 $vb->add (my $hb = new CFPlus::UI::HBox expand => 1);
1172 $hb->add (new CFPlus::UI::Button
1173 text => "Ok",
1174 expand => 1,
1175 on_activate => sub { $QUIT_DIALOG->hide; 0 },
1176 );
1177 $hb->add (new CFPlus::UI::Button
1178 text => "Quit anyway",
1179 expand => 1,
1180 on_activate => sub { exit },
1181 );
1182 }
1183
1184 $QUIT_DIALOG->show;
1185 $QUIT_DIALOG->grab_focus;
1186} 1190}
1187 1191
1188sub autopickup_setup { 1192sub autopickup_setup {
1189 my $table = new CFPlus::UI::Table; 1193 my $table = new CFPlus::UI::Table;
1190 1194
1208 ["Boots" => PICKUP_BOOTS], 1212 ["Boots" => PICKUP_BOOTS],
1209 ["Gloves" => PICKUP_GLOVES], 1213 ["Gloves" => PICKUP_GLOVES],
1210 ["Cloaks" => PICKUP_CLOAK], 1214 ["Cloaks" => PICKUP_CLOAK],
1211 ], 1215 ],
1212 1216
1213 ["Readables", 2, 2, 1217 ["Readables", 2, 0,
1214 ["Spellbooks" => PICKUP_SPELLBOOK], 1218 ["Spellbooks" => PICKUP_SPELLBOOK],
1215 ["Skillscrolls" => PICKUP_SKILLSCROLL], 1219 ["Skillscrolls" => PICKUP_SKILLSCROLL],
1216 ["Normal Books/Scrolls" => PICKUP_READABLES], 1220 ["Normal Books/Scrolls" => PICKUP_READABLES],
1217 ], 1221 ],
1218 ["Misc", 2, 7, 1222 ["Misc", 2, 5,
1219 ["Food" => PICKUP_FOOD], 1223 ["Food" => PICKUP_FOOD],
1220 ["Drinks" => PICKUP_DRINK], 1224 ["Drinks" => PICKUP_DRINK],
1221 ["Valuables (Money, Gems)" => PICKUP_VALUABLES], 1225 ["Valuables (Money, Gems)" => PICKUP_VALUABLES],
1222 ["Keys" => PICKUP_KEY], 1226 ["Keys" => PICKUP_KEY],
1223 ["Magical Items" => PICKUP_MAGICAL], 1227 ["Magical Items" => PICKUP_MAGICAL],
1224 ["Potions" => PICKUP_POTION], 1228 ["Potions" => PICKUP_POTION],
1225 ["Magic Devices" => PICKUP_MAGIC_DEVICE], 1229 ["Magic Devices" => PICKUP_MAGIC_DEVICE],
1226 ["Ignore cursed" => PICKUP_NOT_CURSED], 1230 ["Ignore cursed" => PICKUP_NOT_CURSED],
1227 ["Jewelery" => PICKUP_JEWELS], 1231 ["Jewelery" => PICKUP_JEWELS],
1232 ["Flesh" => PICKUP_FLESH],
1228 ], 1233 ],
1229 ["Weight/Value ratio", 2, 17] 1234 ["Weight/Value ratio", 2, 17]
1230 ) 1235 )
1231 { 1236 {
1232 my ($title, $x, $y, @bits) = @$_; 1237 my ($title, $x, $y, @bits) = @$_;
1282 $table 1287 $table
1283} 1288}
1284 1289
1285my %SORT_ORDER = ( 1290my %SORT_ORDER = (
1286 type => undef, 1291 type => undef,
1287 mtime => sub { sort { 1292 mtime => sub {
1293 my $NOW = time;
1294 sort {
1295 my $atime = $a->{mtime} - $NOW; $atime = $atime < 5 * 60 ? int $atime / 60 : 6;
1296 my $btime = $b->{mtime} - $NOW; $btime = $btime < 5 * 60 ? int $btime / 60 : 6;
1297
1288 ($a->{flags} & F_LOCKED) <=> ($b->{flags} & F_LOCKED) 1298 ($a->{flags} & F_LOCKED) <=> ($b->{flags} & F_LOCKED)
1289 or $b->{mtime} <=> $a->{mtime} 1299 or $btime <=> $atime
1290 or $a->{type} <=> $b->{type} 1300 or $a->{type} <=> $b->{type}
1301 } @_
1291 } @_ }, 1302 },
1292 weight => sub { sort { 1303 weight => sub { sort {
1293 $a->{weight} * ($a->{nrof} || 1) <=> $b->{weight} * ($b->{nrof} || 1) 1304 $a->{weight} * ($a->{nrof} || 1) <=> $b->{weight} * ($b->{nrof} || 1)
1294 or $a->{type} <=> $b->{type} 1305 or $a->{type} <=> $b->{type}
1295 } @_ }, 1306 } @_ },
1296); 1307);
1321 #TODO# update to weigh/maxweight 1332 #TODO# update to weigh/maxweight
1322 $hb1->add ($STATWIDS->{i_weight} = new CFPlus::UI::Label align => -1); 1333 $hb1->add ($STATWIDS->{i_weight} = new CFPlus::UI::Label align => -1);
1323 1334
1324 $vb1->add (my $sw1 = new CFPlus::UI::ScrolledWindow expand => 1, scroll_y => 1); 1335 $vb1->add (my $sw1 = new CFPlus::UI::ScrolledWindow expand => 1, scroll_y => 1);
1325 $sw1->add ($INV = new CFPlus::UI::Inventory); 1336 $sw1->add ($INV = new CFPlus::UI::Inventory);
1337 $INV->set_sort_order ($SORT_ORDER{$::CFG->{inv_sort}});
1326 1338
1327 $hb->add (my $vb2 = new CFPlus::UI::VBox); 1339 $hb->add (my $vb2 = new CFPlus::UI::VBox);
1328 1340
1329 $vb2->add ($INV_RIGHT_HB = new CFPlus::UI::HBox); 1341 $vb2->add ($INV_RIGHT_HB = new CFPlus::UI::HBox);
1330 1342
1370 $ntb->add ( 1382 $ntb->add (
1371 "Skills (F3)" => $SKILL_PAGE = skill_window, 1383 "Skills (F3)" => $SKILL_PAGE = skill_window,
1372 "Shows all your Skills." 1384 "Shows all your Skills."
1373 ); 1385 );
1374 1386
1375 my $spellsw = new CFPlus::UI::ScrolledWindow (expand => 1, scroll_y => 1); 1387 my $spellsw = $SPELL_PAGE = new CFPlus::UI::ScrolledWindow (expand => 1, scroll_y => 1);
1376 $spellsw->add ($SPELL_PAGE = new CFPlus::UI::SpellList); 1388 $spellsw->add ($SPELL_LIST = new CFPlus::UI::SpellList);
1377 $ntb->add ( 1389 $ntb->add (
1378 "Spellbook (F4)" => $spellsw, 1390 "Spellbook (F4)" => $spellsw,
1379 "Displays all spells you have and lets you edit keyboard shortcuts for them." 1391 "Displays all spells you have and lets you edit keyboard shortcuts for them."
1380 ); 1392 );
1381 $ntb->add ( 1393 $ntb->add (
1388 1400
1389 $plwin->add ($ntb); 1401 $plwin->add ($ntb);
1390 $plwin 1402 $plwin
1391} 1403}
1392 1404
1393sub update_bindings {
1394 $BIND_UPD_CB->() if $BIND_UPD_CB;
1395}
1396
1397sub keyboard_setup { 1405sub keyboard_setup {
1398 my $binding_list = new CFPlus::UI::VBox; 1406 CFPlus::Macro::keyboard_setup
1399
1400 my $refresh;
1401 $refresh = $BIND_UPD_CB = sub {
1402 $binding_list->clear ();
1403
1404 for my $mod (keys %{$::CFG->{profile}{default}{bindings}}) {
1405 for my $sym (keys %{$::CFG->{profile}{default}{bindings}{$mod}}) {
1406 my $cmds = $::CFG->{profile}{default}{bindings}{$mod}{$sym};
1407 next unless ref $cmds eq 'ARRAY' and @$cmds > 0;
1408
1409 my $lbl = join "; ", @$cmds;
1410 my $nam = CFPlus::BindingEditor::keycombo_to_name ($mod, $sym);
1411 $binding_list->add (my $hb = new CFPlus::UI::HBox);
1412 $hb->add (new CFPlus::UI::Button
1413 text => "delete",
1414 tooltip => "Deletes the binding",
1415 on_activate => sub {
1416 $binding_list->remove ($hb);
1417 delete $::CFG->{profile}{default}{bindings}{$mod}{$sym};
1418 0
1419 });
1420
1421 $hb->add (new CFPlus::UI::Button
1422 text => "edit",
1423 tooltip => "Edits the binding",
1424 on_activate => sub {
1425 $::BIND_EDITOR->set_binding (
1426 $mod, $sym, $::CFG->{profile}{default}{bindings}{$mod}{$sym},
1427 sub {
1428 my ($nmod, $nsym, $ncmds) = @_;
1429 $::BIND_EDITOR->cfg_unbind ($mod, $sym);
1430 $::BIND_EDITOR->cfg_bind ($nmod, $nsym, $ncmds);
1431 $refresh->();
1432 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1433 $SETUP_DIALOG->show;
1434 },
1435 sub {
1436 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1437 $SETUP_DIALOG->show;
1438 });
1439 $::BIND_EDITOR->show;
1440 $SETUP_DIALOG->hide;
1441 0
1442 });
1443
1444 $hb->add (new CFPlus::UI::Label text => "(Key: $nam)");
1445 $hb->add (new CFPlus::UI::Label text => $lbl, expand => 1);
1446 }
1447 }
1448 };
1449
1450 my $vb = new CFPlus::UI::VBox;
1451 $vb->add (new CFPlus::UI::FancyFrame
1452 label => "Options",
1453 child => (my $hb = new CFPlus::UI::HBox),
1454 );
1455 $hb->add (new CFPlus::UI::Label text => "only shift-up stops fire");
1456 $hb->add (new CFPlus::UI::CheckBox
1457 expand => 1,
1458 state => $CFG->{shift_fire_stop},
1459 tooltip => "If this checkbox is enabled you will stop fire only if you stop pressing shift",
1460 on_changed => sub {
1461 my ($cbox, $value) = @_;
1462 $CFG->{shift_fire_stop} = $value;
1463 0
1464 });
1465
1466 $vb->add (new CFPlus::UI::FancyFrame
1467 label => "Bindings",
1468 child => $binding_list);
1469 $vb->add (my $hb = new CFPlus::UI::HBox);
1470
1471 $hb->add (new CFPlus::UI::Button
1472 text => "record new",
1473 expand => 1,
1474 tooltip => "This button opens the binding editor with an empty binding.",
1475 on_activate => sub {
1476 $::BIND_EDITOR->set_binding (undef, undef, [],
1477 sub {
1478 my ($mod, $sym, $cmds) = @_;
1479 $::BIND_EDITOR->cfg_bind ($mod, $sym, $cmds);
1480 $refresh->();
1481 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1482 $SETUP_DIALOG->show;
1483 },
1484 sub {
1485 $SETUP_NOTEBOOK->set_current_page ($SETUP_KEYBOARD);
1486 $SETUP_DIALOG->show;
1487 },
1488 );
1489 $SETUP_DIALOG->hide;
1490 $::BIND_EDITOR->show;
1491 0
1492 },
1493 );
1494
1495 $hb->add (new CFPlus::UI::Button
1496 text => "close",
1497 tooltip => "Closes the binding window",
1498 expand => 1,
1499 on_activate => sub {
1500 $SETUP_DIALOG->hide;
1501 0
1502 }
1503 );
1504
1505 $refresh->();
1506
1507 $vb
1508} 1407}
1509 1408
1510sub help_window { 1409sub help_window {
1511 my $win = new CFPlus::UI::Toplevel 1410 my $win = new CFPlus::UI::Toplevel
1512 x => 'center', 1411 x => 'center',
1513 y => 'center', 1412 y => 'center',
1514 z => 2, 1413 z => 4,
1515 name => 'doc_browser', 1414 name => 'doc_browser',
1516 force_w => int $WIDTH * 7/8, 1415 force_w => int $WIDTH * 7/8,
1517 force_h => int $HEIGHT * 7/8, 1416 force_h => int $HEIGHT * 7/8,
1518 title => "Help Browser", 1417 title => "Help Browser",
1519 has_close_button => 1; 1418 has_close_button => 1;
1607 }; 1506 };
1608 1507
1609 $win 1508 $win
1610} 1509}
1611 1510
1511sub open_string_query {
1512 my ($title, $cb, $txt, $tooltip) = @_;
1513 my $dialog = new CFPlus::UI::Toplevel
1514 x => "center",
1515 y => "center",
1516 z => 50,
1517 force_w => $WIDTH * 4/5,
1518 title => $title;
1519
1520 $dialog->add (
1521 my $e = new CFPlus::UI::Entry
1522 on_activate => sub { $cb->(@_); $dialog->hide; 0 },
1523 on_key_down => sub { $_[1]->{sym} == 27 and $dialog->hide; 0 },
1524 tooltip => $tooltip
1525 );
1526
1527 $e->grab_focus;
1528 $e->set_text ($txt) if $txt;
1529 $dialog->show;
1530}
1531
1532sub open_quit_dialog {
1533 unless ($QUIT_DIALOG) {
1534 $QUIT_DIALOG = new CFPlus::UI::Toplevel
1535 x => "center",
1536 y => "center",
1537 z => 50,
1538 title => "Really Quit?",
1539 on_key_down => sub {
1540 my ($dialog, $ev) = @_;
1541 $ev->{sym} == 27 and $dialog->hide;
1542 }
1543 ;
1544
1545 $QUIT_DIALOG->add (my $vb = new CFPlus::UI::VBox expand => 1);
1546
1547 $vb->add (new CFPlus::UI::Label
1548 text => "You should find a savebed and apply it first!",
1549 max_w => $WIDTH * 0.25,
1550 ellipsize => 0,
1551 );
1552 $vb->add (my $hb = new CFPlus::UI::HBox expand => 1);
1553 $hb->add (new CFPlus::UI::Button
1554 text => "Ok",
1555 expand => 1,
1556 on_activate => sub { $QUIT_DIALOG->hide; 0 },
1557 );
1558 $hb->add (new CFPlus::UI::Button
1559 text => "Quit anyway",
1560 expand => 1,
1561 on_activate => sub { exit },
1562 );
1563 }
1564
1565 $QUIT_DIALOG->show;
1566 $QUIT_DIALOG->grab_focus;
1567}
1568
1569sub show_tip_of_the_day {
1570 # find all tips
1571 my @tod = CFPlus::Pod::find tip_of_the_day => "*";
1572
1573 my $todindex = $CFPlus::DB_STATE->get ("tip_of_the_day");
1574 $todindex = 0 if $todindex >= @tod;
1575 $CFPlus::DB_STATE->put (tip_of_the_day => $todindex + 1);
1576
1577 # create dialog
1578 my $dialog;
1579
1580 my $close = sub {
1581 $dialog->destroy;
1582 };
1583
1584 $dialog = new CFPlus::UI::Toplevel
1585 x => "center",
1586 y => "center",
1587 z => 3,
1588 name => 'tip_of_the_day',
1589 force_w => int $WIDTH * 4/9,
1590 force_h => int $WIDTH * 2/9,
1591 title => "Tip of the day #" . (1 + $todindex),
1592 child => my $vbox = new CFPlus::UI::VBox,
1593 has_close_button => 1,
1594 on_delete => $close,
1595 ;
1596
1597 $vbox->add (my $viewer = new CFPlus::UI::TextScroller
1598 expand => 1, fontsize => 0.8, padding_x => 4, padding_y => 4);
1599 $viewer->add_paragraph (CFPlus::Pod::as_paragraphs CFPlus::Pod::section_of $tod[$todindex]);
1600
1601 $vbox->add (my $table = new CFPlus::UI::Table col_expand => [0, 1]);
1602
1603 $table->add (0, 0, new CFPlus::UI::Button
1604 text => "Close",
1605 tooltip => "Close the tip of the day window. To never see it again, disable the tip of the day in the <b>Server Setup</b>.",
1606 on_activate => $close,
1607 );
1608
1609 $table->add (2, 0, new CFPlus::UI::Button
1610 text => "Next",
1611 tooltip => "Show the next <b>Tip of the day</b>.",
1612 on_activate => sub {
1613 $close->();
1614 &show_tip_of_the_day;
1615 },
1616 );
1617
1618 $dialog->show;
1619}
1620
1612sub sdl_init { 1621sub sdl_init {
1613 CFPlus::SDL_Init 1622 CFPlus::SDL_Init
1614 and die "SDL::Init failed!\n"; 1623 and die "SDL::Init failed!\n";
1615} 1624}
1616 1625
1648 padding => 0, 1657 padding => 0,
1649 z => 100, 1658 z => 100,
1650 force_x => "max", 1659 force_x => "max",
1651 force_y => 0; 1660 force_y => 0;
1652 $DEBUG_STATUS->show; 1661 $DEBUG_STATUS->show;
1653
1654 $BIND_EDITOR = new CFPlus::BindingEditor (x => "max", y => 0);
1655 1662
1656 $STATUSBOX = new CFPlus::UI::Statusbox; 1663 $STATUSBOX = new CFPlus::UI::Statusbox;
1657 $STATUSBOX->add ("Use <b>Alt-Enter</b> to toggle fullscreen mode", timeout => 864000, pri => -100, color => [1, 1, 1, 0.8]); 1664 $STATUSBOX->add ("Use <b>Alt-Enter</b> to toggle fullscreen mode", timeout => 864000, pri => -100, color => [1, 1, 1, 0.8]);
1658 1665
1659 (new CFPlus::UI::Frame 1666 (new CFPlus::UI::Frame
1760 ); 1767 );
1761 1768
1762 $BUTTONBAR->add (new CFPlus::UI::Flopper text => "Help!", other => $HELP_WINDOW = help_window, 1769 $BUTTONBAR->add (new CFPlus::UI::Flopper text => "Help!", other => $HELP_WINDOW = help_window,
1763 tooltip => "View Documentation"); 1770 tooltip => "View Documentation");
1764 1771
1772
1765 $BUTTONBAR->add (new CFPlus::UI::Button 1773 $BUTTONBAR->add (new CFPlus::UI::Button
1766 text => "Quit", 1774 text => "Quit",
1767 tooltip => "Terminates the program", 1775 tooltip => "Terminates the program",
1768 on_activate => sub { 1776 on_activate => sub {
1769 if ($CONN) { 1777 if ($CONN) {
1780 } 1788 }
1781 1789
1782 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]); 1790 $STATUSBOX->add ("Set video mode $WIDTH×$HEIGHT", timeout => 10, fg => [1, 1, 1, 0.5]);
1783} 1791}
1784 1792
1793sub setup_build_button {
1794 my ($enabled) = @_;
1795 if ($enabled) {
1796 $BUILD_BUTTON->hide if $BUILD_BUTTON;
1797 $BUILD_BUTTON ||= new CFPlus::UI::Button
1798 text => "Build",
1799 tooltip => "Opens the ingame builder",
1800 on_activate => sub {
1801 if ($CONN) {
1802 $CONN->send_ext_req (builder_player_items => sub {
1803 open_ingame_editor ($_[0]) if exists $_[0]->{items};
1804 });
1805 }
1806 0
1807 };
1808 $BUTTONBAR->add ($BUILD_BUTTON);
1809 } else {
1810 $BUILD_BUTTON->hide if $BUILD_BUTTON;
1811 }
1812}
1813
1814sub open_ingame_editor {
1815 my ($msg) = @_;
1816
1817 my $win = new CFPlus::UI::Toplevel
1818 x => 0,
1819 y => 'center',
1820 z => 4,
1821 name => 'builder_window',
1822 force_w => int $WIDTH * 1/4,
1823 force_h => int $HEIGHT * 3/4,
1824 title => "In game builder",
1825 has_close_button => 1;
1826
1827 my $r = new CFPlus::UI::ScrolledWindow (
1828 expand => 1,
1829 scroll_y => 1
1830 );
1831 $r->add (my $vb = new CFPlus::UI::VBox);
1832 $win->add ($r);
1833
1834
1835 $vb->add (
1836 new CFPlus::UI::Button
1837 text => "Disable build mode",
1838 on_activate => sub { $::IN_BUILD_MODE = undef }
1839 );
1840 $vb->add (
1841 new CFPlus::UI::Button
1842 text => "ERASE",
1843 on_activate => sub { $::IN_BUILD_MODE = { do_erase => 1 } }
1844 );
1845
1846 for my $itemarchname (
1847 sort {
1848 $msg->{items}->{$a}->{build_arch_name}
1849 cmp $msg->{items}->{$b}->{build_arch_name}
1850 } keys %{$msg->{items}}
1851 ) {
1852 my $info = $msg->{items}->{$itemarchname};
1853 $vb->add (
1854 new CFPlus::UI::Button text => $info->{build_arch_name},
1855 on_activate => sub {
1856 $::IN_BUILD_MODE = { item => $itemarchname, info => $info };
1857
1858 if (grep { $msg->{items}->{$itemarchname}->{$_} } qw/has_connection has_name has_text/) {
1859 build_mode_query_arch_info ();
1860 }
1861 }
1862 );
1863 }
1864
1865 $win->show;
1866}
1867
1868sub build_mode_query_arch_info {
1869 my ($iteminfo) = $::IN_BUILD_MODE;
1870 my $itemarchname = $iteminfo->{item};
1871 my $info = $iteminfo->{info};
1872
1873 my $dialog = new CFPlus::UI::Toplevel
1874 x => "center",
1875 y => "center",
1876 z => 50,
1877 force_w => int $WIDTH * 1/2,
1878 title => "Enter information for placement of '$itemarchname'",
1879 has_close_button => 1;
1880
1881 $dialog->add (my $vb = new CFPlus::UI::VBox expand => 1);
1882
1883 $vb->add (my $table = new CFPlus::UI::Table expand => 1);
1884 my $row = 0;
1885 if ($info->{has_name}) {
1886 $table->add (0, $row, new CFPlus::UI::Label text => "Name:");
1887 $table->add (1, $row++, new CFPlus::UI::Entry expand => 1, on_changed => sub { $::IN_BUILD_MODE->{name} = $_[1]; 0 });
1888 }
1889 if ($info->{has_text}) {
1890 $table->add (0, $row, new CFPlus::UI::Label text => "Text:");
1891 $table->add (1, $row++, new CFPlus::UI::Entry expand => 1, on_changed => sub { $::IN_BUILD_MODE->{text} = $_[1]; 0 });
1892 }
1893 if ($info->{has_connection}) {
1894 $table->add (0, $row, new CFPlus::UI::Label text => "Connection ID:");
1895 $table->add (1, $row++,
1896 new CFPlus::UI::Entry
1897 expand => 1,
1898 on_changed => sub { $::IN_BUILD_MODE->{connection} = $_[1]; 0 },
1899 tooltip => "Enter the connection ID here. The connection ID connects actors like a lever to a gate or a magic ear to a gate"
1900 );
1901 }
1902
1903 $vb->add (my $hb = new CFPlus::UI::HBox expand => 1);
1904 $hb->add (new CFPlus::UI::Button
1905 text => "Close",
1906 expand => 1,
1907 on_activate => sub { $dialog->hide; 0 },
1908 );
1909 $dialog->show;
1910}
1911
1785sub video_shutdown { 1912sub video_shutdown {
1786 CFPlus::OpenGL::shutdown; 1913 CFPlus::OpenGL::shutdown;
1787 1914
1788 undef $SDL_ACTIVE; 1915 undef $SDL_ACTIVE;
1789} 1916}
1820 CFPlus::Mix_AllocateChannels 8; 1947 CFPlus::Mix_AllocateChannels 8;
1821 CFPlus::MixMusic::volume $CFG->{bgm_volume} * 128; 1948 CFPlus::MixMusic::volume $CFG->{bgm_volume} * 128;
1822 1949
1823 audio_music_finished; 1950 audio_music_finished;
1824 1951
1952 local $_;
1825 while (<$fh>) { 1953 while (<$fh>) {
1826 next if /^\s*#/; 1954 next if /^\s*#/;
1827 next if /^\s*$/; 1955 next if /^\s*$/;
1828 1956
1829 my ($file, $volume, $event) = split /\s+/, $_, 3; 1957 my ($file, $volume, $event) = split /\s+/, $_, 3;
1914 }, 2042 },
1915 CFPlus::SDL_VIDEOEXPOSE => sub { 2043 CFPlus::SDL_VIDEOEXPOSE => sub {
1916 CFPlus::UI::full_refresh; 2044 CFPlus::UI::full_refresh;
1917 }, 2045 },
1918 CFPlus::SDL_ACTIVEEVENT => sub { 2046 CFPlus::SDL_ACTIVEEVENT => sub {
1919# printf "active %x %x\n", $SDL_EV->active_gain, $SDL_EV->active_state;#d# 2047# not useful, as APPACTIVE include sonly iconified state, not unmapped
2048# printf "active %x %x\n", $_[0]{gain}, $_[0]{state};#d#
2049# printf "A\n" if $_[0]{state} & CFPlus::SDL_APPACTIVE;
2050# printf "K\n" if $_[0]{state} & CFPlus::SDL_APPINPUTFOCUS;
2051# printf "M\n" if $_[0]{state} & CFPlus::SDL_APPMOUSEFOCUS;
1920 }, 2052 },
1921 CFPlus::SDL_KEYDOWN => sub { 2053 CFPlus::SDL_KEYDOWN => sub {
1922 if ($_[0]{mod} & CFPlus::KMOD_ALT && $_[0]{sym} == 13) { 2054 if ($_[0]{mod} & CFPlus::KMOD_ALT && $_[0]{sym} == 13) {
1923 # alt-enter 2055 # alt-enter
1924 $FULLSCREEN_ENABLE->toggle; 2056 $FULLSCREEN_ENABLE->toggle;
1963 log_fontsize => 0.7, 2095 log_fontsize => 0.7,
1964 gauge_fontsize => 1, 2096 gauge_fontsize => 1,
1965 gauge_size => 0.35, 2097 gauge_size => 0.35,
1966 stat_fontsize => 0.7, 2098 stat_fontsize => 0.7,
1967 mapsize => 100, 2099 mapsize => 100,
1968 say_command => 'say', 2100 say_command => 'chat',
1969 audio_enable => 1, 2101 audio_enable => 1,
1970 bgm_enable => 1, 2102 bgm_enable => 1,
1971 bgm_volume => 0.25, 2103 bgm_volume => 0.25,
1972 face_prefetch => 0, 2104 face_prefetch => 0,
1973 output_sync => 1, 2105 output_sync => 1,
1974 output_count => 1, 2106 output_count => 1,
2107 output_rate => "",
1975 pickup => 0, 2108 pickup => 0,
1976 inv_sort => "mtime", 2109 inv_sort => "mtime",
1977 default => "profile", # default profile 2110 default => "profile", # default profile
2111 show_tips => 1,
1978 ); 2112 );
1979 2113
1980 while (my ($k, $v) = each %DEF_CFG) { 2114 while (my ($k, $v) = each %DEF_CFG) {
1981 $CFG->{$k} = $v unless exists $CFG->{$k}; 2115 $CFG->{$k} = $v unless exists $CFG->{$k};
1982 } 2116 }
1983 2117
1984 $CFG->{profile}{default}{host} ||= "crossfire.schmorp.de"; 2118 $CFG->{profile}{default}{host} ||= "crossfire.schmorp.de";
2119 $PROFILE = $CFG->{profile}{default};
2120
2121 # convert old bindings (only default profile matters)
2122 if (my $bindings = delete $PROFILE->{bindings}) {
2123 while (my ($mod, $syms) = each %$bindings) {
2124 while (my ($sym, $cmds) = each %$syms) {
2125 push @{ $PROFILE->{macro} }, {
2126 accelkey => [$mod*1, $sym*1],
2127 action => $cmds,
2128 };
2129 }
2130 }
2131 }
1985 2132
1986 sdl_init; 2133 sdl_init;
1987 2134
1988 @SDL_MODES = reverse 2135 @SDL_MODES = reverse
1989 grep $_->[0] >= 640 && $_->[1] >= 480, 2136 grep $_->[0] >= 640 && $_->[1] >= 480,
2026# } 2173# }
2027# my $t2 = Time::HiRes::time; 2174# my $t2 = Time::HiRes::time;
2028# warn $t2-$t1; 2175# warn $t2-$t1;
2029# } 2176# }
2030 2177
2178 $startup_done->();
2179
2031 video_init; 2180 video_init;
2032 audio_init; 2181 audio_init;
2033} 2182}
2183
2184show_tip_of_the_day if $CFG->{show_tips};
2034 2185
2035Event::loop; 2186Event::loop;
2036#CFPlus::SDL_Quit; 2187#CFPlus::SDL_Quit;
2037#CFPlus::_exit 0; 2188#CFPlus::_exit 0;
2038 2189

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines