source: trunk/src/map.cpp @ 221

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

Complete Lol Engine / Deus Hax / Monsterz split.

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