Subversion Repositories tpanel

Rev

Rev 462 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
446 andreas 1
/*
2
 * Copyright (C) 2022 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include "tmap.h"
20
#include "texpat++.h"
21
#include "tresources.h"
22
#include "tconfig.h"
23
#include "terror.h"
486 andreas 24
#include "ttpinit.h"
446 andreas 25
 
26
#if __cplusplus < 201402L
27
#   error "This module requires at least C++14 standard!"
28
#else
29
#   if __cplusplus < 201703L
30
#       include <experimental/filesystem>
31
namespace fs = std::experimental::filesystem;
32
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
33
#   else
34
#       include <filesystem>
35
#       ifdef __ANDROID__
36
namespace fs = std::__fs::filesystem;
37
#       else
38
namespace fs = std::filesystem;
39
#       endif
40
#   endif
41
#endif
42
 
43
using std::string;
44
using std::vector;
45
using namespace Expat;
46
 
462 andreas 47
TMap::TMap(const std::string& file, bool tp)
48
    : mFile(file),
49
      mIsTP5(tp)
446 andreas 50
{
462 andreas 51
    DECL_TRACER("TMap::TMap(std::string& file, bool tp)");
446 andreas 52
 
53
    if (!fs::exists(file))
54
    {
55
        MSG_ERROR("File " << file << " does not exist!");
56
        mError = true;
57
        return;
58
    }
59
 
60
    bool e = readMap();
61
    mError = !e;
62
}
63
 
64
bool TMap::readMap()
65
{
66
    DECL_TRACER("TMap::readMap()");
67
 
68
    string path = makeFileName(mFile, "map.xma");
462 andreas 69
    vector<string> elements = { "cm", "am", "lm", "bm" };
446 andreas 70
 
462 andreas 71
    if (mIsTP5)
72
        elements.push_back("evpf");
73
    else
74
    {
75
        elements.push_back("sm");
76
        elements.push_back("strm");
77
        elements.push_back("pm");
78
    }
79
 
446 andreas 80
    if (!isValidFile())
81
    {
82
        MSG_ERROR("File \"" << path << "\" is not a regular readable file!");
83
        return false;
84
    }
85
 
86
    TExpat xml(path);
87
 
486 andreas 88
    if (!TTPInit::isTP5())
89
        xml.setEncoding(ENC_CP1250);
90
    else
91
        xml.setEncoding(ENC_UTF8);
92
 
446 andreas 93
    if (!xml.parse())
94
        return false;
95
 
96
    int depth = 0;
97
    size_t index = 0;
98
    vector<string>::iterator mapIter;
99
    size_t oldIndex = 0;
100
 
101
    if (elements.size() == 0)
102
        return false;
103
 
104
    for (mapIter = elements.begin(); mapIter != elements.end(); ++mapIter)
105
    {
106
        if ((index = xml.getElementIndex(*mapIter, &depth)) == TExpat::npos)
107
        {
108
            MSG_WARNING("Element \"" << *mapIter << "\" was not found!");
109
            continue;
110
        }
111
 
112
        MAP_T map;
113
        MAP_BM_T mapBm;
114
        MAP_PM_T mapPm;
462 andreas 115
        MAP_EVPF_T mapEvpf;
446 andreas 116
        string name, content;
117
 
118
        while ((index = xml.getNextElementFromIndex(index, &name, nullptr, nullptr)) != TExpat::npos)
119
        {
120
            string el = name;
121
 
122
            if (el.compare("me") == 0)
123
            {
124
                while ((index = xml.getNextElementFromIndex(index, &name, &content, nullptr)) != TExpat::npos)
125
                {
126
                    string e = name;
127
 
128
                    if (mapIter->compare("cm") == 0 || mapIter->compare("am") == 0 ||
129
                        mapIter->compare("lm") == 0 || mapIter->compare("strm") == 0)
130
                    {
131
                        if (e.compare("p") == 0)
132
                            map.p = xml.convertElementToInt(content);
133
                        else if (e.compare("c") == 0)
134
                            map.c = xml.convertElementToInt(content);
135
                        else if (e.compare("ax") == 0)
136
                            map.ax = xml.convertElementToInt(content);
137
                        else if (e.compare("pg") == 0)
138
                            map.pg = xml.convertElementToInt(content);
139
                        else if (e.compare("bt") == 0)
140
                            map.bt = xml.convertElementToInt(content);
141
                        else if (e.compare("pn") == 0)
142
                            map.pn = content;
143
                        else if (e.compare("bn") == 0)
144
                            map.bn = content;
145
                    }
146
                    else if (mapIter->compare("bm") == 0)
147
                    {
148
                        while ((index = xml.getNextElementFromIndex(index, &name, &content, nullptr)) != TExpat::npos)
149
                        {
150
                            string im = name;
151
 
152
                            if (im.compare("i") == 0)
153
                                mapBm.i = content;
154
                            else if (im.compare("id") == 0)
155
                                mapBm.id = xml.convertElementToInt(content);
156
                            else if (im.compare("rt") == 0)
157
                                mapBm.rt = xml.convertElementToInt(content);
158
                            else if (im.compare("pg") == 0)
159
                                mapBm.pg = xml.convertElementToInt(content);
160
                            else if (im.compare("bt") == 0)
161
                                mapBm.bt = xml.convertElementToInt(content);
162
                            else if (im.compare("st") == 0)
163
                                mapBm.st = xml.convertElementToInt(content);
164
                            else if (im.compare("sl") == 0)
165
                                mapBm.sl = xml.convertElementToInt(content);
166
                            else if (im.compare("pn") == 0)
167
                                mapBm.pn = content;
168
                            else if (im.compare("bn") == 0)
169
                                mapBm.bn = content;
462 andreas 170
                            else if (im.compare("rc") == 0)
171
                                mapBm.rc = xml.convertElementToInt(content);
446 andreas 172
 
173
                            oldIndex = index;
174
                        }
175
 
176
                        mMap.map_bm.push_back(mapBm);
177
 
178
                        if (index == TExpat::npos)
179
                            index = oldIndex + 1;
180
                    }
181
                    else if (mapIter->compare("sm") == 0)
182
                    {
183
                        if (e.compare("i") == 0)
184
                            mMap.map_sm.push_back(content);
185
                    }
186
                    else if (mapIter->compare("pm") == 0)
187
                    {
188
                        if (e.compare("a") == 0)
189
                            mapPm.a = xml.convertElementToInt(content);
190
                        else if (e.compare("t") == 0)
191
                            mapPm.t = content;
192
                        else if (e.compare("pg") == 0)
193
                            mapPm.pg = xml.convertElementToInt(content);
194
                        else if (e.compare("bt") == 0)
195
                            mapPm.bt = xml.convertElementToInt(content);
196
                        else if (e.compare("pn") == 0)
197
                            mapPm.pn = content;
198
                        else if (e.compare("bn") == 0)
199
                            mapPm.bn = content;
200
                    }
462 andreas 201
                    else if (mapIter->compare("evpf") == 0)
202
                    {
203
                        if (e.compare("a") == 0)
204
                            mapEvpf.a = xml.convertElementToInt(content);
205
                        else if (e.compare("t") == 0)
206
                            mapEvpf.t = content;
207
                        else if (e.compare("pg") == 0)
208
                            mapEvpf.pg = xml.convertElementToInt(content);
209
                        else if (e.compare("bt") == 0)
210
                            mapEvpf.bt = xml.convertElementToInt(content);
211
                        else if (e.compare("ev") == 0)
212
                            mapEvpf.ev = content;
213
                        else if (e.compare("ai") == 0)
214
                            mapEvpf.ai = xml.convertElementToInt(content);
215
                    }
446 andreas 216
 
217
                    oldIndex = index;
218
                }
219
 
220
                if (mapIter->compare("cm") == 0)
221
                    mMap.map_cm.push_back(map);
222
                else if (mapIter->compare("am") == 0)
223
                    mMap.map_am.push_back(map);
224
                else if (mapIter->compare("lm") == 0)
225
                    mMap.map_lm.push_back(map);
226
                else if (mapIter->compare("strm") == 0)
227
                    mMap.map_strm.push_back(map);
228
                else if (mapIter->compare("pm") == 0)
229
                    mMap.map_pm.push_back(mapPm);
462 andreas 230
                else if (mapIter->compare("evpf") == 0)
231
                    mMap.map_evpf.push_back(mapEvpf);
446 andreas 232
 
233
                if (index == TExpat::npos)
234
                    index = oldIndex + 1;
235
            }
236
 
237
            oldIndex = index;
238
        }
239
    }
240
 
241
    return true;
242
}
243
 
244
vector<TMap::MAP_T> TMap::findButtons(int port, vector<int>& channels, MAP_TYPE mt)
245
{
246
    DECL_TRACER("TMap::findButtons(int port, vector<int>& channels, MAP_TYPE mt)");
247
 
248
    vector<MAP_T> map;
249
    vector<int>::iterator iter;
250
 
251
    if (channels.empty())
252
    {
253
        MSG_WARNING("Got empty channel list!");
254
        return map;
255
    }
256
 
257
    vector<MAP_T> localMap;
258
 
259
    switch (mt)
260
    {
261
        case TYPE_AM:   localMap = mMap.map_am; break;
262
        case TYPE_CM:   localMap = mMap.map_cm; break;
263
        case TYPE_LM:   localMap = mMap.map_lm; break;
264
    }
265
 
266
    if (localMap.empty())
267
    {
268
        MSG_WARNING("The internal list of elements is empty!")
269
        return map;
270
    }
271
 
272
    for (iter = channels.begin(); iter != channels.end(); ++iter)
273
    {
274
        vector<MAP_T>::iterator mapIter;
275
 
276
        for (mapIter = localMap.begin(); mapIter != localMap.end(); ++mapIter)
277
        {
278
            if (mapIter->p == port && mapIter->c == *iter)
279
                map.push_back(*mapIter);
280
        }
281
    }
282
 
283
    MSG_DEBUG("Found " << map.size() << " buttons.");
284
    return map;
285
}
286
 
287
vector<TMap::MAP_T> TMap::findButtonByName(const string& name)
288
{
289
    DECL_TRACER("TAmxCommands::findButtonByName(const string& name)");
290
 
291
    vector<MAP_T> map;
292
 
293
    if (mMap.map_cm.empty())
294
    {
295
        MSG_WARNING("The internal list of elements is empty!")
296
        return map;
297
    }
298
 
299
    vector<MAP_T>::iterator mapIter;
300
 
301
    for (mapIter = mMap.map_cm.begin(); mapIter != mMap.map_cm.end(); ++mapIter)
302
    {
303
        if (mapIter->bn == name)
304
            map.push_back(*mapIter);
305
    }
306
 
307
    MSG_DEBUG("Found " << map.size() << " buttons.");
308
    return map;
309
}
310
 
311
string TMap::findImage(int bt, int page, int instance)
312
{
313
    DECL_TRACER("TAmxCommands::findImage(int bt, int page, int instance)");
314
 
315
    vector<MAP_BM_T> mapBm = mMap.map_bm;
316
    vector<MAP_BM_T>::iterator iter;
317
 
318
    if (mapBm.empty())
319
        return string();
320
 
321
    for (iter = mapBm.begin(); iter != mapBm.end(); ++iter)
322
    {
323
        if (iter->bt == bt && iter->pg == page && !iter->i.empty())
324
        {
325
            if (instance >= 0 && iter->st == (instance + 1))
326
                return iter->i;
327
            else if (instance < 0)
328
                return iter->i;
329
        }
330
    }
331
 
332
    return string();
333
}
334
 
335
string TMap::findImage(const string& name)
336
{
337
    DECL_TRACER("TAmxCommands::findImage(const string& name)");
338
 
339
    vector<MAP_BM_T> mapBm = mMap.map_bm;
340
    vector<MAP_BM_T>::iterator iter;
341
 
342
    if (mapBm.empty() || name.empty())
343
        return string();
344
 
345
    size_t cnt = 0;
346
 
347
    for (iter = mapBm.begin(); iter != mapBm.end(); ++iter)
348
    {
349
        if (!iter->i.empty() && iter->i.find(name) != string::npos)
350
        {
351
            size_t pos = iter->i.find_last_of(".");
352
 
353
            if (pos != string::npos)
354
            {
355
                string left = iter->i.substr(0, pos);
356
 
357
                if (left == name)
358
                    return iter->i;
359
            }
360
        }
361
 
362
        cnt++;
363
    }
364
 
365
    MSG_WARNING("No image with name " << name << " in table found!");
366
    return string();
367
}
368
 
369
vector<TMap::MAP_T> TMap::findBargraphs(int port, vector<int>& channels)
370
{
371
    DECL_TRACER("TAmxCommands::findBargraphs(int port, vector<int>& channels)");
372
 
373
    vector<MAP_T> map;
374
    vector<int>::iterator iter;
375
 
486 andreas 376
    if (channels.empty())
446 andreas 377
        return map;
378
 
379
    for (iter = channels.begin(); iter != channels.end(); ++iter)
380
    {
381
        vector<MAP_T>::iterator mapIter;
382
 
486 andreas 383
        if (!mMap.map_lm.empty())
446 andreas 384
        {
385
            for (mapIter = mMap.map_lm.begin(); mapIter != mMap.map_lm.end(); ++mapIter)
386
            {
387
                // To find also the joysticks, we must test for level codes
388
                // less then and grater then *iter.
389
                if (mapIter->p == port && (mapIter->c == *iter || mapIter->c == (*iter-1) || mapIter->c == (*iter+1)))
390
                    map.push_back(*mapIter);
391
            }
392
        }
393
    }
394
 
395
    MSG_DEBUG("Found " << map.size() << " buttons.");
396
    return map;
397
}
398
 
399
vector<string> TMap::findSounds()
400
{
401
    DECL_TRACER("TAmxCommands::findSounds()");
402
 
403
    return mMap.map_sm;
404
}
405
 
406
bool TMap::soundExist(const string& sname)
407
{
408
    DECL_TRACER("TAmxCommands::soundExist(const string sname)");
409
 
462 andreas 410
    if (mIsTP5)
411
        return false;
412
 
446 andreas 413
    if (mMap.map_sm.size() == 0)
414
        return false;
415
 
416
    vector<string>::iterator iter;
417
 
418
    for (iter = mMap.map_sm.begin(); iter != mMap.map_sm.end(); ++iter)
419
    {
420
        if (iter->compare(sname) == 0)
421
            return true;
422
    }
423
 
424
    return false;
425
}