GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/wallpaper.cpp Lines: 31 55 56.4 %
Date: 2017-11-29 Branches: 33 100 33.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2017  The ManaPlus Developers
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "resources/wallpaper.h"
24
25
#include "configuration.h"
26
27
#include "fs/virtfs/fs.h"
28
#include "fs/virtfs/list.h"
29
30
#include "resources/wallpaperdata.h"
31
32
#include "utils/cast.h"
33
#include "utils/foreach.h"
34
35
#include <algorithm>
36
37
#ifdef WIN32
38
#include <sys/time.h>
39
#endif  // WIN32
40
41
#ifdef __clang__
42
#include <ctime>
43
#endif  // __clang__
44
45
#include "debug.h"
46
47
static bool wallpaperCompare(const WallpaperData &a, const WallpaperData &b);
48
49
2
static STD_VECTOR<WallpaperData> wallpaperData;
50
static bool haveBackup;  // Is the backup (no size given) version available?
51
52
2
static std::string wallpaperPath;
53
2
static std::string wallpaperFile;
54
55
// Search for the wallpaper path values sequentially..
56
2
static void initDefaultWallpaperPaths()
57
{
58
    // Init the path
59

10
    wallpaperPath = branding.getStringValue("wallpapersPath");
60
61


6
    if (wallpaperPath.empty() || !VirtFs::isDirectory(wallpaperPath))
62

16
        wallpaperPath = paths.getValue("wallpapers", "");
63
64


6
    if (wallpaperPath.empty() || !VirtFs::isDirectory(wallpaperPath))
65
        wallpaperPath = "graphics/images/";
66
67
    // Init the default file
68

10
    wallpaperFile = branding.getStringValue("wallpaperFile");
69
70


6
    if (!wallpaperFile.empty() && !VirtFs::isDirectory(wallpaperFile))
71
        return;
72

16
    wallpaperFile = paths.getValue("wallpaperFile", "");
73
74


6
    if (wallpaperFile.empty() || VirtFs::isDirectory(wallpaperFile))
75
        wallpaperFile = "login_wallpaper.png";
76
}
77
78
static bool wallpaperCompare(const WallpaperData &a, const WallpaperData &b)
79
{
80
    const int aa = a.width * a.height;
81
    const int ab = b.width * b.height;
82
83
    return aa > ab ||
84
        (aa == ab && a.width > b.width);
85
}
86
87
2
void Wallpaper::loadWallpapers()
88
{
89
2
    wallpaperData.clear();
90
2
    initDefaultWallpaperPaths();
91
4
    VirtFs::List *const imgs = VirtFs::enumerateFiles(wallpaperPath);
92
93
24
    FOR_EACH (StringVectCIter, i, imgs->names)
94
    {
95
        // First, get the base filename of the image:
96
36
        std::string filename = *i;
97
24
        const std::string name = filename;
98
        // If the backup file is found, we tell it.
99
12
        if (filename.find(wallpaperFile) != std::string::npos)
100
2
            haveBackup = true;
101
102
        // If the image format is terminated by: "_<width>x<height>.png"
103
        // It is taken as a potential wallpaper.
104
105
12
        size_t separator = filename.rfind('_');
106
24
        filename = filename.substr(0, separator);
107
108
        // Check that the base filename doesn't have any '%' markers.
109
12
        separator = filename.find('%');
110
12
        if (separator == std::string::npos)
111
        {
112
            // Then, append the width and height search mask.
113
12
            filename.append("_%10dx%10d.png");
114
115
            int width;
116
            int height;
117
24
            if (sscanf(name.c_str(),
118
                filename.c_str(),
119
                &width,
120
                &height) == 2)
121
            {
122
                WallpaperData wp;
123
                wp.filename = wallpaperPath;
124
                wp.filename.append(*i);
125
                wp.width = width;
126
                wp.height = height;
127
                wallpaperData.push_back(wp);
128
            }
129
        }
130
    }
131
132
2
    VirtFs::freeList(imgs);
133
6
    std::sort(wallpaperData.begin(), wallpaperData.end(), &wallpaperCompare);
134
2
}
135
136
std::string Wallpaper::getWallpaper(const int width, const int height)
137
{
138
    WallpaperData wp;
139
140
    // Wallpaper filename container
141
    StringVect wallPaperVector;
142
143
    FOR_EACH (STD_VECTOR<WallpaperData>::const_iterator, iter, wallpaperData)
144
    {
145
        wp = *iter;
146
        if (wp.width <= width && wp.height <= height)
147
            wallPaperVector.push_back(wp.filename);
148
    }
149
150
    // If we've got more than one occurence of a valid wallpaper...
151
    if (!wallPaperVector.empty())
152
    {
153
        // Return randomly a wallpaper between vector[0] and
154
        // vector[vector.size() - 1]
155
        srand(CAST_U32(time(nullptr)));
156
        return wallPaperVector[CAST_S32(static_cast<double>(
157
            wallPaperVector.size()) * rand() / (RAND_MAX + 1.0))];
158
    }
159
160
    // Return the backup file if everything else failed...
161
    if (haveBackup)
162
        return pathJoin(wallpaperPath, wallpaperFile);
163
164
    // Return an empty string if everything else failed
165
    return std::string();
166

6
}