source: trunk/src/map.cpp @ 1985

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

core: disable our rare uses of realloc() with a proper Array<> object.

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