diff --git a/doc/documentation.md b/doc/documentation.md index 05f455f..81514d7 100644 --- a/doc/documentation.md +++ b/doc/documentation.md @@ -515,6 +515,18 @@ The below table contains some examples of different options. We suppose the disp | 100 | 00100 | 100 | 100 | | 1500 | 01500 | 1500 | 1500 | +*Dot positionr*: You can add dot (period) character to the display lines. It is usefull when the numerical data is not an integer number. For example navigation radio frequesncies are in this form: 118.100 Mhz To add a dot caharacter to the display please use this option on the appropriate lines: +``` +[multi_display:id="RADIO_DISPLAY_ACTIVE_UP"] +line="on_select:SW_UP_COM1,dataref:sim/cockpit2/radios/actuators/com1_frequency_hz, dot_position: 2" +``` +Here the ```dot_position``` option is an index starting at the most right position with index 0 + +| value | dot_position:0 | dot_position:1 | dot_position:2 | +| ------| -------------- | -------------- | -------------- | +| 12345 | 12345. | 1234.5 | 123.45 | + + ### Multipurpose displays The display value can be a conditional display which means the value to display depends on the position of a switch. A display that contains conditions called multi-purpose display (multi_display). diff --git a/src/core/ConfigParser.cpp b/src/core/ConfigParser.cpp index 97d7cca..5af020c 100644 --- a/src/core/ConfigParser.cpp +++ b/src/core/ConfigParser.cpp @@ -626,6 +626,7 @@ int Configparser::handle_on_lit_or_unlit_or_blink(IniFileSectionHeader section_h int Configparser::handle_on_line_add(IniFileSectionHeader section_header, std::string key, std::string value, Configuration& config) { //line="on_select:SW_ALT,dataref:sim/custom/gauges/compas/pkp_helper_course_L" + //line="on_select:SW_ALT,dataref:sim/custom/gauges/compas/pkp_helper_course_L, dot_position: 2" //line="on_select:SW_ALT,dataref:sim/custom/gauges/compas/pkp_helper_course_L, minimum_digit_number: 3" //line="dataref:sim/custom/gauges/compas/pkp_helper_course_L" //line="dataref:sim/custom/gauges/compas/test[0] @@ -658,6 +659,21 @@ int Configparser::handle_on_line_add(IniFileSectionHeader section_header, std::s } } + std::string dot_position = ""; + get_and_remove_token_pair(m, TOKEN_DOT_POSITION, dot_position); + if (dot_position != "") + { + if (section_header.name == TOKEN_SECTION_MULTI_DISPLAY) + config.class_configs.back().multi_displays[section_header.id]->set_dot_position(condition, stoi(dot_position)); + else if (section_header.name == TOKEN_SECTION_DISPLAY) + config.class_configs.back().generic_displays[section_header.id]->set_dot_position(stoi(dot_position)); + else + { + Logger(TLogLevel::logERROR) << "parser: invalid line for device type: " << section_header.name << std::endl; + return EXIT_FAILURE; + } + } + // at this point only the dataref/lua/const key-value pair shall remain if (m.size() != 2) { diff --git a/src/core/ConfigParser.h b/src/core/ConfigParser.h index 67fd91b..a0582fa 100644 --- a/src/core/ConfigParser.h +++ b/src/core/ConfigParser.h @@ -84,6 +84,7 @@ class Configparser const std::string TOKEN_BCD = "bcd"; const std::string TOKEN_BLANK_LEADING_ZEROS = "blank_leading_zeros"; const std::string TOKEN_MIN_DIGIT_NUMBER = "minimum_digit_number"; + const std::string TOKEN_DOT_POSITION = "dot_position"; const std::string TOKEN_ON_SELECT = "on_select"; const std::string TOKEN_BEGIN = "begin"; const std::string TOKEN_END = "end"; diff --git a/src/core/GenericDisplay.cpp b/src/core/GenericDisplay.cpp index c10c0ff..b37a3d5 100644 --- a/src/core/GenericDisplay.cpp +++ b/src/core/GenericDisplay.cpp @@ -23,6 +23,7 @@ GenericDisplay::GenericDisplay(bool _use_bcd) const_value = DBL_MIN; blank_leading_zeros = true; minimum_number_of_digits = 1; + dot_position = -1; //no dot display } GenericDisplay::GenericDisplay(GenericDisplay* other) @@ -37,6 +38,7 @@ GenericDisplay::GenericDisplay(GenericDisplay* other) const_value = other->const_value; nr_of_bytes = other->nr_of_bytes; minimum_number_of_digits = other->minimum_number_of_digits; + dot_position = other->dot_position; dataref_index = other->dataref_index; blank_leading_zeros = other->blank_leading_zeros; } @@ -62,6 +64,17 @@ int GenericDisplay::get_minimum_number_of_digits() return minimum_number_of_digits; } +void GenericDisplay::set_dot_position(int _dot_position) +{ + dot_position = _dot_position; + Logger(TLogLevel::logDEBUG) << "GenericDisplay: set dot position: " << _dot_position << std::endl; +} + +int GenericDisplay::get_dot_position() +{ + return dot_position; +} + void GenericDisplay::set_bcd(bool _use_bcd) { use_bcd = _use_bcd; @@ -139,7 +152,7 @@ void GenericDisplay::evaluate_and_store_dataref_value() display_value_old = display_value; } -bool GenericDisplay::get_decimal_components(int number, unsigned char* buffer, int _minimum_number_of_digits) +bool GenericDisplay::get_decimal_components(int number, unsigned char* buffer, int _minimum_number_of_digits, int _dot_position) { bool negative = false; if (number < 0) @@ -155,6 +168,9 @@ bool GenericDisplay::get_decimal_components(int number, unsigned char* buffer, i for (int dec_pos = nr_of_bytes - 1; dec_pos >= 0; dec_pos--) { buffer[nr_of_bytes - 1 - dec_pos] = remain / (int)pow(10, dec_pos); + if (dec_pos == _dot_position) + buffer[nr_of_bytes - 1 - dec_pos] += PERIOD_CHAR; // turn on period dot + remain = remain % (int)pow(10, dec_pos); } @@ -200,7 +216,7 @@ bool GenericDisplay::get_binary_components(int number, unsigned char* buffer) } // called from UsbHidDevice worker thread -bool GenericDisplay::get_display_value(unsigned char* buffer, int _minimum_number_of_digits) +bool GenericDisplay::get_display_value(unsigned char* buffer, int _minimum_number_of_digits, int _dot_position) { if (!display_value_changed) return false; @@ -221,7 +237,7 @@ bool GenericDisplay::get_display_value(unsigned char* buffer, int _minimum_numbe } else { - buffer_changed = use_bcd ? get_decimal_components((int)_val, buffer, _minimum_number_of_digits) : get_binary_components(int(_val), buffer); + buffer_changed = use_bcd ? get_decimal_components((int)_val, buffer, _minimum_number_of_digits, _dot_position) : get_binary_components(int(_val), buffer); } return buffer_changed; diff --git a/src/core/GenericDisplay.h b/src/core/GenericDisplay.h index 1db8f86..3cd1610 100644 --- a/src/core/GenericDisplay.h +++ b/src/core/GenericDisplay.h @@ -25,8 +25,9 @@ class GenericDisplay void set_nr_bytes(int _nr_of_bytes); // called from UsbHidDevice worker thread - virtual bool get_display_value(unsigned char* buffer, int _minimum_number_of_digits); + virtual bool get_display_value(unsigned char* buffer, int _minimum_number_of_digits, int _dot_position); virtual int get_minimum_number_of_digits(); + virtual int get_dot_position(); // called from XPLane flight loop virtual void evaluate_and_store_dataref_value(); @@ -37,6 +38,7 @@ class GenericDisplay void set_bcd(bool _use_bcd); void set_blank_leading_zeros(bool _blank_leading_zeros); void set_minimum_number_of_digits(int _minimum_number_of_digits); + void set_dot_position(int _dot_position); protected: double display_value; double display_value_old; @@ -45,6 +47,7 @@ class GenericDisplay bool use_bcd; bool blank_leading_zeros; int minimum_number_of_digits; + int dot_position; std::string lua_function; XPLMDataRef condition; XPLMDataTypeID data_ref_type; @@ -53,7 +56,9 @@ class GenericDisplay private: const unsigned char BLANK_CHAR = 0xFF; const unsigned char ZERO_CHAR = 0x00; + const unsigned char PERIOD_CHAR = 0xD0; + int dataref_index; - bool get_decimal_components(int number, unsigned char* buffer, int _minimum_number_of_digits); + bool get_decimal_components(int number, unsigned char* buffer, int _minimum_number_of_digits, int _dot_position); bool get_binary_components(int number, unsigned char* buffer); }; diff --git a/src/core/MultiPurposeDisplay.cpp b/src/core/MultiPurposeDisplay.cpp index 62d6ae1..584e5c2 100644 --- a/src/core/MultiPurposeDisplay.cpp +++ b/src/core/MultiPurposeDisplay.cpp @@ -36,6 +36,7 @@ MultiPurposeDisplay::MultiPurposeDisplay(MultiPurposeDisplay* other) minimum_number_of_digits = other->minimum_number_of_digits; blank_leading_zeros = other->blank_leading_zeros; minimum_number_of_digits_for_condtions = other->minimum_number_of_digits_for_condtions; + dot_positions_for_conditions = other->dot_positions_for_conditions; } void MultiPurposeDisplay::add_condition(std::string selector_sw_name, XPLMDataRef data) @@ -101,6 +102,12 @@ void MultiPurposeDisplay::set_minimum_number_of_digits(std::string _condition, i Logger(TLogLevel::logDEBUG) << "MultiPurposeDisplay: set minimum number of digits [" + _condition + "]: " << _minimum_number_of_digits << std::endl; } +void MultiPurposeDisplay::set_dot_position(std::string _condition, int _dot_position) +{ + dot_positions_for_conditions[_condition] = _dot_position; + Logger(TLogLevel::logDEBUG) << "MultiPurposeDisplay: set dot position [" + _condition + "]: " << _dot_position << std::endl; +} + int MultiPurposeDisplay::get_minimum_number_of_digits() { int result = 1; @@ -117,6 +124,22 @@ int MultiPurposeDisplay::get_minimum_number_of_digits() return result; } +int MultiPurposeDisplay::get_dot_position() +{ + int result = -1; + + guard.lock(); + + if (dot_positions_for_conditions.count(active_condition) != 0) + result = dot_positions_for_conditions[active_condition]; + else + result = -1; //default -1 --> no dot + + guard.unlock(); + + return result; +} + /* call this function only from XPlane flight loop */ void MultiPurposeDisplay::evaluate_and_store_dataref_value() { diff --git a/src/core/MultiPurposeDisplay.h b/src/core/MultiPurposeDisplay.h index 72bd063..967dba5 100644 --- a/src/core/MultiPurposeDisplay.h +++ b/src/core/MultiPurposeDisplay.h @@ -24,7 +24,9 @@ class MultiPurposeDisplay : public GenericDisplay void add_condition(std::string selector_sw_name, std::string lua_str); void set_minimum_number_of_digits(std::string _condition, int _minimum_number_of_digits); + void set_dot_position(std::string _condition, int _dot_position); int get_minimum_number_of_digits(); + int get_dot_position(); // called from UsbHidDevice worker thread void set_condition_active(std::string selector_sw_name); @@ -38,6 +40,8 @@ class MultiPurposeDisplay : public GenericDisplay std::map lua_functions; std::map data_ref_types; std::map minimum_number_of_digits_for_condtions; + std::map dot_positions_for_conditions; + std::string active_condition; double display_value; double display_value_old; diff --git a/src/core/UsbHidDevice.cpp b/src/core/UsbHidDevice.cpp index d60a8ab..c19e68e 100644 --- a/src/core/UsbHidDevice.cpp +++ b/src/core/UsbHidDevice.cpp @@ -192,7 +192,8 @@ bool UsbHidDevice::updateOneDisplay(std::pair conf if (reg_index != -1 && config_display.second != NULL) { int minimum_number_of_digits = config_display.second->get_minimum_number_of_digits(); - write_buffer_changed |= config_display.second->get_display_value(&write_buffer[reg_index], minimum_number_of_digits); + int dot_position = config_display.second->get_dot_position(); + write_buffer_changed |= config_display.second->get_display_value(&write_buffer[reg_index], minimum_number_of_digits, dot_position); } return write_buffer_changed;