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 double mapcell_darkness(int mx, int my) {
309  double opacity = mapdata_cell(mx, my)->darkness / 192.0 * 0.6;
310  if (use_config[CONFIG_FOGWAR] && mapdata_cell(mx, my)->state == FOG) {
311  opacity += 0.2;
312  }
313  return opacity;
314 }
315 
316 static void draw_darkness(cairo_t *cr, int nx, int ny, int mx_start, int my_start) {
321  cairo_surface_t *cst_lm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nx+2, ny+2);
322  cairo_t *cr_lm = cairo_create(cst_lm);
323  for (int x = -1; x <= nx+1; x++) {
324  for (int y = -1; y <= ny+1; y++) {
325  const int dx = MIN(MAX(0, x), nx);
326  const int dy = MIN(MAX(0, y), ny);
327 
328  // Map coordinate to get darkness information from
329  const int mx = mx_start + dx;
330  const int my = my_start + dy;
331 
332  // Destination coordinates on light map
333  const int ax = x + 1;
334  const int ay = y + 1;
335 
336  cairo_rectangle(cr_lm, ax, ay, 1, 1);
337  cairo_set_source_rgba(cr_lm, 0, 0, 0, mapcell_darkness(mx, my));
338  cairo_fill(cr_lm);
339  }
340  }
341  cairo_destroy(cr_lm);
342 
343  // Scale up light map and draw to map.
344  cairo_scale(cr, map_image_size, map_image_size);
345  cairo_translate(cr, -1, -1);
346  cairo_set_source_surface(cr, cst_lm, 0, 0);
347  switch (use_config[CONFIG_LIGHTING]) {
348  case CFG_LT_TILE:
349  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
350  break;
351  case CFG_LT_PIXEL:
352  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
353  break;
354  case CFG_LT_PIXEL_BEST:
355  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST);
356  break;
357  }
358  cairo_paint(cr);
359  cairo_surface_destroy(cst_lm);
360 }
361 
362 // Draw move-to tile.
363 static void draw_move_to(cairo_t *cr, int mx_start, int my_start) {
364  int mx = move_to_x;
365  int my = move_to_y;
366  int x = mx - mx_start;
367  int y = my - my_start;
368  if (!is_at_moveto()) {
369  int sx = x * map_image_size;
370  int sy = y * map_image_size;
371  cairo_rectangle(cr, sx, sy, map_image_size, map_image_size);
372  if (move_to_attack) {
373  cairo_set_source_rgb(cr, 1, 0, 0); // red to attack
374  } else {
375  cairo_set_source_rgb(cr, 1, 1, 0); // yellow to walk
376  }
377  cairo_set_line_width(cr, 2);
378  cairo_stroke(cr);
379  cairo_rectangle(cr, sx + 2, sy + 2, map_image_size - 4, map_image_size - 4);
380  cairo_set_source_rgb(cr, 0, 0, 0); // black
381  cairo_set_line_width(cr, 1);
382  cairo_stroke(cr);
383  }
384 }
385 
389 static void gtk_map_redraw() {
390  if (!map_updated) {
391  return;
392  }
393 
394  GtkAllocation size;
395  gtk_widget_get_allocation(map_drawing_area, &size);
396 
397  // Effective dimensions in pixels, i.e. after adjusting for map scale
398  float scale = use_config[CONFIG_MAPSCALE]/100.0;
399  const double ew = size.width / scale;
400  const double eh = size.height / scale;
401 
402  // Number of tiles to show in x and y dimensions
403  const int nx = (int)ceilf(ew / map_image_size);
404  const int ny = (int)ceilf(eh / map_image_size);
405 
406  // Current viewport dimensions as sent by server, in squares
407  const int vw = use_config[CONFIG_MAPWIDTH];
408  const int vh = use_config[CONFIG_MAPHEIGHT];
409 
410  // The server always centers the player in the viewport. However, if our
411  // drawing area shows more tiles than the viewport, then the player is
412  // no longer centered. Correct that here.
413  const int mx_start = (nx > vw) ? pl_pos.x - (nx - vw)/2 : pl_pos.x;
414  const int my_start = (ny > vh) ? pl_pos.y - (ny - vh)/2 : pl_pos.y;
415 
416  // Create double buffer and associated graphics context.
417  cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ew, eh);
418  cairo_t *cr = cairo_create(cst);
419 
420  // Blank graphics context with a solid black background.
421  cairo_set_source_rgb(cr, 0, 0, 0);
422  cairo_rectangle(cr, 0, 0, ew, eh);
423  cairo_fill(cr);
424 
425  // Set global offset (after blanking background)
426  cairo_translate(cr, global_offset_x, global_offset_y);
427 
428  // Draw layer-by-layer. Drawing cell-by-cell, looping over the layers,
429  // doesn't work because big faces need to be correctly layered on top.
430  for (int layer = 0; layer < MAXLAYERS; layer++) {
431  map_draw_layer(cr, layer, mx_start, nx, my_start, ny);
432  }
433 
434  draw_move_to(cr, mx_start, my_start);
435 
436  if (use_config[CONFIG_LIGHTING] != 0) {
437  draw_darkness(cr, nx, ny, mx_start, my_start);
438  }
439  cairo_destroy(cr);
440 
441  // Copy the double buffer on the map drawing area.
442  cairo_t *map_cr = gdk_cairo_create(gtk_widget_get_window(map_drawing_area));
443  if (use_config[CONFIG_MAPSCALE] != 100) {
444  cairo_scale(map_cr, scale, scale);
445  }
446  cairo_set_source_surface(map_cr, cst, 0, 0);
447  if (use_config[CONFIG_MAPSCALE] % 100 == 0) {
448  cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
449  }
450  cairo_paint(map_cr);
451  cairo_destroy(map_cr);
452 
453  cairo_surface_destroy(cst);
454 }
455 
462 void resize_map_window(int x, int y) {
463 }
464 
465 static void update_global_offset() {
466  int dx, dy;
469  global_offset_x += dx;
470  global_offset_y += dy;
471 }
472 
476 void draw_map() {
477  gint64 t_start, t_end;
478  t_start = g_get_monotonic_time();
479 
481  gtk_map_redraw();
482 
483  t_end = g_get_monotonic_time();
484  gint64 elapsed = t_end - t_start;
485  if (time_map_redraw) {
486  printf("profile/redraw,%"G_GINT64_FORMAT"\n", elapsed);
487  }
488 
489  const unsigned int target_redraw = 100000;
490  const int no_resize_above = 100; // don't resize above this value of mapscale
491  if (elapsed > target_redraw && use_config[CONFIG_MAPSCALE] < no_resize_above) {
492  use_config[CONFIG_MAPSCALE] = MIN(use_config[CONFIG_MAPSCALE] + 5, no_resize_above);
493  LOG(LOG_DEBUG, "draw_map", "Increasing mapscale to %d to reduce draw time below %u us",
494  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:137
PixmapInfo::smooth_face
guint16 smooth_face
Definition: image.h:54
redraw
static gboolean redraw(gpointer data)
Definition: main.c:129
map_image_size
int map_image_size
Definition: map.c:34
PixmapInfo::icon_width
guint16 icon_width
Definition: image.h:47
ClientSocket::fd
GSocketConnection * fd
Definition: client.h:124
PixmapInfo::icon_height
guint16 icon_height
Definition: image.h:47
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:1479
CFG_LT_PIXEL
#define CFG_LT_PIXEL
Definition: client.h:228
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)
Definition: map.c:169
gtk_map_redraw
static void gtk_map_redraw()
Definition: map.c:389
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
PixmapInfo
Definition: image.h:43
PlayerPosition::x
int x
Definition: client.h:525
map_check_resize
void map_check_resize()
Definition: map.c:49
face_info
Face_Information face_info
Definition: image.c:169
CONFIG_FOGWAR
#define CONFIG_FOGWAR
Definition: client.h:188
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:316
draw_move_to
static void draw_move_to(cairo_t *cr, int mx_start, int my_start)
Definition: map.c:363
mapdata_can_smooth
bool mapdata_can_smooth(int x, int y, int layer)
Definition: mapdata.c:152
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
map_notebook
GtkWidget * map_notebook
Definition: map.c:37
MapCell::smooth
guint8 smooth[MAXLAYERS]
Definition: mapdata.h:66
CFG_LT_TILE
#define CFG_LT_TILE
Definition: client.h:227
mapdata.h
global_offset_y
int global_offset_y
Definition: mapdata.c:91
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
map_draw_layer
static void map_draw_layer(cairo_t *cr, int layer, int mx_start, int nx, int my_start, int ny)
Definition: map.c:282
predict_alpha
int predict_alpha
Definition: config.c:54
MapCell::heads
struct MapCellLayer heads[MAXLAYERS]
Definition: mapdata.h:64
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
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
draw_pixmap
static void draw_pixmap(cairo_t *cr, PixmapInfo *pixmap, int ax, int ay)
Definition: map.c:137
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
image.h
mapdata_face_info
gint16 mapdata_face_info(int mx, int my, int layer, int *dx, int *dy)
Definition: mapdata.c:1050
image_size
int image_size
Definition: image.c:30
Face_Information_struct::facesets
FaceSets facesets[MAX_FACE_SETS]
Definition: client.h:420
MapCellLayer::face
gint16 face
Definition: mapdata.h:19
FaceSets_struct::size
char * size
Definition: client.h:396
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:144
FOG
@ FOG
Definition: mapdata.h:46
PlayerPosition::y
int y
Definition: client.h:526
set_move_to
void set_move_to(int dx, int dy)
Definition: mapdata.c:1457
draw_map
void draw_map()
Definition: map.c:476
LOG_ERROR
@ LOG_ERROR
Warning that something definitely didn't work.
Definition: client.h:436
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
map_init
void map_init(GtkWidget *window_root)
Definition: map.c:86
fire_dir
void fire_dir(int dir)
Definition: player.c:129
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
run_move_to
void run_move_to()
Definition: mapdata.c:1489
mapcell_darkness
static double mapcell_darkness(int mx, int my)
Definition: map.c:308
update_global_offset
static void update_global_offset()
Definition: map.c:465
window_root
GtkWidget * window_root
Definition: main.c:103
resize_map_window
void resize_map_window(int x, int y)
Definition: map.c:462
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
map_updated
static gboolean map_updated
Definition: map.c:35
Face_Information_struct::faceset
guint8 faceset
Definition: client.h:406
MapCell::darkness
guint8 darkness
Definition: mapdata.h:67
LOG_DEBUG
@ LOG_DEBUG
Useful debugging information.
Definition: client.h:433
client_mapsize
void client_mapsize(int width, int height)
Definition: client.c:171
client.h
PixmapInfo::map_image
void * map_image
Definition: image.h:53
window_xml
GtkBuilder * window_xml
Definition: main.c:102