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