mirror of
https://github.com/EdgeTX/edgetx.git
synced 2025-07-21 15:25:12 +03:00
[simulation] Fix some potential crashes & 26 memory leaks, improve LCD redraws. (#4634)
* [simulation] Hardening: Fix some potential crashes & 26 memory leaks, improve LCD performance. * [simpgmspace] Init trims; Make sure `REa` is really defined (to match board files). * [simpgmspace][opentxsimulator] Verify current running state before start/stop; Move rotary enc. init. * [simpgmspace][LcdWidget] Improve performance by moving LCD content change check to lcdRefresh() & limiting LcdWidget refresh time to 60 fps max. * [simueeprom] Ensure thread could be started, set default running state to false. * [simufatfs] Fix paths report trace. * [eepromimportexport] Fix memory leaks resulting from import debugging scheme being used. * [customdebug] Introduce new scheme for custom debug output in compliance with Qt recommendations (see docs for QLoggingCategory). * [opentxeeprom] Fix extra conversion table cache elements being created and also not properly deleted (and hence leaking). * [opentxinterface] Unregister EEpromInterfaces in unregisterOpenTxFirmwares(); * [storage] Unregister storage factories on exit (fixes leak); create virtual StorageFormat/StorageFactory destructors (prevents warnings). * [helpers] GVarGroup now emits own signal, no need to pass ModelPanel pointer (removes dependency on modeledit.h) * [DebugOutput] Clear simulator trace hook before exiting (prevent possible issues); Fix leak and possible bad QString allocations when reading from buffer; Fix leak with combo box event filter. * [TelemetrySimulator] Fix leak by deleting LogPlaybackController object on exit; Only set up data fields once; convert timers to static. * [build] Consolidate all Companion/Simulator shared items in `common` library to reduce build time/etc (node & edge still remain awkward). * [simulatorwidget] Delete removed spacer object (previously-forgotten "26th" leak). * [DebugOutput] Fix stray trailing characters issue with new text buffer allocation (from previous commit); Increase maximum buffer sizes to better accommodate slower systems. * Cosmetics.
This commit is contained in:
parent
52e65179a8
commit
4aa0c1bbe4
28 changed files with 290 additions and 210 deletions
|
@ -124,7 +124,9 @@ add_subdirectory(thirdparty/qxtcommandoptions)
|
|||
set(common_SRCS
|
||||
appdebugmessagehandler.cpp
|
||||
boards.cpp
|
||||
customdebug.cpp
|
||||
eeprominterface.cpp
|
||||
helpers.cpp
|
||||
radiodata.cpp
|
||||
firmwares/er9x/er9xeeprom.cpp
|
||||
firmwares/er9x/er9xinterface.cpp
|
||||
|
@ -132,21 +134,25 @@ set(common_SRCS
|
|||
firmwares/ersky9x/ersky9xinterface.cpp
|
||||
firmwares/opentx/opentxeeprom.cpp
|
||||
firmwares/opentx/opentxinterface.cpp
|
||||
modeledit/node.cpp # used in simulator
|
||||
modeledit/edge.cpp # used by node
|
||||
)
|
||||
|
||||
set(common_MOC_HDRS
|
||||
appdebugmessagehandler.h
|
||||
helpers.h
|
||||
modeledit/node.h
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS})
|
||||
|
||||
add_library(common ${common_SRCS})
|
||||
qt5_use_modules(common Core Xml Widgets)
|
||||
target_link_libraries(common simulation)
|
||||
|
||||
############# Companion ###############
|
||||
|
||||
set(companion_SRCS
|
||||
helpers.cpp
|
||||
helpers_html.cpp
|
||||
mdichild.cpp
|
||||
modelslist.cpp
|
||||
|
@ -206,7 +212,6 @@ set(companion_MOC_HDRS
|
|||
mdichild.h
|
||||
mainwindow.h
|
||||
radionotfound.h
|
||||
helpers.h
|
||||
wizarddialog.h
|
||||
modelprinter.h
|
||||
multimodelprinter.h
|
||||
|
@ -259,9 +264,9 @@ qt5_wrap_ui(companion_SRCS ${companion_UIS})
|
|||
qt5_wrap_cpp(companion_SRCS ${companion_MOC_HDRS})
|
||||
qt5_add_translation(companion_QM ${companion_TS})
|
||||
qt5_add_resources(companion_RCC ${companion_RESOURCES})
|
||||
add_custom_target(gen_qrc DEPENDS ${companion_RCC})
|
||||
add_custom_target(gen_qrc DEPENDS ${companion_RCC} ${companion_QM})
|
||||
|
||||
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${companion_RCC} ${companion_QM})
|
||||
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${companion_RCC})
|
||||
|
||||
add_dependencies(${COMPANION_NAME} gen_qrc)
|
||||
qt5_use_modules(${COMPANION_NAME} Core Widgets Network)
|
||||
|
@ -272,19 +277,7 @@ PrintTargetReport("${COMPANION_NAME}")
|
|||
|
||||
############# Standalone simulator ###############
|
||||
|
||||
set(simu_SRCS
|
||||
modeledit/node.cpp
|
||||
modeledit/edge.cpp
|
||||
helpers.cpp
|
||||
simulator.cpp
|
||||
)
|
||||
|
||||
set(simu_MOC_HDRS
|
||||
modeledit/node.h
|
||||
helpers.h
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(simu_SRCS ${simu_MOC_HDRS} )
|
||||
set(simu_SRCS simulator.cpp )
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND simu_SRCS icon.rc)
|
||||
|
@ -293,7 +286,7 @@ endif()
|
|||
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${companion_RCC})
|
||||
add_dependencies(${SIMULATOR_NAME} gen_qrc)
|
||||
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common shared storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
|
||||
############# Translations ####################
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#endif
|
||||
|
||||
#include "appdebugmessagehandler.h"
|
||||
#include "customdebug.h"
|
||||
#include "mainwindow.h"
|
||||
#include "version.h"
|
||||
#include "appdata.h"
|
||||
|
@ -65,6 +66,8 @@ int main(int argc, char *argv[])
|
|||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
|
||||
CustomDebug::setFilterRules();
|
||||
|
||||
g.init();
|
||||
|
||||
QStringList strl = QApplication::arguments();
|
||||
|
@ -134,7 +137,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
unregisterSimulators();
|
||||
unregisterOpenTxFirmwares();
|
||||
unregisterEEpromInterfaces();
|
||||
unregisterStorageFactories();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
|
|
36
companion/src/customdebug.cpp
Normal file
36
companion/src/customdebug.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "customdebug.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(eepromImport, "eeprom.import")
|
||||
|
||||
void CustomDebug::setFilterRules()
|
||||
{
|
||||
QString rules;
|
||||
rules.append("eeprom.import=");
|
||||
#if defined(DEBUG_STORAGE_IMPORT)
|
||||
rules.append("true");
|
||||
#else
|
||||
rules.append("false");
|
||||
#endif
|
||||
|
||||
QLoggingCategory::setFilterRules(rules);
|
||||
}
|
|
@ -21,15 +21,15 @@
|
|||
#ifndef _CUSTOMDEBUG_H_
|
||||
#define _CUSTOMDEBUG_H_
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
// Controls the generation of debug output for EEPROM import
|
||||
#if defined(DEBUG_STORAGE_IMPORT)
|
||||
inline QDebug eepromImportDebug() { return QDebug(QtDebugMsg); }
|
||||
#else
|
||||
#undef eepromImportDebug
|
||||
inline QNoDebug eepromImportDebug() { return QNoDebug(); }
|
||||
#endif
|
||||
Q_DECLARE_LOGGING_CATEGORY(eepromImport)
|
||||
|
||||
class CustomDebug
|
||||
{
|
||||
public:
|
||||
static void setFilterRules();
|
||||
};
|
||||
|
||||
#endif // _CUSTOMDEBUG_H_
|
||||
|
|
|
@ -181,7 +181,7 @@ class BaseUnsignedField: public DataField {
|
|||
if (input[i])
|
||||
field |= ((container)1<<i);
|
||||
}
|
||||
eepromImportDebug() << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
|
@ -238,7 +238,7 @@ class BoolField: public DataField {
|
|||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
field = input[0] ? true : false;
|
||||
eepromImportDebug() << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
|
@ -308,7 +308,7 @@ class SignedField: public DataField {
|
|||
}
|
||||
|
||||
field = (int)value;
|
||||
eepromImportDebug() << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
|
@ -369,7 +369,7 @@ class CharField: public DataField {
|
|||
}
|
||||
field[i] = idx;
|
||||
}
|
||||
eepromImportDebug() << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
|
@ -427,7 +427,7 @@ class ZCharField: public DataField {
|
|||
else
|
||||
break;
|
||||
}
|
||||
eepromImportDebug() << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
|
||||
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
|
||||
}
|
||||
|
||||
virtual unsigned int size()
|
||||
|
@ -453,7 +453,7 @@ class StructField: public DataField {
|
|||
}
|
||||
|
||||
inline void Append(DataField * field) {
|
||||
//eepromImportDebug() << QString("StructField(%1) appending field: %2").arg(name).arg(field->getName());
|
||||
//qCDebug(eepromImport) << QString("StructField(%1) appending field: %2").arg(name).arg(field->getName());
|
||||
fields.append(field);
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,7 @@ class StructField: public DataField {
|
|||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
eepromImportDebug() << QString("\timporting %1[%2]:").arg(name).arg(fields.size());
|
||||
qCDebug(eepromImport) << QString("\timporting %1[%2]:").arg(name).arg(fields.size());
|
||||
int offset = 0;
|
||||
foreach(DataField *field, fields) {
|
||||
unsigned int size = field->size();
|
||||
|
@ -526,7 +526,7 @@ class TransformedField: public DataField {
|
|||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
eepromImportDebug() << QString("\timporting TransformedField %1:").arg(field.getName());
|
||||
qCDebug(eepromImport) << QString("\timporting TransformedField %1:").arg(field.getName());
|
||||
field.ImportBits(input);
|
||||
afterImport();
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ class ConversionTable {
|
|||
after = 0;
|
||||
|
||||
for (std::list<ConversionTuple>::iterator it=exportTable.begin(); it!=exportTable.end(); it++) {
|
||||
ConversionTuple tuple = *it;
|
||||
ConversionTuple & tuple = *it;
|
||||
if (before == tuple.a) {
|
||||
after = tuple.b;
|
||||
return true;
|
||||
|
@ -579,7 +579,7 @@ class ConversionTable {
|
|||
after = 0;
|
||||
|
||||
for (std::list<ConversionTuple>::iterator it=importTable.begin(); it!=importTable.end(); it++) {
|
||||
ConversionTuple tuple = *it;
|
||||
ConversionTuple & tuple = *it;
|
||||
if (before == tuple.b) {
|
||||
after = tuple.a;
|
||||
return true;
|
||||
|
@ -756,7 +756,7 @@ class ConversionField: public TransformedField {
|
|||
if (scale) {
|
||||
field *= scale;
|
||||
}
|
||||
eepromImportDebug() << QString("\timported ConversionField<%1>:").arg(internalField.getName()) << QString(" before: %1, after: %2").arg(_field).arg(field);
|
||||
qCDebug(eepromImport) << QString("\timported ConversionField<%1>:").arg(internalField.getName()) << QString(" before: %1, after: %2").arg(_field).arg(field);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -160,6 +160,7 @@ class SwitchesConversionTable: public ConversionTable {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void addConversion(const RawSwitch & sw, const int b)
|
||||
|
@ -199,7 +200,7 @@ class SwitchesConversionTable: public ConversionTable {
|
|||
static SwitchesConversionTable * getInstance(Board::Type board, unsigned int version, unsigned long flags=0)
|
||||
{
|
||||
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
|
||||
Cache element = *it;
|
||||
Cache & element = *it;
|
||||
if (element.board == board && element.version == version && element.flags == flags)
|
||||
return element.table;
|
||||
}
|
||||
|
@ -211,7 +212,8 @@ class SwitchesConversionTable: public ConversionTable {
|
|||
static void Cleanup()
|
||||
{
|
||||
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
|
||||
Cache element = *it;
|
||||
Cache & element = *it;
|
||||
if (element.table)
|
||||
delete element.table;
|
||||
}
|
||||
internalCache.clear();
|
||||
|
@ -386,7 +388,7 @@ class SourcesConversionTable: public ConversionTable {
|
|||
static SourcesConversionTable * getInstance(Board::Type board, unsigned int version, unsigned int variant, unsigned long flags=0)
|
||||
{
|
||||
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
|
||||
Cache element = *it;
|
||||
Cache & element = *it;
|
||||
if (element.board == board && element.version == version && element.variant == variant && element.flags == flags)
|
||||
return element.table;
|
||||
}
|
||||
|
@ -398,7 +400,8 @@ class SourcesConversionTable: public ConversionTable {
|
|||
static void Cleanup()
|
||||
{
|
||||
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
|
||||
Cache element = *it;
|
||||
Cache & element = *it;
|
||||
if (element.table)
|
||||
delete element.table;
|
||||
}
|
||||
internalCache.clear();
|
||||
|
@ -439,7 +442,7 @@ class SwitchField: public ConversionField< SignedField<N> > {
|
|||
{
|
||||
ConversionField< SignedField<N> >::afterImport();
|
||||
sw = RawSwitch(_switch);
|
||||
eepromImportDebug() << QString("imported %1: %2").arg(ConversionField< SignedField<N> >::internalField.getName()).arg(sw.toString(board));
|
||||
qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< SignedField<N> >::internalField.getName()).arg(sw.toString(board));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -565,7 +568,7 @@ class TelemetrySourceField: public ConversionField< UnsignedField<N> > {
|
|||
{
|
||||
ConversionField< UnsignedField<N> >::afterImport();
|
||||
source = (_source == 0 ? RawSource(0) : RawSource(SOURCE_TYPE_TELEMETRY, _source-1));
|
||||
eepromImportDebug() << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
|
||||
qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -601,7 +604,7 @@ class SourceField: public ConversionField< UnsignedField<N> > {
|
|||
{
|
||||
ConversionField< UnsignedField<N> >::afterImport();
|
||||
source = RawSource(_source);
|
||||
eepromImportDebug() << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
|
||||
qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -760,7 +763,7 @@ class CurveReferenceField: public TransformedField {
|
|||
{
|
||||
curve.type = (CurveReference::CurveRefType)_curve_type;
|
||||
curve.value = smallGvarToC9x(_curve_value);
|
||||
eepromImportDebug() << QString("imported CurveReference(%1)").arg(curve.toString());
|
||||
qCDebug(eepromImport) << QString("imported CurveReference(%1)").arg(curve.toString());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -942,7 +945,7 @@ class FlightModeField: public TransformedField {
|
|||
}
|
||||
}
|
||||
}
|
||||
eepromImportDebug() << QString("imported %1: '%2'").arg(internalField.getName()).arg(phase.name);
|
||||
qCDebug(eepromImport) << QString("imported %1: '%2'").arg(internalField.getName()).arg(phase.name);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -1231,7 +1234,7 @@ class MixField: public TransformedField {
|
|||
}
|
||||
if (mix.carryTrim < 0) mix.carryTrim = 0;
|
||||
}
|
||||
eepromImportDebug() << QString("imported %1: ch %2, name '%3'").arg(internalField.getName()).arg(mix.destCh).arg(mix.name);
|
||||
qCDebug(eepromImport) << QString("imported %1: ch %2, name '%3'").arg(internalField.getName()).arg(mix.destCh).arg(mix.name);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -1412,7 +1415,7 @@ class InputField: public TransformedField {
|
|||
else
|
||||
expo.curve = CurveReference(CurveReference::CURVE_REF_FUNC, _curveParam);
|
||||
}
|
||||
eepromImportDebug() << QString("imported %1: ch %2 name '%3'").arg(internalField.getName()).arg(expo.chn).arg(expo.name);
|
||||
qCDebug(eepromImport) << QString("imported %1: ch %2 name '%3'").arg(internalField.getName()).arg(expo.chn).arg(expo.name);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -1626,7 +1629,7 @@ class CurvesField: public TransformedField {
|
|||
for (int j=0; j<curve->count; j++)
|
||||
curve->points[j].x = -100 + (200*i) / (curve->count-1);
|
||||
}
|
||||
eepromImportDebug() << QString("imported curve: %3 points").arg(curve->count);
|
||||
qCDebug(eepromImport) << QString("imported curve: %3 points").arg(curve->count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1955,7 +1958,7 @@ class LogicalSwitchField: public TransformedField {
|
|||
}
|
||||
}
|
||||
}
|
||||
eepromImportDebug() << QString("imported %1: %2").arg(internalField.getName()).arg(csw.funcToString());
|
||||
qCDebug(eepromImport) << QString("imported %1: %2").arg(internalField.getName()).arg(csw.funcToString());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2115,7 +2118,7 @@ class SwitchesWarningField: public TransformedField {
|
|||
else {
|
||||
sw = _sw;
|
||||
}
|
||||
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
|
||||
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2350,7 +2353,7 @@ class ArmCustomFunctionField: public TransformedField {
|
|||
else {
|
||||
fn.param = value;
|
||||
}
|
||||
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
|
||||
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2539,7 +2542,7 @@ class AvrCustomFunctionField: public TransformedField {
|
|||
else if (version >= 213)
|
||||
fn.repeatParam = _active * 10;
|
||||
}
|
||||
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
|
||||
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2634,7 +2637,7 @@ class FrskyScreenField: public DataField {
|
|||
|
||||
virtual void ImportBits(const QBitArray & input)
|
||||
{
|
||||
eepromImportDebug() << QString("importing %1: type: %2").arg(name).arg(screen.type);
|
||||
qCDebug(eepromImport) << QString("importing %1: type: %2").arg(name).arg(screen.type);
|
||||
|
||||
// NOTA: screen.type should have been imported first!
|
||||
if (IS_ARM(board) && version >= 217) {
|
||||
|
@ -3007,7 +3010,7 @@ class SensorField: public TransformedField {
|
|||
sensor.unit++;
|
||||
}
|
||||
|
||||
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
|
||||
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -3041,7 +3044,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
|
|||
{
|
||||
sprintf(name, "Model %s", modelData.name);
|
||||
|
||||
eepromImportDebug() << QString("OpenTxModelData::OpenTxModelData(name: %1, board: %2, ver: %3, var: %4)").arg(name).arg(board).arg(version).arg(variant);
|
||||
qCDebug(eepromImport) << QString("OpenTxModelData::OpenTxModelData(name: %1, board: %2, ver: %3, var: %4)").arg(name).arg(board).arg(version).arg(variant);
|
||||
|
||||
if (IS_HORUS(board))
|
||||
internalField.Append(new ZCharField<15>(this, modelData.name, "Model name"));
|
||||
|
@ -3452,7 +3455,7 @@ void OpenTxModelData::beforeExport()
|
|||
|
||||
void OpenTxModelData::afterImport()
|
||||
{
|
||||
eepromImportDebug() << QString("OpenTxModelData::afterImport()") << modelData.name;
|
||||
qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name;
|
||||
|
||||
if (IS_TARANIS(board) && version < 216) {
|
||||
for (unsigned int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
|
@ -3520,7 +3523,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
|||
version(version),
|
||||
inputsCount(CPN_MAX_STICKS+MAX_POTS(board, version)+MAX_SLIDERS(board)+MAX_MOUSE_ANALOGS(board))
|
||||
{
|
||||
eepromImportDebug() << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant);
|
||||
qCDebug(eepromImport) << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant);
|
||||
|
||||
generalData.version = version;
|
||||
generalData.variant = variant;
|
||||
|
|
|
@ -1514,6 +1514,7 @@ void unregisterOpenTxFirmwares()
|
|||
foreach (Firmware * f, firmwares) {
|
||||
delete f;
|
||||
}
|
||||
unregisterEEpromInterfaces();
|
||||
}
|
||||
|
||||
template <class T, class M>
|
||||
|
|
|
@ -31,10 +31,12 @@
|
|||
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "modeledit/modeledit.h"
|
||||
#include "simulatormainwindow.h"
|
||||
#include "storage/sdcard.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
|
||||
Stopwatch gStopwatch("global");
|
||||
|
||||
const QColor colors[CPN_MAX_CURVES] = {
|
||||
|
@ -126,7 +128,11 @@ void populatePhasesCB(QComboBox *b, int value)
|
|||
b->setCurrentIndex(value + getCurrentFirmware()->getCapability(FlightModes));
|
||||
}
|
||||
|
||||
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step, bool allowGvars, ModelPanel * panel):
|
||||
/*
|
||||
* GVarGroup
|
||||
*/
|
||||
|
||||
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step, bool allowGvars):
|
||||
QObject(),
|
||||
weightGV(weightGV),
|
||||
weightSB(weightSB),
|
||||
|
@ -135,8 +141,7 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
|
|||
weightCB(weightCB),
|
||||
weight(weight),
|
||||
step(step),
|
||||
lock(true),
|
||||
panel(panel)
|
||||
lock(true)
|
||||
{
|
||||
if (allowGvars && getCurrentFirmware()->getCapability(Gvars)) {
|
||||
populateGVCB(*weightCB, weight, model);
|
||||
|
@ -200,12 +205,15 @@ void GVarGroup::valuesChanged()
|
|||
weight = sb->value();
|
||||
else
|
||||
weight = round(dsb->value()/step);
|
||||
if (panel)
|
||||
emit panel->modified();
|
||||
|
||||
emit valueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CurveGroup
|
||||
*/
|
||||
|
||||
CurveGroup::CurveGroup(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QComboBox * curveValueCB, QSpinBox * curveValueSB, CurveReference & curve, const ModelData & model, unsigned int flags):
|
||||
QObject(),
|
||||
curveTypeCB(curveTypeCB),
|
||||
|
@ -364,6 +372,10 @@ void CurveGroup::valuesChanged()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
void populateGvarUseCB(QComboBox *b, unsigned int phase)
|
||||
{
|
||||
b->addItem(QObject::tr("Own value"));
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#define _HELPERS_H_
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include "modeledit/modeledit.h"
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
#include <QTableWidget>
|
||||
|
@ -69,7 +68,10 @@ class GVarGroup: public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true, ModelPanel * panel=NULL);
|
||||
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true);
|
||||
|
||||
signals:
|
||||
void valueChanged();
|
||||
|
||||
protected slots:
|
||||
void gvarCBChanged(int);
|
||||
|
@ -84,7 +86,6 @@ class GVarGroup: public QObject {
|
|||
int & weight;
|
||||
double step;
|
||||
bool lock;
|
||||
ModelPanel * panel;
|
||||
};
|
||||
|
||||
#define HIDE_DIFF 0x01
|
||||
|
@ -157,26 +158,6 @@ QString getFrSkySrc(int index);
|
|||
|
||||
void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx);
|
||||
|
||||
template <class T>
|
||||
QVector<T> findWidgets(QObject * object, const QString & name)
|
||||
{
|
||||
QVector<T> result;
|
||||
QRegExp rx(name.arg("([0-9]+)"));
|
||||
QList<T> children = object->findChildren<T>();
|
||||
foreach(T child, children) {
|
||||
int pos = rx.indexIn(child->objectName());
|
||||
if (pos >= 0) {
|
||||
QStringList list = rx.capturedTexts();
|
||||
int index = list[1].toInt();
|
||||
if (result.size() <= index) {
|
||||
result.resize(index+1);
|
||||
}
|
||||
result[index] = child;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Format a pixmap to fit on the current firmware
|
||||
QPixmap makePixMap(const QImage & image);
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#ifndef _MACROS_H_
|
||||
#define _MACROS_H_
|
||||
|
||||
#define DIM(arr) (sizeof((arr))/sizeof((arr)[0]))
|
||||
#include <iterator>
|
||||
|
||||
// #define DIM(arr) (sizeof((arr))/sizeof((arr)[0]))
|
||||
// new way for c++11
|
||||
#define DIM(arr__) ((size_t)(std::end((arr__)) - std::begin((arr__))))
|
||||
|
||||
#endif // _MACROS_H_
|
|
@ -23,8 +23,8 @@ set(modeledit_SRCS
|
|||
customfunctions.cpp
|
||||
# templates.cpp
|
||||
mixerslistwidget.cpp
|
||||
node.cpp
|
||||
edge.cpp
|
||||
# node.cpp ## node and edge are built in common lib because also used by simulator
|
||||
# edge.cpp ## commenting them here avoids a "duplicate target" warning eg. from ninja
|
||||
)
|
||||
|
||||
set(modeledit_HDRS
|
||||
|
@ -36,7 +36,7 @@ set(modeledit_HDRS
|
|||
customfunctions.h
|
||||
# templates.h
|
||||
mixerslistwidget.h
|
||||
node.h
|
||||
# node.h
|
||||
)
|
||||
|
||||
set(modeledit_UIS
|
||||
|
|
|
@ -64,7 +64,8 @@ LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row
|
|||
horizontalLayout->addWidget(cb);
|
||||
horizontalLayout->addWidget(spinbox);
|
||||
tableLayout->addLayout(row, col, horizontalLayout);
|
||||
gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, allowGVars, panel);
|
||||
gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, allowGVars);
|
||||
QObject::connect(gvarGroup, &GVarGroup::valueChanged, panel, &ModelPanel::modified);
|
||||
}
|
||||
|
||||
LimitsGroup::~LimitsGroup()
|
||||
|
|
|
@ -71,7 +71,7 @@ DebugOutput::DebugOutput(QWidget * parent, SimulatorInterface *simulator):
|
|||
ui->filterText->addItem(fltr, "no_delete");
|
||||
|
||||
ui->filterText->setValidator(new DebugOutputFilterValidator(ui->filterText));
|
||||
ui->filterText->installEventFilter(new DeleteComboBoxItemEventFilter());
|
||||
ui->filterText->installEventFilter(new DeleteComboBoxItemEventFilter(this));
|
||||
|
||||
ui->actionShowFilterHelp->setIcon(SimulatorIcon("info"));
|
||||
ui->actionWordWrap->setIcon(SimulatorIcon("word_wrap"));
|
||||
|
@ -115,6 +115,7 @@ DebugOutput::DebugOutput(QWidget * parent, SimulatorInterface *simulator):
|
|||
|
||||
DebugOutput::~DebugOutput()
|
||||
{
|
||||
m_simulator->installTraceHook(NULL);
|
||||
saveState();
|
||||
|
||||
if (AppDebugMessageHandler::instance())
|
||||
|
@ -173,15 +174,18 @@ void DebugOutput::restoreState()
|
|||
|
||||
void DebugOutput::processBytesReceived()
|
||||
{
|
||||
static char buf[512];
|
||||
const QTextCursor savedCursor(ui->console->textCursor());
|
||||
const int sbValue = ui->console->verticalScrollBar()->value();
|
||||
const bool sbAtBottom = (sbValue == ui->console->verticalScrollBar()->maximum());
|
||||
qint64 len;
|
||||
QString text;
|
||||
|
||||
while ((len = m_dataBufferDevice->bytesAvailable()) > 0) {
|
||||
QString text(m_dataBufferDevice->read(qMin(len, qint64(512))));
|
||||
if (text.isEmpty())
|
||||
while (m_dataBufferDevice && m_dataBufferDevice->bytesAvailable() > 0) {
|
||||
len = m_dataBufferDevice->read(buf, sizeof(buf));
|
||||
if (len <= 0)
|
||||
break;
|
||||
text = QString::fromLocal8Bit(buf, len);
|
||||
ui->console->moveCursor(QTextCursor::End);
|
||||
ui->console->textCursor().insertText(text);
|
||||
if (sbAtBottom) {
|
||||
|
|
|
@ -29,14 +29,15 @@
|
|||
#include <QValidator>
|
||||
#include <QWidget>
|
||||
|
||||
// NOTE : The buffer sizes need to be large enough to handle the flood of data when X12/X10 simulator starts up (almost 40K!).
|
||||
// NOTE : The buffer sizes need to be large enough to handle the flood of data when X12/X10 simulator starts up with TRACE_SIMPGMSPACE=1 (> 40K!).
|
||||
// These are maximum sizes, not necessarily allocated sizes.
|
||||
#ifndef DEBUG_OUTPUT_WIDGET_OUT_BUFF_SIZE
|
||||
// This buffer holds received and processed data until it can be printed to our console.
|
||||
#define DEBUG_OUTPUT_WIDGET_OUT_BUFF_SIZE (40 * 1024) // [bytes]
|
||||
#define DEBUG_OUTPUT_WIDGET_OUT_BUFF_SIZE (50 * 1024) // [bytes]
|
||||
#endif
|
||||
#ifndef DEBUG_OUTPUT_WIDGET_INP_BUFF_SIZE
|
||||
// This buffer is active if line filter is enabled and holds received data until it can be filtered and placed in output buffer.
|
||||
#define DEBUG_OUTPUT_WIDGET_INP_BUFF_SIZE (30 * 1024) // [bytes]
|
||||
#define DEBUG_OUTPUT_WIDGET_INP_BUFF_SIZE (50 * 1024) // [bytes]
|
||||
#endif
|
||||
|
||||
namespace Ui {
|
||||
|
@ -101,6 +102,8 @@ class DebugOutputFilterValidator : public QValidator
|
|||
class DeleteComboBoxItemEventFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DeleteComboBoxItemEventFilter(QObject *parent = Q_NULLPTR) : QObject(parent) { }
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
};
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
|
||||
extern AppData g; // ensure what "g" means
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#endif
|
||||
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <iostream>
|
||||
|
||||
SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface *simulator, quint8 flags):
|
||||
|
@ -99,6 +100,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface *simulator
|
|||
keymapHelp.append(item);
|
||||
|
||||
ui->radioUiWidget->layout()->removeItem(ui->radioUiTempSpacer);
|
||||
delete ui->radioUiTempSpacer;
|
||||
ui->radioUiWidget->layout()->addWidget(radioUiWidget);
|
||||
radioUiWidget->setFocusPolicy(Qt::WheelFocus);
|
||||
radioUiWidget->setFocus();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "radiodata.h"
|
||||
#include "simulator.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
#include <QVector>
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
|
|||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(10);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(onTimerEvent()));
|
||||
setupDataFields();
|
||||
|
||||
logTimer = new QTimer(this);
|
||||
connect(logTimer, SIGNAL(timeout()), this, SLOT(onLogTimerEvent()));
|
||||
timer.setInterval(10);
|
||||
connect(&timer, &QTimer::timeout, this, &TelemetrySimulator::generateTelemetryFrame);
|
||||
|
||||
connect(&logTimer, &QTimer::timeout, this, &TelemetrySimulator::onLogTimerEvent);
|
||||
|
||||
connect(ui->Simulate, SIGNAL(toggled(bool)), this, SLOT(onSimulateToggled(bool)));
|
||||
connect(ui->loadLogFile, SIGNAL(released()), this, SLOT(onLoadLogFile()));
|
||||
|
@ -64,33 +64,27 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
|
|||
|
||||
TelemetrySimulator::~TelemetrySimulator()
|
||||
{
|
||||
timer->stop();
|
||||
logTimer->stop();
|
||||
timer.stop();
|
||||
logTimer.stop();
|
||||
delete logPlayback;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TelemetrySimulator::onSimulateToggled(bool isChecked)
|
||||
{
|
||||
if (isChecked) {
|
||||
timer->start();
|
||||
timer.start();
|
||||
}
|
||||
else {
|
||||
timer->stop();
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TelemetrySimulator::onLogTimerEvent()
|
||||
{
|
||||
logPlayback->stepForward(false);
|
||||
}
|
||||
|
||||
|
||||
void TelemetrySimulator::onTimerEvent()
|
||||
{
|
||||
generateTelemetryFrame();
|
||||
}
|
||||
|
||||
void TelemetrySimulator::onLoadLogFile()
|
||||
{
|
||||
onStop(); // in case we are in playback mode
|
||||
|
@ -100,7 +94,7 @@ void TelemetrySimulator::onLoadLogFile()
|
|||
void TelemetrySimulator::onPlay()
|
||||
{
|
||||
if (logPlayback->isReady()) {
|
||||
logTimer->start(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
|
||||
logTimer.start(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
|
||||
logPlayback->play();
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +102,7 @@ void TelemetrySimulator::onPlay()
|
|||
void TelemetrySimulator::onRewind()
|
||||
{
|
||||
if (logPlayback->isReady()) {
|
||||
logTimer->stop();
|
||||
logTimer.stop();
|
||||
logPlayback->rewind();
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +110,7 @@ void TelemetrySimulator::onRewind()
|
|||
void TelemetrySimulator::onStepForward()
|
||||
{
|
||||
if (logPlayback->isReady()) {
|
||||
logTimer->stop();
|
||||
logTimer.stop();
|
||||
logPlayback->stepForward(true);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +118,7 @@ void TelemetrySimulator::onStepForward()
|
|||
void TelemetrySimulator::onStepBack()
|
||||
{
|
||||
if (logPlayback->isReady()) {
|
||||
logTimer->stop();
|
||||
logTimer.stop();
|
||||
logPlayback->stepBack();
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +126,7 @@ void TelemetrySimulator::onStepBack()
|
|||
void TelemetrySimulator::onStop()
|
||||
{
|
||||
if (logPlayback->isReady()) {
|
||||
logTimer->stop();
|
||||
logTimer.stop();
|
||||
logPlayback->stop();
|
||||
}
|
||||
}
|
||||
|
@ -147,21 +141,21 @@ void TelemetrySimulator::onPositionIndicatorChanged(int value)
|
|||
|
||||
void TelemetrySimulator::onReplayRateChanged(int value)
|
||||
{
|
||||
if (logTimer->isActive()) {
|
||||
logTimer->setInterval(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
|
||||
if (logTimer.isActive()) {
|
||||
logTimer.setInterval(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
|
||||
}
|
||||
}
|
||||
|
||||
void TelemetrySimulator::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
timer->stop();
|
||||
logTimer->stop();
|
||||
timer.stop();
|
||||
logTimer.stop();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
#define SET_INSTANCE(control, id, def) ui->control->setText(QString::number(simulator->getSensorInstance(id, ((def) & 0x1F) + 1)))
|
||||
|
||||
void TelemetrySimulator::showEvent(QShowEvent *event)
|
||||
void TelemetrySimulator::setupDataFields()
|
||||
{
|
||||
SET_INSTANCE(rxbt_inst, BATT_ID, 0);
|
||||
SET_INSTANCE(rssi_inst, RSSI_ID, 24);
|
||||
|
@ -410,7 +404,7 @@ void TelemetrySimulator::generateTelemetryFrame()
|
|||
if (ok && (buffer[2] || buffer[3]))
|
||||
simulator->sendTelemetry(buffer, FRSKY_SPORT_PACKET_SIZE);
|
||||
else
|
||||
onTimerEvent();
|
||||
generateTelemetryFrame();
|
||||
}
|
||||
|
||||
uint32_t TelemetrySimulator::FlvssEmulator::encodeCellPair(uint8_t cellNum, uint8_t firstCellNo, double cell1, double cell2)
|
||||
|
|
|
@ -49,9 +49,9 @@ class TelemetrySimulator : public QWidget
|
|||
protected slots:
|
||||
|
||||
virtual void closeEvent(QCloseEvent *event);
|
||||
virtual void showEvent(QShowEvent *event);
|
||||
void setupDataFields();
|
||||
void onSimulateToggled(bool isChecked);
|
||||
void onTimerEvent();
|
||||
void generateTelemetryFrame();
|
||||
void onLogTimerEvent();
|
||||
void onLoadLogFile();
|
||||
void onPlay();
|
||||
|
@ -65,10 +65,9 @@ class TelemetrySimulator : public QWidget
|
|||
protected:
|
||||
|
||||
Ui::TelemetrySimulator * ui;
|
||||
QTimer * timer;
|
||||
QTimer * logTimer;
|
||||
QTimer timer;
|
||||
QTimer logTimer;
|
||||
SimulatorInterface *simulator;
|
||||
void generateTelemetryFrame();
|
||||
|
||||
// protected classes follow
|
||||
|
||||
|
|
|
@ -26,10 +26,15 @@
|
|||
#include <QPainter>
|
||||
#include <QClipboard>
|
||||
#include <QDir>
|
||||
#include <QElapsedTimer>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include "appdata.h"
|
||||
#include "appdebugmessagehandler.h"
|
||||
|
||||
#define LCD_WIDGET_REFRESH_PERIOD 16 // [ms] 16 = 62.5fps
|
||||
|
||||
class LcdWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -39,7 +44,7 @@ class LcdWidget : public QWidget
|
|||
LcdWidget(QWidget * parent = 0):
|
||||
QWidget(parent),
|
||||
lcdBuf(NULL),
|
||||
previousBuf(NULL),
|
||||
localBuf(NULL),
|
||||
lightEnable(false),
|
||||
bgDefaultColor(QColor(198, 208, 199))
|
||||
{
|
||||
|
@ -47,8 +52,8 @@ class LcdWidget : public QWidget
|
|||
|
||||
~LcdWidget()
|
||||
{
|
||||
if (previousBuf) {
|
||||
free(previousBuf);
|
||||
if (localBuf) {
|
||||
free(localBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,8 +67,9 @@ class LcdWidget : public QWidget
|
|||
lcdSize = (width * height) * ((depth+7) / 8);
|
||||
else
|
||||
lcdSize = (width * ((height+7)/8)) * depth;
|
||||
previousBuf = (unsigned char *)malloc(lcdSize);
|
||||
memset(previousBuf, 0, lcdSize);
|
||||
|
||||
localBuf = (unsigned char *)malloc(lcdSize);
|
||||
memset(localBuf, 0, lcdSize);
|
||||
}
|
||||
|
||||
void setBgDefaultColor(const QColor & color)
|
||||
|
@ -102,10 +108,12 @@ class LcdWidget : public QWidget
|
|||
|
||||
void onLcdChanged(bool light)
|
||||
{
|
||||
if (light != lightEnable || memcmp(previousBuf, lcdBuf, lcdSize)) {
|
||||
QMutexLocker locker(&lcdMtx);
|
||||
lightEnable = light;
|
||||
memcpy(previousBuf, lcdBuf, lcdSize);
|
||||
memcpy(localBuf, lcdBuf, lcdSize);
|
||||
if (!redrawTimer.isValid() || redrawTimer.hasExpired(LCD_WIDGET_REFRESH_PERIOD)) {
|
||||
update();
|
||||
redrawTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,24 +125,26 @@ class LcdWidget : public QWidget
|
|||
int lcdSize;
|
||||
|
||||
unsigned char *lcdBuf;
|
||||
unsigned char *previousBuf;
|
||||
unsigned char *localBuf;
|
||||
|
||||
bool lightEnable;
|
||||
QColor bgColor;
|
||||
QColor bgDefaultColor;
|
||||
QMutex lcdMtx;
|
||||
QElapsedTimer redrawTimer;
|
||||
|
||||
inline void doPaint(QPainter & p)
|
||||
{
|
||||
QRgb rgb;
|
||||
uint16_t z;
|
||||
|
||||
if (!lcdBuf)
|
||||
if (!localBuf)
|
||||
return;
|
||||
|
||||
if (lcdDepth == 16) {
|
||||
for (int x = 0; x < lcdWidth; x++) {
|
||||
for (int y = 0; y < lcdHeight; y++) {
|
||||
z = ((uint16_t *)lcdBuf)[y * lcdWidth + x];
|
||||
z = ((uint16_t *)localBuf)[y * lcdWidth + x];
|
||||
rgb = qRgb(255 * ((z & 0xF800) >> 11) / 0x1F,
|
||||
255 * ((z & 0x07E0) >> 5) / 0x3F,
|
||||
255 * (z & 0x001F) / 0x1F);
|
||||
|
@ -147,7 +157,7 @@ class LcdWidget : public QWidget
|
|||
if (lcdDepth == 12) {
|
||||
for (int x = 0; x < lcdWidth; x++) {
|
||||
for (int y = 0; y < lcdHeight; y++) {
|
||||
z = ((uint16_t *)lcdBuf)[y * lcdWidth + x];
|
||||
z = ((uint16_t *)localBuf)[y * lcdWidth + x];
|
||||
rgb = qRgb(255 * ((z & 0xF00) >> 8) / 0x0F,
|
||||
255 * ((z & 0x0F0) >> 4) / 0x0F,
|
||||
255 * (z & 0x00F) / 0x0F);
|
||||
|
@ -181,12 +191,12 @@ class LcdWidget : public QWidget
|
|||
mask = (1 << (y % 8));
|
||||
for (int x = 0; x < lcdWidth; x++, idx++) {
|
||||
if (lcdDepth == 1) {
|
||||
if (lcdBuf[idx] & mask)
|
||||
if (localBuf[idx] & mask)
|
||||
p.drawRect(2 * x, 2 * y, 1, 1);
|
||||
continue;
|
||||
}
|
||||
// lcdDepth == 4
|
||||
z = (y & 1) ? (lcdBuf[idx] >> 4) : (lcdBuf[idx] & 0x0F);
|
||||
z = (y & 1) ? (localBuf[idx] >> 4) : (localBuf[idx] & 0x0F);
|
||||
if (!z)
|
||||
continue;
|
||||
if (z != previousDepth) {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "appdata.h"
|
||||
#include "appdebugmessagehandler.h"
|
||||
#include "constants.h"
|
||||
#include "customdebug.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "simulator.h"
|
||||
#include "simulatormainwindow.h"
|
||||
|
@ -95,6 +96,8 @@ int main(int argc, char *argv[])
|
|||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
|
||||
CustomDebug::setFilterRules();
|
||||
|
||||
g.init();
|
||||
|
||||
QTranslator companionTranslator;
|
||||
|
@ -257,6 +260,7 @@ int finish(int exitCode)
|
|||
qDebug() << "SIMULATOR EXIT" << exitCode;
|
||||
unregisterSimulators();
|
||||
unregisterOpenTxFirmwares();
|
||||
unregisterStorageFactories();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "helpers.h"
|
||||
#include "storage.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#define FW_MARK "FW"
|
||||
#define VERS_MARK "VERS"
|
||||
#define DATE_MARK "DATE"
|
||||
|
|
|
@ -64,6 +64,12 @@ void registerStorageFactories()
|
|||
registerStorageFactory(new SdcardStorageFactory());
|
||||
}
|
||||
|
||||
void unregisterStorageFactories()
|
||||
{
|
||||
foreach (StorageFactory * factory, registeredStorageFactories)
|
||||
delete factory;
|
||||
}
|
||||
|
||||
bool Storage::load(RadioData & radioData)
|
||||
{
|
||||
QFile file(filename);
|
||||
|
@ -72,29 +78,36 @@ bool Storage::load(RadioData & radioData)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
foreach(StorageFactory * factory, registeredStorageFactories) {
|
||||
StorageFormat * format = factory->instance(filename);
|
||||
if (format->load(radioData)) {
|
||||
board = format->getBoard();
|
||||
setWarning(format->warning());
|
||||
return true;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
setError(format->error());
|
||||
}
|
||||
delete format;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Storage::write(const RadioData & radioData)
|
||||
{
|
||||
bool ret = false;
|
||||
foreach(StorageFactory * factory, registeredStorageFactories) {
|
||||
if (factory->probe(filename)) {
|
||||
return factory->instance(filename)->write(radioData);
|
||||
StorageFormat * format = factory->instance(filename);
|
||||
ret = format->write(radioData);
|
||||
delete format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool convertEEprom(const QString & sourceEEprom, const QString & destinationEEprom, const QString & firmwareFilename)
|
||||
|
|
|
@ -48,7 +48,7 @@ class StorageFormat
|
|||
board(Board::BOARD_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~StorageFormat() {}
|
||||
virtual bool load(RadioData & radioData) = 0;
|
||||
virtual bool write(const RadioData & radioData) = 0;
|
||||
|
||||
|
@ -104,6 +104,7 @@ class StorageFactory
|
|||
StorageFactory()
|
||||
{
|
||||
}
|
||||
virtual ~StorageFactory() {}
|
||||
virtual QString name() = 0;
|
||||
virtual bool probe(const QString & filename) = 0;
|
||||
virtual StorageFormat * instance(const QString & filename) = 0;
|
||||
|
@ -145,7 +146,7 @@ class Storage : public StorageFormat
|
|||
{
|
||||
}
|
||||
|
||||
virtual QString name() { return "storage"; };
|
||||
virtual QString name() { return "storage"; }
|
||||
|
||||
void setError(const QString & error)
|
||||
{
|
||||
|
@ -162,6 +163,7 @@ class Storage : public StorageFormat
|
|||
};
|
||||
|
||||
void registerStorageFactories();
|
||||
void unregisterStorageFactories();
|
||||
|
||||
#if 0
|
||||
unsigned long LoadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index);
|
||||
|
|
|
@ -40,19 +40,6 @@ uint8_t getStickMode()
|
|||
return limit<uint8_t>(0, g_eeGeneral.stickMode, 3);
|
||||
}
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
void resetTrims()
|
||||
{
|
||||
TRIMS_GPIO_REG_RVD |= TRIMS_GPIO_PIN_RVD;
|
||||
TRIMS_GPIO_REG_RVU |= TRIMS_GPIO_PIN_RVU;
|
||||
TRIMS_GPIO_REG_RHL |= TRIMS_GPIO_PIN_RHL;
|
||||
TRIMS_GPIO_REG_RHR |= TRIMS_GPIO_PIN_RHR;
|
||||
TRIMS_GPIO_REG_LVD |= TRIMS_GPIO_PIN_LVD;
|
||||
TRIMS_GPIO_REG_LVU |= TRIMS_GPIO_PIN_LVU;
|
||||
TRIMS_GPIO_REG_LHL |= TRIMS_GPIO_PIN_LHL;
|
||||
TRIMS_GPIO_REG_LHR |= TRIMS_GPIO_PIN_LHR;
|
||||
}
|
||||
#endif
|
||||
|
||||
OpenTxSimulator::OpenTxSimulator()
|
||||
{
|
||||
|
@ -96,11 +83,8 @@ void OpenTxSimulator::start(QByteArray & ee, bool tests)
|
|||
|
||||
void OpenTxSimulator::start(const char * filename, bool tests)
|
||||
{
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
for (uint8_t i=0; i<DIM(rotencValue); i++) {
|
||||
rotencValue[i] = 0;
|
||||
}
|
||||
#endif
|
||||
if (main_thread_running)
|
||||
return;
|
||||
|
||||
StartEepromThread(filename);
|
||||
StartAudioThread(volumeGain);
|
||||
|
@ -109,6 +93,9 @@ void OpenTxSimulator::start(const char * filename, bool tests)
|
|||
|
||||
void OpenTxSimulator::stop()
|
||||
{
|
||||
if (!main_thread_running)
|
||||
return;
|
||||
|
||||
StopSimu();
|
||||
#if defined(CPUARM)
|
||||
StopAudioThread();
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <string>
|
||||
|
||||
#if !defined _MSC_VER || defined __GNUC__
|
||||
#if !defined (_MSC_VER) || defined (__GNUC__)
|
||||
#include <chrono>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
@ -135,6 +135,13 @@ void simuInit()
|
|||
simuSetSwitch(i, 0);
|
||||
simuSetKey(i, false); // a little dirty, but setting keys that don't exist is perfectly OK here
|
||||
}
|
||||
for (int i=0; i<(NUM_STICKS+NUM_AUX_TRIMS)*2; i++)
|
||||
simuSetTrim(i, false);
|
||||
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
for (uint8_t i=0; i<DIM(rotencValue); i++)
|
||||
rotencValue[i] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define NEG_CASE(sw_or_key, pin, mask) \
|
||||
|
@ -216,9 +223,9 @@ void simuSetKey(uint8_t key, bool state)
|
|||
KEY_CASE(KEY_UP, KEYS_GPIO_REG_UP, KEYS_GPIO_PIN_UP)
|
||||
KEY_CASE(KEY_DOWN, KEYS_GPIO_REG_DOWN, KEYS_GPIO_PIN_DOWN)
|
||||
#endif
|
||||
#if defined(PCBSKY9X) && !defined(REVX) && !defined(AR9X)
|
||||
#if defined(PCBSKY9X) && !defined(REVX) && !defined(AR9X) && defined(ROTARY_ENCODERS)
|
||||
KEY_CASE(BTN_REa, PIOB->PIO_PDSR, 0x40)
|
||||
#elif defined(PCBGRUVIN9X) || defined(PCBMEGA2560)
|
||||
#elif (defined(PCBGRUVIN9X) || defined(PCBMEGA2560)) && (defined(ROTARY_ENCODERS) || defined(ROTARY_ENCODER_NAVIGATION))
|
||||
KEY_CASE(BTN_REa, pind, 0x20)
|
||||
#elif defined(PCB9X) && defined(ROTARY_ENCODER_NAVIGATION)
|
||||
KEY_CASE(BTN_REa, RotEncoder, 0x20)
|
||||
|
@ -337,6 +344,9 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
|
|||
|
||||
void StartSimu(bool tests, const char * sdPath, const char * settingsPath)
|
||||
{
|
||||
if (main_thread_running)
|
||||
return;
|
||||
|
||||
s_current_protocol[0] = 255;
|
||||
menuLevel = 0;
|
||||
|
||||
|
@ -380,6 +390,9 @@ void StartSimu(bool tests, const char * sdPath, const char * settingsPath)
|
|||
|
||||
void StopSimu()
|
||||
{
|
||||
if (!main_thread_running)
|
||||
return;
|
||||
|
||||
main_thread_running = 0;
|
||||
|
||||
#if defined(CPUARM)
|
||||
|
@ -525,6 +538,7 @@ void StartAudioThread(int volumeGain)
|
|||
simuAudio.leftoverLen = 0;
|
||||
simuAudio.threadRunning = true;
|
||||
simuAudio.volumeGain = volumeGain;
|
||||
TRACE_SIMPGMSPACE("StartAudioThread(%d)", volumeGain);
|
||||
setScaledVolume(VOLUME_LEVEL_DEF);
|
||||
|
||||
pthread_attr_t attr;
|
||||
|
@ -569,12 +583,17 @@ void lcdOff()
|
|||
|
||||
void lcdRefresh()
|
||||
{
|
||||
static bool lightEnabled = (bool)isBacklightEnabled();
|
||||
|
||||
#if defined(PCBFLAMENCO)
|
||||
TW8823_SendScreen();
|
||||
#endif
|
||||
|
||||
memcpy(simuLcdBuf, displayBuf, sizeof(simuLcdBuf));
|
||||
if ((bool(isBacklightEnabled()) != lightEnabled) || memcmp(simuLcdBuf, displayBuf, DISPLAY_BUFFER_SIZE)) {
|
||||
memcpy(simuLcdBuf, displayBuf, DISPLAY_BUFFER_SIZE);
|
||||
lightEnabled = (bool)isBacklightEnabled();
|
||||
simuLcdRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
void telemetryPortInit(uint8_t baudrate)
|
||||
|
|
|
@ -28,7 +28,7 @@ uint8_t * eeprom_buffer_data;
|
|||
volatile int32_t eeprom_buffer_size;
|
||||
bool eeprom_read_operation;
|
||||
|
||||
bool eeprom_thread_running = true;
|
||||
bool eeprom_thread_running = false;
|
||||
|
||||
#if defined(EEPROM_SIZE)
|
||||
uint8_t eeprom[EEPROM_SIZE];
|
||||
|
@ -154,6 +154,7 @@ void StartEepromThread(const char * filename)
|
|||
if (!fp)
|
||||
perror("error in fopen");
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
eeprom_write_sem = sem_open("eepromsem", O_CREAT, S_IRUSR | S_IWUSR, 0);
|
||||
#else
|
||||
|
@ -161,8 +162,10 @@ void StartEepromThread(const char * filename)
|
|||
sem_init(eeprom_write_sem, 0, 0);
|
||||
#endif
|
||||
|
||||
if (!pthread_create(&eeprom_thread_pid, NULL, &eeprom_thread_function, NULL))
|
||||
eeprom_thread_running = true;
|
||||
pthread_create(&eeprom_thread_pid, NULL, &eeprom_thread_function, NULL);
|
||||
else
|
||||
perror("Could not create eeprom thread.");
|
||||
}
|
||||
|
||||
void StopEepromThread()
|
||||
|
@ -178,5 +181,6 @@ void StopEepromThread()
|
|||
free(eeprom_write_sem);
|
||||
#endif
|
||||
|
||||
if (fp) fclose(fp);
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
}
|
||||
|
|
|
@ -97,8 +97,8 @@ void simuFatfsSetPaths(const char * sdPath, const char * settingsPath)
|
|||
if (settingsPath) {
|
||||
simuSettingsDirectory = removeTrailingPathDelimiter(fixPathDelimiters(settingsPath));
|
||||
}
|
||||
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSdDirectory: \"\"", simuSdDirectory.c_str());
|
||||
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSettingsDirectory: \"\"", simuSettingsDirectory.c_str());
|
||||
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSdDirectory: \"%s\"", simuSdDirectory.c_str());
|
||||
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSettingsDirectory: \"%s\"", simuSettingsDirectory.c_str());
|
||||
}
|
||||
|
||||
bool startsWith(const char *path, const char * start)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue