1 | #!/opt/bin/perl |
1 | #!/opt/bin/perl |
2 | |
2 | |
3 | use strict; |
3 | use strict; |
4 | use utf8; |
4 | use utf8; |
|
|
5 | |
|
|
6 | BEGIN { |
|
|
7 | if (%PAR::LibCache) { |
|
|
8 | @INC = grep ref, @INC; # weed out all paths except pars loader refs |
|
|
9 | |
|
|
10 | while (my ($filename, $zip) = each %PAR::LibCache) { |
|
|
11 | for ($zip->memberNames) { |
|
|
12 | next unless /^\/root\/(.*)/; |
|
|
13 | $zip->extractMember ($_, "$ENV{PAR_TEMP}/$1") |
|
|
14 | unless -e "$ENV{PAR_TEMP}/$1"; |
|
|
15 | } |
|
|
16 | } |
|
|
17 | |
|
|
18 | unshift @INC, $ENV{PAR_TEMP}; |
|
|
19 | |
|
|
20 | if ($^O eq "MSWin32") { |
|
|
21 | $ENV{GTK_RC_FILES} = "$ENV{PAR_TEMP}/share/themes/MS-Windows/gtk-2.0/gtkrc"; |
|
|
22 | } |
|
|
23 | } |
|
|
24 | } |
|
|
25 | |
|
|
26 | # need to do it again because that pile of garbage called PAR nukes it before main |
|
|
27 | unshift @INC, $ENV{PAR_TEMP}; |
5 | |
28 | |
6 | use Time::HiRes 'time'; |
29 | use Time::HiRes 'time'; |
7 | use Event; |
30 | use Event; |
8 | |
31 | |
9 | use Crossfire; |
32 | use Crossfire; |
… | |
… | |
12 | use Compress::LZF; |
35 | use Compress::LZF; |
13 | |
36 | |
14 | use CFClient; |
37 | use CFClient; |
15 | use CFClient::UI; |
38 | use CFClient::UI; |
16 | use CFClient::MapWidget; |
39 | use CFClient::MapWidget; |
|
|
40 | |
|
|
41 | $Event::DIED = sub { |
|
|
42 | CFClient::error $_[1]; |
|
|
43 | }; |
|
|
44 | |
|
|
45 | #$SIG{__WARN__} = sub { Carp::cluck $_[0] };#d# |
17 | |
46 | |
18 | our $VERSION = '0.1'; |
47 | our $VERSION = '0.1'; |
19 | |
48 | |
20 | my $MAX_FPS = 60; |
49 | my $MAX_FPS = 60; |
21 | my $MIN_FPS = 5; # unused as of yet |
50 | my $MIN_FPS = 5; # unused as of yet |
… | |
… | |
533 | } |
562 | } |
534 | |
563 | |
535 | sub update_metaserver { |
564 | sub update_metaserver { |
536 | my ($HOST) = @_; |
565 | my ($HOST) = @_; |
537 | |
566 | |
538 | status "fetching metaserver list..."; |
567 | my $table = $METASERVER->{table}; |
|
|
568 | $table->clear; |
|
|
569 | $table->add (0, 0, my $label = new CFClient::UI::Label max_w => $WIDTH * 0.8, text => "fetching metaserver list..."); |
539 | |
570 | |
540 | my $buf; |
571 | my $buf; |
541 | |
572 | |
542 | my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0; |
573 | my $fh = new IO::Socket::INET PeerHost => $META_SERVER, Blocking => 0; |
|
|
574 | |
|
|
575 | unless ($fh) { |
|
|
576 | $label->set_text ("unable to contact metaserver: $!"); |
|
|
577 | return; |
|
|
578 | } |
543 | |
579 | |
544 | Event->io (fd => $fh, poll => 'r', cb => sub { |
580 | Event->io (fd => $fh, poll => 'r', cb => sub { |
545 | my $res = sysread $fh, $buf, 8192, length $buf; |
581 | my $res = sysread $fh, $buf, 8192, length $buf; |
546 | |
582 | |
547 | if (!defined $res) { |
583 | if (!defined $res) { |
548 | $_[0]->w->cancel; |
584 | $_[0]->w->cancel; |
549 | status "metaserver: $!"; |
585 | $label->set_text ("error while retrieving server list: $!"); |
550 | } elsif ($res == 0) { |
586 | } elsif ($res == 0) { |
551 | $_[0]->w->cancel; |
587 | $_[0]->w->cancel; |
552 | status "server list retrieved"; |
588 | status "server list retrieved"; |
553 | |
589 | |
554 | my $table = $METASERVER->{table}; |
590 | utf8::decode $buf if utf8::valid $buf; |
555 | |
591 | |
556 | $table->clear; |
592 | $table->clear; |
557 | |
593 | |
558 | my @col = qw(Use #Users Host Uptime Version Description); |
594 | my @col = qw(Use #Users Host Uptime Version Description); |
559 | $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_]) |
595 | $table->add ($_, 0, new CFClient::UI::Label align => 0, fg => [1, 1, 0], text => $col[$_]) |
… | |
… | |
583 | $m = [$users, $host, $uptime, $version, $desc]; |
619 | $m = [$users, $host, $uptime, $version, $desc]; |
584 | |
620 | |
585 | $y++; |
621 | $y++; |
586 | |
622 | |
587 | $table->add (0, $y, new CFClient::UI::VBox children => [ |
623 | $table->add (0, $y, new CFClient::UI::VBox children => [ |
588 | (new CFClient::UI::Button text => " ", connect_activate => sub { |
624 | (new CFClient::UI::Button text => "Use", connect_activate => sub { |
589 | $HOST->set_text ($CFG->{host} = $host); |
625 | $HOST->set_text ($CFG->{host} = $host); |
590 | }), |
626 | }), |
591 | (new CFClient::UI::Empty expand => 1), |
627 | (new CFClient::UI::Empty expand => 1), |
592 | ]); |
628 | ]); |
593 | |
629 | |
… | |
… | |
812 | $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup |
848 | $BUTTONBAR->{children}[1]->emit ("activate"); # pop up server setup |
813 | } |
849 | } |
814 | |
850 | |
815 | sub video_shutdown { |
851 | sub video_shutdown { |
816 | $CFClient::UI::ROOT->{children} = []; |
852 | $CFClient::UI::ROOT->{children} = []; |
|
|
853 | undef $CFClient::UI::GRAB; |
|
|
854 | undef $CFClient::UI::HOVER; |
817 | undef $SDL_ACTIVE; |
855 | undef $SDL_ACTIVE; |
818 | } |
856 | } |
819 | |
857 | |
820 | my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# |
858 | my @bgmusic = qw(game1.ogg game2.ogg game3.ogg game5.ogg game6.ogg ross1.ogg ross2.ogg ross3.ogg ross4.ogg ross5.ogg); #d# |
821 | my $bgmusic;#TODO#hack#d# |
859 | my $bgmusic;#TODO#hack#d# |
… | |
… | |
1435 | |
1473 | |
1436 | Event::loop; |
1474 | Event::loop; |
1437 | |
1475 | |
1438 | END { CFClient::SDL_Quit } |
1476 | END { CFClient::SDL_Quit } |
1439 | |
1477 | |
|
|
1478 | =head1 pclient - Crossfire+ and Crossfire game client |
1440 | |
1479 | |
|
|
1480 | Pclient is a Crossfire+ and Crossfire game client. |
|
|
1481 | |
|
|
1482 | =head2 Features |
|
|
1483 | |
|
|
1484 | =over 4 |
|
|
1485 | |
|
|
1486 | =item Fullscreen Map |
|
|
1487 | |
|
|
1488 | PClient can uses a fullscreen map, which greatly enhances how much of the |
|
|
1489 | game world you can see. |
|
|
1490 | |
|
|
1491 | =item Persistent Map Cache (Crossfire+ only) |
|
|
1492 | |
|
|
1493 | PClient can persistently cache all map data it received from the |
|
|
1494 | server. This not only allows it to display an overview map, but also |
|
|
1495 | ensures that once-explored areas will be available the next time you want |
|
|
1496 | to explore more. |
|
|
1497 | |
|
|
1498 | =item Hardware acceleration |
|
|
1499 | |
|
|
1500 | Unlike most Crossfire clients, PClient take advantage of OpenGL hardware |
|
|
1501 | acceleration. Most modern graphics cards have difficulties with 2D |
|
|
1502 | acceleration, while 3D graphics is accelerated well. |
|
|
1503 | |
|
|
1504 | =item No arbitrary limits |
|
|
1505 | |
|
|
1506 | Unlike other Crossfire clients, pclient does not suffer from arbitrary |
|
|
1507 | limits (like a fixed amount of face numbers). There are still limits, but |
|
|
1508 | they are not arbitrarily low :) |
|
|
1509 | |
|
|
1510 | =back |
|
|
1511 | |
|
|
1512 | =head1 FAQ |
|
|
1513 | |
|
|
1514 | =over 4 |
|
|
1515 | |
|
|
1516 | =item The client is very sluggish and slow, what can I do about this? |
|
|
1517 | |
|
|
1518 | Most likely, you don't have accelerated OpenGL support. Try to find a |
|
|
1519 | newer driver, or a driver from your hardware vendor, that features OpenGL |
|
|
1520 | support. |
|
|
1521 | |
|
|
1522 | If this is not an option, the following Setup options reduce the load and |
|
|
1523 | will likely make the client playable with sofwtare rendering (it will |
|
|
1524 | still be slow, though): |
|
|
1525 | |
|
|
1526 | =over 4 |
|
|
1527 | |
|
|
1528 | =item B<Video Mode> should be set as low as possible (e.g. 640x480) |
|
|
1529 | |
|
|
1530 | =item Enable B<Fast & Ugly> mode |
|
|
1531 | |
|
|
1532 | =item Disable B<Fog of War> |
|
|
1533 | |
|
|
1534 | =item Increase B<Map Scale> |
|
|
1535 | |
|
|
1536 | =back |
|
|
1537 | |
|
|
1538 | =back |
|
|
1539 | |
|
|
1540 | =head1 AUTHOR |
|
|
1541 | |
|
|
1542 | Marc Lehmann <crossfire@schmorp.de>, Robin Redeker <elmex@ta-sa.org> |
|
|
1543 | |
|
|
1544 | |
|
|
1545 | |