Crossfire Client, Trunk
map.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, see the
9  * 'LICENSE' and 'COPYING' files.
10  *
11  * The authors can be reached via e-mail to crossfire-devel@real-time.com
12  */
13 
20 #include "client.h"
21 
22 #include <math.h>
23 #include <gtk/gtk.h>
24 
25 #include "image.h"
26 #include "main.h"
27 #include "mapdata.h"
28 #include "gtk2proto.h"
29 
30 /* Configuration (from config.c) */
31 extern int predict_alpha;
32 extern bool time_map_redraw;
33 
35 static gboolean map_updated = FALSE;
36 
37 GtkWidget *map_notebook;
38 static GtkWidget *map_drawing_area;
39 
40 // Forward declarations for events
41 static gboolean map_button_event(GtkWidget *widget,
42  GdkEventButton *event, gpointer user_data);
43 static gboolean map_expose_event(GtkWidget *widget,
44  GdkEventExpose *event, gpointer user_data);
45 
50  if (!GTK_IS_WIDGET(map_drawing_area)) {
51  // Called by config_check(), but main window layout not yet loaded.
52  return;
53  }
54 
55  GtkAllocation size;
56  gtk_widget_get_allocation(map_drawing_area, &size);
57  int scaled_size = map_image_size * use_config[CONFIG_MAPSCALE] / 100;
58  int w = size.width / scaled_size + 1;
59  int h = size.height / scaled_size + 1;
60  w = (w > MAP_MAX_SIZE) ? MAP_MAX_SIZE : w;
61  h = (h > MAP_MAX_SIZE) ? MAP_MAX_SIZE : h;
62 
63  // If request would be even, make it odd so player is centered.
64  if (w % 2 == 0) {
65  w += 1;
66  }
67 
68  if (h % 2 == 0) {
69  h += 1;
70  }
71 
75  if (csocket.fd) {
76  client_mapsize(w, h);
77  }
78  }
79 }
80 
86 void map_init(GtkWidget *window_root) {
87  static gulong map_button_handler = 0;
88  map_drawing_area = GTK_WIDGET(gtk_builder_get_object(
89  window_xml, "drawingarea_map"));
90  map_notebook = GTK_WIDGET(gtk_builder_get_object(
91  window_xml, "map_notebook"));
92 
93  g_signal_connect(map_drawing_area, "configure_event",
94  G_CALLBACK(map_check_resize), NULL);
95  g_signal_connect(map_drawing_area, "expose_event",
96  G_CALLBACK(map_expose_event), NULL);
97 
98  // Enable event masks and set callbacks to handle mouse events.
99  // If its already connected (e.g. on a second login), then skip
100  // an additional association.
101  if (!g_signal_handler_is_connected(map_drawing_area, map_button_handler)) {
102  gtk_widget_add_events(map_drawing_area,
103  GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
104  map_button_handler = g_signal_connect(map_drawing_area, "event",
105  G_CALLBACK(map_button_event), NULL);
106  }
107 
108  // Set our image sizes.
109  // IIRC, atoi stops at the first nonnumeric char, so the x in the size will be the end.
110  if (face_info.facesets[face_info.faceset].size != NULL) {
112  map_image_size = image_size; // These should be the same.
113  } else {
114  LOG(LOG_ERROR, "map_init", "Invalid faceset size from server");
115  }
116  // If we are not on the default size, we need to resize pixmaps[0].
118  int nx = map_image_size, ny = map_image_size;
119  guint8 *png_tmp = rescale_rgba_data(pixmaps[0]->map_image, &nx, &ny, use_config[CONFIG_MAPSCALE]);
120  // Try to affect pixmap[0] in-place, since it is referenced extensively.
121  pixmaps[0]->icon_width = nx;
122  pixmaps[0]->icon_height = ny;
123  // Do not affect full_icon_width/height, since those are expected to be the unscaled size.
124  do_new_image(png_tmp, pixmaps[0]);
125  }
126 
127  // Set map size based on window size and show widget.
129  gtk_widget_show(map_drawing_area);
130 }
131 
137 static void draw_pixmap(cairo_t *cr, PixmapInfo *pixmap, int ax, int ay) {
138  const int dest_x = ax * map_image_size;
139  const int dest_y = ay * map_image_size;
140  cairo_set_source_surface(cr, pixmap->map_image, dest_x, dest_y);
141  cairo_paint(cr);
142 }
143 
144 static void draw_smooth_pixmap(cairo_t* cr, PixmapInfo* pixmap,
145  const int sx, const int sy, const int dx, const int dy) {
146  const int src_x = map_image_size * sx;
147  const int src_y = map_image_size * sy;
148  const int dest_x = map_image_size * dx;
149  const int dest_y = map_image_size * dy;
150  cairo_set_source_surface(cr, pixmap->map_image, dest_x - src_x, dest_y - src_y);
151  cairo_rectangle(cr, dest_x, dest_y, map_image_size, map_image_size);
152  cairo_fill(cr);
153 }
154 
155 int display_mapscroll(int dx, int dy) {
156  return 0;
157 }
158 
169 static void drawsmooth(cairo_t *cr, int mx, int my, int layer, int picx, int picy) {
170  static int dx[8]= {0,1,1,1,0,-1,-1,-1};
171  static int dy[8]= {-1,-1,0,1,1,1,0,-1};
172  static int bweights[8]= {2,0,4,0,8,0,1,0};
173  static int cweights[8]= {0,2,0,4,0,8,0,1};
174  static int bc_exclude[8]= {
175  1+2,/*north exclude northwest (bit0) and northeast(bit1)*/
176  0,
177  2+4,/*east exclude northeast and southeast*/
178  0,
179  4+8,/*and so on*/
180  0,
181  8+1,
182  0
183  };
184  int partdone[8]= {0,0,0,0,0,0,0,0};
185  int slevels[8];
186  int sfaces[8];
187  int i,weight,weightC;
188  int emx,emy;
189  int smoothface;
190  int hasFace = 0;
191  for (i=0; i<=layer; i++) {
192  hasFace |= mapdata_cell(mx, my)->heads[i].face;
193  }
194  if (!hasFace || !mapdata_can_smooth(mx, my, layer)) {
195  return;
196  }
197  for (i=0; i<8; i++) {
198  emx=mx+dx[i];
199  emy=my+dy[i];
200  if (!mapdata_contains(emx, emy)) {
201  slevels[i]=0;
202  sfaces[i]=0; /*black picture*/
203  } else if (mapdata_cell(emx, emy)->smooth[layer] <= mapdata_cell(mx, my)->smooth[layer]) {
204  slevels[i]=0;
205  sfaces[i]=0; /*black picture*/
206  } else {
207  slevels[i]=mapdata_cell(emx, emy)->smooth[layer];
208  sfaces[i]=pixmaps[mapdata_cell(emx, emy)->heads[layer].face]->smooth_face;
209  }
210  }
211  /*
212  * Now we have a list of smoothlevel higher than current square. There are
213  * at most 8 different levels. so... check 8 times for the lowest one (we
214  * draw from bottom to top!).
215  */
216  while (1) {
217  int lowest = -1;
218  for (i=0; i<8; i++) {
219  if ( (slevels[i]>0) && (!partdone[i]) &&
220  ((lowest<0) || (slevels[i]<slevels[lowest]))
221  ) {
222  lowest=i;
223  }
224  }
225  if (lowest<0) {
226  break; /*no more smooth to do on this square*/
227  }
228  /*printf ("hey, must smooth something...%d\n",sfaces[lowest]);*/
229  /* Here we know 'what' to smooth
230  *
231  * Calculate the weight for border and weight for corners. Then
232  * 'markdone' the corresponding squares
233  *
234  * First, the border, which may exclude some corners
235  */
236  weight=0;
237  weightC=15; /*works in backward. remove where there is nothing*/
238  /*for (i=0;i<8;i++)
239  cornermask[i]=1;*/
240  for (i=0; i<8; i++) { /*check all nearby squares*/
241  if ( (slevels[i]==slevels[lowest]) &&
242  (sfaces[i]==sfaces[lowest])) {
243  partdone[i]=1;
244  weight=weight+bweights[i];
245  weightC&=~bc_exclude[i];
246  } else {
247  /*must rmove the weight of a corner if not in smoothing*/
248  weightC&=~cweights[i];
249  }
250  }
251  /*We can't do this before since we need the partdone to be adjusted*/
252  if (sfaces[lowest]<=0) {
253  continue; /*Can't smooth black*/
254  }
255  smoothface=sfaces[lowest];
256  if (smoothface<=0) {
257  continue; /*picture for smoothing not yet available*/
258  }
259  /*
260  * now, it's quite easy. We must draw using a 32x32 part of the picture
261  * smoothface. This part is located using the 2 weights calculated:
262  * (32*weight,0) and (32*weightC,32)
263  */
264  if ( (!pixmaps[smoothface]->map_image) ||
265  (pixmaps[smoothface] == pixmaps[0])) {
266  continue; /*don't have the picture associated*/
267  }
268 
269  if (weight > 0) {
270  draw_smooth_pixmap(cr, pixmaps[smoothface], weight, 0, picx, picy);
271  }
272 
273  if (weightC > 0) {
274  draw_smooth_pixmap(cr, pixmaps[smoothface], weightC, 1, picx, picy);
275  }
276  }
277 }
278 
282 static void map_draw_layer(cairo_t *cr, int layer, int mx_start, int nx, int my_start, int ny) {
283  for (int x = 0; x <= nx; x++) {
284  for (int y = 0; y <= ny; y++) {
285  // Translate on-screen coordinates to virtual map coordinates.
286  const int mx = mx_start + x;
287  const int my = my_start + y;
288 
289  // Skip current cell if not visible and not using fog of war.
290  if (!use_config[CONFIG_FOGWAR] && mapdata_cell(mx, my)->state == FOG) {
291  continue;
292  }
293 
294  // Draw pixmaps
295  int dx, dy, face = mapdata_face_info(mx, my, layer, &dx, &dy);
296  if (face > 0 && pixmaps[face]->map_image != NULL) {
297  draw_pixmap(cr, pixmaps[face], x + dx, y + dy);
298  }
299 
300  // Draw smoothing
301  if (use_config[CONFIG_SMOOTH]) {
302  drawsmooth(cr, mx, my, layer, x, y);
303  }
304  }
305  }
306 }
307 
308 static void map_draw_labels(cairo_t *cr, int mx_start, int nx, int my_start, int ny) {
309  cairo_font_face_t *font = cairo_toy_font_face_create("", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
310  cairo_set_font_face(cr, font);
311  for (int x = 0; x <= nx; x++) {
312  for (int y = 0; y <= ny; y++) {
313  // Translate on-screen coordinates to virtual map coordinates.
314  const int mx = mx_start + x;
315  const int my = my_start + y;
316 
317  struct MapLabel *next = mapdata_cell(mx, my)->label;
318  double off_y = 0;
319  while (next != NULL) {
320  // calculate extents to center text above square
321  cairo_text_extents_t extents;
322  cairo_text_extents(cr, next->label, &extents);
323  double off_x = map_image_size/2 - extents.width/2;
324  double sx = (mx-mx_start)*map_image_size + off_x;
325  double sy = (my-my_start)*map_image_size + off_y;
326 
327  // background shading
328  int bx = 3;
329  double lineheight = extents.height+2*bx;
330  cairo_set_source_rgba(cr, 0.3, 0.3, 0.3, 0.5);
331  cairo_rectangle(cr, sx - bx, sy-extents.height-bx, extents.width+2*bx, lineheight);
332  cairo_fill(cr);
333 
334  // render text
335  cairo_move_to(cr, sx, sy);
336  switch (next->subtype) {
337  case MAP2_LABEL_DM:
338  cairo_set_source_rgb(cr, 1, 0, 0);
339  break;
341  cairo_set_source_rgb(cr, 177.0/255, 225.0/255, 255.0/255);
342  break;
343  default:
344  cairo_set_source_rgb(cr, 1, 1, 1);
345  }
346  cairo_show_text(cr, next->label);
347 
348  next = next->next;
349  off_y += lineheight;
350  }
351  }
352  }
353  cairo_font_face_destroy(font);
354 }
355 
356 static double mapcell_darkness(int mx, int my) {
357  double opacity = mapdata_cell(mx, my)->darkness / 192.0 * 0.6;
358  if (use_config[CONFIG_FOGWAR] && mapdata_cell(mx, my)->state == FOG) {
359  opacity += 0.2;
360  }
361  return opacity;
362 }
363 
364 static void draw_darkness(cairo_t *cr, int nx, int ny, int mx_start, int my_start) {
369  cairo_surface_t *cst_lm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nx+2, ny+2);
370  cairo_t *cr_lm = cairo_create(cst_lm);
371  for (int x = -1; x <= nx+1; x++) {
372  for (int y = -1; y <= ny+1; y++) {
373  const int dx = MIN(MAX(0, x), nx);
374  const int dy = MIN(MAX(0, y), ny);
375 
376  // Map coordinate to get darkness information from
377  const int mx = mx_start + dx;
378  const int my = my_start + dy;
379 
380  // Destination coordinates on light map
381  const int ax = x + 1;
382  const int ay = y + 1;
383 
384  cairo_rectangle(cr_lm, ax, ay, 1, 1);
385  cairo_set_source_rgba(cr_lm, 0, 0, 0, mapcell_darkness(mx, my));
386  cairo_fill(cr_lm);
387  }
388  }
389  cairo_destroy(cr_lm);
390 
391  // Scale up light map and draw to map.
392  cairo_scale(cr, map_image_size, map_image_size);
393  cairo_translate(cr, -1, -1);
394  cairo_set_source_surface(cr, cst_lm, 0, 0);
395  switch (use_config[CONFIG_LIGHTING]) {
396  case CFG_LT_TILE:
397  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
398  break;
399  case CFG_LT_PIXEL:
400  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
401  break;
402  case CFG_LT_PIXEL_BEST:
403  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
404  break;
405  }
406  cairo_paint(cr);
407  cairo_surface_destroy(cst_lm);
408 }
409 
410 // Draw move-to tile.
411 static void draw_move_to(cairo_t *cr, int mx_start, int my_start) {
412  int mx = move_to_x;
413  int my = move_to_y;
414  int x = mx - mx_start;
415  int y = my - my_start;
416  if (!is_at_moveto()) {
417  int sx = x * map_image_size;
418  int sy = y * map_image_size;
419  cairo_rectangle(cr, sx, sy, map_image_size, map_image_size);
420  if (move_to_attack) {
421  cairo_set_source_rgb(cr, 1, 0, 0); // red to attack
422  } else {
423  cairo_set_source_rgb(cr, 1, 1, 0); // yellow to walk
424  }
425  cairo_set_line_width(cr, 2);
426  cairo_stroke(cr);
427  cairo_rectangle(cr, sx + 2, sy + 2, map_image_size - 4, map_image_size - 4);
428  cairo_set_source_rgb(cr, 0, 0, 0); // black
429  cairo_set_line_width(cr, 1);
430  cairo_stroke(cr);
431  }
432 }
433 
437 static void gtk_map_redraw() {
438  if (!map_updated) {
439  return;
440  }
441 
442  GtkAllocation size;
443  gtk_widget_get_allocation(map_drawing_area, &size);
444 
445  // Effective dimensions in pixels, i.e. after adjusting for map scale
446  float scale = use_config[CONFIG_MAPSCALE]/100.0;
447  const double ew = size.width / scale;
448  const double eh = size.height / scale;
449 
450  // Number of tiles to show in x and y dimensions
451  const int nx = (int)ceilf(ew / map_image_size);
452  const int ny = (int)ceilf(eh / map_image_size);
453 
454  // Current viewport dimensions as sent by server, in squares
455  const int vw = use_config[CONFIG_MAPWIDTH];
456  const int vh = use_config[CONFIG_MAPHEIGHT];
457 
458  // The server always centers the player in the viewport. However, if our
459  // drawing area shows more tiles than the viewport, then the player is
460  // no longer centered. Correct that here.
461  const int mx_start = (nx > vw) ? pl_pos.x - (nx - vw)/2 : pl_pos.x;
462  const int my_start = (ny > vh) ? pl_pos.y - (ny - vh)/2 : pl_pos.y;
463 
464  // Create double buffer and associated graphics context.
465  cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ew, eh);
466  cairo_t *cr = cairo_create(cst);
467 
468  // Blank graphics context with a solid black background.
469  cairo_set_source_rgb(cr, 0, 0, 0);
470  cairo_rectangle(cr, 0, 0, ew, eh);
471  cairo_fill(cr);
472 
473  // Set global offset (after blanking background)
474  cairo_translate(cr, global_offset_x, global_offset_y);
475 
476  // Draw layer-by-layer. Drawing cell-by-cell, looping over the layers,
477  // doesn't work because big faces need to be correctly layered on top.
478  for (int layer = 0; layer < MIN(render_debug_layers, MAXLAYERS); layer++) {
479  map_draw_layer(cr, layer, mx_start, nx, my_start, ny);
480  }
481 
482  draw_move_to(cr, mx_start, my_start);
483  map_draw_labels(cr, mx_start, nx, my_start, ny);
484 
485  if (use_config[CONFIG_LIGHTING] != 0) {
486  draw_darkness(cr, nx, ny, mx_start, my_start);
487  }
488  cairo_destroy(cr);
489 
490  // Copy the double buffer on the map drawing area.
491  cairo_t *map_cr = gdk_cairo_create(gtk_widget_get_window(map_drawing_area));
492  if (use_config[CONFIG_MAPSCALE] != 100) {
493  cairo_scale(map_cr, scale, scale);
494  }
495  cairo_set_source_surface(map_cr, cst, 0, 0);
496  if (use_config[CONFIG_MAPSCALE] % 100 == 0) {
497  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
498  }
499  cairo_paint(map_cr);
500  cairo_destroy(map_cr);
501 
502  cairo_surface_destroy(cst);
503 }
504 
511 void resize_map_window(int x, int y) {
512 }
513 
514 static void update_global_offset() {
515  int dx, dy;
518  global_offset_x += dx;
519  global_offset_y += dy;
520 }
521 
525 void draw_map() {
526  gint64 t_start, t_end;
527  t_start = g_get_monotonic_time();
528 
530  gtk_map_redraw();
531 
532  t_end = g_get_monotonic_time();
533  gint64 elapsed = t_end - t_start;
534  if (time_map_redraw) {
535  printf("profile/redraw,%"G_GINT64_FORMAT"\n", elapsed);
536  }
537 
538  const unsigned int target_redraw = 100000;
539  const int no_resize_above = 100; // don't resize above this value of mapscale
540  if (elapsed > target_redraw && use_config[CONFIG_MAPSCALE] < no_resize_above) {
541  use_config[CONFIG_MAPSCALE] = MIN(use_config[CONFIG_MAPSCALE] + 5, no_resize_above);
542  LOG(LOG_DEBUG, "draw_map", "Increasing mapscale to %d to reduce draw time below %u us",
543  use_config[CONFIG_MAPSCALE], target_redraw);
545  }
546 }
547 
548 static gboolean map_expose_event(GtkWidget *widget, GdkEventExpose *event,
549  gpointer user_data) {
550  draw_map();
551  return FALSE;
552 }
553 
560 int relative_direction(int dx, int dy) {
561  if (dx == 0 && dy == 0) {
562  return 0;
563  } else if (dx == 0 && dy < 0) {
564  return 1;
565  } else if (dx > 0 && dy < 0) {
566  return 2;
567  } else if (dx > 0 && dy == 0) {
568  return 3;
569  } else if (dx > 0 && dy > 0) {
570  return 4;
571  } else if (dx == 0 && dy > 0) {
572  return 5;
573  } else if (dx < 0 && dy > 0) {
574  return 6;
575  } else if (dx < 0 && dy == 0) {
576  return 7;
577  } else if (dx < 0 && dy < 0) {
578  return 8;
579  } else {
580  g_assert_not_reached();
581  }
582 }
583 
589 static void coord_to_tile(int x, int y, int *dx, int *dy) {
590  // Calculate tile below (x, y) coordinates. The top left corner is (0, 0).
591  // This is easy, just floor divide the coordinates by tile size.
592  const float tile_size = map_image_size * use_config[CONFIG_MAPSCALE]/100.0;
593  int mx = x / tile_size;
594  int my = y / tile_size;
595 
596  // Now calculate where the player is drawn. The code below is copied from
597  // gtk_map_redraw() (see the comments there):
598  GtkAllocation size;
599  gtk_widget_get_allocation(map_drawing_area, &size);
600 
601  float scale = use_config[CONFIG_MAPSCALE]/100.0;
602  const double ew = size.width / scale;
603  const double eh = size.height / scale;
604 
605  const int nx = (int)ceilf(ew / map_image_size);
606  const int ny = (int)ceilf(eh / map_image_size);
607 
608  const int vw = use_config[CONFIG_MAPWIDTH];
609  const int vh = use_config[CONFIG_MAPHEIGHT];
610 
611  // Normally, the player is centered in the middle of the server viewport
612  // (with floor division).
613  int ox = vw / 2;
614  int oy = vh / 2;
615 
616  // If mapscale is less than 100, what is shown in the client no longer
617  // matches the viewport. Add the right offset.
618  if (nx > vw) {
619  ox += (nx - vw)/2;
620  }
621 
622  if (ny > vh) {
623  oy += (ny - vh)/2;
624  }
625 
626  // Shift the clicked tile by the player's position.
627  *dx = mx - ox;
628  *dy = my - oy;
629 }
630 
634 static gboolean map_button_event(GtkWidget *widget,
635  GdkEventButton *event, gpointer user_data) {
636  int dx, dy;
637  coord_to_tile((int)event->x, (int)event->y, &dx, &dy);
638  int dir = relative_direction(dx, dy);
639 
640  switch (event->button) {
641  case 1:
642  if (event->type == GDK_BUTTON_PRESS) {
643  look_at(dx,dy);
644  }
645  break;
646  case 2:
647  if (event->type == GDK_BUTTON_RELEASE) {
648  clear_fire();
649  } else {
650  fire_dir(dir);
651  }
652  break;
653  case 3:
654  if (event->type == GDK_BUTTON_PRESS) {
655  set_move_to(dx, dy);
656  run_move_to();
657  }
658  break;
659  }
660 
661  return FALSE;
662 }
663 
671 void display_map_doneupdate(int redraw, int notice) {
672  map_updated |= redraw || !notice;
673 }
mapdata_cell
struct MapCell * mapdata_cell(const int x, const int y)
Get the stored map cell at the given map coordinate.
Definition: mapdata.c:139
redraw
static gboolean redraw(gpointer data)
Redraw the map.
Definition: main.c:137
map_image_size
int map_image_size
Definition: map.c:34
PlayerPosition::x
int x
Definition: client.h:528
draw_smooth_pixmap
static void draw_smooth_pixmap(cairo_t *cr, PixmapInfo *pixmap, const int sx, const int sy, const int dx, const int dy)
Definition: map.c:144
is_at_moveto
bool is_at_moveto()
Definition: mapdata.c:1516
CFG_LT_PIXEL
#define CFG_LT_PIXEL
Definition: client.h:231
ClientSocket::fd
GSocketConnection * fd
Definition: client.h:124
want_offset_x
int want_offset_x
Definition: mapdata.c:92
drawsmooth
static void drawsmooth(cairo_t *cr, int mx, int my, int layer, int picx, int picy)
Draw anything in adjacent squares that could smooth on given square.
Definition: map.c:169
gtk_map_redraw
static void gtk_map_redraw()
Redraw the entire map using GTK.
Definition: map.c:437
move_to_x
int move_to_x
Move to coordinates on the current map.
Definition: mapdata.c:39
do_new_image
void do_new_image(guint8 *data, PixmapInfo *pi)
Wrapper for accessing outside this file.
Definition: image.c:105
pixmaps
PixmapInfo * pixmaps[MAXPIXMAPNUM]
Definition: image.c:34
face_info
Face_Information face_info
Definition: image.c:169
CONFIG_FOGWAR
#define CONFIG_FOGWAR
Definition: client.h:188
FaceSets_struct::size
char * size
Definition: client.h:399
CONFIG_MAPSCALE
#define CONFIG_MAPSCALE
Definition: client.h:190
MIN
#define MIN(X__, Y__)
Definition: client.h:618
coord_to_tile
static void coord_to_tile(int x, int y, int *dx, int *dy)
Given x, y coordinates on the map drawing area, determine the tile that the coordinates are on with r...
Definition: map.c:589
draw_darkness
static void draw_darkness(cairo_t *cr, int nx, int ny, int mx_start, int my_start)
Definition: map.c:364
draw_move_to
static void draw_move_to(cairo_t *cr, int mx_start, int my_start)
Definition: map.c:411
map_check_resize
void map_check_resize()
Calculate and set desired map size based on map window size.
Definition: map.c:49
mapdata_can_smooth
bool mapdata_can_smooth(int x, int y, int layer)
Definition: mapdata.c:154
move_to_attack
bool move_to_attack
Definition: mapdata.c:40
CONFIG_LIGHTING
#define CONFIG_LIGHTING
Definition: client.h:199
clear_fire
void clear_fire()
Definition: player.c:111
MAP2_LABEL_PLAYER_PARTY
@ MAP2_LABEL_PLAYER_PARTY
Definition: newclient.h:58
PlayerPosition::y
int y
Definition: client.h:529
map_notebook
GtkWidget * map_notebook
Definition: map.c:37
render_debug_layers
int render_debug_layers
Current number of layers to render for renderer debugging purposes.
Definition: p_cmd.c:46
CFG_LT_TILE
#define CFG_LT_TILE
Definition: client.h:230
MapLabel::subtype
int subtype
Definition: mapdata.h:75
mapdata.h
global_offset_y
int global_offset_y
Definition: mapdata.c:91
PixmapInfo::icon_height
guint16 icon_height
Definition: image.h:47
Face_Information_struct::facesets
FaceSets facesets[MAX_FACE_SETS]
Definition: client.h:423
MapCellLayer::face
gint16 face
Definition: mapdata.h:19
DEFAULT_IMAGE_SIZE
#define DEFAULT_IMAGE_SIZE
Definition: image.h:40
map_button_event
static gboolean map_button_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Handle a mouse event in the drawing area.
Definition: map.c:634
time_map_redraw
bool time_map_redraw
Definition: config.c:53
MapCell::heads
struct MapCellLayer heads[MAXLAYERS]
Definition: mapdata.h:64
map_draw_layer
static void map_draw_layer(cairo_t *cr, int layer, int mx_start, int nx, int my_start, int ny)
Draw a single map layer to the given cairo context.
Definition: map.c:282
predict_alpha
int predict_alpha
Speed of local map prediction scrolling, 0-100 (0 to disable).
Definition: config.c:56
move_to_y
int move_to_y
Definition: mapdata.c:39
gtk2proto.h
display_mapscroll
int display_mapscroll(int dx, int dy)
Definition: map.c:155
want_offset_y
int want_offset_y
Definition: mapdata.c:93
map_draw_labels
static void map_draw_labels(cairo_t *cr, int mx_start, int nx, int my_start, int ny)
Definition: map.c:308
MapCell::smooth
guint8 smooth[MAXLAYERS]
Definition: mapdata.h:67
LOG
void LOG(LogLevel level, const char *origin, const char *format,...)
Log messages of a certain importance to stderr.
Definition: misc.c:111
global_offset_x
int global_offset_x
Definition: mapdata.c:90
draw_pixmap
static void draw_pixmap(cairo_t *cr, PixmapInfo *pixmap, int ax, int ay)
Draw a pixmap to the given map tile on screen.
Definition: map.c:137
PixmapInfo::smooth_face
guint16 smooth_face
A face used for smoothing with this face.
Definition: image.h:54
MAP_MAX_SIZE
#define MAP_MAX_SIZE
Map size the client will request the map to be.
Definition: client.h:469
CFG_LT_PIXEL_BEST
#define CFG_LT_PIXEL_BEST
Definition: client.h:232
MapLabel
Definition: mapdata.h:74
want_config
gint16 want_config[CONFIG_NUMS]
Definition: init.c:44
csocket
ClientSocket csocket
Definition: client.c:70
MapCell::darkness
guint8 darkness
Definition: mapdata.h:68
image.h
MapLabel::label
char * label
Definition: mapdata.h:76
mapdata_face_info
gint16 mapdata_face_info(int mx, int my, int layer, int *dx, int *dy)
Return the face number of the pixmap in the given map cell and set the offset pointers to indicate wh...
Definition: mapdata.c:1087
image_size
int image_size
Definition: image.c:30
map_expose_event
static gboolean map_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
Definition: map.c:548
mapdata_contains
bool mapdata_contains(int x, int y)
Determine whether the map data contains the given cell.
Definition: mapdata.c:146
FOG
@ FOG
Definition: mapdata.h:46
MAP2_LABEL_DM
@ MAP2_LABEL_DM
Definition: newclient.h:59
set_move_to
void set_move_to(int dx, int dy)
Definition: mapdata.c:1494
draw_map
void draw_map()
Draw the map window using the appropriate backend.
Definition: map.c:525
LOG_ERROR
@ LOG_ERROR
Warning that something definitely didn't work.
Definition: client.h:439
relative_direction
int relative_direction(int dx, int dy)
Given a relative tile coordinate, determine its compass direction.
Definition: map.c:560
main.h
CONFIG_MAPWIDTH
#define CONFIG_MAPWIDTH
Definition: client.h:201
CONFIG_SMOOTH
#define CONFIG_SMOOTH
Definition: client.h:208
PixmapInfo::map_image
void * map_image
Definition: image.h:53
map_init
void map_init(GtkWidget *window_root)
This initializes the stuff we need for the map.
Definition: map.c:86
fire_dir
void fire_dir(int dir)
Definition: player.c:125
Face_Information_struct::faceset
guint8 faceset
Definition: client.h:409
map_drawing_area
static GtkWidget * map_drawing_area
Definition: map.c:38
pl_pos
PlayerPosition pl_pos
Position of the player on the internal map.
Definition: mapdata.c:30
use_config
gint16 use_config[CONFIG_NUMS]
Definition: client.h:245
look_at
void look_at(int x, int y)
Definition: player.c:78
MAXLAYERS
#define MAXLAYERS
The protocol supports 10 layers, so set MAXLAYERS accordingly.
Definition: mapdata.h:6
PixmapInfo
Definition: image.h:43
run_move_to
void run_move_to()
Definition: mapdata.c:1526
mapcell_darkness
static double mapcell_darkness(int mx, int my)
Definition: map.c:356
update_global_offset
static void update_global_offset()
Definition: map.c:514
window_root
GtkWidget * window_root
In main.c.
Definition: main.c:109
resize_map_window
void resize_map_window(int x, int y)
Resize_map_window is a NOOP for the time being - not sure if it will in fact need to do something,...
Definition: map.c:511
CONFIG_MAPHEIGHT
#define CONFIG_MAPHEIGHT
Definition: client.h:202
MapLabel::next
struct MapLabel * next
Definition: mapdata.h:77
display_map_doneupdate
void display_map_doneupdate(int redraw, int notice)
This is called after the map has been all digested.
Definition: map.c:671
rescale_rgba_data
guint8 * rescale_rgba_data(guint8 *data, int *width, int *height, int scale)
Takes png data and scales it accordingly.
Definition: png.c:235
PixmapInfo::icon_width
guint16 icon_width
Definition: image.h:47
map_updated
static gboolean map_updated
Definition: map.c:35
LOG_DEBUG
@ LOG_DEBUG
Useful debugging information.
Definition: client.h:436
client_mapsize
void client_mapsize(int width, int height)
Ask the server for the given map size.
Definition: client.c:171
client.h
MapCell::label
struct MapLabel * label
Definition: mapdata.h:66
window_xml
GtkBuilder * window_xml
Definition: main.c:108