source: trunk/src/map.cpp @ 126

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

Minor updates here and there. Not worth mentioning.

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