source: trunk/src/map.cpp @ 1184

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

core: allow to stretch 2D sprits in both X and Y directions.

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