#!/opt/bin/perl use strict; use Crossfire; use Crossfire::Client; use Crossfire::Protocol; use Client::Util; package Crossfire::Client; # uh, yeah use strict; our $CFG; our $VERSION = '0.1'; use SDL; use SDL::App; use SDL::Event; use SDL::Surface; use SDL::OpenGL; use SDL::OpenGL::Constants; my $conn; my $app; my $WIDTH = 640; my $HEIGHT = 480; sub glinit { # nuke all gl context data $app = new SDL::App -flags => SDL_ANYFORMAT | SDL_HWSURFACE, -title => "Crossfire+ Client", -width => $WIDTH, -height => $HEIGHT, -opengl => 1, -red_size => 8, -green_size => 8, -blue_size => 8, -double_buffer => 1, -resizeable => 0; glEnable GL_TEXTURE_2D; glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE; glShadeModel GL_FLAT; glDisable GL_DEPTH_TEST; glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; glEnable GL_BLEND; glMatrixMode GL_PROJECTION; glLoadIdentity; glOrtho 0, $WIDTH / 32, $HEIGHT / 32, 0, -1 , 1; # re-bind all textures } sub refresh { glClearColor 0, 0, 0, 0; glClear GL_COLOR_BUFFER_BIT; my $map = $conn->{map}; for my $x (0 .. $conn->{mapw} - 1) { for my $y (0 .. $conn->{maph} - 1) { my $cell = $map->[$x][$y] or next; my $darkness = $cell->[3] * (1 / 255); my $darkness = 0.8 + 0.2*rand; glColor $darkness, $darkness, $darkness; for my $num (grep $_, $cell->[0], $cell->[1], $cell->[2]) { my $tex = $conn->{face}[$num]{texture} || 0; glBindTexture GL_TEXTURE_2D, $tex; glBegin GL_QUADS; glTexCoord 0, 0; glVertex $x, $y; glTexCoord 0, 1; glVertex $x, $y + 1; glTexCoord 1, 1; glVertex $x + 1, $y + 1; glTexCoord 1, 0; glVertex $x + 1, $y; glEnd; } } } SDL::GLSwapBuffers; } my $ev = new SDL::Event; my %ev_cb; sub event(&$) { $ev_cb{$_[0]->()} = $_[1]; } sub does(&) { shift } event {SDL_QUIT} does { exit; }; event {SDL_VIDEORESIZE} does { print "resize\n"; }; event {SDL_VIDEOEXPOSE} does { refresh; }; event {SDL_KEYDOWN} does { print "keypress\n"; }; event {SDL_KEYUP} does { print "keyup\n";#d# }; event {SDL_MOUSEMOTION} does { print "motion\n"; }; event {SDL_MOUSEBUTTONDOWN} does { print "button\n"; }; event {SDL_MOUSEBUTTONUP} does { print "buttup\n"; }; event {SDL_ACTIVEEVENT} does { print "active\n"; }; package Crossfire::Client; @conn::ISA = Crossfire::Protocol::; sub conn::map_update { my ($self, $dirty) = @_; refresh; } sub conn::map_scroll { my ($self, $dx, $dy) = @_; refresh; } sub conn::map_clear { my ($self) = @_; refresh; } sub conn::face_update { my ($self, $num, $face) = @_; warn "up face $self,$num,$face\n";#d# use Gtk2; my $pb = new Gtk2::Gdk::PixbufLoader; $pb->write ($face->{image}); $pb->close; $pb = $pb->get_pixbuf; $pb = $pb->add_alpha (0, 0, 0, 0); glGetError(); my ($tex) = @{glGenTextures 1}; $face->{texture} = $tex; glBindTexture GL_TEXTURE_2D, $tex; my $glerr=glGetError(); die "a: ".gluErrorString($glerr)."\n" if $glerr; glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR; glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR;#_MIPMAP_LINEAR; glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP; glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP; glTexImage2D GL_TEXTURE_2D, 0, GL_RGBA8, $pb->get_width, $pb->get_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, $pb->get_pixels; my $glerr=glGetError(); die "Problem setting up 2d Texture (dimensions not a power of 2?)):".gluErrorString($glerr)."\n" if $glerr; } ############################################################################# use Event; Client::Util::read_cfg "$Crossfire::VARDIR/pclientrc"; glinit; $conn = new conn host => "cf.schmorp.de", port => 13327; Event->timer (after => 0, interval => 1/20, hard => 1, cb => sub { while ($ev->poll) { ($ev_cb{$ev->type} || sub { warn "unhandled event ", $ev->type })->(); } }); Event::loop;