source: trunk/src/map.cpp @ 259

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

Slightly change the ...Data initialisation in classes.

  • 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. */
[222]130            data->tilers[data->ntilers] = Tiler::Register(str, 32, 32,
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
[79]163void Map::Render(Scene *scene, int x, int y, int z)
[38]164{
[75]165    for (int i = 0; i < data->nlayers; i++)
[79]166        data->layers[i]->Render(scene, 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.