#!/opt/bin/perl use strict; use Glib; use Gtk2 -init; use SDL; use SDL::App; use SDL::Event; use SDL::Surface; use SDL::OpenGL; use SDL::OpenGL::Constants; use Crossfire; use Crossfire::Client; use Crossfire::Protocol; use Client::Util; use Client::Widget; our $VERSION = '0.1'; our $CFG; our $CONN; our $SDL_TIMER; our $SDL_APP; our $SDL_EV = new SDL::Event; our %SDL_CB; our @GL_INIT; sub init_screen { $SDL_APP = new SDL::App -flags => SDL_ANYFORMAT | SDL_HWSURFACE, -title => "Crossfire+ Client", -width => $CFG->{width}, -height => $CFG->{height}, -opengl => 1, -red_size => 8, -green_size => 8, -blue_size => 8, -double_buffer => 1, -fullscreen => $CFG->{fullscreen}, -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, $CFG->{width} / 32, $CFG->{height} / 32, 0, -1 , 1; $_->() for @GL_INIT; } sub start_game { $SDL_TIMER = add Glib::Timeout 1000/20, sub { while ($SDL_EV->poll) { ($SDL_CB{$SDL_EV->type} || sub { warn "unhandled event ", $SDL_EV->type })->(); } 1 }; init_screen; $CONN = new conn host => $CFG->{host}, port => $CFG->{port}; } sub stop_game { remove Glib::Source $SDL_TIMER; undef $SDL_APP; SDL::Quit; } sub refresh { glClearColor 0, 0, 0, 0; glClear GL_COLOR_BUFFER_BIT; for (values %Client::Widget::ACTIVE_WIDGETS) { $_->draw } SDL::GLSwapBuffers; } %SDL_CB = ( SDL_QUIT() => sub { warn "sdl quit\n";#d# exit; }, SDL_VIDEORESIZE() => sub { }, SDL_VIDEOEXPOSE() => sub { refresh; }, SDL_KEYDOWN() => sub { Client::Widget::feed_sdl_key_down_event ($SDL_EV); }, SDL_KEYUP() => sub { Client::Widget::feed_sdl_key_up_event ($SDL_EV); }, SDL_MOUSEMOTION() => sub { warn "sdl motion\n";#d# }, SDL_MOUSEBUTTONDOWN() => sub { Client::Widget::feed_sdl_button_down_event ($SDL_EV); }, SDL_MOUSEBUTTONUP() => sub { Client::Widget::feed_sdl_button_up_event ($SDL_EV); }, SDL_ACTIVEEVENT() => sub { warn "active\n";#d# }, ); @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) = @_; } ############################################################################# my $mapwidget = Client::MapWidget->new; $mapwidget->activate; $mapwidget->focus_in; Client::Util::read_cfg "$Crossfire::VARDIR/pclientrc"; $CFG ||= { width => 640, height => 480, fullscreen => 0, host => "crossfire.schmorp.de", port => 13327, }; Client::Util::run_config_dialog login => sub { start_game }, logout => sub { stop_game }; main Gtk2;