GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/map/speciallayer.cpp Lines: 35 83 42.2 %
Date: 2017-11-29 Branches: 25 90 27.8 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2011-2017  The ManaPlus Developers
4
 *
5
 *  This file is part of The ManaPlus Client.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "resources/map/speciallayer.h"
22
23
#include "const/resources/map/map.h"
24
25
#include "enums/resources/map/mapitemtype.h"
26
27
#include "resources/map/mapitem.h"
28
29
#include "utils/delete2.h"
30
#include "utils/foreach.h"
31
32
#include "debug.h"
33
34
212
SpecialLayer::SpecialLayer(const std::string &name,
35
                           const int width,
36
212
                           const int height) :
37
    MemoryCounter(),
38
    mName(name),
39

212
    mTiles(new MapItem*[width * height]),
40
212
    mCache(new int[width * height]),
41
    mWidth(width),
42
848
    mHeight(height)
43
{
44
212
    std::fill_n(mTiles, mWidth * mHeight, static_cast<MapItem*>(nullptr));
45
212
    std::fill_n(mCache, mWidth * mHeight, 10000);
46
212
}
47
48
848
SpecialLayer::~SpecialLayer()
49
{
50
680952
    for (int f = 0; f < mWidth * mHeight; f ++)
51
680740
        delete2(mTiles[f])
52
212
    delete [] mTiles;
53
212
    delete [] mCache;
54
424
}
55
56
MapItem* SpecialLayer::getTile(const int x, const int y) const
57
{
58
    if (x < 0 || x >= mWidth ||
59
        y < 0 || y >= mHeight)
60
    {
61
        return nullptr;
62
    }
63
    return mTiles[x + y * mWidth];
64
}
65
66
void SpecialLayer::setTile(const int x, const int y, MapItem *const item)
67
{
68
    if (x < 0 || x >= mWidth ||
69
        y < 0 || y >= mHeight)
70
    {
71
        return;
72
    }
73
74
    const int idx = x + y * mWidth;
75
    delete mTiles[idx];
76
    if (item != nullptr)
77
        item->setPos(x, y);
78
    mTiles[idx] = item;
79
}
80
81
20158
void SpecialLayer::setTile(const int x, const int y, const int type)
82
{
83

20158
    if (x < 0 || x >= mWidth ||
84
20158
        y < 0 || y >= mHeight)
85
    {
86
        return;
87
    }
88
89
20158
    const int idx = x + y * mWidth;
90
20158
    MapItem *const tile = mTiles[idx];
91
20158
    if (tile != nullptr)
92
    {
93
        tile->setType(type);
94
        tile->setPos(x, y);
95
    }
96
    else
97
    {
98
20158
        mTiles[idx] = new MapItem(type);
99
20158
        mTiles[idx]->setPos(x, y);
100
    }
101
}
102
103
void SpecialLayer::addRoad(const Path &road)
104
{
105
    FOR_EACH (Path::const_iterator, i, road)
106
    {
107
        const Position &pos = *i;
108
        MapItem *const item = getTile(pos.x, pos.y);
109
        if (item == nullptr)
110
            setTile(pos.x, pos.y, new MapItem(MapItemType::ROAD));
111
        else
112
            item->setType(MapItemType::ROAD);
113
    }
114
    updateCache();
115
}
116
117
void SpecialLayer::clean()
118
{
119
    if (mTiles == nullptr)
120
        return;
121
122
    for (int f = 0; f < mWidth * mHeight; f ++)
123
    {
124
        MapItem *const item = mTiles[f];
125
        if (item != nullptr)
126
            item->setType(MapItemType::EMPTY);
127
    }
128
    updateCache();
129
}
130
131
void SpecialLayer::draw(Graphics *const graphics, int startX, int startY,
132
                        int endX, int endY,
133
                        const int scrollX, const int scrollY) const
134
{
135
    BLOCK_START("SpecialLayer::draw")
136
    if (startX < 0)
137
        startX = 0;
138
    if (startY < 0)
139
        startY = 0;
140
    if (endX > mWidth)
141
        endX = mWidth;
142
    if (endY > mHeight)
143
        endY = mHeight;
144
145
    for (int y = startY; y < endY; y ++)
146
    {
147
        const int py = y * mapTileSize - scrollY;
148
        const int y2 = y * mWidth;
149
        for (int x = startX; x < endX; x ++)
150
        {
151
            const MapItem *const item = mTiles[x + y2];
152
            if (item != nullptr)
153
            {
154
                item->draw(graphics, x * mapTileSize - scrollX, py,
155
                    mapTileSize, mapTileSize);
156
            }
157
        }
158
    }
159
    BLOCK_END("SpecialLayer::draw")
160
}
161
162
int SpecialLayer::calcMemoryLocal() const
163
{
164
    return static_cast<int>(sizeof(SpecialLayer) +
165
        sizeof(MapItem) * mWidth * mHeight);
166
}
167
168
60
void SpecialLayer::updateCache()
169
{
170
1108
    for (int y = 0; y < mHeight; y ++)
171
    {
172
1048
        const int y2 = y * mWidth;
173
101160
        for (int x = 0; x < mWidth; x ++)
174
        {
175
100112
            int c = 10000;
176
4045954
            for (int f = x + 1; f < mWidth; f ++)
177
            {
178
3965988
                MapItem *const item = mTiles[f + y2];
179

3986172
                if (item != nullptr &&
180
20184
                    item->mType != MapItemType::EMPTY)
181
                {
182
20146
                    c = f - x - 1;
183
20146
                    break;
184
                }
185
            }
186
100112
            mCache[x + y2] = c;
187
        }
188
    }
189
64
}