Atrinik Client  4.0
region_map.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <region_map.h>
34 
36 #define RM_BORDER_SIZE 25
37 
39 #define RM_SCROLL 10
40 
41 #define RM_SCROLL_SHIFT 50
42 
48 #define RM_MAP_STARTX 25
49 
50 #define RM_MAP_STARTY 60
51 
52 #define RM_MAP_WIDTH 630
53 
54 #define RM_MAP_HEIGHT 345
55 
62 #define RM_BUTTON_LEFT_STARTX 25
63 
64 #define RM_BUTTON_LEFT_STARTY 25
65 
72 #define RM_BUTTON_RIGHT_STARTX 649
73 
74 #define RM_BUTTON_RIGHT_STARTY 25
75 
82 #define RM_TITLE_STARTX 60
83 
84 #define RM_TITLE_STARTY 27
85 
86 #define RM_TITLE_WIDTH 580
87 
88 #define RM_TITLE_HEIGHT 22
89 
96 #define RM_SCROLLBAR_STARTX 662
97 
98 #define RM_SCROLLBAR_STARTY 60
99 
100 #define RM_SCROLLBAR_WIDTH 13
101 
102 #define RM_SCROLLBAR_HEIGHT 345
103 
110 #define RM_SCROLLBARH_STARTX 25
111 
112 #define RM_SCROLLBARH_STARTY 412
113 
114 #define RM_SCROLLBARH_WIDTH 630
115 
116 #define RM_SCROLLBARH_HEIGHT 13
117 
122 #define RM_IN_MAP(_popup, _mx, _my) ((_mx) >= (_popup)->x + RM_MAP_STARTX && \
123  (_mx) < (_popup)->x + RM_MAP_STARTX + RM_MAP_WIDTH && \
124  (_my) >= (_popup)->y + RM_MAP_STARTY && \
125  (_my) < (_popup)->y + RM_MAP_STARTY + RM_MAP_HEIGHT)
126 
141 static bool region_map_dragging = false;
145 static region_map_t *region_map = NULL;
146 
149 {
150  SDL_Rect box, dest;
151  SDL_Surface *surface;
152 
153  box.w = popup->surface->w;
154  box.h = popup->surface->h;
155 
156  /* Show direction markers. */
157  text_show(ScreenSurface, FONT_SERIF14, "N", popup->x,
158  popup->y + RM_BORDER_SIZE / 2 - FONT_HEIGHT(FONT_SERIF14) / 2,
160  text_show(ScreenSurface, FONT_SERIF14, "E",
161  popup->x + popup->surface->w - RM_BORDER_SIZE / 2 -
162  text_get_width(FONT_SERIF14, "E", 0) / 2, popup->y,
164  text_show(ScreenSurface, FONT_SERIF14, "S", popup->x,
165  popup->y + popup->surface->h - RM_BORDER_SIZE / 2 -
166  FONT_HEIGHT(FONT_SERIF14) / 2,
168  text_show(ScreenSurface, FONT_SERIF14, "W", popup->x + RM_BORDER_SIZE / 2 -
169  text_get_width(FONT_SERIF14, "W", 0) / 2, popup->y,
171 
172  box.w = RM_TITLE_WIDTH;
173  box.h = RM_TITLE_HEIGHT;
175 
176  box.x = popup->x + RM_MAP_STARTX;
177  box.y = popup->y + RM_MAP_STARTY;
178  box.w = RM_MAP_WIDTH;
179  box.h = RM_MAP_HEIGHT;
180 
182  /* Check the status of the downloads. */
183  curl_state_t state_png =
184  curl_request_get_state(MapData.region_map->request_png);
185  curl_state_t state_def =
186  curl_request_get_state(MapData.region_map->request_def);
187 
188  /* We failed. */
189  if (state_png == CURL_STATE_ERROR || state_def == CURL_STATE_ERROR) {
190  curl_request_t *request;
191  if (state_png == CURL_STATE_ERROR) {
192  request = MapData.region_map->request_png;
193  } else {
194  request = MapData.region_map->request_def;
195  }
196 
197  int http_code = curl_request_get_http_code(request);
198  if (http_code != -1) {
199  text_show_format(ScreenSurface, FONT_SERIF14,
200  box.x, box.y, COLOR_WHITE,
202  &box, "Error: %d", http_code);
203  } else {
204  text_show(ScreenSurface, FONT_SERIF14,
205  "Connection timed out.", box.x, box.y, COLOR_WHITE,
207  &box);
208  }
209  } else if (state_png == CURL_STATE_INPROGRESS ||
210  state_def == CURL_STATE_INPROGRESS) {
211  curl_request_t *request;
212  if (state_png == CURL_STATE_INPROGRESS) {
213  request = MapData.region_map->request_png;
214  } else {
215  request = MapData.region_map->request_def;
216  }
217 
218  char buf[MAX_BUF];
219  text_show_format(ScreenSurface, FONT_SERIF14,
220  box.x, box.y, COLOR_WHITE,
222  "Downloading the map, please wait...\n%s",
223  curl_request_speedinfo(request, VS(buf)));
224  }
225 
226  return 1;
227  }
228 
229  if (region_map == NULL) {
230  region_map = region_map_clone(MapData.region_map);
231  region_map->pos.w = RM_MAP_WIDTH;
232  region_map->pos.h = RM_MAP_HEIGHT;
233  region_map_pan(region_map);
234  }
235 
236  surface = region_map_surface(region_map);
237 
238  if (scrollbar_info.redraw) {
239  scrollbar_info.redraw = 0;
240  region_map->pos.y = scrollbar_info.scroll_offset;
241  surface_pan(surface, &region_map->pos);
242  } else {
243  scrollbar_info.num_lines = surface->h;
244  scrollbar_info.scroll_offset = region_map->pos.y;
245  scrollbar.max_lines = region_map->pos.h;
246  }
247 
248  if (scrollbar_horizontal_info.redraw) {
249  scrollbar_horizontal_info.redraw = 0;
250  region_map->pos.x = scrollbar_horizontal_info.scroll_offset;
251  surface_pan(surface, &region_map->pos);
252  } else {
253  scrollbar_horizontal_info.num_lines = surface->w;
254  scrollbar_horizontal_info.scroll_offset = region_map->pos.x;
255  scrollbar_horizontal.max_lines = region_map->pos.w;
256  }
257 
258  scrollbar_show(&scrollbar, ScreenSurface,
259  popup->x + RM_SCROLLBAR_STARTX, popup->y + RM_SCROLLBAR_STARTY);
260  scrollbar_show(&scrollbar_horizontal, ScreenSurface,
261  popup->x + RM_SCROLLBARH_STARTX, popup->y + RM_SCROLLBARH_STARTY);
262 
263  dest.x = box.x;
264  dest.y = box.y;
265 
266  /* Actually draw the map. */
267  SDL_BlitSurface(surface, &region_map->pos, ScreenSurface, &dest);
268  region_map_render_fow(region_map, ScreenSurface, dest.x, dest.y);
269  region_map_render_marker(region_map, ScreenSurface, dest.x, dest.y);
270 
271  return 1;
272 }
273 
276 {
277  help_show("region map");
278  return 1;
279 }
280 
282 static int popup_event_func(popup_struct *popup, SDL_Event *event)
283 {
284  if (region_map == NULL) {
285  return -1;
286  }
287 
288  /* Start dragging the map. */
289  if (event->type == SDL_MOUSEBUTTONDOWN &&
290  event->button.button == SDL_BUTTON_LEFT &&
291  RM_IN_MAP(popup, event->motion.x, event->motion.y)) {
293  }
294 
295  /* Dragging the map? */
296  if (region_map_dragging) {
297  /* Stop dragging the map if the left mouse button has been released. */
298  if (event->type == SDL_MOUSEBUTTONUP &&
299  event->button.button == SDL_BUTTON_LEFT) {
301  return 1;
302  }
303 
304  /* Fake slider events. */
305  scrollbar.slider.highlight = 1;
306  scrollbar_horizontal.slider.highlight = 1;
307  /* Reverse the x/y, so "dragging the map" makes more sense. */
308  event->motion.x = -event->motion.x;
309  event->motion.y = -event->motion.y;
310  scrollbar_event(&scrollbar, event);
311  scrollbar_event(&scrollbar_horizontal, event);
312  return 1;
313  }
314 
315  /* Handle scrollbars. */
316  if (scrollbar_event(&scrollbar, event)) {
317  return 1;
318  } else if (scrollbar_event(&scrollbar_horizontal, event)) {
319  return 1;
320  }
321 
322  if (event->type == SDL_MOUSEBUTTONDOWN) {
323  if (event->button.button == SDL_BUTTON_WHEELUP) {
324  /* Zoom in. */
325  if (region_map->zoom < RM_ZOOM_MAX) {
326  region_map_resize(region_map, RM_ZOOM_PROGRESS);
327  return 1;
328  }
329  } else if (event->button.button == SDL_BUTTON_WHEELDOWN) {
330  /* Zoom out. */
331  if (region_map->zoom > RM_ZOOM_MIN) {
332  region_map_resize(region_map, -RM_ZOOM_PROGRESS);
333  return 1;
334  }
335  } else if (event->button.button == SDL_BUTTON_MIDDLE &&
337  RM_IN_MAP(popup, event->motion.x, event->motion.y)) {
338  int xpos, ypos, map_x, map_y, map_w, map_h;
339  double zoomfactor;
340  size_t i;
341  char buf[HUGE_BUF];
342 
343  /* Quickport. */
344  xpos = region_map->pos.x + event->motion.x - popup->x -
346  ypos = region_map->pos.y + event->motion.y - popup->y -
348  zoomfactor = region_map->zoom / 100.0;
349  map_w = region_map->def->map_size_x * region_map->def->pixel_size *
350  zoomfactor;
351  map_h = region_map->def->map_size_y * region_map->def->pixel_size *
352  zoomfactor;
353 
354  for (i = 0; i < region_map->def->num_maps; i++) {
355  map_x = region_map->def->maps[i].xpos * zoomfactor;
356  map_y = region_map->def->maps[i].ypos * zoomfactor;
357 
358  if (xpos < map_x || xpos > map_x + map_w ||
359  ypos < map_y || ypos > map_y + map_h) {
360  continue;
361  }
362 
363  xpos = (xpos - region_map->def->maps[i].xpos * zoomfactor) /
364  (region_map->def->pixel_size * zoomfactor);
365  ypos = (ypos - region_map->def->maps[i].ypos * zoomfactor) /
366  (region_map->def->pixel_size * zoomfactor);
367  snprintf(buf, sizeof(buf), "/tpto %s %d %d",
368  region_map->def->maps[i].path, xpos, ypos);
369  send_command(buf);
370 
371  popup_destroy(popup);
372  return 1;
373  }
374  }
375  } else if (event->type == SDL_MOUSEMOTION) {
376  if (RM_IN_MAP(popup, event->motion.x, event->motion.y)) {
377  int xpos, ypos, tooltip_x, tooltip_y, tooltip_w, tooltip_h;
378  size_t i;
379  double zoomfactor;
380 
381  xpos = region_map->pos.x + event->motion.x - popup->x -
383  ypos = region_map->pos.y + event->motion.y - popup->y -
385  zoomfactor = region_map->zoom / 100.0;
386 
387  for (i = 0; i < region_map->def->num_tooltips; i++) {
388  tooltip_x = region_map->def->tooltips[i].x * zoomfactor;
389  tooltip_y = region_map->def->tooltips[i].y * zoomfactor;
390  tooltip_w = region_map->def->tooltips[i].w * zoomfactor;
391  tooltip_h = region_map->def->tooltips[i].h * zoomfactor;
392 
393  if (xpos < tooltip_x || xpos > tooltip_x + tooltip_w ||
394  ypos < tooltip_y || ypos > tooltip_y + tooltip_h) {
395  continue;
396  }
397 
398  if (region_map_fow_is_visible(MapData.region_map, xpos /
399  (double) region_map->def->pixel_size / zoomfactor,
400  ypos / (double) region_map->def->pixel_size /
401  zoomfactor)) {
402  tooltip_create(event->motion.x, event->motion.y,
403  FONT_ARIAL11, region_map->def->tooltips[i].text);
404  tooltip_multiline(200);
406  }
407 
408  break;
409  }
410  }
411  } else if (event->type == SDL_KEYDOWN) {
412  int pos = RM_SCROLL;
413 
414  if (event->key.keysym.mod & KMOD_SHIFT) {
415  pos = RM_SCROLL_SHIFT;
416  }
417 
418  if (event->key.keysym.sym == SDLK_UP) {
419  region_map->pos.y -= pos;
420  surface_pan(region_map_surface(region_map), &region_map->pos);
421  return 1;
422  } else if (event->key.keysym.sym == SDLK_DOWN) {
423  region_map->pos.y += pos;
424  surface_pan(region_map_surface(region_map), &region_map->pos);
425  return 1;
426  } else if (event->key.keysym.sym == SDLK_LEFT) {
427  region_map->pos.x -= pos;
428  surface_pan(region_map_surface(region_map), &region_map->pos);
429  return 1;
430  } else if (event->key.keysym.sym == SDLK_RIGHT) {
431  region_map->pos.x += pos;
432  surface_pan(region_map_surface(region_map), &region_map->pos);
433  return 1;
434  } else if (event->key.keysym.sym == SDLK_PAGEUP) {
435  if (region_map->zoom < RM_ZOOM_MAX) {
436  region_map_resize(region_map, RM_ZOOM_PROGRESS);
437  return 1;
438  }
439  } else if (event->key.keysym.sym == SDLK_PAGEDOWN) {
440  if (region_map->zoom > RM_ZOOM_MIN) {
441  region_map_resize(region_map, -RM_ZOOM_PROGRESS);
442  return 1;
443  }
444  }
445  }
446 
447  return -1;
448 }
449 
452 {
453  if (region_map != NULL) {
454  region_map_free(region_map);
455  region_map = NULL;
456  }
457 
458  return 1;
459 }
460 
464 void region_map_open(void)
465 {
466  popup_struct *popup;
467 
468  if (MapData.region_name[0] == '\0') {
469  draw_info(COLOR_WHITE, "You don't appear to be in a region...");
470  return;
471  }
472 
473  if (region_map != NULL) {
474  region_map_free(region_map);
475  region_map = NULL;
476  }
477 
478  popup = popup_create(texture_get(TEXTURE_TYPE_CLIENT, "region_map"));
480  popup->event_func = popup_event_func;
482 
486  popup_button_set_text(&popup->button_left, "?");
487 
490 
491  scrollbar_info_create(&scrollbar_info);
492  scrollbar_create(&scrollbar, RM_SCROLLBAR_WIDTH, RM_SCROLLBAR_HEIGHT, &scrollbar_info.scroll_offset, &scrollbar_info.num_lines, 0);
493  scrollbar.redraw = &scrollbar_info.redraw;
494  scrollbar.arrow_adjust = RM_SCROLL;
495 
496  scrollbar_info_create(&scrollbar_horizontal_info);
497  scrollbar_create(&scrollbar_horizontal, RM_SCROLLBARH_WIDTH, RM_SCROLLBARH_HEIGHT, &scrollbar_horizontal_info.scroll_offset, &scrollbar_horizontal_info.num_lines, 0);
498  scrollbar_horizontal.redraw = &scrollbar_horizontal_info.redraw;
499  scrollbar_horizontal.arrow_adjust = RM_SCROLL;
500 }
scrollbar_element slider
Definition: scrollbar.h:126
#define RM_BUTTON_RIGHT_STARTY
Definition: region_map.c:74
uint8_t highlight
Definition: scrollbar.h:50
int(* event_func)(struct popup_struct *popup, SDL_Event *event)
Definition: popup.h:148
size_t num_tooltips
Definition: region_map.h:126
#define RM_TITLE_STARTY
Definition: region_map.c:84
void draw_info(const char *color, const char *str)
Definition: textwin.c:448
#define RM_ZOOM_PROGRESS
Definition: region_map.h:44
int(* draw_post_func)(struct popup_struct *popup)
Definition: popup.h:137
void region_map_resize(region_map_t *region_map, int adjust)
Definition: region_map.c:362
struct region_map * region_map
Definition: map.h:169
#define RM_SCROLLBARH_HEIGHT
Definition: region_map.c:116
#define RM_TITLE_WIDTH
Definition: region_map.c:86
int(* destroy_callback_func)(struct popup_struct *popup)
Definition: popup.h:159
int y
Definition: popup.h:41
void text_show(SDL_Surface *surface, font_struct *font, const char *text, int x, int y, const char *color_notation, uint64_t flags, SDL_Rect *box)
Definition: text.c:1983
#define RM_BUTTON_LEFT_STARTX
Definition: region_map.c:62
int x
Definition: popup.h:87
#define COLOR_HGOLD
Definition: text.h:319
void tooltip_create(int mx, int my, font_struct *font, const char *text)
Definition: tooltip.c:60
texture_struct * texture_get(texture_type_t type, const char *name)
Definition: texture.c:279
SDL_Surface * ScreenSurface
Definition: main.c:47
char region_name[MAX_BUF]
Definition: map.h:125
region_map_def_map_t * maps
Definition: region_map.h:117
#define RM_SCROLLBARH_STARTY
Definition: region_map.c:112
uint32_t max_lines
Definition: scrollbar.h:77
void send_command(const char *command)
Definition: player.c:175
#define TEXT_ALIGN_CENTER
Definition: text.h:230
static int tooltip_y
Definition: tooltip.c:41
#define RM_TITLE_STARTX
Definition: region_map.c:82
void scrollbar_show(scrollbar_struct *scrollbar, SDL_Surface *surface, int x, int y)
Definition: scrollbar.c:443
_mapdata MapData
Definition: map.c:64
void help_show(const char *name)
Definition: help.c:219
static int popup_draw_post_func(popup_struct *popup)
Definition: region_map.c:148
bool region_map_ready(region_map_t *region_map)
Definition: region_map.c:200
#define RM_MAP_STARTX
Definition: region_map.c:48
region_map_def_t * def
Definition: region_map.h:206
static int popup_button_event_func(popup_button *button)
Definition: region_map.c:275
#define RM_BUTTON_LEFT_STARTY
Definition: region_map.c:64
SDL_Rect pos
Definition: region_map.h:224
static scrollbar_struct scrollbar_horizontal
Definition: region_map.c:132
#define RM_ZOOM_MAX
Definition: region_map.h:42
void scrollbar_info_create(scrollbar_info_struct *info)
Definition: scrollbar.c:382
#define RM_MAP_STARTY
Definition: region_map.c:50
#define RM_TITLE_HEIGHT
Definition: region_map.c:88
SDL_Surface * region_map_surface(region_map_t *region_map)
Definition: region_map.c:319
static scrollbar_struct scrollbar
Definition: region_map.c:128
curl_request_t * request_def
Definition: region_map.h:234
int64_t setting_get_int(int cat, int setting)
Definition: settings.c:414
void region_map_open(void)
Definition: region_map.c:464
#define RM_IN_MAP(_popup, _mx, _my)
Definition: region_map.c:122
int(* event_func)(struct popup_button *button)
Definition: popup.h:56
static int popup_event_func(popup_struct *popup, SDL_Event *event)
Definition: region_map.c:282
void region_map_free(region_map_t *region_map)
Definition: region_map.c:93
#define RM_SCROLLBAR_WIDTH
Definition: region_map.c:100
#define FONT_HEIGHT(font)
Definition: text.h:327
static bool region_map_dragging
Definition: region_map.c:141
#define RM_SCROLL_SHIFT
Definition: region_map.c:41
void scrollbar_create(scrollbar_struct *scrollbar, int w, int h, uint32_t *scroll_offset, uint32_t *num_lines, uint32_t max_lines)
Definition: scrollbar.c:350
#define RM_SCROLLBAR_STARTY
Definition: region_map.c:98
#define RM_BUTTON_RIGHT_STARTX
Definition: region_map.c:72
void tooltip_enable_delay(uint32_t delay)
Definition: tooltip.c:82
#define TEXT_OUTLINE
Definition: text.h:255
size_t num_maps
Definition: region_map.h:120
int y
Definition: popup.h:90
static scrollbar_info_struct scrollbar_horizontal_info
Definition: region_map.c:137
static int tooltip_x
Definition: tooltip.c:39
uint8_t * redraw
Definition: scrollbar.h:87
popup_button button_left
Definition: popup.h:93
void tooltip_multiline(int max_width)
Definition: tooltip.c:96
#define RM_SCROLLBAR_STARTX
Definition: region_map.c:96
region_map_t * region_map_clone(region_map_t *region_map)
Definition: region_map.c:73
int x
Definition: popup.h:38
int text_get_width(font_struct *font, const char *text, uint64_t flags)
Definition: text.c:2328
#define RM_SCROLL
Definition: region_map.c:39
#define RM_ZOOM_MIN
Definition: region_map.h:40
int scrollbar_event(scrollbar_struct *scrollbar, SDL_Event *event)
Definition: scrollbar.c:529
popup_button button_right
Definition: popup.h:96
#define RM_SCROLLBAR_HEIGHT
Definition: region_map.c:102
#define RM_MAP_WIDTH
Definition: region_map.c:52
#define RM_SCROLLBARH_STARTX
Definition: region_map.c:110
static curl_request_t * request
Definition: updater.c:95
static scrollbar_info_struct scrollbar_info
Definition: region_map.c:130
SDL_Surface * surface
Definition: popup.h:65
char region_longname[MAX_BUF]
Definition: map.h:131
void text_show_format(SDL_Surface *surface, font_struct *font, int x, int y, const char *color_notation, uint64_t flags, SDL_Rect *box, const char *format,...)
Definition: text.c:2289
void region_map_render_marker(region_map_t *region_map, SDL_Surface *surface, int x, int y)
Definition: region_map.c:417
static int popup_destroy_callback(popup_struct *popup)
Definition: region_map.c:451
#define RM_MAP_HEIGHT
Definition: region_map.c:54
#define RM_SCROLLBARH_WIDTH
Definition: region_map.c:114
region_map_def_tooltip_t * tooltips
Definition: region_map.h:123
#define RM_BORDER_SIZE
Definition: region_map.c:36
#define TEXT_VALIGN_CENTER
Definition: text.h:246
curl_request_t * request_png
Definition: region_map.h:229
void surface_pan(SDL_Surface *surface, SDL_Rect *box)
Definition: sprite.c:1151
uint32_t scroll_offset
Definition: scrollbar.h:135
#define COLOR_WHITE
Definition: text.h:289