source: trunk/src/map.cpp @ 76

Last change on this file since 76 was 76, checked in by sam, 11 years ago

Fix error in tile code computation.

  • Property svn:keywords set to Id
File size: 3.5 KB
RevLine 
[38]1
2#include <cstdio>
[74]3#include <cstring>
4#include <cstdlib>
[38]5#include <malloc.h>
[74]6#include <ctype.h>
[38]7
8#include "map.h"
9#include "layer.h"
[75]10#include "tiler.h"
[38]11
[75]12#define MAX_TILERS 128
13
14/*
15 * Map implementation class
16 */
17
18class MapData
[38]19{
[75]20    friend class Map;
21
22private:
23    int tilers[MAX_TILERS];
24    int ntilers;
25    Layer **layers;
26    int nlayers;
27};
28
29/*
30 * Public Map class
31 */
32
33Map::Map(char const *path)
34{
35    data = new MapData();
36    data->ntilers = 0;
37    data->layers = NULL;
38    data->nlayers = 0;
39
[70]40    char tmp[BUFSIZ];
[75]41    int gids[MAX_TILERS];
42    uint32_t *tiles = NULL;
43    int width = 0, height = 0, level = 0, orientation = 0, ntiles = 0;
[70]44
45    FILE *fp = fopen(path, "r");
46
47    if (!fp)
48        return;
49
50    while (!feof(fp))
51    {
52        char str[1024];
53        int i, j, k;
54        char a, b;
55
[75]56        /* Read a line, then decide what to do with it. */
[70]57        fgets(tmp, BUFSIZ, fp);
58
[75]59        if (tiles)
[70]60        {
[74]61            /* We are in the process of reading layer data. Only stop
62             * when we have read the expected number of tiles. */
63            char const *parser = tmp;
64            while (ntiles < width * height)
[70]65            {
[75]66                uint32_t code = 0;
67                int id = atoi(parser);
68                if (id)
69                {
70                    for (int n = 0; n < data->ntilers; n++)
71                    {
72                        if (id < gids[n])
73                            continue;
74                        if (n == data->ntilers - 1
75                             || id < gids[n + 1])
76                        {
[76]77                            code = (data->tilers[n] << 16) | (id - gids[n]);
[75]78                            break;
79                        }
80                    }
81                }
82
83                tiles[ntiles++] = code;
[74]84                while (isdigit(*parser))
85                    parser++;
86                if (*parser == ',')
87                    parser++;
88                if (!isdigit(*parser))
89                    break;
90            }
91
92            if (ntiles == width * height)
93            {
[75]94                data->layers[data->nlayers] = new Layer(width, height, level, tiles);
95                data->nlayers++;
96                tiles = NULL;
[70]97            }
98        }
99        else if (sscanf(tmp, " <tileset firstgid=\"%i\"", &i) == 1)
100        {
[75]101            /* This is a tileset description. Remember its first gid value. */
102            gids[data->ntilers] = i;
[70]103        }
104        else if (sscanf(tmp, " <image source=\"%[^\"]\"", str) == 1)
105        {
[74]106            /* This is a tileset image file. Associate it with firstgid. */
[75]107            data->tilers[data->ntilers] = Tiler::Register(str);
108            data->ntilers++;
[70]109        }
[74]110        else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" "
111                        "width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5)
[70]112        {
[74]113            /* This is a layer description. Prepare to read the data. */
[75]114            data->layers = (Layer **)realloc(data->layers,
115                                       sizeof(Layer **) * (data->nlayers + 1));
[74]116            orientation = toupper(a) == 'V' ? 1 : 0;
[70]117            width = j;
118            height = k;
[75]119            tiles = (uint32_t *)malloc(width * height * sizeof(uint32_t));
[74]120            ntiles = 0;
[70]121        }
122    }
123
124    fclose(fp);
[38]125}
126
127Map::~Map()
128{
[75]129    for (int i = 0; i < data->ntilers; i++)
130        Tiler::Deregister(data->tilers[i]);
131    for (int i = 0; i < data->nlayers; i++)
132        delete data->layers[i];
133    free(data->layers);
134    delete data;
[38]135}
136
[75]137void Map::Draw()
[38]138{
[75]139    for (int i = 0; i < data->nlayers; i++)
140        data->layers[i]->Draw();
[38]141}
142
Note: See TracBrowser for help on using the repository browser.