ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/MapWidget.pm
Revision: 1.2
Committed: Wed Apr 19 09:40:00 2006 UTC (18 years, 1 month ago) by root
Branch: MAIN
Changes since 1.1: +7 -0 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 package CFClient::MapWidget;
2
3 use strict;
4
5 use List::Util qw(min max);
6
7 use SDL;
8 use SDL::OpenGL;
9
10 our @ISA = CFClient::UI::Base::;
11
12 sub new {
13 my $class = shift;
14
15 $class->SUPER::new (
16 z => -1,
17 can_focus => 1,
18 list => (glGenLists 1),
19 @_
20 )
21 }
22
23 sub key_down {
24 print "MAPKEYDOWN\n";
25 }
26
27 sub key_up {
28 }
29
30 sub button_down {
31 my ($self, $ev, $x, $y) = @_;
32
33 $self->focus_in;
34
35 if ($ev->button == 2) {
36 my ($ox, $oy) = ($ev->button_x, $ev->button_y);
37 my ($bw, $bh) = ($::CFG->{map_shift_x}, $::CFG->{map_shift_y});
38
39 $self->{motion} = sub {
40 my ($ev, $x, $y) = @_;
41
42 ($x, $y) = ($ev->motion_x, $ev->motion_y);
43
44 $::CFG->{map_shift_x} = $bw + $x - $ox;
45 $::CFG->{map_shift_y} = $bh + $y - $oy;
46
47 $self->update;
48 };
49 }
50 }
51
52 sub button_up {
53 my ($self, $ev, $x, $y) = @_;
54
55 delete $self->{motion};
56 }
57
58 sub mouse_motion {
59 my ($self, $ev, $x, $y) = @_;
60
61 $self->{motion}->($ev, $x, $y) if $self->{motion};
62 }
63
64 sub size_request {
65 (
66 1 + 32 * int $::WIDTH / 32,
67 1 + 32 * int $::HEIGHT / 32,
68 )
69 }
70
71 sub update {
72 my ($self) = @_;
73
74 $self->{need_update} = 1;
75 $self->SUPER::update;
76 }
77
78 sub draw {
79 my ($self) = @_;
80
81 if (delete $self->{need_update}) {
82 glNewList $self->{list}, GL_COMPILE;
83
84 if ($::MAP) {
85 my $sw = int $::WIDTH / 32;
86 my $sh = int $::HEIGHT / 32;
87
88 my $sx = $::CFG->{map_shift_x}; my $sx0 = $sx & 31; $sx = ($sx - $sx0) / 32;
89 my $sy = $::CFG->{map_shift_y}; my $sy0 = $sy & 31; $sy = ($sy - $sy0) / 32;
90
91 glTranslate $sx0 - 32, $sy0 - 32, 0;
92
93 my ($w, $h, $data) = $::MAP->draw ($sx, $sy, 0, 0, $sw + 1, $sh + 1);
94
95 if ($::CFG->{fow_enable}) {
96 if ($::CFG->{fow_smooth} && $CFClient::GL_VERSION >= 1.2) { # smooth fog of war
97 glConvolutionParameter (GL_CONVOLUTION_2D, GL_CONVOLUTION_BORDER_MODE, GL_CONSTANT_BORDER);
98 glConvolutionFilter2D (
99 GL_CONVOLUTION_2D,
100 GL_ALPHA,
101 3, 3,
102 GL_ALPHA, GL_FLOAT,
103 pack "f*",
104 0.1, 0.1, 0.1,
105 0.1, 0.2, 0.1,
106 0.1, 0.1, 0.1,
107 );
108 glEnable GL_CONVOLUTION_2D;
109 }
110
111 $self->{fow_texture} = new CFClient::Texture
112 w => $w,
113 h => $h,
114 data => $data,
115 internalformat => GL_ALPHA,
116 format => GL_ALPHA;
117
118 glDisable GL_CONVOLUTION_2D if $::CFG->{fow_smooth};
119
120 glEnable GL_BLEND;
121 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
122 glEnable GL_TEXTURE_2D;
123 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE;
124
125 glColor +($::CFG->{fow_intensity}) x 3, 1;
126 $self->{fow_texture}->draw_quad (0, 0, $w * 32, $h * 32);
127
128 glDisable GL_TEXTURE_2D;
129 glDisable GL_BLEND;
130 }
131
132 # HACK BEGIN
133 {
134 glTranslate -($sx0 - 32), -($sy0 - 32), 0;#remove
135 my ($w, $h) = (250, 250);
136
137 glEnable GL_BLEND;
138 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
139 glEnable GL_TEXTURE_2D;
140 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
141
142 $self->{mapmap_texture} =
143 new CFClient::Texture
144 w => $w,
145 h => $h,
146 data => $::MAP->mapmap ($w, $h),
147 type => $CFClient::GL_VERSION >= 1.2 ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_BYTE;
148
149 $self->{mapmap_texture}->draw_quad (100, 100);
150
151 glDisable GL_TEXTURE_2D;
152 glDisable GL_BLEND;
153 }
154 # HACK END
155 }
156
157 glEndList;
158 }
159
160 glPushMatrix;
161 glCallList $self->{list};
162 glPopMatrix;
163
164 if ($CFClient::UI::FOCUS != $self) {
165 glColor 64/255, 64/255, 64/255;
166 glLogicOp GL_AND;
167 glEnable GL_COLOR_LOGIC_OP;
168 glBegin GL_QUADS;
169 glVertex 0, 0;
170 glVertex 0, $::HEIGHT;
171 glVertex $::WIDTH, $::HEIGHT;
172 glVertex $::WIDTH, 0;
173 glEnd;
174 glDisable GL_COLOR_LOGIC_OP;
175 }
176 }
177
178 my %DIR = (
179 SDLK_KP8, [1, "north"],
180 SDLK_KP9, [2, "northeast"],
181 SDLK_KP6, [3, "east"],
182 SDLK_KP3, [4, "southeast"],
183 SDLK_KP2, [5, "south"],
184 SDLK_KP1, [6, "southwest"],
185 SDLK_KP4, [7, "west"],
186 SDLK_KP7, [8, "northwest"],
187
188 SDLK_UP, [1, "north"],
189 SDLK_RIGHT, [3, "east"],
190 SDLK_DOWN, [5, "south"],
191 SDLK_LEFT, [7, "west"],
192 );
193
194 sub key_down {
195 my ($self, $ev) = @_;
196
197 my $mod = $ev->key_mod;
198 my $sym = $ev->key_sym;
199
200 if ($sym == SDLK_KP5) {
201 $::CONN->user_send ("stay fire");
202 } elsif ($sym == SDLK_a) {
203 $::CONN->user_send ("apply");
204 } elsif ($sym == SDLK_QUOTE) {
205 $self->emit ('activate_console');
206 } elsif ($sym == SDLK_SLASH) {
207 $self->emit ('activate_console' => '/');
208 } elsif (exists $DIR{$sym}) {
209 if ($mod & KMOD_SHIFT) {
210 $self->{shft}++;
211 $::CONN->user_send ("fire $DIR{$sym}[0]");
212 } elsif ($mod & KMOD_CTRL) {
213 $self->{ctrl}++;
214 $::CONN->user_send ("run $DIR{$sym}[0]");
215 } else {
216 $::CONN->user_send ("$DIR{$sym}[1]");
217 }
218 }
219 }
220
221 sub key_up {
222 my ($self, $ev) = @_;
223
224 my $mod = $ev->key_mod;
225 my $sym = $ev->key_sym;
226
227 if (!($mod & KMOD_SHIFT) && delete $self->{shft}) {
228 $::CONN->user_send ("fire_stop");
229 }
230 if (!($mod & KMOD_CTRL ) && delete $self->{ctrl}) {
231 $::CONN->user_send ("run_stop");
232 }
233 }
234
235 sub add_command {
236 my ($self, $command, $widget, $cb) = @_;
237
238 (my $abbrev = $command) =~ s/(\S)[^[:space:]_]*[[:space:]_]*/$1/g;
239 warn "$command|$abbrev|$widget\n";#d#
240 }
241
242 1