source: trunk/src/map.cpp @ 1687

Last change on this file since 1687 was 1513, checked in by sam, 9 years ago

core: replace usage of sin() or std::sin() with lol::sin() where appropriate.

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