Subversion Repositories tpanel

Rev

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