~ubuntu-branches/ubuntu/precise/crossfire-client/precise

« back to all changes in this revision

Viewing changes to common/mapdata.c

  • Committer: Bazaar Package Importer
  • Author(s): Kari Pahula
  • Date: 2006-07-06 05:28:42 UTC
  • mfrom: (1.2.4 upstream) (3.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060706052842-gyjncpvl56luk1nd
Tags: 1.9.1-1
* New upstream release
* asound [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386] (Closes: #375398)
* Patched gcfclient2 to make Configure menu option not segfault when no
  existing configuration file is present

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: mapdata.c,v 1.2 2005/09/05 20:16:53 ryo_saeba Exp $ */
 
1
/* $Id: mapdata.c,v 1.4 2006/05/17 17:58:12 ryo_saeba Exp $ */
2
2
/*
3
3
    Crossfire client, a client program for the crossfire program.
4
4
 
31
31
/**
32
32
 * Clear cells the_map.cells[x][y..y+len_y-1].
33
33
 */
34
 
#define CLEAR_CELLS(x, y, len_y) do { \
35
 
    int clear_cells_i; \
 
34
#define CLEAR_CELLS(x, y, len_y) \
 
35
do { \
 
36
    int clear_cells_i, j; \
36
37
    memset(&the_map.cells[(x)][(y)], 0, sizeof(the_map.cells[(x)][(y)])*(len_y)); \
37
38
    for (clear_cells_i = 0; clear_cells_i < (len_y); clear_cells_i++) \
38
39
    { \
39
 
        the_map.cells[(x)][(y)+clear_cells_i].heads[0].size_x = 1; \
40
 
        the_map.cells[(x)][(y)+clear_cells_i].heads[0].size_y = 1; \
41
 
        the_map.cells[(x)][(y)+clear_cells_i].heads[1].size_x = 1; \
42
 
        the_map.cells[(x)][(y)+clear_cells_i].heads[1].size_y = 1; \
43
 
        the_map.cells[(x)][(y)+clear_cells_i].heads[2].size_x = 1; \
44
 
        the_map.cells[(x)][(y)+clear_cells_i].heads[2].size_y = 1; \
 
40
        for (j=0; j < MAXLAYERS; j++) { \
 
41
            the_map.cells[(x)][(y)+clear_cells_i].heads[j].size_x = 1; \
 
42
            the_map.cells[(x)][(y)+clear_cells_i].heads[j].size_y = 1; \
 
43
        } \
45
44
    } \
46
 
    } while(0)
 
45
} while(0)
47
46
 
48
47
 
49
48
/**
67
66
 */
68
67
#define MAX_VIEW 64
69
68
 
 
69
/* Max it can currently be.  Important right now because
 
70
 * animation has to look at everything that may be viewable,
 
71
 * and reducing this size basically reduces processing it needs
 
72
 * to do by 75% (64^2 vs 33^2)
 
73
 */
 
74
#define CURRENT_MAX_VIEW    33
70
75
 
71
76
/**
72
77
 * The struct BigCell describes a tile *outside* the view area. head contains
197
202
    }
198
203
 
199
204
    cell->heads[layer].face = 0;
 
205
    cell->heads[layer].animation = 0;
 
206
    cell->heads[layer].animation_speed = 0;
 
207
    cell->heads[layer].animation_left = 0;
 
208
    cell->heads[layer].animation_phase = 0;
200
209
    cell->heads[layer].size_x = 1;
201
210
    cell->heads[layer].size_y = 1;
202
211
    cell->need_update = 1;
218
227
    assert(0 <= layer && layer < MAXLAYERS);
219
228
 
220
229
    cell = &the_map.cells[x][y].heads[layer];
221
 
    expand_clear_face(x, y, cell->size_x, cell->size_y, layer);
 
230
    if (cell->size_x && cell->size_y) 
 
231
        expand_clear_face(x, y, cell->size_x, cell->size_y, layer);
222
232
}
223
233
 
224
234
/**
228
238
 * pl_pos.
229
239
 *
230
240
 * face is the new face to set.
 
241
 * if clear is set, clear this face.  If not set, don't clear.  the reason
 
242
 * clear may not be set is because this is an animation update - animations
 
243
 * must all be the same size, so when we set the data for the space,
 
244
 * we will just overwrite the old data.  Problem with clearing is that 
 
245
 * clobbers the animation data.
231
246
 */
232
 
static void expand_set_face(int x, int y, int layer, sint16 face)
 
247
static void expand_set_face(int x, int y, int layer, sint16 face, int clear)
233
248
{
234
249
    struct MapCell *cell;
235
250
    int dx, dy;
241
256
 
242
257
    cell = &the_map.cells[x][y];
243
258
 
244
 
    expand_clear_face_from_layer(x, y, layer);
 
259
    if (clear)
 
260
        expand_clear_face_from_layer(x, y, layer);
245
261
 
246
262
    mapdata_get_image_size(face, &w, &h);
247
263
    assert(1 <= w && w <= MAX_FACE_SIZE);
249
265
    cell->heads[layer].face = face;
250
266
    cell->heads[layer].size_x = w;
251
267
    cell->heads[layer].size_y = h;
 
268
    cell->need_update=1;
252
269
 
253
270
    for (dx = 0; dx < w; dx++) {
254
271
        for (dy = !dx; dy < h; dy++) {
373
390
 *
374
391
 * face is the new face to set.
375
392
 */
376
 
static void expand_set_bigface(int x, int y, int layer, sint16 face)
 
393
static void expand_set_bigface(int x, int y, int layer, sint16 face, int clear)
377
394
{
378
395
    struct BigCell *headcell;
379
396
    struct MapCellLayer *head;
386
403
 
387
404
    headcell = &bigfaces[x][y][layer];
388
405
    head = &headcell->head;
389
 
    expand_clear_bigface_from_layer(x, y, layer, 1);
 
406
    if (clear)
 
407
        expand_clear_bigface_from_layer(x, y, layer, 1);
390
408
 
391
409
    /* add to bigfaces_head list */
392
410
    if (face != 0) {
567
585
    int is_blank;
568
586
    int i;
569
587
 
570
 
    assert(MAXLAYERS == 3);
 
588
    assert(MAP1_LAYERS == 3);
571
589
    face[0] = face0;
572
590
    face[1] = face1;
573
591
    face[2] = face2;
601
619
 
602
620
            the_map.cells[px][py].need_update = 1;
603
621
            if (the_map.cells[px][py].cleared) {
604
 
                assert(MAXLAYERS == 3);
605
 
                expand_clear_face_from_layer(px, py, 0);
606
 
                expand_clear_face_from_layer(px, py, 1);
607
 
                expand_clear_face_from_layer(px, py, 2);
 
622
                assert(MAP1_LAYERS == 3);
 
623
                expand_clear_face_from_layer(px, py, 0);
 
624
                expand_clear_face_from_layer(px, py, 1);
 
625
                expand_clear_face_from_layer(px, py, 2);
608
626
                the_map.cells[px][py].darkness = 0;
609
627
                the_map.cells[px][py].have_darkness = 0;
610
628
            }
611
 
            for (i = 0; i < MAXLAYERS; i++) {
 
629
            for (i = 0; i < MAP1_LAYERS; i++) {
612
630
                if (face[i] != -1) {
613
 
                    expand_set_face(px, py, i, face[i]);
 
631
                    expand_set_face(px, py, i, face[i], TRUE);
614
632
                }
615
633
            }
616
634
            the_map.cells[px][py].cleared = 0;
617
 
        }
 
635
            if (darkness != -1)
 
636
                set_darkness(px, py, 255-darkness);
 
637
        }
 
638
    }
 
639
    else {
 
640
        /* tile is invisible (outside view area, i.e. big face update) */
 
641
 
 
642
        for (i = 0; i < MAP1_LAYERS; i++) {
 
643
            if (is_blank || face[i] != -1) {
 
644
                expand_set_bigface(x, y, i, is_blank ? 0 : face[i], TRUE);
 
645
            }
 
646
        }
 
647
    }
 
648
}
 
649
 
 
650
/* mapdate_clear_space() is used by Map2Cmd()
 
651
 * Basically, server has told us there is nothing on
 
652
 * this space.  So clear it.
 
653
 */
 
654
void mapdata_clear_space(int x, int y)
 
655
{
 
656
    int px, py;
 
657
    int i;
 
658
 
 
659
    assert(0 <= x && x < MAX_VIEW);
 
660
    assert(0 <= y && y < MAX_VIEW);
 
661
 
 
662
    px = pl_pos.x+x;
 
663
    py = pl_pos.y+y;
 
664
    assert(0 <= px && px < FOG_MAP_SIZE);
 
665
    assert(0 <= py && py < FOG_MAP_SIZE);
 
666
 
 
667
    if (x < width && y < height) {
 
668
        /* tile is visible */
 
669
 
 
670
        /* visible tile is now blank ==> do not clear but mark as cleared */
 
671
        if (!the_map.cells[px][py].cleared) {
 
672
            the_map.cells[px][py].cleared = 1;
 
673
            the_map.cells[px][py].need_update = 1;
 
674
 
 
675
            for (i=0; i < MAXLAYERS; i++)
 
676
                if (the_map.cells[px][py].heads[i].face)
 
677
                    expand_need_update_from_layer(px, py, i);
 
678
        }
618
679
    }
619
680
    else {
620
681
        /* tile is invisible (outside view area, i.e. big face update) */
621
682
 
622
683
        for (i = 0; i < MAXLAYERS; i++) {
623
 
            if (is_blank || face[i] != -1) {
624
 
                expand_set_bigface(x, y, i, is_blank ? 0 : face[i]);
625
 
            }
626
 
        }
627
 
    }
 
684
            expand_set_bigface(x, y, i, 0, TRUE);
 
685
        }
 
686
    }
 
687
}
 
688
 
 
689
 
 
690
/* With map2, we basically process a piece of data at a time.  Thus,
 
691
 * for each piece, we don't know what the final state of the space
 
692
 * will be.  So once Map2Cmd() has processed all the information for
 
693
 * a space, it calls mapdata_set_check_space() which can see if
 
694
 * the space is cleared or other inconsistencies.
 
695
 */
 
696
void mapdata_set_check_space(int x, int y)
 
697
{
 
698
    int px, py;
 
699
    int is_blank;
 
700
    int i;
 
701
    struct MapCell *cell;
 
702
 
 
703
    assert(0 <= x && x < MAX_VIEW);
 
704
    assert(0 <= y && y < MAX_VIEW);
 
705
 
 
706
    px = pl_pos.x+x;
 
707
    py = pl_pos.y+y;
 
708
 
 
709
    assert(0 <= px && px < FOG_MAP_SIZE);
 
710
    assert(0 <= py && py < FOG_MAP_SIZE);
 
711
 
 
712
 
 
713
    is_blank=1;
 
714
    cell = &the_map.cells[px][py];
 
715
    for (i=0; i < MAXLAYERS; i++) {
 
716
        if (cell->heads[i].face>0 || cell->tails[i].face>0) {
 
717
            is_blank=0;
 
718
            break;
 
719
        }
 
720
    }
 
721
 
 
722
    if (cell->have_darkness) is_blank=0;
 
723
 
 
724
    /* We only care if this space needs to be blanked out */
 
725
    if (!is_blank) return;
 
726
 
 
727
    if (x < width && y < height) {
 
728
        /* tile is visible */
 
729
 
 
730
        /* visible tile is now blank ==> do not clear but mark as cleared */
 
731
        if (!the_map.cells[px][py].cleared) {
 
732
            the_map.cells[px][py].cleared = 1;
 
733
            the_map.cells[px][py].need_update = 1;
 
734
 
 
735
            for (i=0; i < MAXLAYERS; i++)
 
736
                expand_need_update_from_layer(px, py, i);
 
737
        }
 
738
    }
 
739
}
 
740
 
 
741
 
 
742
 
 
743
/* This just sets the darkness for a space.
 
744
 * Used by Map2Cmd()
 
745
 */
 
746
void mapdata_set_darkness(int x, int y, int darkness)
 
747
{
 
748
    int px, py;
 
749
 
 
750
    assert(0 <= x && x < MAX_VIEW);
 
751
    assert(0 <= y && y < MAX_VIEW);
 
752
 
 
753
    px = pl_pos.x+x;
 
754
    py = pl_pos.y+y;
 
755
    assert(0 <= px && px < FOG_MAP_SIZE);
 
756
    assert(0 <= py && py < FOG_MAP_SIZE);
628
757
 
629
758
    /* Ignore darkness information for tile outside the viewable area: if
630
759
     * such a tile becomes visible again, it is either "fog of war" (and
636
765
    }
637
766
}
638
767
 
 
768
/* Sets smooth information for layer */
 
769
void mapdata_set_smooth(int x, int y, int smooth, int layer)
 
770
{
 
771
    static int dx[8]={0,1,1,1,0,-1,-1,-1};
 
772
    static int dy[8]={-1,-1,0,1,1,1,0,-1};
 
773
    int rx, ry, px, py, i;
 
774
 
 
775
    assert(0 <= x && x < MAX_VIEW);
 
776
    assert(0 <= y && y < MAX_VIEW);
 
777
 
 
778
    px = pl_pos.x+x;
 
779
    py = pl_pos.y+y;
 
780
    assert(0 <= px && px < FOG_MAP_SIZE);
 
781
    assert(0 <= py && py < FOG_MAP_SIZE);
 
782
 
 
783
    if (the_map.cells[px][py].smooth[layer] != smooth) {
 
784
        for (i=0;i<8;i++){
 
785
            rx=px+dx[i];
 
786
            ry=py+dy[i];
 
787
            if ( (rx<0) || (ry<0) || (the_map.x<=rx) || (the_map.y<=ry))
 
788
                continue;
 
789
            the_map.cells[rx][ry].need_resmooth=1;
 
790
        }
 
791
        the_map.cells[px][py].need_resmooth=1;
 
792
        the_map.cells[px][py].smooth[layer] = smooth;
 
793
    }
 
794
}
 
795
 
 
796
/* This is vaguely related to the mapdata_set_face() above, but rather
 
797
 * than take all the faces, takes 1 face and the layer this face is
 
798
 * on.  This is used by the Map2Cmd()
 
799
 */
 
800
void mapdata_set_face_layer(int x, int y, sint16 face, int layer)
 
801
{
 
802
    int px, py;
 
803
    int i;
 
804
 
 
805
    assert(0 <= x && x < MAX_VIEW);
 
806
    assert(0 <= y && y < MAX_VIEW);
 
807
 
 
808
    px = pl_pos.x+x;
 
809
    py = pl_pos.y+y;
 
810
    assert(0 <= px && px < FOG_MAP_SIZE);
 
811
    assert(0 <= py && py < FOG_MAP_SIZE);
 
812
 
 
813
    if (x < width && y < height) {
 
814
        the_map.cells[px][py].need_update = 1;
 
815
        if (the_map.cells[px][py].cleared) {
 
816
            for (i=0; i < MAXLAYERS; i++)
 
817
                expand_clear_face_from_layer(px, py, i);
 
818
 
 
819
            the_map.cells[px][py].darkness = 0;
 
820
            the_map.cells[px][py].have_darkness = 0;
 
821
        }
 
822
        if (face >0)
 
823
            expand_set_face(px, py, layer, face, TRUE);
 
824
        else {
 
825
            expand_clear_face_from_layer(px, py, layer);
 
826
        }
 
827
 
 
828
        the_map.cells[px][py].cleared = 0;
 
829
    }
 
830
    else {
 
831
        expand_set_bigface(x, y, layer, face, TRUE);
 
832
    }
 
833
}
 
834
 
 
835
 
 
836
/* This is vaguely related to the mapdata_set_face() above, but rather
 
837
 * than take all the faces, takes 1 face and the layer this face is
 
838
 * on.  This is used by the Map2Cmd()
 
839
 */
 
840
void mapdata_set_anim_layer(int x, int y, uint16 anim, uint8 anim_speed, int layer)
 
841
{
 
842
    int px, py;
 
843
    int i, face, animation, phase, speed_left;
 
844
 
 
845
    assert(0 <= x && x < MAX_VIEW);
 
846
    assert(0 <= y && y < MAX_VIEW);
 
847
 
 
848
    px = pl_pos.x+x;
 
849
    py = pl_pos.y+y;
 
850
    assert(0 <= px && px < FOG_MAP_SIZE);
 
851
    assert(0 <= py && py < FOG_MAP_SIZE);
 
852
 
 
853
    animation = anim & ANIM_MASK;
 
854
    face = 0;
 
855
 
 
856
    /* Random animation is pretty easy */
 
857
    if ((anim & ANIM_FLAGS_MASK) == ANIM_RANDOM) {
 
858
        phase = random() % animations[animation].num_animations;
 
859
        face = animations[animation].faces[phase];
 
860
        speed_left = anim_speed % random();
 
861
    } else if ((anim & ANIM_FLAGS_MASK) == ANIM_SYNC) {
 
862
        animations[animation].speed = anim_speed;
 
863
        phase = animations[animation].phase;
 
864
        speed_left = animations[animation].speed_left;
 
865
        face = animations[animation].faces[phase];
 
866
    }
 
867
 
 
868
    if (x < width && y < height) {
 
869
        the_map.cells[px][py].need_update = 1;
 
870
        if (the_map.cells[px][py].cleared) {
 
871
            for (i=0; i < MAXLAYERS; i++)
 
872
                expand_clear_face_from_layer(px, py, i);
 
873
 
 
874
            the_map.cells[px][py].darkness = 0;
 
875
            the_map.cells[px][py].have_darkness = 0;
 
876
        }
 
877
        if (face >0) {
 
878
            expand_set_face(px, py, layer, face, TRUE);
 
879
            the_map.cells[px][py].heads[layer].animation = animation;
 
880
            the_map.cells[px][py].heads[layer].animation_phase = phase;
 
881
            the_map.cells[px][py].heads[layer].animation_speed = anim_speed;
 
882
            the_map.cells[px][py].heads[layer].animation_left = speed_left;
 
883
        }
 
884
        else {
 
885
            expand_clear_face_from_layer(px, py, layer);
 
886
        }
 
887
 
 
888
        the_map.cells[px][py].cleared = 0;
 
889
 
 
890
    }
 
891
    else {
 
892
        expand_set_bigface(x, y, layer, face, TRUE);
 
893
    }
 
894
}
 
895
 
 
896
 
639
897
void mapdata_scroll(int dx, int dy)
640
898
{
641
899
    int x, y;
821
1079
    return(0);
822
1080
}
823
1081
 
 
1082
/* This is used by the opengl logic.
 
1083
 * Basically the opengl code draws the the entire image,
 
1084
 * and doesn't care if if portions are off the edge
 
1085
 * (opengl takes care of that).  So basically, this
 
1086
 * function returns only if the head for a space is set,
 
1087
 * otherwise, returns 0 - we don't care about the tails
 
1088
 * or other details really.
 
1089
 */
 
1090
sint16 mapdata_bigface_head(int x, int y, int layer, int *ww, int *hh)
 
1091
{
 
1092
    sint16 result;
 
1093
 
 
1094
    if (width <= 0) return(0);
 
1095
 
 
1096
    assert(0 <= x && x < MAX_VIEW);
 
1097
    assert(0 <= y && y < MAX_VIEW);
 
1098
    assert(0 <= layer && layer < MAXLAYERS);
 
1099
 
 
1100
    result = bigfaces[x][y][layer].head.face;
 
1101
    if (result != 0) {
 
1102
        int w = bigfaces[x][y][layer].head.size_x;
 
1103
        int h = bigfaces[x][y][layer].head.size_y;
 
1104
        *ww = w;
 
1105
        *hh = h;
 
1106
        return(result);
 
1107
    }
 
1108
 
 
1109
    *ww = 1;
 
1110
    *hh = 1;
 
1111
    return(0);
 
1112
}
 
1113
 
824
1114
/**
825
1115
 * Check if current map position is out of bounds if shifted by (dx, dy). If
826
1116
 * so, shift the virtual map so that the map view is within bounds again.
1005
1295
    if (*w > MAX_FACE_SIZE) *w = MAX_FACE_SIZE;
1006
1296
    if (*h > MAX_FACE_SIZE) *h = MAX_FACE_SIZE;
1007
1297
}
 
1298
 
 
1299
/* This basically goes through all the map spaces and does the necessary
 
1300
 * animation.
 
1301
 */
 
1302
void mapdata_animation()
 
1303
{
 
1304
    int x, y, layer, face, smooth;
 
1305
    struct MapCellLayer *cell;
 
1306
 
 
1307
 
 
1308
    /* For synchronized animations, what we do is set the initial values
 
1309
     * in the mapdata to the fields in the animations[] array.  In this way,
 
1310
     * the code below the iterates the spaces doesn't need to do anything
 
1311
     * special.  But we have to update the animations[] array here to
 
1312
     * keep in sync.
 
1313
     */
 
1314
    for (x=0; x < MAXANIM; x++) {
 
1315
        if (animations[x].speed) {
 
1316
            animations[x].speed_left++;
 
1317
            if (animations[x].speed_left >= animations[x].speed) {
 
1318
                animations[x].speed_left=0;
 
1319
                animations[x].phase++;
 
1320
                if (animations[x].phase >= animations[x].num_animations)
 
1321
                    animations[x].phase=0;
 
1322
            }
 
1323
        }
 
1324
    }
 
1325
 
 
1326
    for (x=0; x < CURRENT_MAX_VIEW; x++) {
 
1327
        for (y=0; y < CURRENT_MAX_VIEW; y++) {
 
1328
 
 
1329
            /* Short cut some processing here.  It makes sense to me
 
1330
             * not to animate stuff out of view
 
1331
             */
 
1332
            if (the_map.cells[pl_pos.x + x][pl_pos.y + y].cleared) continue;
 
1333
 
 
1334
            for (layer=0; layer<MAXLAYERS; layer++) {
 
1335
                smooth = the_map.cells[pl_pos.x + x][pl_pos.y + y].smooth[layer];
 
1336
 
 
1337
                /* Using the cell structure just makes life easier here */
 
1338
                cell = &the_map.cells[pl_pos.x+x][pl_pos.y+y].heads[layer];
 
1339
 
 
1340
                if (cell->animation) {
 
1341
                    cell->animation_left++;
 
1342
                    if (cell->animation_left >= cell->animation_speed) {
 
1343
                        cell->animation_left=0;
 
1344
                        cell->animation_phase++;
 
1345
                        if (cell->animation_phase >= animations[cell->animation].num_animations)
 
1346
                            cell->animation_phase=0;
 
1347
                        face = animations[cell->animation].faces[cell->animation_phase];
 
1348
 
 
1349
                        /* I don't think we send any to the client, but it is possible
 
1350
                         * for animations to have blank faces.
 
1351
                         */
 
1352
                        if (face >0) {
 
1353
                            expand_set_face(pl_pos.x + x, pl_pos.y + y, layer, face, FALSE);
 
1354
/*                          mapdata_set_smooth(x, y, smooth, layer);*/
 
1355
                        } else {
 
1356
                            expand_clear_face_from_layer(pl_pos.x + x, pl_pos.y + y , layer);
 
1357
                        }
 
1358
                    }
 
1359
                }
 
1360
                cell = &bigfaces[x][y][layer].head;
 
1361
                if (cell->animation) {
 
1362
                    cell->animation_left++;
 
1363
                    if (cell->animation_left >= cell->animation_speed) {
 
1364
                        cell->animation_left=0;
 
1365
                        cell->animation_phase++;
 
1366
                        if (cell->animation_phase >= animations[cell->animation].num_animations)
 
1367
                            cell->animation_phase=0;
 
1368
                        face = animations[cell->animation].faces[cell->animation_phase];
 
1369
 
 
1370
                        /* I don't think we send any to the client, but it is possible
 
1371
                         * for animations to have blank faces.
 
1372
                         */
 
1373
                        expand_set_bigface(x, y, layer, face, FALSE);
 
1374
                    }
 
1375
                }
 
1376
            }
 
1377
        }
 
1378
    }
 
1379
}