1 #include <stdlib.h>
2 #include <string.h>
3 #include <SDL.h>
4 #include "minimap.h"
5 #include "asc.h"
6 #include "buddy.h"
7 #include "colors.h"
8 #include "context_menu.h"
9 #include "cursors.h"
10 #include "elconfig.h"
11 #include "elwindows.h"
12 #include "errors.h"
13 #include "framebuffer.h"
14 #include "gamewin.h"
15 #include "gl_init.h"
16 #include "hud.h"
17 #include "init.h"
18 #include "interface.h"
19 #include "mines.h"
20 #include "misc.h"
21 #include "named_colours.h"
22 #include "spells.h"
23 #include "textures.h"
24 #include "tiles.h"
25 #include "pathfinder.h"
26 #include "translate.h"
27 #include "io/map_io.h"
28 #include "io/elpathwrapper.h"
29 #include "io/elfilewrapper.h"
30 #include "mapwin.h"
31 #include "map.h"
32 #include "image_loading.h"
33
34 float minimap_tiles_distance = 48;
35 int rotate_minimap = 1;
36 int pin_minimap = 0;
37 int open_minimap_on_start = 0;
38 float minimap_size_coefficient = 0.7f;
39
40 static int minimap_size;
41 static float float_minimap_size;
42 static int enable_controls = 0;
43 static int title_len = 0;
44
45 static GLuint compass_tex;
46 static GLuint minimap_texture = 0;
47 static GLuint exploration_texture = 0;
48 //static GLubyte exploration_map[256][256];
49 //static char current_exploration_map_filename[256];
50
minimap_get_zoom()51 static __inline__ float minimap_get_zoom ()
52 {
53 float zoom = minimap_tiles_distance * 2 / (tile_map_size_x*6);
54 return zoom;
55 }
56
rotate_actor_points(float zoom_multip,float px,float py)57 static __inline__ void rotate_actor_points(float zoom_multip, float px, float py)
58 {
59 float x,y;
60 x = (px - (float_minimap_size/2) ) + float_minimap_size/2;
61 y = (py - (float_minimap_size/2) ) + float_minimap_size/2;
62
63 glTranslatef(float_minimap_size/2, float_minimap_size/2, 0.0f);
64
65 if(rotate_minimap)
66 glRotatef(-rz, 0.0f,0.0f,1.0f );
67 glTranslatef(-x,-y,0.0f);
68
69 glScalef(1.0f / zoom_multip, 1.0f / zoom_multip, 1.0f);
70 x = x * zoom_multip * ((1.0f / zoom_multip) - 1);
71 y = y * zoom_multip * ((1.0f / zoom_multip) - 1);
72 glTranslatef(-x,-y,0.0f);
73 }
74
rotate_at_player(float zoom_multip,float px,float py)75 static __inline__ void rotate_at_player(float zoom_multip, float px, float py)
76 {
77 float x,y;
78 x = (px - (float_minimap_size/2) );
79 y = (py - (float_minimap_size/2) );
80 if(rotate_minimap)
81 glRotatef(-rz, 0.0f,0.0f,1.0f );
82 glTranslatef(-x,-y,0.0f);
83
84 glScalef(1.0f / zoom_multip, 1.0f / zoom_multip, 1.0f);
85
86 x = x * zoom_multip * ((1.0f / zoom_multip) - 1);
87 y = y * zoom_multip * ((1.0f / zoom_multip) - 1);
88 glTranslatef(-x,-y,0.0f);
89 }
90
rotate_click_coords(float * x,float * y)91 static __inline__ void rotate_click_coords(float * x,float * y)
92 {
93 if(rotate_minimap)
94 {
95 float fx,fy;
96 float angel = -rz*0.0174532925f;
97 fx = cos(angel) * (*x - float_minimap_size/2.0f) - sin(angel) * (*y - float_minimap_size/2.0f);
98 fy = sin(angel) * (*x - float_minimap_size/2.0f) + cos(angel) * (*y - float_minimap_size/2.0f);
99 *x = fx + float_minimap_size/2;
100 *y = fy + float_minimap_size/2;
101 }
102 }
103
is_within_radius(float mx,float my,float px,float py,float radius)104 static __inline__ int is_within_radius(float mx, float my,float px,float py,float radius)
105 {
106 float distance;
107
108 distance = sqrt(pow(px - mx,2) + pow(py-my,2));
109 if(distance <= radius)
110 return 1;
111 else
112 return 0;
113 }
114
draw_actor_points(window_info * win,float zoom_multip,float px,float py)115 static __inline__ void draw_actor_points(window_info *win, float zoom_multip, float px, float py)
116 {
117 float size_x = float_minimap_size / (tile_map_size_x * 6);
118 float size_y = float_minimap_size / (tile_map_size_y * 6);
119 actor *a;
120 int i;
121 float x, y;
122
123 glPushMatrix();
124 glDisable(GL_TEXTURE_2D);
125
126 //display the actors
127 glEnable( GL_POINT_SMOOTH );
128 glEnable( GL_BLEND );
129 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
130 glPointSize((int)(0.5 + win->current_scale * 8));
131
132 rotate_actor_points(zoom_multip,px,py);
133
134 glBegin(GL_POINTS);
135
136 for (i = 0; i < max_actors; i++)
137 {
138 if (actors_list[i])
139 {
140 a = actors_list[i];
141 if (a->attached_actor != -1 && a->actor_id == -1)
142 continue;
143 x = a->x_tile_pos * size_x;
144 y = float_minimap_size - (a->y_tile_pos * size_y);
145
146 glColor4f(0.0f,0.0f,0.0f,1.0f);
147 glVertex2f(x+2*zoom_multip, y+2*zoom_multip);
148
149 if (a->kind_of_actor == NPC)
150 elglColourN("minimap.npc");
151 else if(a->actor_id == yourself)
152 elglColourN("minimap.yourself");
153 else if(a->is_enhanced_model && (a->kind_of_actor == PKABLE_HUMAN || a->kind_of_actor == PKABLE_COMPUTER_CONTROLLED))
154 elglColourN("minimap.pkable");
155 else if(a->is_enhanced_model && is_in_buddylist(a->actor_name))
156 elglColourN("minimap.buddy");
157 else if (is_color ((unsigned char)a->actor_name[0]))
158 {
159 if(a->is_enhanced_model && is_in_buddylist(a->actor_name))
160 elglColourN("minimap.buddy");
161 else
162 { // Use the colour of their name. This gives purple bots, green demigods, etc.
163 int color = from_color_char (a->actor_name[0]);
164 glColor4ub (colors_list[color].r1,
165 colors_list[color].g1,
166 colors_list[color].b1, 255);
167 }
168 }
169 else if(!a->is_enhanced_model)
170 {
171 if (a->dead)
172 elglColourN("minimap.deadcreature");
173 else // alive
174 elglColourN("minimap.creature");
175 }
176 else
177 elglColourN("minimap.otherplayer");
178 // Draw it!
179 glVertex2f(x, y);
180 }
181 }
182
183 // mines
184 for (i = 0; i < NUM_MINES; i++)
185 {
186 mine *m = &mine_list[i];
187 if (m->obj_3d_id != -1)
188 {
189 x = m->x * size_x;
190 y = float_minimap_size - (m->y * size_y);
191 if(is_within_radius(x,y,px,py,zoom_multip*(minimap_size/2-15)))
192 {
193 elglColourN("minimap.mine");
194 glVertex2f(x, y);
195 }
196 }
197 }
198
199 glEnd();//GL_POINTS
200 glDisable(GL_BLEND);
201 glDisable(GL_POINT_SMOOTH);
202
203 glPopMatrix();
204
205 if (pf_follow_path)
206 {
207 x = pf_dst_tile->x * size_x;
208 y = float_minimap_size - (pf_dst_tile->y * size_y);
209
210 if (x != px || y != py)
211 {
212 float diff = 6.0f * zoom_multip * win->current_scale;
213
214 if(is_within_radius(x,y,px,py,zoom_multip*(minimap_size/2-15)))
215 {
216 glPushMatrix();
217 glDisable(GL_TEXTURE_2D);
218 rotate_actor_points(zoom_multip,px,py);
219 glBegin(GL_LINES);
220 elglColourN("minimap.cross");
221 glVertex2f(x-diff, y-diff);
222 glVertex2f(x+diff, y+diff);
223 glVertex2f(x-diff, y+diff);
224 glVertex2f(x+diff, y-diff);
225 glEnd();//GL_LINES
226 glPopMatrix();
227 }
228 }
229 }
230
231 //draw map markings
232 for(i=0;i<max_mark;i++){
233 if(!marks[i].server_side) continue;
234 x= marks[i].x*size_x;
235 y= float_minimap_size-(marks[i].y*size_y);
236 if (x != px || y != py)
237 {
238 float diff = 4.0f*zoom_multip;
239
240 if(is_within_radius(x,y,px,py,zoom_multip*(minimap_size/2-15)))
241 {
242 glPushMatrix();
243 glDisable(GL_TEXTURE_2D);
244 rotate_actor_points(zoom_multip,px,py);
245 glBegin(GL_LINES);
246 elglColourN("minimap.servermark");
247 glVertex2f(x-diff, y-diff);
248 glVertex2f(x+diff, y+diff);
249 glVertex2f(x-diff, y+diff);
250 glVertex2f(x+diff, y-diff);
251 glEnd();//GL_LINES
252 glPopMatrix();
253 }
254 }
255 }
256
257
258 glColor4f(1.0f,1.0f,1.0f,1.0f);
259 glEnable(GL_TEXTURE_2D);
260 }
261
draw_compass()262 static __inline__ void draw_compass()
263 {
264 glPushMatrix();
265 glColor3f(1.0f,1.0f,1.0f);
266 glTranslatef(float_minimap_size/2, float_minimap_size/2, 0.0f);
267 if(rotate_minimap)
268 glRotatef(-rz - 90, 0.0f,0.0f,1.0f );
269 else
270 glRotatef(-90, 0.0f,0.0f,1.0f );
271 glRotatef(180, 1.0f,0.0f,0.0f );
272 glEnable(GL_TEXTURE_2D);
273 glEnable(GL_BLEND);
274 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
275 bind_texture(compass_tex);
276
277 glBegin(GL_QUADS);
278 glTexCoord2f(0.0f, 1.0f);
279 glVertex2f(-float_minimap_size/2, float_minimap_size/2);
280 glTexCoord2f(0.0f, 0.0f);
281 glVertex2f(float_minimap_size/2, float_minimap_size/2);
282 glTexCoord2f(1.0f, 0.0f);
283 glVertex2f(float_minimap_size/2, -float_minimap_size/2);
284 glTexCoord2f(1.0f, 1.0f);
285 glVertex2f(-float_minimap_size/2, -float_minimap_size/2);
286 glEnd();
287
288 glDisable(GL_ALPHA_TEST);
289 glDisable( GL_BLEND );
290 glPopMatrix();
291 }
292
draw_map(window_info * win,float zoom_multip,float px,float py)293 static __inline__ void draw_map(window_info *win,float zoom_multip, float px, float py)
294 {
295 float sx = 0.0f, sy = 0.0f;
296 int i;
297 float x, y;
298
299 glPushMatrix();
300
301 sx = float_minimap_size/2;
302 sy = float_minimap_size/2;
303
304 glTranslatef(sx, sy, 0.0f);
305
306 glClearStencil(0);
307 glClear(GL_STENCIL_BUFFER_BIT);
308 glEnable(GL_STENCIL_TEST);
309 glStencilFunc(GL_ALWAYS, 1, 1);
310 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
311 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
312 glDepthMask(GL_FALSE);
313
314 glColor3f(0.0f,0.0f,0.0f);
315 glBegin(GL_POLYGON);
316 for (i=0; i<=360; i +=10)
317 {
318 x = sin((i)*0.0174532925f)/2*float_minimap_size;
319 y = cos((i)*0.0174532925f)/2*float_minimap_size;
320 glVertex2f(x, y);
321 }
322 glEnd();
323
324 glStencilFunc(GL_EQUAL, 1, 1);
325 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
326
327 // re-enable the drawing in the current buffer
328 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
329 glDepthMask(GL_TRUE);
330
331 glEnable(GL_TEXTURE_2D);
332
333 //draw the map
334 bind_texture(minimap_texture);
335 glColor4f(1.0f,1.0f,1.0f,1.0f);
336
337 rotate_at_player(zoom_multip,px,py);
338 glBegin(GL_QUADS);
339 glTexCoord2f(0.0f, 1.0f);
340 glVertex2f(-float_minimap_size/2, float_minimap_size/2);
341 glTexCoord2f(1.0f, 1.0f);
342 glVertex2f(float_minimap_size/2, float_minimap_size/2);
343 glTexCoord2f(1.0f, 0.0f);
344 glVertex2f(float_minimap_size/2, -float_minimap_size/2);
345 glTexCoord2f(0.0f, 0.0f);
346 glVertex2f(-float_minimap_size/2, -float_minimap_size/2);
347 glEnd();
348
349 glDisable(GL_STENCIL_TEST);
350
351 glPopMatrix();
352 if (compass_tex)
353 {
354 //draw the compass texture
355 draw_compass();
356 }
357 }
358
draw_minimap_title_bar(window_info * win)359 static void draw_minimap_title_bar(window_info *win)
360 {
361 float u_first_start= (float)31/255;
362 float u_first_end = 0.5f/255.0f;
363 float v_first_start = (float)160/255;
364 float v_first_end = (float)175/255;
365
366 float u_last_start = 0.5f/255.0f;
367 float u_last_end = (float)31/255;
368 float v_last_start = (float)160/255;
369 float v_last_end = (float)175/255;
370
371 int close_button_x = win->len_x/2 + title_len - 1;
372
373 glPushMatrix();
374
375 glColor3f(1.0f,1.0f,1.0f);
376
377 bind_texture(icons_text);
378 glEnable(GL_ALPHA_TEST);
379 glAlphaFunc(GL_GREATER,0.03f);
380 glEnable(GL_TEXTURE_2D);
381
382 glBegin(GL_QUADS);
383
384 glTexCoord2f(u_first_end, v_first_start);
385 glVertex3i(win->len_x/2-title_len, win->title_height, 0);
386 glTexCoord2f(u_first_end, v_first_end);
387 glVertex3i(win->len_x/2-title_len, 0, 0);
388 glTexCoord2f(u_first_start, v_first_end);
389 glVertex3i(win->len_x/2, 0, 0);
390 glTexCoord2f(u_first_start, v_first_start);
391 glVertex3i(win->len_x/2, win->title_height, 0);
392
393 glTexCoord2f(u_last_end, v_last_start);
394 glVertex3i(win->len_x/2, win->title_height, 0);
395 glTexCoord2f(u_last_end, v_last_end);
396 glVertex3i(win->len_x/2, 0, 0);
397 glTexCoord2f(u_last_start, v_last_end);
398 glVertex3i(win->len_x/2+title_len, 0, 0);
399 glTexCoord2f(u_last_start, v_last_start);
400 glVertex3i(win->len_x/2+title_len, win->title_height, 0);
401
402 glEnd();
403 glDisable(GL_ALPHA_TEST);
404 glDisable(GL_TEXTURE_2D);
405
406 //draw the X background
407 glColor3f(0.156f,0.078f,0.0f);
408 glBegin(GL_POLYGON);
409 glVertex2f(close_button_x + win->title_height, win->title_height);
410 glVertex2f(close_button_x, win->title_height);
411 glVertex2f(close_button_x, 0);
412 glVertex2f(close_button_x + win->title_height, 0);
413 glEnd();
414 //draw the rectngle
415 glColor3f(win->line_color[0],win->line_color[1],win->line_color[2]);
416 glBegin(GL_LINE_STRIP);
417 glVertex2i(close_button_x + win->title_height, win->title_height);
418 glVertex2i(close_button_x, win->title_height);
419 glVertex2i(close_button_x, 0);
420 glVertex2i(close_button_x + win->title_height, 0);
421 glVertex2i(close_button_x + win->title_height, win->title_height);
422 glEnd();
423 //draw the X
424 draw_cross(close_button_x + win->title_height / 2, win->title_height / 2,
425 win->title_height / 2 - win->title_height / 6, 1);
426 glPopMatrix();
427 #ifdef OPENGL_TRACE
428 CHECK_GL_ERRORS();
429 #endif //OPENGL_TRACE
430 }
431
display_minimap_handler(window_info * win)432 static int display_minimap_handler(window_info *win)
433 {
434 float zoom_multip;
435 float size_x = float_minimap_size / (tile_map_size_x * 6);
436 float size_y = float_minimap_size / (tile_map_size_y * 6);
437 float px = 0.0f, py = 0.0f;
438 actor *me;
439 float x,y;
440 int i;
441
442 if (win->pos_x + win->len_x/2 < 0)
443 move_window(win->window_id, win->pos_id, win->pos_loc, -win->len_x/2, win->pos_y);
444 else if (win->pos_x > window_width - win->len_x/2)
445 move_window(win->window_id, win->pos_id, win->pos_loc, window_width - win->len_x/2, win->pos_y);
446 if (win->pos_y < 0)
447 move_window(win->window_id, win->pos_id, win->pos_loc, win->pos_x, win->title_height);
448 else if (win->pos_y > window_height - win->title_height)
449 move_window(win->window_id, win->pos_id, win->pos_loc, win->pos_x, window_height - win->title_height);
450
451 if (enable_controls)
452 {
453 draw_minimap_title_bar(win);
454 enable_controls = 0;
455 }
456
457 zoom_multip = minimap_get_zoom();
458
459 if(!minimap_texture)
460 {
461 //there's no minimap for this map :( draw a X
462 glTranslatef(0.0f, win->title_height, 0.0f);
463 glPushMatrix();
464 glDisable(GL_TEXTURE_2D);
465 //draw black background
466 glColor3f(0.0f,0.0f,0.0f);
467 glBegin(GL_POLYGON);
468 for (i=0; i<=360; i +=10)
469 {
470 x = sin((i)*0.0174532925f)/2*float_minimap_size+float_minimap_size/2;
471 y = cos((i)*0.0174532925f)/2*float_minimap_size+float_minimap_size/2;
472 glVertex2f(x, y);
473 }
474 glEnd();
475
476 glPopMatrix();
477 draw_compass();
478 return 0;
479 }
480 //draw minimap
481
482 //get player position in window coordinates
483 if( (me = get_our_actor ()) == NULL)
484 {
485 //Don't know who we are? can't draw then
486 return 0;
487 }
488 px = me->x_tile_pos * size_x;
489 py = float_minimap_size - (me->y_tile_pos * size_y);
490
491 glTranslatef(0.0f, win->title_height, 0.0f);
492
493 glDisable(GL_TEXTURE_2D);
494 //draw black background
495 glColor3f(0.0f,0.0f,0.0f);
496 glBegin(GL_POLYGON);
497 for (i=0; i<=360; i +=10)
498 {
499 x = sin((i)*0.0174532925f)/2*float_minimap_size+float_minimap_size/2;
500 y = cos((i)*0.0174532925f)/2*float_minimap_size+float_minimap_size/2;
501 glVertex2f(x, y);
502 }
503 glEnd();
504
505 draw_map(win,zoom_multip, px, py);
506 draw_actor_points(win, zoom_multip, px, py);
507
508
509 #ifdef OPENGL_TRACE
510 CHECK_GL_ERRORS();
511 #endif //OPENGL_TRACE
512
513 return 0;
514 }
515
516 /*
517 * Handler for clicks into minimap. Coordinates are given as window pixels with origin at bottom-left corner
518 */
minimap_walkto(int mx,int my)519 static int minimap_walkto(int mx, int my)
520 {
521 float fmx = mx, fmy = my;
522 actor *me;
523
524 if ( (me = get_our_actor ()) == NULL)
525 return 0;
526
527 rotate_click_coords(&fmx,&fmy);
528
529 fmx = me->x_tile_pos - minimap_tiles_distance
530 + minimap_tiles_distance * 2 * fmx/float_minimap_size;
531 fmy = me->y_tile_pos - minimap_tiles_distance
532 + minimap_tiles_distance * 2 * fmy/float_minimap_size;
533
534 /* Do path finding */
535 if (pf_find_path(fmx, fmy))
536 {
537 return 1;
538 }
539
540 return 0;
541 }
542
increase_zoom()543 static void increase_zoom()
544 {
545 minimap_tiles_distance -=8;
546 if(minimap_tiles_distance < 48)
547 minimap_tiles_distance = 48;
548 }
549
decrease_zoom()550 static void decrease_zoom()
551 {
552 minimap_tiles_distance +=8;
553 if(minimap_tiles_distance > 144)
554 minimap_tiles_distance = 144;
555 }
556
click_minimap_handler(window_info * win,int mx,int my,Uint32 flags)557 static int click_minimap_handler(window_info * win, int mx, int my, Uint32 flags)
558 {
559 int close_button_x = win->len_x/2 + title_len - 1;
560 if(left_click)
561 {
562 //check for close button click
563 if((mx >=close_button_x) && (mx <=close_button_x + win->title_height)
564 && (my <= win->title_height))
565 {
566 hide_window(win->window_id);
567 return 1;
568 }
569 else if(my >= win->title_height)
570 {
571 //check if the click is in the round area
572 if(is_within_radius(mx,my-win->title_height,float_minimap_size/2,float_minimap_size/2,float_minimap_size/2))
573 {
574 minimap_walkto(mx, win->len_y - my);
575 return 1;
576 }
577 }
578 // title bar?
579 else if ((mx > win->len_x/2-title_len) && (mx < win->len_x/2+title_len) && (my >= 0) && (my <= 2*win->title_height))
580 return 1;
581 }
582 else if((flags & ELW_WHEEL) && is_within_radius(mx,my-win->title_height,float_minimap_size/2,float_minimap_size/2,float_minimap_size/2))
583 {
584 if(flags & ELW_WHEEL_UP)
585 increase_zoom();
586 else
587 decrease_zoom();
588 return 1;
589 }
590
591 return 0;
592 }
593
keypress_minimap_handler(window_info * win,int mx,int my,SDL_Keycode key_code,Uint32 key_unicode,Uint16 key_mod)594 static int keypress_minimap_handler (window_info *win, int mx, int my, SDL_Keycode key_code, Uint32 key_unicode, Uint16 key_mod)
595 {
596 if (is_within_radius(mx,my-win->title_height,float_minimap_size/2,float_minimap_size/2,float_minimap_size/2))
597 {
598 if((key_code == SDLK_KP_PLUS) || (key_code == SDLK_PAGEUP))
599 {
600 increase_zoom();
601 return 1;
602 }
603 else if ((key_code == SDLK_KP_MINUS) || (key_code == SDLK_PAGEDOWN))
604 {
605 decrease_zoom();
606 return 1;
607 }
608 }
609
610 return 0;
611 }
612
613 #if 0
614 static void load_exploration_map (void)
615 {
616 FILE *fp = NULL;
617 char exploration_map_filename[256];
618
619 if(!minimap_texture)
620 return;
621
622 safe_strncpy(exploration_map_filename, map_file_name, sizeof(exploration_map_filename));
623 exploration_map_filename[strlen(exploration_map_filename)-4] = 0;
624 strcat (exploration_map_filename, ".xm");
625 safe_strncpy (current_exploration_map_filename, exploration_map_filename, sizeof (current_exploration_map_filename));
626 fp = open_file_config (exploration_map_filename, "rb");
627 if(fp)
628 {
629 if (fread(exploration_map, sizeof(GLubyte), 256 * 256, fp) != 256 * 256)
630 {
631 memset(exploration_map, 0, 256 * 256 * sizeof(GLubyte));
632 LOG_ERROR("%s() read failed for file [%s]\n", __FUNCTION__, exploration_map_filename);
633 }
634 fclose(fp);
635 }
636 else
637 {
638 memset(exploration_map, 0, 256 * 256 * sizeof(GLubyte));
639 }
640
641 if(poor_man)
642 {
643 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
644 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
645 }
646 else if(use_mipmaps)
647 {
648 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
649 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
650 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
651 }
652 else
653 {
654 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
655 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
656 }
657
658 if(have_extension(arb_texture_compression))
659 {
660 if(have_extension(ext_texture_compression_s3tc))
661 glTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGB_S3TC_DXT1_EXT, minimap_size, minimap_size,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,&exploration_map);
662 else
663 glTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_LUMINANCE, minimap_size, minimap_size,0,GL_ALPHA,GL_UNSIGNED_BYTE,&exploration_map);
664
665 }
666 else
667 glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE, minimap_size, minimap_size,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,&exploration_map);
668
669
670 CHECK_GL_ERRORS();
671 }
672
673 void save_exploration_map(void)
674 {
675 FILE *fp = NULL;
676
677 if(!minimap_texture)
678 return;
679
680 fp = open_file_config (current_exploration_map_filename, "wb");
681 if (fp)
682 {
683 fwrite(exploration_map, sizeof(GLubyte), 256 * 256, fp);
684 fclose(fp);
685 }
686 else
687 {
688 //log error and quit
689 }
690 }
691 #endif
692
change_minimap(void)693 void change_minimap(void)
694 {
695 char minimap_file_name[256];
696
697 if(get_id_MW(MW_MINIMAP) < 0)
698 return;
699 //save_exploration_map();
700
701 //unload all textures
702 if(exploration_texture)
703 glDeleteTextures(1,&exploration_texture);
704
705 //make filename
706 if (check_image_name(map_file_name, sizeof(minimap_file_name), minimap_file_name) == 1)
707 {
708 minimap_texture = load_texture_cached(minimap_file_name, tt_image);
709 }
710 else
711 {
712 minimap_texture = 0;
713 }
714
715 compass_tex = load_texture_cached("./textures/compass", tt_gui);
716
717 glGenTextures(1, &exploration_texture);
718 bind_texture_id(exploration_texture);
719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
721 //load_exploration_map();
722
723 #ifdef OPENGL_TRACE
724 CHECK_GL_ERRORS();
725 #endif //OPENGL_TRACE
726 }
727
mouseover_minimap_handler(window_info * win,int mx,int my,Uint32 flags)728 static int mouseover_minimap_handler(window_info * win, int mx, int my, Uint32 flags)
729 {
730 if(is_within_radius(mx,my-win->title_height,float_minimap_size/2,float_minimap_size/2,float_minimap_size/2) ||
731 ((mx > win->len_x/2-title_len) && (mx < win->len_x/2+title_len+win->title_height) && (my >= 0) && (my <= 2*win->title_height)))
732 {
733 elwin_mouse=CURSOR_ARROW;
734 enable_controls = 1;
735 return 1;
736 }
737 else
738 return 0;
739 }
740
cm_minimap_title_handler(window_info * win,int widget_id,int mx,int my,int option)741 static int cm_minimap_title_handler(window_info *win, int widget_id, int mx, int my, int option)
742 {
743 return cm_title_handler(win, widget_id, mx, my, option);
744 }
745
ui_scale_minimap_handler(window_info * win)746 static int ui_scale_minimap_handler(window_info *win)
747 {
748 title_len = (int)(0.5 + win->current_scale * 32);
749 if (title_len + win->title_height > win->len_x/2)
750 title_len = win->len_x/2 - win->title_height;
751 cm_remove_regions(win->cm_id);
752 cm_add_region(win->cm_id, win->window_id, win->len_x/2-title_len, 0, title_len*2, win->title_height );
753 resize_window(win->window_id, minimap_size, minimap_size + win->title_height);
754 return 1;
755 }
756
display_minimap(void)757 void display_minimap(void)
758 {
759 int minimap_win = get_id_MW(MW_MINIMAP);
760
761 minimap_size = 256 * minimap_size_coefficient;
762 float_minimap_size = 256.0 * minimap_size_coefficient;
763
764 if(minimap_tiles_distance < 48)
765 minimap_tiles_distance = 48;
766 if(minimap_tiles_distance > 144)
767 minimap_tiles_distance = 144;
768
769 if(minimap_win < 0)
770 {
771 //init minimap
772 window_info *win;
773 minimap_win = create_window(win_minimap, (not_on_top_now(MW_MANU) ?game_root_win : -1), 0, get_pos_x_MW(MW_MINIMAP), get_pos_y_MW(MW_MINIMAP),
774 minimap_size, minimap_size+ELW_TITLE_HEIGHT, ELW_USE_UISCALE|ELW_CLICK_TRANSPARENT|ELW_SHOW|ELW_TITLE_NAME|ELW_ALPHA_BORDER|ELW_SWITCHABLE_OPAQUE|ELW_DRAGGABLE);
775 set_id_MW(MW_MINIMAP, minimap_win);
776 set_window_handler(minimap_win, ELW_HANDLER_DISPLAY, &display_minimap_handler);
777 set_window_handler(minimap_win, ELW_HANDLER_CLICK, &click_minimap_handler);
778 set_window_handler(minimap_win, ELW_HANDLER_MOUSEOVER, &mouseover_minimap_handler);
779 set_window_handler(minimap_win, ELW_HANDLER_KEYPRESS, (int (*)())&keypress_minimap_handler );
780 set_window_handler(minimap_win, ELW_HANDLER_UI_SCALE, &ui_scale_minimap_handler);
781 win = &(windows_list.window[minimap_win]);
782 win->owner_drawn_title_bar = 1;
783 change_minimap();
784
785 if (!cm_valid(win->cm_id))
786 {
787 win->cm_id = cm_create(cm_title_menu_str, cm_minimap_title_handler);
788 cm_grey_line(win->cm_id, 1, 1);
789 cm_bool_line(win->cm_id, 2, &windows_on_top, "windows_on_top");
790 }
791
792 ui_scale_minimap_handler(win);
793 check_proportional_move(MW_MINIMAP);
794
795 cm_add(win->cm_id, cm_minimap_menu_str, NULL);
796 cm_add_region(win->cm_id, minimap_win, win->len_x/2-title_len, 0, title_len*2, win->title_height );
797 cm_bool_line(win->cm_id, ELW_CM_MENU_LEN+1, &rotate_minimap, "rotate_minimap");
798 cm_bool_line(win->cm_id, ELW_CM_MENU_LEN+2, &pin_minimap, "pin_minimap");
799 cm_bool_line(win->cm_id, ELW_CM_MENU_LEN+3, &open_minimap_on_start, NULL);
800 } else {
801 show_window(minimap_win);
802 select_window(minimap_win);
803 }
804 }
805
806
807
808 //EOF
809