GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/map/speciallayer.cpp Lines: 35 84 41.7 %
Date: 2021-03-17 Branches: 26 92 28.3 %

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

106
    mTiles(new MapItem*[width * height]),
41

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

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

1993086
                if (item != nullptr &&
181
10092
                    item->mType != MapItemType::EMPTY)
182
                {
183
10073
                    c = f - x - 1;
184
10073
                    break;
185
                }
186
            }
187
50056
            mCache[x + y2] = c;
188
        }
189
    }
190
32
}