Crossfire Client, Branches  R11627
mapdata.c
Go to the documentation of this file.
1 /* $Id: mapdata.c 10973 2008-12-14 08:51:26Z ryo_saeba $ */
2 /*
3  Crossfire client, a client program for the crossfire program.
4 
5  Copyright (C) 2005 Mark Wedel & Crossfire Development Team
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  The author can be reached via e-mail to crossfire-devel@real-time.com
22 */
23 
24 #include <assert.h>
25 #include <stdlib.h>
26 
27 #include "client.h"
28 #include "external.h"
29 #include "mapdata.h"
30 
31 
35 #define CLEAR_CELLS(x, y, len_y) \
36 do { \
37  int clear_cells_i, j; \
38  memset(&the_map.cells[(x)][(y)], 0, sizeof(the_map.cells[(x)][(y)])*(len_y)); \
39  for (clear_cells_i = 0; clear_cells_i < (len_y); clear_cells_i++) \
40  { \
41  for (j=0; j < MAXLAYERS; j++) { \
42  the_map.cells[(x)][(y)+clear_cells_i].heads[j].size_x = 1; \
43  the_map.cells[(x)][(y)+clear_cells_i].heads[j].size_y = 1; \
44  } \
45  } \
46 } while(0)
47 
48 
52 #define FOG_MAP_SIZE 512
53 
58 #define FOG_BORDER_MIN 128
59 
63 #define MAX_FACE_SIZE 16
64 
65 /* Max it can currently be. Important right now because
66  * animation has to look at everything that may be viewable,
67  * and reducing this size basically reduces processing it needs
68  * to do by 75% (64^2 vs 33^2)
69  */
70 #define CURRENT_MAX_VIEW 33
71 
85 struct BigCell {
86  struct BigCell *next;
87  struct BigCell *prev;
88 
91 
94 };
95 
96 
97 static void recenter_virtual_map_view(int diff_x, int diff_y);
98 static void mapdata_get_image_size(int face, uint8 *w, uint8 *h);
99 
100 
104 static int width, height;
105 
106 
111 static struct BigCell *bigfaces_head;
112 
119 
120 
121 struct Map the_map;
122 
123 
132 static void set_darkness(int x, int y, int darkness)
133 {
134  the_map.cells[x][y].have_darkness = 1;
135  if (the_map.cells[x][y].darkness == darkness) {
136  return;
137  }
138 
139  the_map.cells[x][y].darkness = darkness;
140  the_map.cells[x][y].need_update = 1;
141 
142  /* pretty ugly - since the light code with pngximage uses neighboring
143  * spaces to adjust the darkness, we now need to let the neighbors know
144  * they should update their darkness now.
145  */
149  if (x > 1) the_map.cells[x-1][y].need_update = 1;
150  if (y > 1) the_map.cells[x][y-1].need_update = 1;
151  if (x < width-1) the_map.cells[x+1][y].need_update = 1;
152  if (y < height-1) the_map.cells[x][y+1].need_update = 1;
153  }
154 }
155 
156 static void mark_resmooth(int x, int y, int layer){
157  int sdx,sdy;
158  if (the_map.cells[x][y].smooth[layer]>1){
159  for (sdx=-1;sdx<2;sdx++)
160  for (sdy=-1;sdy<2;sdy++)
161  if ( (sdx || sdy) /* ignore (0,0) */
162  && ( (x+sdx >0) && (x+sdx < FOG_MAP_SIZE) && /* only inside map */
163  (y+sdy >0) && (y+sdy < FOG_MAP_SIZE) ) )
164  the_map.cells[x+sdx][y+sdy].need_resmooth=1;
165  }
166 }
175 static void expand_clear_face(int x, int y, int w, int h, int layer)
176 {
177  int dx, dy;
178  struct MapCell *cell;
179 
180  assert(0 <= x && x < FOG_MAP_SIZE);
181  assert(0 <= y && y < FOG_MAP_SIZE);
182  assert(1 <= w && w <= MAX_FACE_SIZE);
183  assert(1 <= h && h <= MAX_FACE_SIZE);
184 
185  assert(0 <= x-w+1 && x-w+1 < FOG_MAP_SIZE);
186  assert(0 <= y-h+1 && y-h+1 < FOG_MAP_SIZE);
187 
188  cell = &the_map.cells[x][y];
189 
190  for (dx = 0; dx < w; dx++) {
191  for (dy = !dx; dy < h; dy++) {
192  struct MapCellLayer *tail = &the_map.cells[x-dx][y-dy].tails[layer];
193  assert(0 <= x-dx && x-dx < FOG_MAP_SIZE);
194  assert(0 <= y-dy && y-dy < FOG_MAP_SIZE);
195  assert(0 <= layer && layer < MAXLAYERS);
196 
197  /* Do not clear faces that already have been overwritten by another
198  * face.
199  */
200  if (tail->face == cell->heads[layer].face
201  && tail->size_x == dx
202  && tail->size_y == dy) {
203  tail->face = 0;
204  tail->size_x = 0;
205  tail->size_y = 0;
206  the_map.cells[x-dx][y-dy].need_update = 1;
207  }
208  mark_resmooth(x-dx,y-dy,layer);
209  }
210  }
211 
212  cell->heads[layer].face = 0;
213  cell->heads[layer].animation = 0;
214  cell->heads[layer].animation_speed = 0;
215  cell->heads[layer].animation_left = 0;
216  cell->heads[layer].animation_phase = 0;
217  cell->heads[layer].size_x = 1;
218  cell->heads[layer].size_y = 1;
219  cell->need_update = 1;
220  cell->need_resmooth = 1;
221  mark_resmooth(x,y,layer);
222 }
223 
230 static void expand_clear_face_from_layer(int x, int y, int layer)
231 {
232  const struct MapCellLayer *cell;
233 
234  assert(0 <= x && x < FOG_MAP_SIZE);
235  assert(0 <= y && y < FOG_MAP_SIZE);
236  assert(0 <= layer && layer < MAXLAYERS);
237 
238  cell = &the_map.cells[x][y].heads[layer];
239  if (cell->size_x && cell->size_y)
240  expand_clear_face(x, y, cell->size_x, cell->size_y, layer);
241 }
242 
256 static void expand_set_face(int x, int y, int layer, sint16 face, int clear)
257 {
258  struct MapCell *cell;
259  int dx, dy;
260  uint8 w, h;
261 
262  assert(0 <= x && x < FOG_MAP_SIZE);
263  assert(0 <= y && y < FOG_MAP_SIZE);
264  assert(0 <= layer && layer < MAXLAYERS);
265 
266  cell = &the_map.cells[x][y];
267 
268  if (clear)
269  expand_clear_face_from_layer(x, y, layer);
270 
271  mapdata_get_image_size(face, &w, &h);
272  assert(1 <= w && w <= MAX_FACE_SIZE);
273  assert(1 <= h && h <= MAX_FACE_SIZE);
274  cell->heads[layer].face = face;
275  cell->heads[layer].size_x = w;
276  cell->heads[layer].size_y = h;
277  cell->need_update=1;
278  mark_resmooth(x,y,layer);
279 
280  for (dx = 0; dx < w; dx++) {
281  for (dy = !dx; dy < h; dy++) {
282  struct MapCellLayer *tail = &the_map.cells[x-dx][y-dy].tails[layer];
283  assert(0 <= x-dx && x-dx < FOG_MAP_SIZE);
284  assert(0 <= y-dy && y-dy < FOG_MAP_SIZE);
285  assert(0 <= layer && layer < MAXLAYERS);
286 
287  tail->face = face;
288  tail->size_x = dx;
289  tail->size_y = dy;
290  the_map.cells[x-dx][y-dy].need_update = 1;
291  mark_resmooth(x-dx,y-dy,layer);
292  }
293  }
294 }
295 
306 static void expand_clear_bigface(int x, int y, int w, int h, int layer, int set_need_update)
307 {
308  int dx, dy;
309  struct MapCellLayer *head;
310 
311  assert(0 <= x && x < MAX_VIEW);
312  assert(0 <= y && y < MAX_VIEW);
313  assert(1 <= w && w <= MAX_FACE_SIZE);
314  assert(1 <= h && h <= MAX_FACE_SIZE);
315 
316  head = &bigfaces[x][y][layer].head;
317 
318  for (dx = 0; dx < w && dx <= x; dx++) {
319  for (dy = !dx; dy < h && dy <= y; dy++) {
320  struct MapCellLayer *tail = &bigfaces[x-dx][y-dy][layer].tail;
321  assert(0 <= x-dx && x-dx < MAX_VIEW);
322  assert(0 <= y-dy && y-dy < MAX_VIEW);
323  assert(0 <= layer && layer < MAXLAYERS);
324 
325  /* Do not clear faces that already have been overwritten by another
326  * face.
327  */
328  if (tail->face == head->face
329  && tail->size_x == dx
330  && tail->size_y == dy) {
331  tail->face = 0;
332  tail->size_x = 0;
333  tail->size_y = 0;
334 
335  if (0 <= x-dx && x-dx < width
336  && 0 <= y-dy && y-dy < height) {
337  assert(0 <= pl_pos.x+x-dx && pl_pos.x+x-dx < FOG_MAP_SIZE);
338  assert(0 <= pl_pos.y+y-dy && pl_pos.y+y-dy < FOG_MAP_SIZE);
339  if (set_need_update) {
340  the_map.cells[pl_pos.x+x-dx][pl_pos.y+y-dy].need_update = 1;
341  }
342  }
343  }
344  }
345  }
346 
347  head->face = 0;
348  head->size_x = 1;
349  head->size_y = 1;
350 }
351 
360 static void expand_clear_bigface_from_layer(int x, int y, int layer, int set_need_update)
361 {
362  struct BigCell *headcell;
363  const struct MapCellLayer *head;
364 
365  assert(0 <= x && x < MAX_VIEW);
366  assert(0 <= y && y < MAX_VIEW);
367  assert(0 <= layer && layer < MAXLAYERS);
368 
369  headcell = &bigfaces[x][y][layer];
370  head = &headcell->head;
371  if (head->face != 0) {
372  assert(headcell->prev != NULL || headcell == bigfaces_head);
373 
374  /* remove from bigfaces_head list */
375  if (headcell->prev != NULL) headcell->prev->next = headcell->next;
376  if (headcell->next != NULL) headcell->next->prev = headcell->prev;
377  if (bigfaces_head == headcell) {
378  assert(headcell->prev == NULL);
379  bigfaces_head = headcell->next;
380  }
381  else {
382  assert(headcell->prev != NULL);
383  }
384  headcell->prev = NULL;
385  headcell->next = NULL;
386 
387  expand_clear_bigface(x, y, head->size_x, head->size_y, layer, set_need_update);
388  }
389  else {
390  assert(headcell->prev == NULL && headcell != bigfaces_head);
391  assert(head->size_x == 1);
392  assert(head->size_y == 1);
393  }
394 }
395 
404 static void expand_set_bigface(int x, int y, int layer, sint16 face, int clear)
405 {
406  struct BigCell *headcell;
407  struct MapCellLayer *head;
408  int dx, dy;
409  uint8 w, h;
410 
411  assert(0 <= x && x < MAX_VIEW);
412  assert(0 <= y && y < MAX_VIEW);
413  assert(0 <= layer && layer < MAXLAYERS);
414 
415  headcell = &bigfaces[x][y][layer];
416  head = &headcell->head;
417  if (clear)
418  expand_clear_bigface_from_layer(x, y, layer, 1);
419 
420  /* add to bigfaces_head list */
421  if (face != 0) {
422  assert(headcell->prev == NULL);
423  assert(headcell->next == NULL);
424  assert(headcell != bigfaces_head);
425  if (bigfaces_head != NULL) {
426  assert(bigfaces_head->prev == NULL);
427  bigfaces_head->prev = headcell;
428  }
429  headcell->next = bigfaces_head;
430  bigfaces_head = headcell;
431  }
432 
433  mapdata_get_image_size(face, &w, &h);
434  assert(1 <= w && w <= MAX_FACE_SIZE);
435  assert(1 <= h && h <= MAX_FACE_SIZE);
436  head->face = face;
437  head->size_x = w;
438  head->size_y = h;
439 
440  for (dx = 0; dx < w && dx <= x; dx++) {
441  for (dy = !dx; dy < h && dy <= y; dy++) {
442  struct MapCellLayer *tail = &bigfaces[x-dx][y-dy][layer].tail;
443  assert(0 <= x-dx && x-dx < MAX_VIEW);
444  assert(0 <= y-dy && y-dy < MAX_VIEW);
445  assert(0 <= layer && layer < MAXLAYERS);
446 
447  tail->face = face;
448  tail->size_x = dx;
449  tail->size_y = dy;
450 
451  if (0 <= x-dx && x-dx < width
452  && 0 <= y-dy && y-dy < height) {
453  assert(0 <= pl_pos.x+x-dx && pl_pos.x+x-dx < FOG_MAP_SIZE);
454  assert(0 <= pl_pos.y+y-dy && pl_pos.y+y-dy < FOG_MAP_SIZE);
455  the_map.cells[pl_pos.x+x-dx][pl_pos.y+y-dy].need_update = 1;
456  }
457  }
458  }
459 }
460 
468 static void expand_need_update(int x, int y, int w, int h)
469 {
470  int dx, dy;
471 
472  assert(0 <= x && x < FOG_MAP_SIZE);
473  assert(0 <= y && y < FOG_MAP_SIZE);
474  assert(1 <= w && w <= MAX_FACE_SIZE);
475  assert(1 <= h && h <= MAX_FACE_SIZE);
476 
477  assert(0 <= x-w+1 && x-w+1 < FOG_MAP_SIZE);
478  assert(0 <= y-h+1 && y-h+1 < FOG_MAP_SIZE);
479 
480  for (dx = 0; dx < w; dx++) {
481  for (dy = 0; dy < h; dy++) {
482  struct MapCell *cell = &the_map.cells[x-dx][y-dy];
483  assert(0 <= x-dx && x-dx < FOG_MAP_SIZE);
484  assert(0 <= y-dy && y-dy < FOG_MAP_SIZE);
485  cell->need_update = 1;
486  }
487  }
488 }
489 
496 static void expand_need_update_from_layer(int x, int y, int layer)
497 {
498  struct MapCellLayer *head;
499 
500  assert(0 <= x && x < FOG_MAP_SIZE);
501  assert(0 <= y && y < FOG_MAP_SIZE);
502  assert(0 <= layer && layer < MAXLAYERS);
503 
504  head = &the_map.cells[x][y].heads[layer];
505  if (head->face != 0) {
506  expand_need_update(x, y, head->size_x, head->size_y);
507  }
508  else {
509  assert(head->size_x == 1);
510  assert(head->size_y == 1);
511  }
512 }
513 
514 void mapdata_init(void)
515 {
516  int x, y;
517  int i;
518 
519  if (the_map.cells == NULL) {
520  the_map.cells = malloc(
521  sizeof(*the_map.cells)*FOG_MAP_SIZE+
523  if (the_map.cells == NULL) {
524  LOG(LOG_ERROR, "mapdata_init", "%s\n", "out of memory");
525  exit(1);
526  }
527 
528  /* Skip past the first row of pointers to rows and assign the
529  * start of the actual map data
530  */
531  the_map.cells[0] = (struct MapCell *)((char *)the_map.cells+(sizeof(struct MapCell *)*FOG_MAP_SIZE));
532 
533  /* Finish assigning the beginning of each row relative to the
534  * first row assigned above
535  */
536  for (i = 0; i < FOG_MAP_SIZE; i++) {
538  }
541  }
542 
543  width = 0;
544  height = 0;
545  pl_pos.x = FOG_MAP_SIZE/2-width/2;
546  pl_pos.y = FOG_MAP_SIZE/2-height/2;
547 
548  for (x = 0; x < FOG_MAP_SIZE; x++) {
549  CLEAR_CELLS(x, 0, FOG_MAP_SIZE);
550  }
551 
552  for (y = 0; y < MAX_VIEW; y++) {
553  for (x = 0; x < MAX_VIEW; x++) {
554  for (i = 0; i < MAXLAYERS; i++) {
555  bigfaces[x][y][i].next = NULL;
556  bigfaces[x][y][i].prev = NULL;
557  bigfaces[x][y][i].head.face = 0;
558  bigfaces[x][y][i].head.size_x = 1;
559  bigfaces[x][y][i].head.size_y = 1;
560  bigfaces[x][y][i].tail.face = 0;
561  bigfaces[x][y][i].tail.size_x = 0;
562  bigfaces[x][y][i].tail.size_y = 0;
563  bigfaces[x][y][i].x = x;
564  bigfaces[x][y][i].y = y;
565  bigfaces[x][y][i].layer = i;
566  }
567  }
568  }
569  bigfaces_head = NULL;
570 }
571 
572 void mapdata_reset(void)
573 {
574  mapdata_init();
575 }
576 
577 void mapdata_set_size(int viewx, int viewy)
578 {
579  mapdata_init();
580 
581  width = viewx;
582  height = viewy;
583  pl_pos.x = FOG_MAP_SIZE/2-width/2;
584  pl_pos.y = FOG_MAP_SIZE/2-height/2;
585 }
586 
587 int mapdata_is_inside(int x, int y)
588 {
589  return(x >= 0 && x < width && y >= 0 && y < height);
590 }
591 
592 /* mapdate_clear_space() is used by Map2Cmd()
593  * Basically, server has told us there is nothing on
594  * this space. So clear it.
595  */
596 void mapdata_clear_space(int x, int y)
597 {
598  int px, py;
599  int i;
600 
601  assert(0 <= x && x < MAX_VIEW);
602  assert(0 <= y && y < MAX_VIEW);
603 
604  px = pl_pos.x+x;
605  py = pl_pos.y+y;
606  assert(0 <= px && px < FOG_MAP_SIZE);
607  assert(0 <= py && py < FOG_MAP_SIZE);
608 
609  if (x < width && y < height) {
610  /* tile is visible */
611 
612  /* visible tile is now blank ==> do not clear but mark as cleared */
613  if (!the_map.cells[px][py].cleared) {
614  the_map.cells[px][py].cleared = 1;
615  the_map.cells[px][py].need_update = 1;
616 
617  for (i=0; i < MAXLAYERS; i++)
618  if (the_map.cells[px][py].heads[i].face)
620  }
621  }
622  else {
623  /* tile is invisible (outside view area, i.e. big face update) */
624 
625  for (i = 0; i < MAXLAYERS; i++) {
626  expand_set_bigface(x, y, i, 0, TRUE);
627  }
628  }
629 }
630 
631 
632 /* With map2, we basically process a piece of data at a time. Thus,
633  * for each piece, we don't know what the final state of the space
634  * will be. So once Map2Cmd() has processed all the information for
635  * a space, it calls mapdata_set_check_space() which can see if
636  * the space is cleared or other inconsistencies.
637  */
638 void mapdata_set_check_space(int x, int y)
639 {
640  int px, py;
641  int is_blank;
642  int i;
643  struct MapCell *cell;
644 
645  assert(0 <= x && x < MAX_VIEW);
646  assert(0 <= y && y < MAX_VIEW);
647 
648  px = pl_pos.x+x;
649  py = pl_pos.y+y;
650 
651  assert(0 <= px && px < FOG_MAP_SIZE);
652  assert(0 <= py && py < FOG_MAP_SIZE);
653 
654 
655  is_blank=1;
656  cell = &the_map.cells[px][py];
657  for (i=0; i < MAXLAYERS; i++) {
658  if (cell->heads[i].face>0 || cell->tails[i].face>0) {
659  is_blank=0;
660  break;
661  }
662  }
663 
664  if (cell->have_darkness) is_blank=0;
665 
666  /* We only care if this space needs to be blanked out */
667  if (!is_blank) return;
668 
669  if (x < width && y < height) {
670  /* tile is visible */
671 
672  /* visible tile is now blank ==> do not clear but mark as cleared */
673  if (!the_map.cells[px][py].cleared) {
674  the_map.cells[px][py].cleared = 1;
675  the_map.cells[px][py].need_update = 1;
676 
677  for (i=0; i < MAXLAYERS; i++)
679  }
680  }
681 }
682 
683 
684 
685 /* This just sets the darkness for a space.
686  * Used by Map2Cmd()
687  */
688 void mapdata_set_darkness(int x, int y, int darkness)
689 {
690  int px, py;
691 
692  assert(0 <= x && x < MAX_VIEW);
693  assert(0 <= y && y < MAX_VIEW);
694 
695  px = pl_pos.x+x;
696  py = pl_pos.y+y;
697  assert(0 <= px && px < FOG_MAP_SIZE);
698  assert(0 <= py && py < FOG_MAP_SIZE);
699 
700  /* Ignore darkness information for tile outside the viewable area: if
701  * such a tile becomes visible again, it is either "fog of war" (and
702  * darkness information is ignored) or it will be updated (including
703  * the darkness information).
704  */
705  if (darkness != -1 && x < width && y < height) {
706  set_darkness(px, py, 255-darkness);
707  }
708 }
709 
710 /* Sets smooth information for layer */
711 void mapdata_set_smooth(int x, int y, int smooth, int layer)
712 {
713  static int dx[8]={0,1,1,1,0,-1,-1,-1};
714  static int dy[8]={-1,-1,0,1,1,1,0,-1};
715  int rx, ry, px, py, i;
716 
717  assert(0 <= x && x < MAX_VIEW);
718  assert(0 <= y && y < MAX_VIEW);
719 
720  px = pl_pos.x+x;
721  py = pl_pos.y+y;
722  assert(0 <= px && px < FOG_MAP_SIZE);
723  assert(0 <= py && py < FOG_MAP_SIZE);
724 
725  if (the_map.cells[px][py].smooth[layer] != smooth) {
726  for (i=0;i<8;i++){
727  rx=px+dx[i];
728  ry=py+dy[i];
729  if ( (rx<0) || (ry<0) || (the_map.x<=rx) || (the_map.y<=ry))
730  continue;
731  the_map.cells[rx][ry].need_resmooth=1;
732  }
733  the_map.cells[px][py].need_resmooth=1;
734  the_map.cells[px][py].smooth[layer] = smooth;
735  }
736 }
737 
738 /* If old cell data is set and is to be cleared, clear it.
739  * This used to be in mapdata_set_face_layer(), however it needs to be
740  * called here, earlier in the Map2Cmd() because otherwise darkness
741  * doesn't work went sent before the layer data when that square was
742  * going to be cleared. This is used by the Map2Cmd()
743  */
744 void mapdata_clear_old(int x, int y) {
745  int px, py;
746  int i;
747 
748  assert(0 <= x && x < MAX_VIEW);
749  assert(0 <= y && y < MAX_VIEW);
750 
751  px = pl_pos.x+x;
752  py = pl_pos.y+y;
753  assert(0 <= px && px < FOG_MAP_SIZE);
754  assert(0 <= py && py < FOG_MAP_SIZE);
755 
756  if (x < width && y < height)
757  if (the_map.cells[px][py].cleared) {
758  for (i=0; i < MAXLAYERS; i++)
759  expand_clear_face_from_layer(px, py, i);
760 
761  the_map.cells[px][py].darkness = 0;
762  the_map.cells[px][py].have_darkness = 0;
763  }
764 }
765 
766 /* This is vaguely related to the mapdata_set_face() above, but rather
767  * than take all the faces, takes 1 face and the layer this face is
768  * on. This is used by the Map2Cmd()
769  */
770 void mapdata_set_face_layer(int x, int y, sint16 face, int layer)
771 {
772  int px, py;
773 
774  assert(0 <= x && x < MAX_VIEW);
775  assert(0 <= y && y < MAX_VIEW);
776 
777  px = pl_pos.x+x;
778  py = pl_pos.y+y;
779  assert(0 <= px && px < FOG_MAP_SIZE);
780  assert(0 <= py && py < FOG_MAP_SIZE);
781 
782  if (x < width && y < height) {
783  the_map.cells[px][py].need_update = 1;
784  if (face >0)
785  expand_set_face(px, py, layer, face, TRUE);
786  else {
787  expand_clear_face_from_layer(px, py, layer);
788  }
789 
790  the_map.cells[px][py].cleared = 0;
791  }
792  else {
793  expand_set_bigface(x, y, layer, face, TRUE);
794  }
795 }
796 
797 
798 /* This is vaguely related to the mapdata_set_face() above, but rather
799  * than take all the faces, takes 1 face and the layer this face is
800  * on. This is used by the Map2Cmd()
801  */
802 void mapdata_set_anim_layer(int x, int y, uint16 anim, uint8 anim_speed, int layer)
803 {
804  int px, py;
805  int i, face, animation, phase, speed_left;
806 
807  assert(0 <= x && x < MAX_VIEW);
808  assert(0 <= y && y < MAX_VIEW);
809 
810  px = pl_pos.x+x;
811  py = pl_pos.y+y;
812  assert(0 <= px && px < FOG_MAP_SIZE);
813  assert(0 <= py && py < FOG_MAP_SIZE);
814 
815  animation = anim & ANIM_MASK;
816  face = 0;
817 
818  /* Random animation is pretty easy */
819  if ((anim & ANIM_FLAGS_MASK) == ANIM_RANDOM) {
820  phase = random() % animations[animation].num_animations;
821  face = animations[animation].faces[phase];
822  speed_left = anim_speed % random();
823  } else if ((anim & ANIM_FLAGS_MASK) == ANIM_SYNC) {
824  animations[animation].speed = anim_speed;
825  phase = animations[animation].phase;
826  speed_left = animations[animation].speed_left;
827  face = animations[animation].faces[phase];
828  }
829 
830  if (x < width && y < height) {
831  the_map.cells[px][py].need_update = 1;
832  if (the_map.cells[px][py].cleared) {
833  for (i=0; i < MAXLAYERS; i++)
834  expand_clear_face_from_layer(px, py, i);
835 
836  the_map.cells[px][py].darkness = 0;
837  the_map.cells[px][py].have_darkness = 0;
838  }
839  if (face >0) {
840  expand_set_face(px, py, layer, face, TRUE);
841  the_map.cells[px][py].heads[layer].animation = animation;
842  the_map.cells[px][py].heads[layer].animation_phase = phase;
843  the_map.cells[px][py].heads[layer].animation_speed = anim_speed;
844  the_map.cells[px][py].heads[layer].animation_left = speed_left;
845  }
846  else {
847  expand_clear_face_from_layer(px, py, layer);
848  }
849 
850  the_map.cells[px][py].cleared = 0;
851 
852  }
853  else {
854  expand_set_bigface(x, y, layer, face, TRUE);
855  }
856 }
857 
858 
859 void mapdata_scroll(int dx, int dy)
860 {
861  int x, y;
862 
864 
866  struct BigCell *cell;
867 
868  /* Mark all tiles as "need_update" that are overlapped by a big face
869  * from outside the view area.
870  */
871  for (cell = bigfaces_head; cell != NULL; cell = cell->next) {
872  for (x = 0; x < cell->head.size_x; x++) {
873  for (y = !x; y < cell->head.size_y; y++) {
874  if (0 <= cell->x-x && cell->x-x < width
875  && 0 <= cell->y-y && cell->y-y < height) {
876  the_map.cells[pl_pos.x+cell->x-x][pl_pos.y+cell->y-y].need_update = 1;
877  }
878  }
879  }
880  }
881  }
882  else {
883  /* Emulate map scrolling by redrawing all tiles. */
884  for (x = 0; x < width; x++) {
885  for (y = 0; y < height; y++) {
887  }
888  }
889  }
890 
891  pl_pos.x += dx;
892  pl_pos.y += dy;
893 
894  /* clear all newly visible tiles */
895  if (dx > 0) {
896  for (y = 0; y < height; y++) {
897  for (x = width-dx; x < width; x++) {
900  }
901  }
902  }
903  else {
904  for (y = 0; y < height; y++) {
905  for (x = 0; x < -dx; x++) {
908  }
909  }
910  }
911 
912  if (dy > 0) {
913  for (x = 0; x < width; x++) {
914  for (y = height-dy; y < height; y++) {
917  }
918  }
919  }
920  else {
921  for (x = 0; x < width; x++) {
922  for (y = 0; y < -dy; y++) {
925  }
926  }
927  }
928 
929  /* Remove all big faces outside the view area. */
930  while (bigfaces_head != NULL) {
931  expand_clear_bigface_from_layer(bigfaces_head->x, bigfaces_head->y, bigfaces_head->layer, 0);
932  }
933 }
934 
935 void mapdata_newmap(void)
936 {
937  int x, y;
938 
939  /* Clear the_map.cells[]. */
940  for (x = 0; x < FOG_MAP_SIZE; x++) {
941  CLEAR_CELLS(x, 0, FOG_MAP_SIZE);
942  for (y = 0; y < FOG_MAP_SIZE; y++) {
943  the_map.cells[x][y].need_update = 1;
944  }
945  }
946 
947  /* Clear bigfaces[]. */
948  while (bigfaces_head != NULL) {
949  expand_clear_bigface_from_layer(bigfaces_head->x, bigfaces_head->y, bigfaces_head->layer, 0);
950  }
951 
953 }
954 
955 sint16 mapdata_face(int x, int y, int layer)
956 {
957  if (width <= 0) return(0);
958 
959  assert(0 <= x && x < width);
960  assert(0 <= y && y < height);
961  assert(0 <= layer && layer < MAXLAYERS);
962 
963  return(the_map.cells[pl_pos.x+x][pl_pos.y+y].heads[layer].face);
964 }
965 
966 sint16 mapdata_bigface(int x, int y, int layer, int *ww, int *hh)
967 {
968  sint16 result;
969 
970  if (width <= 0) return(0);
971 
972  assert(0 <= x && x < width);
973  assert(0 <= y && y < height);
974  assert(0 <= layer && layer < MAXLAYERS);
975 
976  result = the_map.cells[pl_pos.x+x][pl_pos.y+y].tails[layer].face;
977  if (result != 0) {
978  int clear_bigface;
979  int dx = the_map.cells[pl_pos.x+x][pl_pos.y+y].tails[layer].size_x;
980  int dy = the_map.cells[pl_pos.x+x][pl_pos.y+y].tails[layer].size_y;
981  int w = the_map.cells[pl_pos.x+x+dx][pl_pos.y+y+dy].heads[layer].size_x;
982  int h = the_map.cells[pl_pos.x+x+dx][pl_pos.y+y+dy].heads[layer].size_y;
983  assert(1 <= w && w <= MAX_FACE_SIZE);
984  assert(1 <= h && h <= MAX_FACE_SIZE);
985  assert(0 <= dx && dx < w);
986  assert(0 <= dy && dy < h);
987 
988  /* Now check if we are about to display an obsolete big face: such a
989  * face has a cleared ("fog of war") head but the current tile is not
990  * fog of war. Since the server would have sent an appropriate head
991  * tile if it was already valid, just clear the big face and do not
992  * return it.
993  */
994  if (the_map.cells[pl_pos.x+x][pl_pos.y+y].cleared) {
995  /* Current face is a "fog of war" tile ==> do not clear
996  * old information.
997  */
998  clear_bigface = 0;
999  }
1000  else {
1001  if (x+dx < width && y+dy < height) {
1002  /* Clear face if current tile is valid but the
1003  * head is marked as cleared.
1004  */
1005  clear_bigface = the_map.cells[pl_pos.x+x+dx][pl_pos.y+y+dy].cleared;
1006  }
1007  else {
1008  /* Clear face if current tile is valid but the
1009  * head is not set.
1010  */
1011  clear_bigface = bigfaces[x+dx][y+dy][layer].head.face == 0;
1012  }
1013  }
1014 
1015  if (!clear_bigface) {
1016  *ww = w-1-dx;
1017  *hh = h-1-dy;
1018  return(result);
1019  }
1020 
1021  assert(the_map.cells[pl_pos.x+x][pl_pos.y+y].tails[layer].face == result);
1022  expand_clear_face_from_layer(pl_pos.x+x+dx, pl_pos.y+y+dy, layer);
1023  assert(the_map.cells[pl_pos.x+x][pl_pos.y+y].tails[layer].face == 0);
1024  }
1025 
1026  result = bigfaces[x][y][layer].tail.face;
1027  if (result != 0) {
1028  int dx = bigfaces[x][y][layer].tail.size_x;
1029  int dy = bigfaces[x][y][layer].tail.size_y;
1030  int w = bigfaces[x+dx][y+dy][layer].head.size_x;
1031  int h = bigfaces[x+dx][y+dy][layer].head.size_y;
1032  assert(0 <= dx && dx < w);
1033  assert(0 <= dy && dy < h);
1034  *ww = w-1-dx;
1035  *hh = h-1-dy;
1036  return(result);
1037  }
1038 
1039  *ww = 1;
1040  *hh = 1;
1041  return(0);
1042 }
1043 
1044 /* This is used by the opengl logic.
1045  * Basically the opengl code draws the the entire image,
1046  * and doesn't care if if portions are off the edge
1047  * (opengl takes care of that). So basically, this
1048  * function returns only if the head for a space is set,
1049  * otherwise, returns 0 - we don't care about the tails
1050  * or other details really.
1051  */
1052 sint16 mapdata_bigface_head(int x, int y, int layer, int *ww, int *hh)
1053 {
1054  sint16 result;
1055 
1056  if (width <= 0) return(0);
1057 
1058  assert(0 <= x && x < MAX_VIEW);
1059  assert(0 <= y && y < MAX_VIEW);
1060  assert(0 <= layer && layer < MAXLAYERS);
1061 
1062  result = bigfaces[x][y][layer].head.face;
1063  if (result != 0) {
1064  int w = bigfaces[x][y][layer].head.size_x;
1065  int h = bigfaces[x][y][layer].head.size_y;
1066  *ww = w;
1067  *hh = h;
1068  return(result);
1069  }
1070 
1071  *ww = 1;
1072  *hh = 1;
1073  return(0);
1074 }
1075 
1084 static void recenter_virtual_map_view(int diff_x, int diff_y)
1085 {
1086  int new_x, new_y;
1087  int shift_x, shift_y;
1088  int src_x, src_y;
1089  int dst_x, dst_y;
1090  int len_x, len_y;
1091  int sx;
1092  int dx;
1093  int i;
1094 
1095  /* shift player position in virtual map */
1096  new_x = pl_pos.x+diff_x;
1097  new_y = pl_pos.y+diff_y;
1098 
1099  /* determine neccessary amount to shift */
1100 
1101  /* if(new_x < 1) is not possible: a big face may reach up to
1102  * (MAX_FACE_SIZE-1) tiles to the left of pl_pos. Therefore maintain a
1103  * border of at least MAX_FACE_SIZE to the left of the virtual map
1104  * edge.
1105  */
1106  if (new_x < MAX_FACE_SIZE) {
1107  shift_x = FOG_BORDER_MIN+MAX_FACE_SIZE-new_x;
1108  /* This yields: new_x+shift_x == FOG_BORDER_MIN+MAX_FACE_SIZE,
1109  * i.e. left border is FOG_BORDER_MIN+MAX_FACE_SIZE after
1110  * shifting.
1111  */
1112  }
1113  else if (new_x+MAX_VIEW > FOG_MAP_SIZE) {
1114  shift_x = FOG_MAP_SIZE-FOG_BORDER_MIN-MAX_VIEW-new_x;
1115  /* This yields: new_x+shift_x ==
1116  * FOG_MAP_SIZE-FOG_BODER_MIN-MAX_VIEW, i.e. right border is
1117  * FOGBORDER_MIN after shifting.
1118  */
1119  }
1120  else {
1121  shift_x = 0;
1122  }
1123 
1124  /* Same as above but for y. */
1125  if (new_y < MAX_FACE_SIZE) {
1126  shift_y = FOG_BORDER_MIN+MAX_FACE_SIZE-new_y;
1127  }
1128  else if (new_y+MAX_VIEW > FOG_MAP_SIZE) {
1129  shift_y = FOG_MAP_SIZE-FOG_BORDER_MIN-MAX_VIEW-new_y;
1130  }
1131  else {
1132  shift_y = 0;
1133  }
1134 
1135  /* No shift neccessary? ==> nothing to do. */
1136  if (shift_x == 0 && shift_y == 0) {
1137  return;
1138  }
1139 
1140  /* If shifting at all: maintain a border size of FOG_BORDER_MIN to all
1141  * directions. For example: if pl_pos=30/MAX_FACE_SIZE, and map_scroll is
1142  * 0/-1: shift pl_pos to FOG_BORDER_MIN+1/FOG_BORDER_MIN+1, not to
1143  * 30/FOG_BORDER_MIN+1.
1144  */
1145  if (shift_x == 0) {
1146  if (new_x < FOG_BORDER_MIN+MAX_FACE_SIZE) {
1147  shift_x = FOG_BORDER_MIN+MAX_FACE_SIZE-new_x;
1148  }
1149  else if (new_x+MAX_VIEW+FOG_BORDER_MIN > FOG_MAP_SIZE) {
1150  shift_x = FOG_MAP_SIZE-FOG_BORDER_MIN-MAX_VIEW-new_x;
1151  }
1152  }
1153  if (shift_y == 0) {
1154  if (new_y < FOG_BORDER_MIN+MAX_FACE_SIZE) {
1155  shift_y = FOG_BORDER_MIN+MAX_FACE_SIZE-new_y;
1156  }
1157  else if (new_y+MAX_VIEW+FOG_BORDER_MIN > FOG_MAP_SIZE) {
1158  shift_y = FOG_MAP_SIZE-FOG_BORDER_MIN-MAX_VIEW-new_y;
1159  }
1160  }
1161 
1162  /* Shift for more than virtual map size? ==> clear whole virtual map
1163  * and recenter.
1164  */
1165  if (shift_x <= -FOG_MAP_SIZE || shift_x >= FOG_MAP_SIZE
1166  || shift_y <= -FOG_MAP_SIZE || shift_y >= FOG_MAP_SIZE) {
1167  for (dx = 0; dx < FOG_MAP_SIZE; dx++) {
1168  CLEAR_CELLS(dx, 0, FOG_MAP_SIZE);
1169  }
1170 
1171  pl_pos.x = FOG_MAP_SIZE/2-width/2;
1172  pl_pos.y = FOG_MAP_SIZE/2-height/2;
1173  return;
1174  }
1175 
1176  /* Move player position. */
1177  pl_pos.x += shift_x;
1178  pl_pos.y += shift_y;
1179 
1180  /* Actually shift the virtual map by shift_x/shift_y */
1181  if (shift_x < 0) {
1182  src_x = -shift_x;
1183  dst_x = 0;
1184  len_x = FOG_MAP_SIZE+shift_x;
1185  }
1186  else {
1187  src_x = 0;
1188  dst_x = shift_x;
1189  len_x = FOG_MAP_SIZE-shift_x;
1190  }
1191 
1192  if (shift_y < 0) {
1193  src_y = -shift_y;
1194  dst_y = 0;
1195  len_y = FOG_MAP_SIZE+shift_y;
1196  }
1197  else {
1198  src_y = 0;
1199  dst_y = shift_y;
1200  len_y = FOG_MAP_SIZE-shift_y;
1201  }
1202 
1203  if (shift_x < 0) {
1204  for (sx = src_x, dx = dst_x, i = 0; i < len_x; sx++, dx++, i++) {
1205  /* srcx!=dstx ==> can use memcpy since source and
1206  * destination to not overlap.
1207  */
1208  memcpy(&the_map.cells[dx][dst_y], &the_map.cells[sx][src_y], len_y*sizeof(the_map.cells[dx][dst_y]));
1209  }
1210  }
1211  else if (shift_x > 0) {
1212  for (sx = src_x+len_x-1, dx = dst_x+len_x-1, i = 0; i < len_x; sx--, dx--, i++) {
1213  /* srcx!=dstx ==> can use memcpy since source and
1214  * destination to not overlap.
1215  */
1216  memcpy(&the_map.cells[dx][dst_y], &the_map.cells[sx][src_y], len_y*sizeof(the_map.cells[dx][dst_y]));
1217  }
1218  }
1219  else {
1220  assert(src_x == dst_x);
1221  for (dx = src_x, i = 0; i < len_x; dx++, i++) {
1222  /* srcx==dstx ==> use memmove since source and
1223  * destination probably do overlap.
1224  */
1225  memmove(&the_map.cells[dx][dst_y], &the_map.cells[dx][src_y], len_y*sizeof(the_map.cells[dx][dst_y]));
1226  }
1227  }
1228 
1229  /* Clear newly opened area */
1230  for (dx = 0; dx < dst_x; dx++) {
1231  CLEAR_CELLS(dx, 0, FOG_MAP_SIZE);
1232  }
1233  for (dx = dst_x+len_x; dx < FOG_MAP_SIZE; dx++) {
1234  CLEAR_CELLS(dx, 0, FOG_MAP_SIZE);
1235  }
1236  if (shift_y > 0) {
1237  for (dx = 0; dx < len_x; dx++) {
1238  CLEAR_CELLS(dx+dst_x, 0, shift_y);
1239  }
1240  }
1241  else if (shift_y < 0) {
1242  for (dx = 0; dx < len_x; dx++) {
1243  CLEAR_CELLS(dx+dst_x, FOG_MAP_SIZE+shift_y, -shift_y);
1244  }
1245  }
1246 }
1247 
1252 static void mapdata_get_image_size(int face, uint8 *w, uint8 *h)
1253 {
1254  get_map_image_size(face, w, h);
1255  if (*w < 1) *w = 1;
1256  if (*h < 1) *h = 1;
1257  if (*w > MAX_FACE_SIZE) *w = MAX_FACE_SIZE;
1258  if (*h > MAX_FACE_SIZE) *h = MAX_FACE_SIZE;
1259 }
1260 
1261 /* This basically goes through all the map spaces and does the necessary
1262  * animation.
1263  */
1265 {
1266  int x, y, layer, face, smooth;
1267  struct MapCellLayer *cell;
1268 
1269 
1270  /* For synchronized animations, what we do is set the initial values
1271  * in the mapdata to the fields in the animations[] array. In this way,
1272  * the code below the iterates the spaces doesn't need to do anything
1273  * special. But we have to update the animations[] array here to
1274  * keep in sync.
1275  */
1276  for (x=0; x < MAXANIM; x++) {
1277  if (animations[x].speed) {
1278  animations[x].speed_left++;
1279  if (animations[x].speed_left >= animations[x].speed) {
1280  animations[x].speed_left=0;
1281  animations[x].phase++;
1282  if (animations[x].phase >= animations[x].num_animations)
1283  animations[x].phase=0;
1284  }
1285  }
1286  }
1287 
1288  for (x=0; x < CURRENT_MAX_VIEW; x++) {
1289  for (y=0; y < CURRENT_MAX_VIEW; y++) {
1290 
1291  /* Short cut some processing here. It makes sense to me
1292  * not to animate stuff out of view
1293  */
1294  if (the_map.cells[pl_pos.x + x][pl_pos.y + y].cleared) continue;
1295 
1296  for (layer=0; layer<MAXLAYERS; layer++) {
1297  smooth = the_map.cells[pl_pos.x + x][pl_pos.y + y].smooth[layer];
1298 
1299  /* Using the cell structure just makes life easier here */
1300  cell = &the_map.cells[pl_pos.x+x][pl_pos.y+y].heads[layer];
1301 
1302  if (cell->animation) {
1303  cell->animation_left++;
1304  if (cell->animation_left >= cell->animation_speed) {
1305  cell->animation_left=0;
1306  cell->animation_phase++;
1307  if (cell->animation_phase >= animations[cell->animation].num_animations)
1308  cell->animation_phase=0;
1309  face = animations[cell->animation].faces[cell->animation_phase];
1310 
1311  /* I don't think we send any to the client, but it is possible
1312  * for animations to have blank faces.
1313  */
1314  if (face >0) {
1315  expand_set_face(pl_pos.x + x, pl_pos.y + y, layer, face, FALSE);
1316 /* mapdata_set_smooth(x, y, smooth, layer);*/
1317  } else {
1318  expand_clear_face_from_layer(pl_pos.x + x, pl_pos.y + y , layer);
1319  }
1320  }
1321  }
1322  cell = &bigfaces[x][y][layer].head;
1323  if (cell->animation) {
1324  cell->animation_left++;
1325  if (cell->animation_left >= cell->animation_speed) {
1326  cell->animation_left=0;
1327  cell->animation_phase++;
1328  if (cell->animation_phase >= animations[cell->animation].num_animations)
1329  cell->animation_phase=0;
1330  face = animations[cell->animation].faces[cell->animation_phase];
1331 
1332  /* I don't think we send any to the client, but it is possible
1333  * for animations to have blank faces.
1334  */
1335  expand_set_bigface(x, y, layer, face, FALSE);
1336  }
1337  }
1338  }
1339  }
1340  }
1341 }
Animations animations[MAXANIM]
Definition: commands.c:419
uint8 layer
Definition: mapdata.c:93
signed short sint16
Definition: client-types.h:80
static int height
Definition: mapdata.c:104
int y
Definition: mapdata.h:93
void mapdata_set_anim_layer(int x, int y, uint16 anim, uint8 anim_speed, int layer)
Definition: mapdata.c:802
void mapdata_animation(void)
Definition: mapdata.c:1264
#define CLEAR_CELLS(x, y, len_y)
Definition: mapdata.c:35
void mapdata_set_check_space(int x, int y)
Definition: mapdata.c:638
void mapdata_clear_space(int x, int y)
Definition: mapdata.c:596
uint8 animation_left
Definition: mapdata.h:58
sint16 mapdata_bigface_head(int x, int y, int layer, int *ww, int *hh)
Definition: mapdata.c:1052
uint16 y
Definition: mapdata.c:92
void mapdata_reset(void)
Definition: mapdata.c:572
static void expand_clear_face(int x, int y, int w, int h, int layer)
Definition: mapdata.c:175
struct MapCellLayer tails[MAXLAYERS]
Definition: mapdata.h:78
sint16 want_config[CONFIG_NUMS]
Definition: init.c:50
static void expand_need_update(int x, int y, int w, int h)
Definition: mapdata.c:468
uint16 x
Definition: mapdata.c:92
static void expand_set_face(int x, int y, int layer, sint16 face, int clear)
Definition: mapdata.c:256
#define CFG_LT_PIXEL_BEST
Definition: client.h:189
uint8 have_darkness
Definition: mapdata.h:82
void mapdata_newmap(void)
Definition: mapdata.c:935
static void expand_set_bigface(int x, int y, int layer, sint16 face, int clear)
Definition: mapdata.c:404
uint8 need_update
Definition: mapdata.h:81
static void expand_need_update_from_layer(int x, int y, int layer)
Definition: mapdata.c:496
#define CFG_DM_SDL
Definition: client.h:195
sint16 face
Definition: mapdata.h:45
static void recenter_virtual_map_view(int diff_x, int diff_y)
Definition: mapdata.c:1084
static int width
Definition: mapdata.c:104
void display_map_newmap(void)
Definition: gx11.c:5319
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:178
uint8 phase
Definition: client.h:78
#define TRUE
Definition: client-types.h:71
#define FOG_BORDER_MIN
Definition: mapdata.c:58
uint8 speed
Definition: client.h:76
uint8 speed_left
Definition: client.h:77
static struct BigCell * bigfaces_head
Definition: mapdata.c:111
sint8 size_x
Definition: mapdata.h:46
sint16 use_config[CONFIG_NUMS]
Definition: init.c:50
static void mark_resmooth(int x, int y, int layer)
Definition: mapdata.c:156
Definition: mapdata.h:87
sint16 mapdata_face(int x, int y, int layer)
Definition: mapdata.c:955
uint8 darkness
Definition: mapdata.h:80
#define FOG_MAP_SIZE
Definition: mapdata.c:52
#define CFG_LT_PIXEL
Definition: client.h:188
struct MapCellLayer head
Definition: mapdata.c:89
void mapdata_clear_old(int x, int y)
Definition: mapdata.c:744
int display_mapscroll(int dx, int dy)
Definition: map.c:88
uint8 cleared
Definition: mapdata.h:84
struct Map the_map
Definition: mapdata.c:121
static void expand_clear_bigface_from_layer(int x, int y, int layer, int set_need_update)
Definition: mapdata.c:360
void mapdata_init(void)
Definition: mapdata.c:514
struct MapCell ** cells
Definition: mapdata.h:95
#define CONFIG_MAPSCROLL
Definition: client.h:180
void get_map_image_size(int face, uint8 *w, uint8 *h)
Definition: image.c:459
int x
Definition: mapdata.h:92
#define ANIM_FLAGS_MASK
Definition: newclient.h:275
unsigned short uint16
Definition: client-types.h:79
sint16 animation
Definition: mapdata.h:56
static void set_darkness(int x, int y, int darkness)
Definition: mapdata.c:132
uint8 animation_speed
Definition: mapdata.h:57
static void expand_clear_face_from_layer(int x, int y, int layer)
Definition: mapdata.c:230
void mapdata_set_face_layer(int x, int y, sint16 face, int layer)
Definition: mapdata.c:770
static void expand_clear_bigface(int x, int y, int w, int h, int layer, int set_need_update)
Definition: mapdata.c:306
uint8 need_resmooth
Definition: mapdata.h:83
#define MAXLAYERS
Definition: mapdata.h:32
#define ANIM_SYNC
Definition: newclient.h:272
void mapdata_scroll(int dx, int dy)
Definition: mapdata.c:859
uint16 smooth[MAXLAYERS]
Definition: mapdata.h:79
#define CURRENT_MAX_VIEW
Definition: mapdata.c:70
#define ANIM_RANDOM
Definition: newclient.h:271
sint16 mapdata_bigface(int x, int y, int layer, int *ww, int *hh)
Definition: mapdata.c:966
int mapdata_is_inside(int x, int y)
Definition: mapdata.c:587
struct MapCellLayer tail
Definition: mapdata.c:90
struct BigCell * next
Definition: mapdata.c:86
static void mapdata_get_image_size(int face, uint8 *w, uint8 *h)
Definition: mapdata.c:1252
#define MAX_VIEW
Definition: mapdata.h:37
#define CONFIG_DISPLAYMODE
Definition: client.h:161
#define MAX_FACE_SIZE
Definition: mapdata.c:63
unsigned char uint8
Definition: client-types.h:81
struct MapCellLayer heads[MAXLAYERS]
Definition: mapdata.h:77
#define ANIM_MASK
Definition: newclient.h:278
#define MAXANIM
Definition: client.h:63
#define CONFIG_LIGHTING
Definition: client.h:168
static struct BigCell bigfaces[MAX_VIEW][MAX_VIEW][MAXLAYERS]
Definition: mapdata.c:118
#define FALSE
Definition: client-types.h:68
uint8 num_animations
Definition: client.h:73
sint8 size_y
Definition: mapdata.h:47
void mapdata_set_size(int viewx, int viewy)
Definition: mapdata.c:577
uint8 animation_phase
Definition: mapdata.h:59
void mapdata_set_darkness(int x, int y, int darkness)
Definition: mapdata.c:688
PlayerPosition pl_pos
Definition: map.c:69
uint16 * faces
Definition: client.h:79
struct BigCell * prev
Definition: mapdata.c:87
void mapdata_set_smooth(int x, int y, int smooth, int layer)
Definition: mapdata.c:711