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  pixmaps[0]->full_icon_width = nx;
124  pixmaps[0]->full_icon_height = ny;
125  do_new_image(png_tmp, pixmaps[0]);
126  }
127 
128  // Set map size based on window size and show widget.
130  gtk_widget_show(map_drawing_area);
131 }
132 
138 static void draw_pixmap(cairo_t *cr, PixmapInfo *pixmap, int ax, int ay, int off_x, int off_y) {
139  const int dest_x = ax * map_image_size;
140  const int dest_y = ay * map_image_size;
141  cairo_set_source_surface(cr, pixmap->map_image, dest_x + global_offset_x + off_x, dest_y + global_offset_y + off_y);
142  cairo_paint(cr);
143 }
144 
145 static void draw_smooth_pixmap(cairo_t* cr, PixmapInfo* pixmap,
146  const int sx, const int sy, const int dx, const int dy) {
147  const int src_x = map_image_size * sx;
148  const int src_y = map_image_size * sy;
149  const int dest_x = map_image_size * dx + global_offset_x;
150  const int dest_y = map_image_size * dy + global_offset_y;
151  cairo_set_source_surface(cr, pixmap->map_image, dest_x - src_x, dest_y - src_y);
152  cairo_rectangle(cr, dest_x, dest_y, map_image_size, map_image_size);
153  cairo_fill(cr);
154 }
155 
156 int display_mapscroll(int dx, int dy) {
157  return 0;
158 }
159 
170 static void drawsmooth(cairo_t *cr, int mx, int my, int layer, int picx, int picy) {
171  static int dx[8]= {0,1,1,1,0,-1,-1,-1};
172  static int dy[8]= {-1,-1,0,1,1,1,0,-1};
173  static int bweights[8]= {2,0,4,0,8,0,1,0};
174  static int cweights[8]= {0,2,0,4,0,8,0,1};
175  static int bc_exclude[8]= {
176  1+2,/*north exclude northwest (bit0) and northeast(bit1)*/
177  0,
178  2+4,/*east exclude northeast and southeast*/
179  0,
180  4+8,/*and so on*/
181  0,
182  8+1,
183  0
184  };
185  int partdone[8]= {0,0,0,0,0,0,0,0};
186  int slevels[8];
187  int sfaces[8];
188  int i,weight,weightC;
189  int emx,emy;
190  int smoothface;
191  int hasFace = 0;
192  for (i=0; i<=layer; i++) {
193  hasFace |= mapdata_cell(mx, my)->heads[i].face;
194  }
195  if (!hasFace || !mapdata_can_smooth(mx, my, layer)) {
196  return;
197  }
198  for (i=0; i<8; i++) {
199  emx=mx+dx[i];
200  emy=my+dy[i];
201  if (!mapdata_contains(emx, emy)) {
202  slevels[i]=0;
203  sfaces[i]=0; /*black picture*/
204  } else if (mapdata_cell(emx, emy)->smooth[layer] <= mapdata_cell(mx, my)->smooth[layer]) {
205  slevels[i]=0;
206  sfaces[i]=0; /*black picture*/
207  } else {
208  slevels[i]=mapdata_cell(emx, emy)->smooth[layer];
209  sfaces[i]=pixmaps[mapdata_cell(emx, emy)->heads[layer].face]->smooth_face;
210  }
211  }
212  /*
213  * Now we have a list of smoothlevel higher than current square. There are
214  * at most 8 different levels. so... check 8 times for the lowest one (we
215  * draw from bottom to top!).
216  */
217  while (1) {
218  int lowest = -1;
219  for (i=0; i<8; i++) {
220  if ( (slevels[i]>0) && (!partdone[i]) &&
221  ((lowest<0) || (slevels[i]<slevels[lowest]))
222  ) {
223  lowest=i;
224  }
225  }
226  if (lowest<0) {
227  break; /*no more smooth to do on this square*/
228  }
229  /*printf ("hey, must smooth something...%d\n",sfaces[lowest]);*/
230  /* Here we know 'what' to smooth
231  *
232  * Calculate the weight for border and weight for corners. Then
233  * 'markdone' the corresponding squares
234  *
235  * First, the border, which may exclude some corners
236  */
237  weight=0;
238  weightC=15; /*works in backward. remove where there is nothing*/
239  /*for (i=0;i<8;i++)
240  cornermask[i]=1;*/
241  for (i=0; i<8; i++) { /*check all nearby squares*/
242  if ( (slevels[i]==slevels[lowest]) &&
243  (sfaces[i]==sfaces[lowest])) {
244  partdone[i]=1;
245  weight=weight+bweights[i];
246  weightC&=~bc_exclude[i];
247  } else {
248  /*must rmove the weight of a corner if not in smoothing*/
249  weightC&=~cweights[i];
250  }
251  }
252  /*We can't do this before since we need the partdone to be adjusted*/
253  if (sfaces[lowest]<=0) {
254  continue; /*Can't smooth black*/
255  }
256  smoothface=sfaces[lowest];
257  if (smoothface<=0) {
258  continue; /*picture for smoothing not yet available*/
259  }
260  /*
261  * now, it's quite easy. We must draw using a 32x32 part of the picture
262  * smoothface. This part is located using the 2 weights calculated:
263  * (32*weight,0) and (32*weightC,32)
264  */
265  if ( (!pixmaps[smoothface]->map_image) ||
266  (pixmaps[smoothface] == pixmaps[0])) {
267  continue; /*don't have the picture associated*/
268  }
269 
270  if (weight > 0) {
271  draw_smooth_pixmap(cr, pixmaps[smoothface], weight, 0, picx, picy);
272  }
273 
274  if (weightC > 0) {
275  draw_smooth_pixmap(cr, pixmaps[smoothface], weightC, 1, picx, picy);
276  }
277  }
278 }
279 
283 static void map_draw_layer(cairo_t *cr, int layer, int pass, int mx_start, int nx, int my_start, int ny, int off_x, int off_y) {
284  for (int x = 0; x <= nx; x++) {
285  for (int y = 0; y <= ny; y++) {
286  // Translate on-screen coordinates to virtual map coordinates.
287  const int mx = mx_start + x;
288  const int my = my_start + y;
289 
290  // Skip current cell if not visible and not using fog of war.
291  if (!use_config[CONFIG_FOGWAR] && mapdata_cell(mx, my)->cleared) {
292  continue;
293  }
294 
295  if (pass == 0) {
296  int dx, dy, face = mapdata_face_info(mx, my, layer, &dx, &dy);
297  if (face > 0 && pixmaps[face]->map_image != NULL) {
298  draw_pixmap(cr, pixmaps[face], x + dx, y + dy, off_x, off_y);
299  }
300  } else if (pass == 1) {
301  if (use_config[CONFIG_SMOOTH]) {
302  drawsmooth(cr, mx, my, layer, x + off_x, y + off_y);
303  }
304  }
305  }
306  }
307 }
308 
309 static double mapcell_darkness(int mx, int my) {
310  double opacity = mapdata_cell(mx, my)->darkness / 192.0 * 0.6;
311  if (use_config[CONFIG_FOGWAR] && mapdata_cell(mx, my)->cleared) {
312  opacity += 0.2;
313  }
314  return opacity;
315 }
316 
317 static void draw_darkness(cairo_t *cr, int nx, int ny, int mx_start, int my_start) {
322  cairo_surface_t *cst_lm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nx+2, ny+2);
323  cairo_t *cr_lm = cairo_create(cst_lm);
324  for (int x = -1; x <= nx+1; x++) {
325  for (int y = -1; y <= ny+1; y++) {
326  const int dx = MIN(MAX(0, x), nx);
327  const int dy = MIN(MAX(0, y), ny);
328 
329  // Map coordinate to get darkness information from
330  const int mx = mx_start + dx;
331  const int my = my_start + dy;
332 
333  // Destination coordinates on light map
334  const int ax = x + 1;
335  const int ay = y + 1;
336 
337  cairo_rectangle(cr_lm, ax, ay, 1, 1);
338  cairo_set_source_rgba(cr_lm, 0, 0, 0, mapcell_darkness(mx, my));
339  cairo_fill(cr_lm);
340  }
341  }
342  cairo_destroy(cr_lm);
343 
344  // Scale up light map and draw to map.
345  cairo_translate(cr, global_offset_x, global_offset_y);
346  cairo_scale(cr, map_image_size, map_image_size);
347  cairo_translate(cr, -1, -1);
348  cairo_set_source_surface(cr, cst_lm, 0, 0);
349  switch (use_config[CONFIG_LIGHTING]) {
350  case CFG_LT_TILE:
351  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
352  break;
353  case CFG_LT_PIXEL:
354  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
355  break;
356  case CFG_LT_PIXEL_BEST:
357  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
358  break;
359  }
360  cairo_paint(cr);
361  cairo_surface_destroy(cst_lm);
362 }
363 
367 static void gtk_map_redraw() {
368  if (!map_updated) {
369  return;
370  }
371 
372  GtkAllocation size;
373  gtk_widget_get_allocation(map_drawing_area, &size);
374 
375  // Effective dimensions in pixels, i.e. after adjusting for map scale
376  float scale = use_config[CONFIG_MAPSCALE]/100.0;
377  const double ew = size.width / scale;
378  const double eh = size.height / scale;
379 
380  // Number of tiles to show in x and y dimensions
381  const int nx = (int)ceilf(ew / map_image_size);
382  const int ny = (int)ceilf(eh / map_image_size);
383 
384  // Current viewport dimensions as sent by server, in squares
385  const int vw = use_config[CONFIG_MAPWIDTH];
386  const int vh = use_config[CONFIG_MAPHEIGHT];
387 
388  // The server always centers the player in the viewport. However, if our
389  // drawing area shows more tiles than the viewport, then the player is
390  // no longer centered. Correct that here.
391  const int mx_start = (nx > vw) ? pl_pos.x - (nx - vw)/2 : pl_pos.x;
392  const int my_start = (ny > vh) ? pl_pos.y - (ny - vh)/2 : pl_pos.y;
393 
394  // Create double buffer and associated graphics context.
395  cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ew, eh);
396  cairo_t *cr = cairo_create(cst);
397 
398  // Blank graphics context with a solid black background.
399  cairo_set_source_rgb(cr, 0, 0, 0);
400  cairo_rectangle(cr, 0, 0, ew, eh);
401  cairo_fill(cr);
402 
403  for (int layer = 0; layer < MAXLAYERS; layer++) {
404  map_draw_layer(cr, layer, 0, mx_start, nx, my_start, ny, 0, 0);
405  map_draw_layer(cr, layer, 1, mx_start, nx, my_start, ny, 0, 0);
406  }
407 
408  for (int x = 0; x <= nx; x++) {
409  for (int y = 0; y <= ny; y++) {
410  // Translate on-screen coordinates to virtual map coordinates.
411  const int mx = mx_start + x;
412  const int my = my_start + y;
413 
414  mapdata_cell(mx, my)->need_update = 0;
415  mapdata_cell(mx, my)->need_resmooth = 0;
416 
417  // Draw move-to tile.
418  if (mx == move_to_x && my == move_to_y && !is_at_moveto()) {
419  int sx = x * map_image_size;
420  int sy = y * map_image_size;
421  cairo_rectangle(cr, sx + global_offset_x, sy + global_offset_y, map_image_size, map_image_size);
422  if (move_to_attack) {
423  cairo_set_source_rgb(cr, 1, 0, 0); // red to attack
424  } else {
425  cairo_set_source_rgb(cr, 1, 1, 0); // yellow to walk
426  }
427  cairo_set_line_width(cr, 2);
428  cairo_stroke(cr);
429  cairo_rectangle(cr, sx + global_offset_x + 2, sy + global_offset_y + 2, map_image_size - 4, map_image_size - 4);
430  cairo_set_source_rgb(cr, 0, 0, 0); // black
431  cairo_set_line_width(cr, 1);
432  cairo_stroke(cr);
433  }
434  }
435  }
436 
437  if (use_config[CONFIG_LIGHTING] != 0) {
438  draw_darkness(cr, nx, ny, mx_start, my_start);
439  }
440  cairo_destroy(cr);
441 
442  // Copy the double buffer on the map drawing area.
443  cairo_t *map_cr = gdk_cairo_create(gtk_widget_get_window(map_drawing_area));
444  if (use_config[CONFIG_MAPSCALE] != 100) {
445  cairo_scale(map_cr, scale, scale);
446  }
447  cairo_set_source_surface(map_cr, cst, 0, 0);
448  if (use_config[CONFIG_MAPSCALE] % 100 == 0) {
449  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
450  }
451  cairo_paint(map_cr);
452  cairo_destroy(map_cr);
453 
454  cairo_surface_destroy(cst);
455 }
456 
463 void resize_map_window(int x, int y) {
464 }
465 
466 static void update_global_offset() {
467  int dx, dy;
470  global_offset_x += dx;
471  global_offset_y += dy;
472 }
473 
477 void draw_map() {
478  gint64 t_start, t_end;
479  t_start = g_get_monotonic_time();
480 
482  gtk_map_redraw();
483 
484  t_end = g_get_monotonic_time();
485  gint64 elapsed = t_end - t_start;
486  if (time_map_redraw) {
487  printf("profile/redraw,%"G_GINT64_FORMAT"\n", elapsed);
488  }
489 
490  const unsigned int target_redraw = 100000;
491  if (elapsed > target_redraw) {
492  LOG(LOG_DEBUG, "draw_map", "Increasing mapscale to %d to reduce draw time below %u us",
493  use_config[CONFIG_MAPSCALE], target_redraw);
496  }
497 }
498 
499 static gboolean map_expose_event(GtkWidget *widget, GdkEventExpose *event,
500  gpointer user_data) {
501  draw_map();
502  return FALSE;
503 }
504 
511 int relative_direction(int dx, int dy) {
512  if (dx == 0 && dy == 0) {
513  return 0;
514  } else if (dx == 0 && dy < 0) {
515  return 1;
516  } else if (dx > 0 && dy < 0) {
517  return 2;
518  } else if (dx > 0 && dy == 0) {
519  return 3;
520  } else if (dx > 0 && dy > 0) {
521  return 4;
522  } else if (dx == 0 && dy > 0) {
523  return 5;
524  } else if (dx < 0 && dy > 0) {
525  return 6;
526  } else if (dx < 0 && dy == 0) {
527  return 7;
528  } else if (dx < 0 && dy < 0) {
529  return 8;
530  } else {
531  g_assert_not_reached();
532  }
533 }
534 
540 static void coord_to_tile(int x, int y, int *dx, int *dy) {
541  // Calculate tile below (x, y) coordinates. The top left corner is (0, 0).
542  // This is easy, just floor divide the coordinates by tile size.
543  const float tile_size = map_image_size * use_config[CONFIG_MAPSCALE]/100.0;
544  int mx = x / tile_size;
545  int my = y / tile_size;
546 
547  // Now calculate where the player is drawn. The code below is copied from
548  // gtk_map_redraw() (see the comments there):
549  GtkAllocation size;
550  gtk_widget_get_allocation(map_drawing_area, &size);
551 
552  float scale = use_config[CONFIG_MAPSCALE]/100.0;
553  const double ew = size.width / scale;
554  const double eh = size.height / scale;
555 
556  const int nx = (int)ceilf(ew / map_image_size);
557  const int ny = (int)ceilf(eh / map_image_size);
558 
559  const int vw = use_config[CONFIG_MAPWIDTH];
560  const int vh = use_config[CONFIG_MAPHEIGHT];
561 
562  // Normally, the player is centered in the middle of the server viewport
563  // (with floor division).
564  int ox = vw / 2;
565  int oy = vh / 2;
566 
567  // If mapscale is less than 100, what is shown in the client no longer
568  // matches the viewport. Add the right offset.
569  if (nx > vw) {
570  ox += (nx - vw)/2;
571  }
572 
573  if (ny > vh) {
574  oy += (ny - vh)/2;
575  }
576 
577  // Shift the clicked tile by the player's position.
578  *dx = mx - ox;
579  *dy = my - oy;
580 }
581 
585 static gboolean map_button_event(GtkWidget *widget,
586  GdkEventButton *event, gpointer user_data) {
587  int dx, dy;
588  coord_to_tile((int)event->x, (int)event->y, &dx, &dy);
589  int dir = relative_direction(dx, dy);
590 
591  switch (event->button) {
592  case 1:
593  if (event->type == GDK_BUTTON_PRESS) {
594  look_at(dx,dy);
595  }
596  break;
597  case 2:
598  if (event->type == GDK_BUTTON_RELEASE) {
599  clear_fire();
600  } else {
601  fire_dir(dir);
602  }
603  break;
604  case 3:
605  if (event->type == GDK_BUTTON_PRESS) {
606  set_move_to(dx, dy);
607  run_move_to();
608  }
609  break;
610  }
611 
612  return FALSE;
613 }
614 
622 void display_map_doneupdate(int redraw, int notice) {
623  map_updated |= redraw || !notice;
624 }
mapdata_cell
struct MapCell * mapdata_cell(const int x, const int y)
Definition: mapdata.c:135
redraw
static gboolean redraw(gpointer data)
Definition: main.c:129
PixmapInfo::full_icon_width
guint16 full_icon_width
Definition: image.h:51
map_image_size
int map_image_size
Definition: map.c:34
PlayerPosition::x
int x
Definition: client.h:525
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:145
is_at_moveto
bool is_at_moveto()
Definition: mapdata.c:1484
CFG_LT_PIXEL
#define CFG_LT_PIXEL
Definition: client.h:228
ClientSocket::fd
GSocketConnection * fd
Definition: client.h:124
want_offset_x
int want_offset_x
Definition: mapdata.c:92
PixmapInfo::full_icon_height
guint16 full_icon_height
Definition: image.h:51
drawsmooth
static void drawsmooth(cairo_t *cr, int mx, int my, int layer, int picx, int picy)
Definition: map.c:170
gtk_map_redraw
static void gtk_map_redraw()
Definition: map.c:367
move_to_x
int move_to_x
Definition: mapdata.c:39
do_new_image
void do_new_image(guint8 *data, PixmapInfo *pi)
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:396
CONFIG_MAPSCALE
#define CONFIG_MAPSCALE
Definition: client.h:190
MIN
#define MIN(X__, Y__)
Definition: client.h:615
coord_to_tile
static void coord_to_tile(int x, int y, int *dx, int *dy)
Definition: map.c:540
draw_darkness
static void draw_darkness(cairo_t *cr, int nx, int ny, int mx_start, int my_start)
Definition: map.c:317
map_check_resize
void map_check_resize()
Definition: map.c:49
mapdata_can_smooth
bool mapdata_can_smooth(int x, int y, int layer)
Definition: mapdata.c:150
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:115
PlayerPosition::y
int y
Definition: client.h:526
map_notebook
GtkWidget * map_notebook
Definition: map.c:37
CFG_LT_TILE
#define CFG_LT_TILE
Definition: client.h:227
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:420
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)
Definition: map.c:585
time_map_redraw
bool time_map_redraw
Definition: config.c:51
MapCell::heads
struct MapCellLayer heads[MAXLAYERS]
Definition: mapdata.h:57
predict_alpha
int predict_alpha
Definition: config.c:54
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:156
want_offset_y
int want_offset_y
Definition: mapdata.c:93
MapCell::smooth
guint8 smooth[MAXLAYERS]
Definition: mapdata.h:59
LOG
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:111
global_offset_x
int global_offset_x
Definition: mapdata.c:90
PixmapInfo::smooth_face
guint16 smooth_face
Definition: image.h:54
MAP_MAX_SIZE
#define MAP_MAX_SIZE
Definition: client.h:466
CFG_LT_PIXEL_BEST
#define CFG_LT_PIXEL_BEST
Definition: client.h:229
want_config
gint16 want_config[CONFIG_NUMS]
Definition: init.c:41
csocket
ClientSocket csocket
Definition: client.c:70
MapCell::darkness
guint8 darkness
Definition: mapdata.h:60
image.h
mapdata_face_info
gint16 mapdata_face_info(int mx, int my, int layer, int *dx, int *dy)
Definition: mapdata.c:1055
map_draw_layer
static void map_draw_layer(cairo_t *cr, int layer, int pass, int mx_start, int nx, int my_start, int ny, int off_x, int off_y)
Definition: map.c:283
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:499
mapdata_contains
bool mapdata_contains(int x, int y)
Definition: mapdata.c:142
MapCell::need_resmooth
guint8 need_resmooth
Definition: mapdata.h:63
set_move_to
void set_move_to(int dx, int dy)
Definition: mapdata.c:1462
draw_map
void draw_map()
Definition: map.c:477
LOG_ERROR
@ LOG_ERROR
Warning that something definitely didn't work.
Definition: client.h:436
draw_pixmap
static void draw_pixmap(cairo_t *cr, PixmapInfo *pixmap, int ax, int ay, int off_x, int off_y)
Definition: map.c:138
relative_direction
int relative_direction(int dx, int dy)
Definition: map.c:511
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)
Definition: map.c:86
fire_dir
void fire_dir(int dir)
Definition: player.c:129
Face_Information_struct::faceset
guint8 faceset
Definition: client.h:406
map_drawing_area
static GtkWidget * map_drawing_area
Definition: map.c:38
pl_pos
PlayerPosition pl_pos
Definition: mapdata.c:30
use_config
gint16 use_config[CONFIG_NUMS]
Definition: client.h:242
look_at
void look_at(int x, int y)
Definition: player.c:82
MAXLAYERS
#define MAXLAYERS
Definition: mapdata.h:6
PixmapInfo
Definition: image.h:43
run_move_to
void run_move_to()
Definition: mapdata.c:1494
mapcell_darkness
static double mapcell_darkness(int mx, int my)
Definition: map.c:309
update_global_offset
static void update_global_offset()
Definition: map.c:466
window_root
GtkWidget * window_root
Definition: main.c:103
resize_map_window
void resize_map_window(int x, int y)
Definition: map.c:463
CONFIG_MAPHEIGHT
#define CONFIG_MAPHEIGHT
Definition: client.h:202
display_map_doneupdate
void display_map_doneupdate(int redraw, int notice)
Definition: map.c:622
rescale_rgba_data
guint8 * rescale_rgba_data(guint8 *data, int *width, int *height, int scale)
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:433
MapCell::need_update
guint8 need_update
Definition: mapdata.h:61
client_mapsize
void client_mapsize(int width, int height)
Definition: client.c:171
client.h
window_xml
GtkBuilder * window_xml
Definition: main.c:102