source: trunk/src/map.cpp @ 758

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

ps3: start a minimal PS3 port using PSGL, but not CG yet.

  • Property svn:keywords set to Id
File size: 4.7 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 <cmath>
19#include <ctype.h>
20
21#include "core.h"
22
23using namespace std;
24
25namespace lol
26{
27
28/*
29 * Map implementation class
30 */
31
32class MapData
33{
34    friend class Map;
35
36    static int const MAX_TILERS = 128;
37
38private:
39    int tilers[MAX_TILERS];
40    int ntilers;
41
42    Layer **layers;
43    int nlayers;
44
45    int width, height;
46};
47
48/*
49 * Public Map class
50 */
51
52Map::Map(char const *path)
53  : data(new MapData())
54{
55    data->ntilers = 0;
56    data->layers = NULL;
57    data->nlayers = 0;
58    data->width = 0;
59    data->height = 0;
60
61    char tmp[BUFSIZ];
62    int gids[MapData::MAX_TILERS];
63    uint32_t *tiles = NULL;
64    int level = 0, orientation = 0, ntiles = 0;
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
77        /* Read a line, then decide what to do with it. */
78        fgets(tmp, BUFSIZ, fp);
79
80        if (tiles && !strchr(tmp, '<'))
81        {
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;
85            while (ntiles < data->width * data->height)
86            {
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                        {
98                            code = (data->tilers[n] << 16) | (id - gids[n]);
99                            break;
100                        }
101                    }
102                }
103
104                int x = ntiles % data->width;
105                int y = data->height - 1 - (ntiles / data->width);
106                tiles[y * data->width + x] = code;
107                ntiles++;
108
109                while (isdigit(*parser))
110                    parser++;
111                if (*parser == ',')
112                    parser++;
113                if (!isdigit(*parser))
114                    break;
115            }
116
117            if (ntiles == data->width * data->height)
118            {
119                Layer *l = new Layer(data->width, data->height,
120                                     level, orientation, tiles);
121                data->layers[data->nlayers] = l;
122                data->nlayers++;
123                tiles = NULL;
124                //Log::Debug("new layer %ix%i\n", data->width, data->height);
125            }
126        }
127        else if (sscanf(tmp, " <tileset firstgid=\"%i\"", &i) == 1)
128        {
129            /* This is a tileset description. Remember its first gid value. */
130            gids[data->ntilers] = i;
131        }
132        else if (sscanf(tmp, " <image source=\"%[^\"]\"", str) == 1)
133        {
134            /* This is a tileset image file. Associate it with firstgid. */
135            data->tilers[data->ntilers] = Tiler::Register(str, 32, 0,
136                                                          sqrtf(2));
137            data->ntilers++;
138            //Log::Debug("new tiler %s\n", str);
139        }
140        else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" "
141                        "width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5)
142        {
143            /* This is a layer description. Prepare to read the data. */
144            data->layers = (Layer **)realloc(data->layers,
145                                       sizeof(Layer **) * (data->nlayers + 1));
146            orientation = toupper(a) == 'V' ? 1 : 0;
147            level = i * 32;
148            data->width = j;
149            data->height = k;
150            tiles = (uint32_t *)malloc(j * k * sizeof(uint32_t));
151            ntiles = 0;
152        }
153    }
154
155    fclose(fp);
156}
157
158Map::~Map()
159{
160    for (int i = 0; i < data->ntilers; i++)
161        Tiler::Deregister(data->tilers[i]);
162    for (int i = 0; i < data->nlayers; i++)
163        delete data->layers[i];
164    free(data->layers);
165    delete data;
166}
167
168void Map::Render(int x, int y, int z)
169{
170    for (int i = 0; i < data->nlayers; i++)
171        data->layers[i]->Render(x, y, z);
172}
173
174int Map::GetWidth()
175{
176    return data->width * 32;
177}
178
179int Map::GetHeight()
180{
181    return data->height * 32;
182}
183
184} /* namespace lol */
185
Note: See TracBrowser for help on using the repository browser.