source: trunk/src/map.cpp @ 112

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

Slightly improve the documentation in a few files, add the missing
joystick class, and put a header in each source file.

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