1 #include <stdlib.h>
2 #include <string.h>
3 #include <math.h>
4 #include <SDL.h>
5 #include <errno.h>
6 #include "interface.h"
7 #include "asc.h"
8 #include "bbox_tree.h"
9 #include "chat.h"
10 #include "consolewin.h"
11 #include "cursors.h"
12 #include "elconfig.h"
13 #include "elwindows.h"
14 #include "elmemory.h"
15 #include "gamewin.h"
16 #include "gl_init.h"
17 #include "hud.h"
18 #include "langselwin.h"
19 #include "loginwin.h"
20 #include "map.h"
21 #include "mapwin.h"
22 #include "new_character.h"
23 #include "openingwin.h"
24 #include "pathfinder.h"
25 #include "rules.h"
26 #ifdef DEBUG_MAP_SOUND
27 #include "sound.h"
28 #endif // DEBUG_MAP_SOUND
29 #include "spells.h"
30 #include "textures.h"
31 #include "tiles.h"
32 #include "translate.h"
33 #include "update.h"
34 #include "weather.h"
35 #include "io/map_io.h"
36  #include "errors.h"
37  #include "io/elpathwrapper.h"
38  #include "io/elfilewrapper.h"
39 #include "3d_objects.h"
40 #include "image_loading.h"
41 #include "weather.h"
42 
43 #define DEFAULT_CONTMAPS_SIZE 20
44 
45 int mouse_x = 0;
46 int mouse_y = 0;
47 int right_click = 0;
48 int middle_click = 0;
49 int left_click = 0;
50 
51 dynamic_banner_colour_def dynamic_banner_colour =
52 {
53 	.yourself = 1,
54 	.other_players = 1,
55 	.creatures = 1
56 };
57 
58 int have_a_map=0;
59 int view_health_bar=1;
60 int view_ether_bar=0;
61 int view_names=1;
62 int view_hp=0;
63 int view_ether=0;
64 int view_chat_text_as_overtext=0;
65 int view_mode_instance=0;
66 float view_mode_instance_banner_height=5.0f;
67 float view_mode_instance_damage_height=5.0f;
68 
69 //instance mode banners config:
70 int im_creature_view_names = 1;
71 int im_creature_view_hp = 1;
72 int im_creature_view_hp_bar = 0;
73 int im_creature_banner_bg = 0;
74 int im_other_player_view_names = 1;
75 int im_other_player_view_hp = 1;
76 int im_other_player_view_hp_bar = 0;
77 int im_other_player_banner_bg = 0;
78 int im_other_player_show_banner_on_damage = 0;
79 
80 Uint32 click_time=0;
81 
82 int small_map_screen_x_left = 0;
83 int small_map_screen_x_right = 0;
84 int small_map_screen_y_top = 0;
85 int small_map_screen_y_bottom = 0;
86 int main_map_screen_x_left = 0;
87 int main_map_screen_x_right = 0;
88 int main_map_screen_y_top = 0;
89 int main_map_screen_y_bottom = 0;
90 
91 static float map_font_scale_fac = 1.0f;
92 
93 static GLdouble model_mat[16];
94 static GLdouble projection_mat[16];
95 static GLint viewport[4];
96 
97 // Grum: attempt to work around bug in Ati linux drivers.
98 int ati_click_workaround = 0;
99 
save_scene_matrix(void)100 void save_scene_matrix (void)
101 {
102 	glGetDoublev (GL_MODELVIEW_MATRIX, model_mat);
103 	glGetDoublev (GL_PROJECTION_MATRIX, projection_mat);
104 	glGetIntegerv (GL_VIEWPORT, viewport);
105 }
106 
get_world_x_y(short * scene_x,short * scene_y)107 void get_world_x_y (short *scene_x, short *scene_y)
108 {
109 	double sx, sy, sz;
110 	float mouse_z;
111 
112 	glReadPixels (mouse_x, window_height-mouse_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &mouse_z);
113 
114 	// XXX FIXME (Grum): hack to work around a bug in the Ati drivers or
115 	// a giant misconception on the part of all EL developers so far.
116 	if (ati_click_workaround && bpp == 32)
117 		mouse_z = ldexp (mouse_z, 8);
118 
119 	gluUnProject (mouse_x, window_height-hud_y-mouse_y, mouse_z, model_mat, projection_mat, viewport, &sx, &sy, &sz);
120 
121 	*scene_x = (sx / 0.5);
122 	*scene_y = (sy / 0.5);
123 }
124 
get_old_world_x_y(short * scene_x,short * scene_y)125 void get_old_world_x_y (short *scene_x, short *scene_y)
126 {
127 	AABBOX box;
128 	float t, x, y, z, t1, t2, tx, ty, dx, dy, h, len, h1, h2, h3, h4;
129 	int i, j, h_max, h_min, sx, sy, zx, zy, i_min, i_max, j_min, j_max;
130 
131 	x = click_line.center[X];
132 	y = click_line.center[Y];
133 	z = click_line.center[Z];
134 	dx = click_line.direction[X];
135 	dy = click_line.direction[Y];
136 	t = min2f(4.0f, max2f(-2.2f, z));
137 	if (t != z)
138 	{
139 		t = (t-z)/click_line.direction[Z];
140 		x += t*dx;
141 		y += t*dy;
142 	}
143 	t = 6.2f / click_line.direction[Z];
144 	len = min2f(max2f(t, -t), click_line.length);
145 
146 	len = click_line.length;
147 	if (max2f(dx, -dx) < 0.000001f)
148 	{
149 		zx = 1;
150 		sx = 0;
151 	}
152 	else
153 	{
154 		zx = 0;
155 		if (dx < 0.0f) sx = -1;
156 		else sx = 1;
157 	}
158 	if (max2f(dy, -dy) < 0.000001f)
159 	{
160 		zy = 1;
161 		sy = 0;
162 	}
163 	else
164 	{
165 		zy = 0;
166 		if (dy < 0.0f) sy = -1;
167 		else sy = 1;
168 	}
169 	i = x*2.0f;
170 	j = y*2.0f;
171 
172 	i_min = min2f(x, x+dx*len)*2.0f;
173 	i_max = max2f(x, x+dx*len)*2.0f;
174 	j_min = min2f(y, y+dy*len)*2.0f;
175 	j_max = max2f(y, y+dy*len)*2.0f;
176 
177 	i_min = max2i(min2i(i_min, tile_map_size_x*6), 0);
178 	i_max = max2i(min2i(i_max, tile_map_size_x*6-1), 0);
179 	j_min = max2i(min2i(j_min, tile_map_size_y*6), 0);
180 	j_max = max2i(min2i(j_max, tile_map_size_y*6-1), 0);
181 
182 	i = min2i(max2i(i, i_min), i_max-1);
183 	j = min2i(max2i(j, j_min), j_max-1);
184 
185 	h = 0.0f;
186 	while ((i >= i_min) && (j >= j_min) && (i < i_max) && (j < j_max))
187 	{
188 		h1 = get_tile_height(i, j);
189 		h2 = get_tile_height(i + 1, j);
190 		h3 = get_tile_height(i, j + 1);
191 		h4 = get_tile_height(i + 1, j + 1);
192 		h_max = max2f(max2f(h1, h2), max2f(h3, h4));
193 		h_min = min2f(min2f(h1, h2), min2f(h3, h4));
194 		tx = i*0.5f;
195 		ty = j*0.5f;
196 		box.bbmin[X] = tx;
197 		box.bbmin[Y] = ty;
198 		box.bbmin[Z] = h_min;
199 		box.bbmax[X] = tx+1.0f;
200 		box.bbmax[Y] = ty+1.0f;
201 		box.bbmax[Z] = h_max;
202 		if (click_line_bbox_intersection(box))
203 		{
204 			box.bbmin[X] = tx+0.0f;
205 			box.bbmin[Y] = ty+0.0f;
206 			box.bbmin[Z] = h1;
207 			box.bbmax[X] = tx+0.5f;
208 			box.bbmax[Y] = ty+0.5f;
209 			box.bbmax[Z] = h1;
210 			if (click_line_bbox_intersection(box))
211 			{
212 				h = h1;
213 				break;
214 			}
215 			box.bbmin[X] = tx+0.5f;
216 			box.bbmin[Y] = ty+0.0f;
217 			box.bbmin[Z] = h2;
218 			box.bbmax[X] = tx+1.0f;
219 			box.bbmax[Y] = ty+0.5f;
220 			box.bbmax[Z] = h2;
221 			if (click_line_bbox_intersection(box))
222 			{
223 				h = h2;
224 				break;
225 			}
226 			box.bbmin[X] = tx+0.0f;
227 			box.bbmin[Y] = ty+0.5f;
228 			box.bbmin[Z] = h3;
229 			box.bbmax[X] = tx+0.5f;
230 			box.bbmax[Y] = ty+1.0f;
231 			box.bbmax[Z] = h3;
232 			if (click_line_bbox_intersection(box))
233 			{
234 				h = h3;
235 				break;
236 			}
237 			box.bbmin[X] = tx+0.5f;
238 			box.bbmin[Y] = ty+0.5f;
239 			box.bbmin[Z] = h4;
240 			box.bbmax[X] = tx+1.0f;
241 			box.bbmax[Y] = ty+1.0f;
242 			box.bbmax[Z] = h4;
243 			if (click_line_bbox_intersection(box))
244 			{
245 				h = h4;
246 				break;
247 			}
248 		}
249 		if ((zx == 1) && (zy == 1)) break;
250 		if (zx == 0) t1 = (tx+sx-x)/dx;
251 		else t1 = 10e30;
252 		if (zx == 0) t2 = (ty+sy-y)/dy;
253 		else t2 = -10e30;
254 		if (t1 < t2) i += 2*sx;
255 		else j += 2*sy;
256 
257 		t = min2f(t1, t2);
258 		x += dx*t;
259 		y += dy*t;
260 	}
261 	t = (h-click_line.center[Z])/click_line.direction[Z];
262 	*scene_x = (click_line.center[X]+click_line.direction[X]*t) / 0.5;
263 	*scene_y = (click_line.center[Y]+click_line.direction[Y]*t) / 0.5;
264 }
265 
Enter2DModeExtended(int width,int height)266 void Enter2DModeExtended(int width, int height)
267 {
268 #ifdef OPENGL_TRACE
269 CHECK_GL_ERRORS();
270 #endif //OPENGL_TRACE
271 	if (use_fog) glDisable(GL_FOG);
272 	glPushAttrib(GL_LIGHTING_BIT|GL_DEPTH_BUFFER_BIT);
273 	glDisable(GL_LIGHTING);
274 	glDisable(GL_DEPTH_TEST);
275 
276 	glViewport(0, 0, width, height);
277 
278 #ifdef OPENGL_TRACE
279 	CHECK_GL_ERRORS();
280 #endif //OPENGL_TRACE
281 	glMatrixMode(GL_PROJECTION);
282 	glPushMatrix();
283 	glLoadIdentity();
284 	glOrtho(0.0, (GLdouble)width, (GLdouble)height, 0.0, -1.0, 1.0);
285 	glMatrixMode(GL_MODELVIEW);
286 	glPushMatrix();
287 	glLoadIdentity();
288 #ifdef OPENGL_TRACE
289 	CHECK_GL_ERRORS();
290 #endif //OPENGL_TRACE
291 }
292 
Enter2DMode(void)293 void Enter2DMode(void)
294 {
295 	Enter2DModeExtended(window_width, window_height);
296 }
297 
Leave2DMode(void)298 void Leave2DMode(void)
299 {
300 #ifdef OPENGL_TRACE
301 CHECK_GL_ERRORS();
302 #endif //OPENGL_TRACE
303 	glMatrixMode(GL_MODELVIEW);
304 	glPopMatrix();
305 	glMatrixMode(GL_PROJECTION);
306 	glPopMatrix();
307 	glMatrixMode(GL_MODELVIEW);
308 	glPopAttrib();
309 	glViewport(0, hud_y, window_width-hud_x, window_height-hud_y);
310 	if (use_fog) glEnable(GL_FOG);
311 	else glDisable(GL_FOG);
312 	//glViewport(0, 0, window_width-hud_x, window_height-hud_y);	// Reset The Current Viewport
313 #ifdef OPENGL_TRACE
314 CHECK_GL_ERRORS();
315 #endif //OPENGL_TRACE
316 }
317 
318 /* The video modes start with index 1. So field 0 stands for video mode 1 */
319 video_mode_t video_modes[] = {
320 	{ 640,  480, 16, NULL}, /*  1 */
321 	{ 640,  480, 32, NULL}, /*  2 */
322 	{ 800,  600, 16, NULL}, /*  3 */
323 	{ 800,  600, 32, NULL}, /*  4 */
324 	{1024,  768, 16, NULL}, /*  5 */
325 	{1024,  768, 32, NULL}, /*  6 */
326 	{1152,  864, 16, NULL}, /*  7 */
327 	{1152,  864, 32, NULL}, /*  8 */
328 	{1280, 1024, 16, NULL}, /*  9 */
329 	{1280, 1024, 32, NULL}, /* 10 */
330 	{1600, 1200, 16, NULL}, /* 11 */
331 	{1600, 1200, 32, NULL}, /* 12 */
332 	{1280,  800, 16, NULL}, /* 13 */
333 	{1280,  800, 32, NULL}, /* 14 */
334 	{1440,  900, 16, NULL}, /* 15 */
335 	{1440,  900, 32, NULL}, /* 16 */
336 	{1680, 1050, 16, NULL}, /* 17 */
337 	{1680, 1050, 32, NULL}, /* 18 */
338 	{1400, 1050, 16, NULL}, /* 19 */
339 	{1400, 1050, 32, NULL}, /* 20 */
340 	{ 800,  480, 16, NULL}, /* 21 */
341 	{ 800,  480, 32, NULL}, /* 22 */
342 	{1920, 1200, 16, NULL}, /* 23 */
343 	{1920, 1200, 32, NULL}, /* 24 */
344 	{1024,  600, 16, NULL}, /* 25 */
345 	{1024,  600, 32, NULL}, /* 26 */
346 	{1920, 1080, 16, NULL}, /* 27 */
347 	{1920, 1080, 32, NULL}, /* 28 */
348 	{1366, 768, 16, NULL}, /* 29 */
349 	{1366, 768, 32, NULL}, /* 30 */
350 	{2560, 1440, 16, NULL}, /* 31 */
351 	{2560, 1440, 32, NULL}, /* 32 */
352 	{3840, 2160, 16, NULL}, /* 33 */
353 	{3840, 2160, 32, NULL}, /* 34 */
354 };
355 const int video_modes_count = sizeof(video_modes)/sizeof(*video_modes);
356 
draw_console_pic(int which_texture)357 void draw_console_pic(int which_texture)
358 {
359 	bind_texture(which_texture);
360 
361 	glColor3f(1.0f,1.0f,1.0f);
362 	glBegin(GL_QUADS);
363 	//draw the texture
364 
365 	glTexCoord2f(0.0f, 0.0f);
366 	glVertex3i(0,0,0);
367 
368 	glTexCoord2f(0.0f, 1.0f);
369 	glVertex3i(0,window_height,0);
370 
371 	glTexCoord2f(1.0f, 1.0f);
372 	glVertex3i(window_width,window_height,0);
373 
374 	glTexCoord2f(1.0f, 0.0f);
375 	glVertex3i(window_width,0,0);
376 
377 	glEnd();
378 #ifdef OPENGL_TRACE
379 CHECK_GL_ERRORS();
380 #endif //OPENGL_TRACE
381 }
382 
draw_2d_thing(float u_start,float v_start,float u_end,float v_end,int x_start,int y_start,int x_end,int y_end)383 void draw_2d_thing(float u_start,float v_start,float u_end,float v_end,int x_start,
384 				   int y_start,int x_end,int y_end)
385 {
386 	glTexCoord2f(u_start,v_end);
387 	glVertex3i(x_start,y_end,0);
388 
389 	glTexCoord2f(u_start,v_start);
390 	glVertex3i(x_start,y_start,0);
391 
392 	glTexCoord2f(u_end,v_start);
393 	glVertex3i(x_end,y_start,0);
394 
395 	glTexCoord2f(u_end,v_end);
396 	glVertex3i(x_end,y_end,0);
397 }
398 
draw_2d_thing_r(float u_start,float v_start,float u_end,float v_end,int x_start,int y_start,int x_end,int y_end)399 void draw_2d_thing_r(float u_start,float v_start,float u_end,float v_end,int x_start,
400 				   int y_start,int x_end,int y_end)
401 {
402 	glTexCoord2f(u_start,v_start);
403 	glVertex3i(x_start,y_end,0);
404 
405 	glTexCoord2f(u_end,v_start);
406 	glVertex3i(x_start,y_start,0);
407 
408 	glTexCoord2f(u_end,v_end);
409 	glVertex3i(x_end,y_start,0);
410 
411 	glTexCoord2f(u_start,v_end);
412 	glVertex3i(x_end,y_end,0);
413 }
414 
415 GLuint map_text;
416 static int cont_text = -1; // index in texture cache for continent map
417 
418 GLuint inspect_map_text = 0;
419 int show_continent_map_boundaries = 1;
420 GLuint legend_text=0;
421 int cur_map;  //Is there a better way to do this?
422 
423 #ifdef DEBUG_MAP_SOUND
424 int cur_tab_map = -1;
425 #endif // DEBUG_MAP_SOUND
426 
427 typedef struct
428 {
429 	char* name;
430 	char* file_name;
431 } cont_overview_maps_t;
432 static cont_overview_maps_t * cont_overview_maps = NULL;
433 static int nr_continents = 0;
434 struct draw_map *continent_maps = NULL;
435 
436 /*	Free allocated memory during exit
437 */
cleanup_mapinfo(void)438 void cleanup_mapinfo(void)
439 {
440 	size_t i;
441 
442 	LOG_INFO("cont_overview_maps[]");
443 	for (i = 0; i < nr_continents; i++)
444 	{
445 		free(cont_overview_maps[i].name);
446 		free(cont_overview_maps[i].file_name);
447 	}
448 	LOG_INFO("cont_overview_maps");
449 	free(cont_overview_maps);
450 	cont_overview_maps = NULL;
451 	nr_continents = 0;
452 
453 	LOG_INFO("continent_maps[]");
454 	for (i = 0; continent_maps[i].name; i++)
455 		free(continent_maps[i].name);
456 	LOG_INFO("continent_maps");
457 	free (continent_maps);
458 	continent_maps = NULL;
459 }
460 
461 //	Read the list of continent maps from file or fallback to original hardwired list.
462 //
read_cont_info(void)463 static void read_cont_info(void)
464 {
465 	FILE *fin;
466 	char line[256];
467 
468 	fin = open_file_data ("continfo.lst", "r");
469 
470 	// if the file does not exist, fall back to hardwired continents
471 	if (fin == NULL)
472 	{
473 		size_t i;
474 		cont_overview_maps_t tmp_cont_maps[] = { { "Seridia", "./maps/seridia" }, { "Irilion", "./maps/irilion" } };
475 		nr_continents = sizeof(tmp_cont_maps) / sizeof(cont_overview_maps_t);
476 		cont_overview_maps = malloc(nr_continents * sizeof(cont_overview_maps_t));
477 		for (i = 0; i < nr_continents; i++)
478 		{
479 			cont_overview_maps[i].name = malloc(strlen(tmp_cont_maps[i].name) + 1);
480 			strcpy(cont_overview_maps[i].name, tmp_cont_maps[i].name);
481 			cont_overview_maps[i].file_name = malloc(strlen(tmp_cont_maps[i].file_name) + 1);
482 			strcpy(cont_overview_maps[i].file_name, tmp_cont_maps[i].file_name);
483 		}
484 		LOG_INFO("Using hardwired continent overview maps: %d", nr_continents);
485 	}
486 
487 	// else, if the file exists read one contenent definition per line, "<continent name> <map image file name>"
488 	else
489 	{
490 		char name[256], file_name[256], tmp[1];
491 		nr_continents = 0;
492 		while (fgets (line, sizeof (line), fin) != NULL)
493 		{
494 			// strip comments, the # and anything after is ignored
495 			char *cmt_pos = strchr(line, '#');
496 			if (cmt_pos != NULL)
497 				*cmt_pos = '\0';
498 			// only use lines with exactly 2 strings, both stripped of leading and trailing space
499 			if (sscanf (line, "%s %s %s", name, file_name, tmp) != 2)
500 				continue;
501 			cont_overview_maps = realloc(cont_overview_maps, (nr_continents + 1) * sizeof(cont_overview_maps_t));
502 			cont_overview_maps[nr_continents].name = malloc(strlen(name) + 1);
503 			strcpy(cont_overview_maps[nr_continents].name, name);
504 			cont_overview_maps[nr_continents].file_name = malloc(strlen(file_name) + 1);
505 			strcpy(cont_overview_maps[nr_continents].file_name, file_name);
506 			//printf("%d: name=[%s] file_name=[%s]\n", nr_continents, cont_overview_maps[nr_continents].name, cont_overview_maps[nr_continents].file_name);
507 			nr_continents++;
508 		}
509 		fclose (fin);
510 		LOG_INFO("Using file defined continent overview maps: count %d", nr_continents);
511 	}
512 }
513 
read_mapinfo(void)514 void read_mapinfo (void)
515 {
516 	FILE *fin;
517 	char line[256];
518 	int maps_size, imap;
519 	char *cmt_pos;
520 	char cont_name[64];
521 	unsigned short continent, x_start, y_start, x_end, y_end;
522 	char map_name[128];
523 
524 	maps_size = DEFAULT_CONTMAPS_SIZE;
525 	continent_maps = calloc (maps_size, sizeof (struct draw_map));
526 	imap = 0;
527 
528 	read_cont_info();
529 	fin = open_file_data ("mapinfo.lst", "r");
530 	if (fin == NULL){
531 		LOG_ERROR("%s: %s \"mapinfo.lst\": %s\n", reg_error_str, cant_open_file, strerror(errno));
532 	} else {
533 		while (fgets (line, sizeof (line), fin) != NULL)
534 		{
535 			size_t i;
536 			int cont_found = 0;
537 			char weather_name[11] = "";
538 
539 			// strip comments
540 			cmt_pos = strchr (line, '#');
541 			if (cmt_pos != NULL)
542 				*cmt_pos = '\0';
543 
544 			// weather_name is optional so a valid line is 6 or more parameters read
545 			if (sscanf (line, "%63s %hu %hu %hu %hu %127s %10s", cont_name, &x_start, &y_start, &x_end, &y_end, map_name, weather_name) < 6)
546 				// not a valid line
547 				continue;
548 
549 			cont_found = 0;
550 			for (i = 0; i < nr_continents; ++i)
551 			{
552 				if (strcasecmp(cont_name, cont_overview_maps[i].name) == 0)
553 				{
554 					continent = i;
555 					cont_found = 1;
556 					break;
557 				}
558 			}
559 			if (!cont_found)
560 				// not a valid continent
561 				continue;
562 
563 			if (imap >= maps_size - 1)
564 			{
565 				// Uh oh, we didn't allocate enough space
566 				maps_size += DEFAULT_CONTMAPS_SIZE;
567 				continent_maps = realloc (continent_maps, maps_size * sizeof (struct draw_map));
568 			}
569 
570 			continent_maps[imap].cont = continent;
571 			continent_maps[imap].x_start = x_start;
572 			continent_maps[imap].y_start = y_start;
573 			continent_maps[imap].x_end = x_end;
574 			continent_maps[imap].y_end = y_end;
575 			continent_maps[imap].name = malloc ((strlen (map_name) + 1) * sizeof (char));
576 			continent_maps[imap].weather = get_weather_type_from_string(weather_name);
577 			strcpy(continent_maps[imap].name, map_name);
578 			imap++;
579 		}
580 
581 		fclose (fin);
582 	}
583 
584 	continent_maps[imap].cont = 0;
585 	continent_maps[imap].x_start = 0;
586 	continent_maps[imap].y_start = 0;
587 	continent_maps[imap].x_end = 0;
588 	continent_maps[imap].y_end = 0;
589 	continent_maps[imap].name = NULL;
590 	continent_maps[imap].weather = 0;
591 }
592 
switch_to_game_map(void)593 int switch_to_game_map(void)
594 {
595 	char buffer[1024];
596 	short int cur_cont;
597 	static short int old_cont = -1;
598 	int size;
599 
600 	/* check we loaded the mapinfo data */
601 	if (continent_maps == NULL || continent_maps[0].name == NULL)
602 	{
603 		LOG_TO_CONSOLE(c_yellow2,err_nomap_str);
604 		return 0;
605 	}
606 
607 	if (check_image_name(map_file_name, sizeof(buffer), buffer) == 1)
608 	{
609 		map_text = load_texture_cached(buffer, tt_image);
610 	}
611 	else
612 	{
613 		map_text = 0;
614 	}
615 	if(!map_text)
616 	{
617 		LOG_TO_CONSOLE(c_yellow2,err_nomap_str);
618 		return 0;
619 	}
620 
621 	if (cur_map < 0)
622 	{
623 		cur_cont = -1;
624 	}
625 	else
626 	{
627 		cur_cont = continent_maps[cur_map].cont;
628 	}
629 	if (cur_cont != old_cont && cur_cont >= 0 && cur_cont < nr_continents)
630 	{
631 		cont_text = load_texture_cached (cont_overview_maps[cur_cont].file_name, tt_image);
632 		old_cont = cur_cont;
633 	}
634 #ifdef DEBUG_MAP_SOUND
635 	cur_tab_map = cur_map;
636 #endif // DEBUG_MAP_SOUND
637 
638 	if(current_cursor != CURSOR_ARROW)
639 	{
640 		change_cursor(CURSOR_ARROW);
641 	}
642 
643 	map_font_scale_fac = get_global_scale();
644 	// Set screen coordinates of the edges of the map
645 	size = min2i(4*(window_width-hud_x)/5, window_height-hud_y);
646 	small_map_screen_x_left = (window_width - hud_x - 5*size/4) / 2;
647 	small_map_screen_x_right = small_map_screen_x_left + size/4;
648 	small_map_screen_y_top = (window_height - hud_y - size) / 2;
649 	small_map_screen_y_bottom = small_map_screen_y_top + size/4;
650 	main_map_screen_x_left = small_map_screen_x_right;
651 	main_map_screen_x_right = main_map_screen_x_left + size;
652 	main_map_screen_y_top = small_map_screen_y_top;
653 	main_map_screen_y_bottom = main_map_screen_y_top + size;
654 
655 	return 1;
656 }
657 
draw_mark_filter(void)658 static void draw_mark_filter(void)
659 {
660 	int x = small_map_screen_x_left + (small_map_screen_x_right - small_map_screen_x_left) / 2;
661 	int h = small_map_screen_y_bottom - small_map_screen_y_top, y = main_map_screen_y_bottom - h;
662 	int text_height = get_line_height(MAPMARK_FONT, map_font_scale_fac);
663 
664 	// display the Mark filter title
665 	glColor3f(1.0f,1.0f,0.0f);
666 	draw_text(x, (int)(y + (h - text_height) / 2), (const unsigned char*)label_mark_filter, strlen(label_mark_filter),
667 		MAPMARK_FONT, TDO_ALIGNMENT, CENTER, TDO_ZOOM, map_font_scale_fac, TDO_END);
668 
669 	// if filtering marks, display the label and the current filter text
670 	if (mark_filter_active) {
671 		char * show_mark_filter_text;
672 		int max_show_len = 15;
673 		if (strlen(mark_filter_text) > max_show_len)
674 		  show_mark_filter_text = &mark_filter_text[strlen(mark_filter_text)-max_show_len];
675 		else if (strlen(mark_filter_text) == 0)
676 			show_mark_filter_text = "_";
677 		else
678 		  show_mark_filter_text = mark_filter_text;
679 		draw_text(x, (int)(y + (h + text_height) / 2), (const unsigned char*)show_mark_filter_text,
680 			strlen(show_mark_filter_text), MAPMARK_FONT, TDO_ALIGNMENT, CENTER,
681 			TDO_ZOOM, map_font_scale_fac, TDO_END);
682 	}
683 	// display which key to activate the filter
684 	else
685 	{
686 		char buf[20];
687 		get_key_string(K_MARKFILTER, buf, sizeof(buf));
688 		draw_text(x, (int)(y + (h + text_height) / 2), (const unsigned char *)buf, strlen(buf), MAPMARK_FONT,
689 			TDO_ALIGNMENT, CENTER, TDO_ZOOM, map_font_scale_fac, TDO_END);
690 	}
691 }
692 
draw_marks(marking * the_marks,int the_max_mark,int the_tile_map_size_x,int the_tile_map_size_y)693 static void draw_marks(marking *the_marks, int the_max_mark, int the_tile_map_size_x, int the_tile_map_size_y)
694 {
695 	size_t i;
696 	int screen_x=0;
697 	int screen_y=0;
698 	float mapmark_zoom = map_font_scale_fac * font_scales[MAPMARK_FONT];
699 	int left = main_map_screen_x_left, width = main_map_screen_x_right - main_map_screen_x_left,
700 		bottom = main_map_screen_y_bottom, height = main_map_screen_y_bottom - main_map_screen_y_top;
701 
702 	// crave the markings
703 	for(i=0;i<the_max_mark;i++)
704 	 {
705 		int x = the_marks[i].x;
706 		int y = the_marks[i].y;
707 		if ( x > 0 ) {
708 
709 			// if filtering marks, don't display if it doesn't match the current filter
710 			if (mark_filter_active
711 				  && (get_string_occurance(mark_filter_text, the_marks[i].text, strlen(the_marks[i].text), 1) == -1))
712 				continue;
713 
714 			screen_x = left + width*x/(the_tile_map_size_x*6);
715 			screen_y = bottom - height*y/(the_tile_map_size_y*6);
716 
717 			if(!the_marks[i].server_side) glColor3f((float)the_marks[i].r/255,(float)the_marks[i].g/255,(float)the_marks[i].b/255);//glColor3f(0.4f,1.0f,0.0f);
718 			else glColor3f(0.33f,0.6f,1.0f);
719 			glDisable(GL_TEXTURE_2D);
720 			glBegin(GL_LINES);
721 				glVertex2i(screen_x-9*mapmark_zoom,screen_y-9*mapmark_zoom);
722 				glVertex2i(screen_x+6*mapmark_zoom,screen_y+6*mapmark_zoom);
723 
724 				glVertex2i(screen_x+6*mapmark_zoom,screen_y-9*mapmark_zoom);
725 				glVertex2i(screen_x-9*mapmark_zoom,screen_y+6*mapmark_zoom);
726 			glEnd();
727 				glEnable(GL_TEXTURE_2D);
728 				if(!the_marks[i].server_side) glColor3f((float)the_marks[i].r/255,(float)the_marks[i].g/255,(float)the_marks[i].b/255);//glColor3f(0.2f,1.0f,0.0f);
729 				else glColor3f(0.33f,0.6f,1.0f);
730 			draw_text(screen_x, screen_y, (const unsigned char*)the_marks[i].text, strlen(the_marks[i].text),
731 				MAPMARK_FONT, TDO_ZOOM, map_font_scale_fac, TDO_END);
732 		}
733 	}
734 }
735 
draw_coordinates(int the_tile_map_size_x,int the_tile_map_size_y)736 void draw_coordinates(int the_tile_map_size_x, int the_tile_map_size_y)
737 {
738 	int x = small_map_screen_x_left + (small_map_screen_x_right - small_map_screen_x_left) / 2;
739 	int h = small_map_screen_y_bottom - small_map_screen_y_top, y = main_map_screen_y_bottom - h;
740 	int text_height = get_line_height(MAPMARK_FONT, map_font_scale_fac);
741 	int map_x, map_y;
742 
743 	// draw coordinates
744 	if (pf_get_mouse_position_extended(mouse_x, mouse_y, &map_x, &map_y, the_tile_map_size_x, the_tile_map_size_y)) {
745 		// we're pointing on the map, display position
746 		char buf[10];
747 		safe_snprintf(buf, sizeof(buf), "%d,%d", map_x, map_y);
748 		glColor3f(1.0f,1.0f,0.0f);
749 		draw_text(x, y + 1.1 * text_height, (const unsigned char*)buf, strlen(buf), MAPMARK_FONT,
750 			TDO_ALIGNMENT, CENTER, TDO_ZOOM, map_font_scale_fac, TDO_END);
751 		draw_text(x, y + 0.1 * text_height, (const unsigned char*)label_cursor_coords, strlen(label_cursor_coords),
752 			MAPMARK_FONT, TDO_ALIGNMENT, CENTER, TDO_ZOOM, map_font_scale_fac, TDO_END);
753 	}
754 }
755 
draw_game_map(int map,int mouse_mini)756 void draw_game_map (int map, int mouse_mini)
757 {
758 	float mapmark_zoom = map_font_scale_fac * font_scales[MAPMARK_FONT];
759 	int screen_x=0;
760 	int screen_y=0;
761 	int x=-1,y=-1;
762 	float x_size=0,y_size=0;
763 	GLuint map_small, map_large;
764 	actor *me;
765 	static int fallback_text = -1;
766 	int win_width, win_height;
767 	int main_l = main_map_screen_x_left, main_r = main_map_screen_x_right,
768 		main_w = main_r - main_l;
769 	int main_t = main_map_screen_y_top, main_b = main_map_screen_y_bottom,
770 		main_h = main_b - main_t;
771 	int small_l = small_map_screen_x_left, small_r = small_map_screen_x_right,
772 		small_w = small_r - small_l;
773 	int small_t = small_map_screen_y_top, small_b = small_map_screen_y_bottom,
774 		small_h = small_b - small_t;
775 
776 	// if we don't have a continent texture (instance may be), fallback to blank paper
777 	if (cont_text < 0)
778 	{
779 		if (fallback_text < 0)
780 		{
781 			fallback_text = load_texture_cached("./textures/paper1", tt_gui);
782 		}
783 		cont_text = fallback_text;
784 	}
785 
786 	if(map){
787 		map_small = cont_text;
788 		if(inspect_map_text == 0) {
789 			map_large=map_text;
790 		} else {
791 			map_large = inspect_map_text;
792 		}
793 	} else {
794 		map_small=map_text;
795 		map_large = cont_text;
796 		if(cur_map!=-1){
797 			x_size = ((float)(continent_maps[cur_map].x_end - continent_maps[cur_map].x_start)) / tile_map_size_x;
798 			y_size = ((float)(continent_maps[cur_map].y_end - continent_maps[cur_map].y_start)) / tile_map_size_y;
799 		} else {
800 			x_size=y_size=0;
801 		}
802 	}
803 
804 	win_width = window_width - hud_x;
805 	win_height = window_height - hud_y;
806 
807 	glDisable(GL_DEPTH_TEST);
808 	glDisable(GL_LIGHTING);
809 
810 	glViewport(0, hud_y, win_width, win_height);
811 	glMatrixMode(GL_PROJECTION);
812 	glPushMatrix();
813 	glLoadIdentity();
814 
815 	glOrtho(0.0, (GLdouble)win_width, (GLdouble)win_height, 0.0, -250.0, 250.0);
816 	glMatrixMode(GL_MODELVIEW);
817 	glPushMatrix();
818 	glLoadIdentity();
819 
820 	glLineWidth(get_global_scale());
821 
822 	// Draw a black background
823 	glDisable(GL_TEXTURE_2D);
824 	glColor3f(0.0f, 0.0f, 0.0f);
825 	glBegin(GL_QUADS);
826 		glVertex2i(0,         0);
827 		glVertex2i(0,         win_height);
828 		glVertex2i(win_width, win_height);
829 		glVertex2i(win_width, 0);
830 	glEnd();
831 	glEnable(GL_TEXTURE_2D);
832 
833 	glColor3f(1.0, 1.0, 1.0);
834 
835 	bind_texture(map_large);
836 	glBegin(GL_QUADS);
837 		glTexCoord2f(0.0f, 1.0f); glVertex3i(main_l, main_b, 0);
838 		glTexCoord2f(0.0f, 0.0f); glVertex3i(main_l, main_t, 0);
839 		glTexCoord2f(1.0f, 0.0f); glVertex3i(main_r, main_t, 0);
840 		glTexCoord2f(1.0f, 1.0f); glVertex3i(main_r, main_b, 0);
841 	glEnd();
842 
843 	if (mouse_mini)
844 		glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
845 	else
846 		glColor4f (0.7f, 0.7f, 0.7f, 0.7f);
847 
848 	glEnable(GL_ALPHA_TEST);
849 
850 	bind_texture(map_small);
851 	glBegin(GL_QUADS);
852 		glTexCoord2f(0.0f, 1.0f); glVertex3i(small_l, small_b, 0);
853 		glTexCoord2f(0.0f, 0.0f); glVertex3i(small_l, small_t, 0);
854 		glTexCoord2f(1.0f, 0.0f); glVertex3i(small_r, small_t, 0);
855 		glTexCoord2f(1.0f, 1.0f); glVertex3i(small_r, small_b, 0);
856 	glEnd();
857 
858 	glDisable(GL_ALPHA_TEST);
859 
860 	glColor3f(1.0f,1.0f,1.0f);
861 
862 	bind_texture(legend_text);
863 	glBegin(GL_QUADS);
864 		glTexCoord2f(0.0f, 1.0f); glVertex3i(small_l, small_b + 2*small_h, 0);
865 		glTexCoord2f(0.0f, 0.0f); glVertex3i(small_l, small_b,             0);
866 		glTexCoord2f(1.0f, 0.0f); glVertex3i(small_r, small_b,             0);
867 		glTexCoord2f(1.0f, 1.0f); glVertex3i(small_r, small_b + 2*small_h, 0);
868 	glEnd();
869 
870 // this is necessary for the text over map
871 // need to execute this for any map now
872 // because of the coordinate display - Lachesis
873 	if(map/*&&(adding_mark||max_mark>0)*/)
874 	{
875 		// Draw help for toggling the mini-map
876 		{
877 			char buf[80];
878 			char keybuf[20];
879 			glEnable(GL_TEXTURE_2D);
880 			safe_snprintf(buf, sizeof(buf), "%s %s", win_minimap, get_key_string(K_MINIMAP, keybuf, sizeof(keybuf)));
881 			glColor3f (1.0f, 1.0f, 0.0f);
882 			draw_text(small_l+small_w/2, (int)(main_t + main_h - 1.1 * get_line_height(MAPMARK_FONT, map_font_scale_fac)), (const unsigned char *)buf,
883 				strlen(buf), MAPMARK_FONT, TDO_ALIGNMENT, CENTER, TDO_ZOOM, map_font_scale_fac, TDO_END);
884 		}
885 
886 		// draw a temporary mark until the text is entered
887 		if (adding_mark)
888 		{
889 			int x = mark_x;
890 			int y = mark_y;
891 
892 			screen_x = main_l + main_w*x/(tile_map_size_x*6);
893 			screen_y = main_b - main_h*y/(tile_map_size_y*6);
894 
895 			glColor3f(1.0f,1.0f,0.0f);
896 			glDisable(GL_TEXTURE_2D);
897 			glBegin(GL_LINES);
898 				glVertex2i(screen_x-9*mapmark_zoom,screen_y-9*mapmark_zoom);
899 				glVertex2i(screen_x+6*mapmark_zoom,screen_y+6*mapmark_zoom);
900 
901 				glVertex2i(screen_x+6*mapmark_zoom,screen_y-9*mapmark_zoom);
902 				glVertex2i(screen_x-9*mapmark_zoom,screen_y+6*mapmark_zoom);
903 			glEnd();
904 		        glEnable(GL_TEXTURE_2D);
905 		        glColor3f(1.0f,1.0f,0.0f);
906 			draw_text(screen_x, screen_y, (const unsigned char*)input_text_line.data,
907 				strlen(input_text_line.data), MAPMARK_FONT, TDO_ZOOM, map_font_scale_fac, TDO_END);
908 		}
909 
910 		draw_mark_filter();
911 		if(inspect_map_text == 0) {
912 			draw_marks(marks, max_mark, tile_map_size_x, tile_map_size_y);
913 			draw_coordinates(tile_map_size_x, tile_map_size_y);
914 		}
915 		else {
916 			draw_marks(temp_marks, max_temp_mark, temp_tile_map_size_x, temp_tile_map_size_y);
917 			draw_coordinates(temp_tile_map_size_x, temp_tile_map_size_y);
918 		}
919 	}
920 
921 	//if we're following a path, draw the destination on the map
922 	if (pf_follow_path && inspect_map_text == 0)
923 	{
924 		int px = pf_dst_tile->x;
925 		int py = pf_dst_tile->y;
926 
927 		if (!map)
928 		{
929 			if (cur_map!=-1)
930 			{
931 				screen_x = main_l + main_w * ( (px * x_size / 6) + continent_maps[cur_map].x_start) / 512;
932 				screen_y = main_b - main_h * ( (py * y_size / 6) + continent_maps[cur_map].y_start) / 512;
933 			}
934 			else
935 			{
936 				screen_x = screen_y = 0;
937 			}
938 		}
939 		else
940 		{
941 			screen_x = main_l + main_w*px/(tile_map_size_x*6);
942 			screen_y = main_b - main_h*py/(tile_map_size_y*6);
943 		}
944 
945 		glColor3f(1.0f,0.0f,0.0f);
946 
947 		glDisable(GL_TEXTURE_2D);
948 		glBegin(GL_LINES);
949 
950 		glVertex2i(screen_x-9*mapmark_zoom,screen_y-9*mapmark_zoom);
951 		glVertex2i(screen_x+6*mapmark_zoom,screen_y+6*mapmark_zoom);
952 
953 		glVertex2i(screen_x+6*mapmark_zoom,screen_y-9*mapmark_zoom);
954 		glVertex2i(screen_x-9*mapmark_zoom,screen_y+6*mapmark_zoom);
955 
956 		glEnd();
957 	}
958 
959 	//ok, now let's draw our position...
960 	if ( (me = get_our_actor ()) != NULL && inspect_map_text == 0)
961 	{
962 		x = me->x_tile_pos;
963 		y = me->y_tile_pos;
964 	}
965 	else
966 	{
967 		//We don't exist (usually happens when teleporting)
968 		x = -1;
969 		y = -1;
970 	}
971 
972 	if (!map)
973 	{
974 		if (cur_map != -1)
975 		{
976 			screen_x = main_l + main_w * ( (x * x_size / 6) + continent_maps[cur_map].x_start) / 512;
977 			screen_y = main_b - main_h * ( (y * y_size / 6) + continent_maps[cur_map].y_start) / 512;
978 		}
979 		else
980 		{
981 			screen_x = screen_y = 0;
982 		}
983 	}
984 	else
985 	{
986 		screen_x = main_l + main_w*x/(tile_map_size_x*6);
987 		screen_y = main_b - main_h*y/(tile_map_size_y*6);
988 	}
989 
990 	if ( (map || !dungeon) && x != -1 )
991 	{
992 		glColor3f (0.0f, 0.0f, 1.0f);
993 		glDisable (GL_TEXTURE_2D);
994 		glPushAttrib(GL_LINE_BIT);
995 		glLineWidth(2.0);
996 		glEnable(GL_LINE_SMOOTH);
997 		glBegin (GL_LINES);
998 
999 		glVertex2i(screen_x-9*mapmark_zoom,screen_y-9*mapmark_zoom);
1000 		glVertex2i(screen_x+6*mapmark_zoom,screen_y+6*mapmark_zoom);
1001 
1002 		glVertex2i(screen_x+6*mapmark_zoom,screen_y-9*mapmark_zoom);
1003 		glVertex2i(screen_x-9*mapmark_zoom,screen_y+6*mapmark_zoom);
1004 
1005 		glEnd();
1006 		glPopAttrib();
1007 	}
1008 
1009 	if(!map && show_continent_map_boundaries && cont_text!=fallback_text) {
1010 		int i;
1011 		/* Convert mouse coordinates to map coordinates (stolen from pf_get_mouse_position()) */
1012 		int screen_map_width = main_map_screen_x_right - main_map_screen_x_left;
1013 		int screen_map_height = main_map_screen_y_bottom - main_map_screen_y_top;
1014 		int m_px = ((mouse_x-main_map_screen_x_left) * 512) / screen_map_width;
1015 		int m_py = 512 - ((mouse_y-main_map_screen_y_top) * 512) / screen_map_height;
1016 		int mouse_over = -1;
1017 
1018 		glColor3f (0.267f, 0.267f, 0.267f);
1019 		glDisable (GL_TEXTURE_2D);
1020 		glBegin(GL_LINES);
1021 		/* Draw borders for the maps except the one with the mouse over it */
1022 		glColor3f (0.267f, 0.267f, 0.267f);
1023 		for(i = 0; continent_maps[i].name != NULL; i++) {
1024 			if(continent_maps[i].cont == continent_maps[cur_map].cont) {
1025 				if(!mouse_mini && mouse_over == -1
1026 				&& m_px > continent_maps[i].x_start && m_px < continent_maps[i].x_end
1027 				&& m_py > continent_maps[i].y_start && m_py < continent_maps[i].y_end)
1028 				{
1029 					/* Mouse over this map */
1030 					mouse_over = i;
1031 				} else {
1032 					int x_start = main_l + main_w*continent_maps[i].x_start/512;
1033 					int x_end = main_l + main_w*continent_maps[i].x_end/512;
1034 					int y_start = main_b - main_h*continent_maps[i].y_start / 512;
1035 					int y_end = main_b - main_h*continent_maps[i].y_end / 512;
1036 
1037 					glVertex2i(x_start, y_start);
1038 					glVertex2i(x_start, y_end);
1039 
1040 					glVertex2i(x_start, y_end);
1041 					glVertex2i(x_end, y_end);
1042 
1043 					glVertex2i(x_end, y_end);
1044 					glVertex2i(x_end, y_start);
1045 
1046 					glVertex2i(x_end, y_start);
1047 					glVertex2i(x_start, y_start);
1048 				}
1049 			}
1050 		}
1051 		/* Draw border for the map with the mouse over it */
1052 		if(mouse_over >= 0) {
1053 			float flash_effect_colour = 0.90f - sin((float)SDL_GetTicks()/100.0f) / 10.0f;
1054 			int x_start = main_l + main_w*continent_maps[mouse_over].x_start/512;
1055 			int x_end = main_l + main_w*continent_maps[mouse_over].x_end/512;
1056 			int y_start = main_b - main_h*continent_maps[mouse_over].y_start / 512;
1057 			int y_end = main_b - main_h*continent_maps[mouse_over].y_end / 512;
1058 
1059 			glColor3f(flash_effect_colour, flash_effect_colour, flash_effect_colour);
1060 			glVertex2i(x_start, y_start);
1061 			glVertex2i(x_start, y_end);
1062 
1063 			glVertex2i(x_start, y_end);
1064 			glVertex2i(x_end, y_end);
1065 
1066 			glVertex2i(x_end, y_end);
1067 			glVertex2i(x_end, y_start);
1068 
1069 			glVertex2i(x_end, y_start);
1070 			glVertex2i(x_start, y_start);
1071 		}
1072 		glEnd();
1073 	}
1074 
1075 #ifdef DEBUG_MAP_SOUND
1076 	// If we are in map view (not continent view) draw the sound area boundaries
1077 	if (map) {
1078 		print_sound_boundaries(map_file_name);
1079 	}
1080 #endif // DEBUG_MAP_SOUND
1081 
1082 	glEnable (GL_TEXTURE_2D);
1083 	glColor3f (1.0f, 1.0f, 1.0f);
1084 
1085 	glLineWidth(1.0f);
1086 
1087 	glMatrixMode (GL_MODELVIEW);
1088 	glPopMatrix ();
1089 	glMatrixMode (GL_PROJECTION);
1090 	glPopMatrix ();
1091 	glMatrixMode (GL_MODELVIEW);
1092 
1093 	glEnable(GL_DEPTH_TEST);
1094 	glEnable(GL_LIGHTING);
1095 #ifdef OPENGL_TRACE
1096 	CHECK_GL_ERRORS();
1097 #endif //OPENGL_TRACE
1098 }
1099 
1100 
put_mark_on_position(int map_x,int map_y,const char * name)1101 int put_mark_on_position(int map_x, int map_y, const char * name)
1102 {
1103 		if (map_x < 0
1104 		|| map_x >= tile_map_size_x*6
1105 		|| map_y < 0
1106 		|| map_y >= tile_map_size_y*6)
1107 		{
1108 			return 0;
1109 		}
1110 		if (max_mark>=MAX_USER_MARKS)
1111 		{
1112 			LOG_TO_CONSOLE(c_red2, err_mapmarks_str);
1113 			return 0;
1114 		}
1115 		marks[max_mark].x = map_x;
1116 		marks[max_mark].y = map_y;
1117 		memset(marks[max_mark].text,0,sizeof(marks[max_mark].text));
1118 
1119 		safe_strncpy(marks[max_mark].text,name,sizeof(marks[max_mark].text));
1120 		rtrim_string(marks[max_mark].text); //remove trailing white space
1121 
1122 		marks[max_mark].server_side=0;
1123 		marks[max_mark].server_side_id=-1;
1124 
1125 		marks[max_mark].r=curmark_r;
1126 		marks[max_mark].g=curmark_g;
1127 		marks[max_mark].b=curmark_b;
1128 
1129 		max_mark++;
1130 		save_markings();
1131 		return 1;
1132 }
1133 
put_mark_on_map_on_mouse_position(void)1134 void put_mark_on_map_on_mouse_position(void)
1135 {
1136 	if (pf_get_mouse_position(mouse_x, mouse_y, &mark_x, &mark_y))
1137 		adding_mark = 1;
1138 }
put_mark_on_current_position(const char * name)1139 int put_mark_on_current_position(const char *name)
1140 {
1141 	actor *me = get_our_actor ();
1142 
1143 	if (me != NULL)
1144 	{
1145 		if (put_mark_on_position(me->x_tile_pos, me->y_tile_pos, name))
1146 			return 1;
1147 	}
1148 	return 0;
1149 }
1150 
delete_mark_on_map_on_mouse_position(void)1151 void delete_mark_on_map_on_mouse_position(void)
1152 {
1153 	int mx , my , i;
1154 
1155 	int screen_map_width = main_map_screen_x_right - main_map_screen_x_left;
1156 	int screen_map_height = main_map_screen_y_bottom - main_map_screen_y_top;
1157 
1158 	int min_distance;
1159 	marking * closest_mark;
1160 
1161 	// FIXME (Malaclypse): should be moved above the screen_map_* init, to avoid additional computation
1162 	if (mouse_x < main_map_screen_x_left || mouse_x > main_map_screen_x_right
1163 		|| mouse_y < main_map_screen_y_top || mouse_y > main_map_screen_y_bottom) {
1164 		return;
1165 	}
1166 
1167 	mx = ((mouse_x - main_map_screen_x_left) * tile_map_size_x * 6) / screen_map_width;
1168 	my = (tile_map_size_y * 6) - ((mouse_y - main_map_screen_y_top) * tile_map_size_y * 6) / screen_map_height;
1169 
1170 	// delete mark closest to cursor
1171 	min_distance = screen_map_width/10 * screen_map_height/10; // only check close marks
1172 	closest_mark = NULL;
1173 	for ( i = 0 ; i < max_mark ; i ++ ) {
1174 		int distance, dx, dy;
1175 		marking * const mark = &marks[i];
1176 
1177 		// skip marks not shown due to filter
1178 		if (mark_filter_active
1179 			  && (get_string_occurance(mark_filter_text, mark->text, strlen(mark->text), 1) == -1))
1180 			continue;
1181 
1182 		// skip masked marks
1183 		if (mark->x < 0)
1184 			continue;
1185 
1186 		// get mark to cursor distance (squared)
1187 		dx = mark->x - mx;
1188 		dy = mark->y - my;
1189 		distance = dx*dx + dy*dy;
1190 
1191 		// prefer deleting closer and newer marks
1192 		if (distance <= min_distance) {
1193 			// found a closer mark
1194 			closest_mark = mark;
1195 			min_distance = distance;
1196 		}
1197 	}
1198 
1199 	if (closest_mark != NULL) {
1200 		// we found a close mark
1201 		closest_mark->x =  -1 ;
1202 		closest_mark->y =  -1 ;
1203 		if (closest_mark->server_side) {
1204 			hash_delete(server_marks,(void *)(uintptr_t)(closest_mark->server_side_id));
1205 			save_server_markings();
1206 		}
1207 	}
1208 
1209 	save_markings();
1210 	load_map_marks(); // simply to compact the array and make room for new marks
1211 
1212 }
1213 
1214 
destroy_all_root_windows(void)1215 void destroy_all_root_windows (void)
1216 {
1217 	if (game_root_win >= 0) destroy_window (game_root_win);
1218 	if (get_id_MW(MW_CONSOLE) >= 0) destroy_window (get_id_MW(MW_CONSOLE));
1219 	if (get_id_MW(MW_TABMAP) >= 0) destroy_window (get_id_MW(MW_TABMAP));
1220 	if (login_root_win >= 0) destroy_window (login_root_win);
1221 	if (rules_root_win >= 0) destroy_window (rules_root_win);
1222 	if (opening_root_win >= 0) destroy_window (opening_root_win);
1223 	if (newchar_root_win >= 0) destroy_window (newchar_root_win);
1224 	if (update_root_win >= 0) destroy_window (update_root_win);
1225 	if (langsel_rootwin >= 0) destroy_window (langsel_rootwin);
1226 }
hide_all_root_windows(void)1227 void hide_all_root_windows (void)
1228 {
1229 	if (game_root_win >= 0) hide_window (game_root_win);
1230 	hide_window_MW(MW_CONSOLE);
1231 	hide_window_MW(MW_TABMAP);
1232 	if (login_root_win >= 0) hide_window (login_root_win);
1233 	if (rules_root_win >= 0) hide_window (rules_root_win);
1234 	if (opening_root_win >= 0) hide_window (opening_root_win);
1235 	if (newchar_root_win >= 0) hide_window (newchar_root_win);
1236 	if (update_root_win >= 0) hide_window (update_root_win);
1237 	if (langsel_rootwin >= 0) hide_window (langsel_rootwin);
1238 }
1239 
resize_all_root_windows(Uint32 ow,Uint32 w,Uint32 oh,Uint32 h)1240 void resize_all_root_windows (Uint32 ow, Uint32 w, Uint32 oh, Uint32 h)
1241 {
1242 	move_windows_proportionally((float)w / (float)ow, (float)h / (float)oh);
1243 	if (game_root_win >= 0) resize_window (game_root_win, w, h);
1244 	if (get_id_MW(MW_CONSOLE) >= 0) resize_window (get_id_MW(MW_CONSOLE), w, h);
1245 	if (get_id_MW(MW_TABMAP) >= 0) resize_window (get_id_MW(MW_TABMAP), w, h);
1246 	if (login_root_win >= 0) resize_window (login_root_win, w, h);
1247 	if (rules_root_win >= 0) resize_window (rules_root_win, w, h);
1248 	if (opening_root_win >= 0) resize_window (opening_root_win, w, h);
1249 	if (newchar_root_win >= 0) resize_window (newchar_root_win, w, h);
1250 	if (update_root_win >= 0) resize_window (update_root_win, w, h);
1251 	if (langsel_rootwin >= 0) resize_window (langsel_rootwin, w, h);
1252 	input_widget_move_to_win(-1);
1253 	resize_newchar_hud_window();
1254 }
1255