source: trunk/src/map.cpp @ 133

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

Fix z-sorting of tiles. For now.

  • 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                Layer *l = new Layer(data->width, data->height,
107                                     level, orientation, tiles);
108                data->layers[data->nlayers] = l;
109                data->nlayers++;
110                tiles = NULL;
111                //fprintf(stderr, "new layer %ix%i\n", data->width, data->height);
112            }
113        }
114        else if (sscanf(tmp, " <tileset firstgid=\"%i\"", &i) == 1)
115        {
116            /* This is a tileset description. Remember its first gid value. */
117            gids[data->ntilers] = i;
118        }
119        else if (sscanf(tmp, " <image source=\"%[^\"]\"", str) == 1)
120        {
121            /* This is a tileset image file. Associate it with firstgid. */
122            data->tilers[data->ntilers] = Tiler::Register(str);
123            data->ntilers++;
124            //fprintf(stderr, "new tiler %s\n", str);
125        }
126        else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" "
127                        "width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5)
128        {
129            /* This is a layer description. Prepare to read the data. */
130            data->layers = (Layer **)realloc(data->layers,
131                                       sizeof(Layer **) * (data->nlayers + 1));
132            orientation = toupper(a) == 'V' ? 1 : 0;
133            data->width = j;
134            data->height = k;
135            tiles = (uint32_t *)malloc(j * k * sizeof(uint32_t));
136            ntiles = 0;
137        }
138    }
139
140    fclose(fp);
141}
142
143Map::~Map()
144{
145    for (int i = 0; i < data->ntilers; i++)
146        Tiler::Deregister(data->tilers[i]);
147    for (int i = 0; i < data->nlayers; i++)
148        delete data->layers[i];
149    free(data->layers);
150    delete data;
151}
152
153void Map::Render(Scene *scene, int x, int y, int z)
154{
155    for (int i = 0; i < data->nlayers; i++)
156        data->layers[i]->Render(scene, x, y, z);
157}
158
159int Map::GetWidth()
160{
161    return data->width * 32;
162}
163
164int Map::GetHeight()
165{
166    return data->height * 32;
167}
168
Note: See TracBrowser for help on using the repository browser.