source: trunk/src/map.cpp @ 75

Last change on this file since 75 was 75, checked in by sam, 10 years ago

Much better resource allocation and release. Scene manager stub.

  • Property svn:keywords set to Id
File size: 3.5 KB
Line 
1
2#include <cstdio>
3#include <cstring>
4#include <cstdlib>
5#include <malloc.h>
6#include <ctype.h>
7
8#include "map.h"
9#include "layer.h"
10#include "tiler.h"
11
12#define MAX_TILERS 128
13
14/*
15 * Map implementation class
16 */
17
18class MapData
19{
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
40    char tmp[BUFSIZ];
41    int gids[MAX_TILERS];
42    uint32_t *tiles = NULL;
43    int width = 0, height = 0, level = 0, orientation = 0, ntiles = 0;
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
56        /* Read a line, then decide what to do with it. */
57        fgets(tmp, BUFSIZ, fp);
58
59        if (tiles)
60        {
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)
65            {
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                        {
77                            code = (data->tilers[n] << 16) | (id - 1);
78                            break;
79                        }
80                    }
81                }
82
83                tiles[ntiles++] = code;
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            {
94                data->layers[data->nlayers] = new Layer(width, height, level, tiles);
95                data->nlayers++;
96                tiles = NULL;
97            }
98        }
99        else if (sscanf(tmp, " <tileset firstgid=\"%i\"", &i) == 1)
100        {
101            /* This is a tileset description. Remember its first gid value. */
102            gids[data->ntilers] = i;
103        }
104        else if (sscanf(tmp, " <image source=\"%[^\"]\"", str) == 1)
105        {
106            /* This is a tileset image file. Associate it with firstgid. */
107            data->tilers[data->ntilers] = Tiler::Register(str);
108            data->ntilers++;
109        }
110        else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" "
111                        "width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5)
112        {
113            /* This is a layer description. Prepare to read the data. */
114            data->layers = (Layer **)realloc(data->layers,
115                                       sizeof(Layer **) * (data->nlayers + 1));
116            orientation = toupper(a) == 'V' ? 1 : 0;
117            width = j;
118            height = k;
119            tiles = (uint32_t *)malloc(width * height * sizeof(uint32_t));
120            ntiles = 0;
121        }
122    }
123
124    fclose(fp);
125}
126
127Map::~Map()
128{
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;
135}
136
137void Map::Draw()
138{
139    for (int i = 0; i < data->nlayers; i++)
140        data->layers[i]->Draw();
141}
142
Note: See TracBrowser for help on using the repository browser.