source: trunk/src/map.cpp @ 633

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

TileSets can now be initialised either using the tile size, or the
known number of tiles in a row and a column. Necessary for ticket #24.

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