From ba45a24daa613b084633a3a23c17dc25546a68ad Mon Sep 17 00:00:00 2001 From: Norbert Takacs Date: Sun, 6 Jul 2025 14:57:37 +0200 Subject: [PATCH 1/2] Generic display: add period to the ned of the file in case of truncate Signed-off-by: Norbert Takacs --- src/core/GenericDisplay.cpp | 28 +++++++++++++------ test/test-radio-panel-config.ini | 3 +- test/test_radio_panel.cpp | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/core/GenericDisplay.cpp b/src/core/GenericDisplay.cpp index b37a3d5..67af37c 100644 --- a/src/core/GenericDisplay.cpp +++ b/src/core/GenericDisplay.cpp @@ -161,17 +161,29 @@ bool GenericDisplay::get_decimal_components(int number, unsigned char* buffer, i negative = true; } - if (number > pow(10, nr_of_bytes)) - return false; + for (int i = 0; i < nr_of_bytes; i++) + buffer[i] = ZERO_CHAR; - int remain = number; - for (int dec_pos = nr_of_bytes - 1; dec_pos >= 0; dec_pos--) + if (number != 0) { - 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 + // how many decimal positions do we need? + const int base_10_of_number = (int)log10(number); + + int remain = number; + int buffer_index = nr_of_bytes > (base_10_of_number + 1) ? nr_of_bytes - (base_10_of_number+1) : 0; + + for (int dec_pos = base_10_of_number; dec_pos >= 0 && buffer_index < nr_of_bytes; dec_pos--) + { + buffer[buffer_index] = remain / (int)pow(10, dec_pos); + if (dec_pos == _dot_position) + buffer[buffer_index] += PERIOD_CHAR; // turn on period dot + + remain = remain % (int)pow(10, dec_pos); + buffer_index++; + } - remain = remain % (int)pow(10, dec_pos); + if (remain != 0) + buffer[nr_of_bytes - 1] += PERIOD_CHAR; // a dot at the end of display indicates the truncated line } if (blank_leading_zeros) diff --git a/test/test-radio-panel-config.ini b/test/test-radio-panel-config.ini index cf880c1..6aded90 100644 --- a/test/test-radio-panel-config.ini +++ b/test/test-radio-panel-config.ini @@ -10,11 +10,12 @@ pid="d05" [multi_display:id="RADIO_DISPLAY_ACTIVE_UP"] line="on_select:SW_UP_COM1,dataref:sim/cockpit2/radios/actuators/com1_frequency_hz" -line="on_select:SW_UP_COM2,dataref:sim/cockpit/radios/com1_stdby_freq_hz" +line="on_select:SW_UP_COM2,dataref:sim/cockpit2/radios/actuators/com1_frequency_hz_833" line="on_select:SW_UP_NAV1,dataref:sim/cockpit2/radios/actuators/nav1_frequency_hz" line="on_select:SW_UP_NAV2,dataref:sim/cockpit2/radios/actuators/nav2_frequency_hz" line="on_select:SW_UP_ADF,const:12345" line="on_select:SW_UP_DME,lua:get_display_value()" +line="on_select:SW_UP_IDT,dataref:sim/cockpit2/radios/actuators/transponder_code" [button:id="KNOB_UP_BIG_PLUS"] on_push="on_select:SW_UP_COM1,dataref:sim/cockpit2/radios/actuators/com1_frequency_hz:100:0:99999" diff --git a/test/test_radio_panel.cpp b/test/test_radio_panel.cpp index b93e330..42aca34 100644 --- a/test/test_radio_panel.cpp +++ b/test/test_radio_panel.cpp @@ -39,11 +39,15 @@ namespace test std::string nav2_freq_dataref_str = "sim/cockpit2/radios/actuators/nav2_frequency_hz"; std::string com1_freq_dataref_str = "sim/cockpit2/radios/actuators/com1_frequency_hz"; std::string com2_freq_dataref_str = "sim/cockpit/radios/com1_stdby_freq_hz"; + std::string com1_freq_833khz_dataref_str = "sim/cockpit2/radios/actuators/com1_frequency_hz_833"; + std::string transponder_code_str = "sim/cockpit2/radios/actuators/transponder_code"; XPLMDataRef nav1_freq_dataref; XPLMDataRef nav2_freq_dataref; XPLMDataRef com1_freq_dataref; XPLMDataRef com2_freq_dataref; + XPLMDataRef com1_freq_833khz_dataref; + XPLMDataRef transponder_code_dataref; public: TEST_METHOD_INITIALIZE(TestMultiPanelInit) @@ -66,11 +70,15 @@ namespace test nav2_freq_dataref = XPLMFindDataRef(nav2_freq_dataref_str.c_str()); com1_freq_dataref = XPLMFindDataRef(com1_freq_dataref_str.c_str()); com2_freq_dataref = XPLMFindDataRef(com2_freq_dataref_str.c_str()); + com1_freq_833khz_dataref = XPLMFindDataRef(com1_freq_833khz_dataref_str.c_str()); + transponder_code_dataref = XPLMFindDataRef(transponder_code_str.c_str()); XPLMSetDatai(nav1_freq_dataref, 11111); XPLMSetDatai(nav2_freq_dataref, 22222); XPLMSetDatai(com1_freq_dataref, 33333); XPLMSetDatai(com2_freq_dataref, 44444); + XPLMSetDatai(com1_freq_833khz_dataref, 120375); // 120.375 Mhz is a 8.33kHz channel + XPLMSetDatai(transponder_code_dataref, 7001); } TEST_METHOD(Test_VID_PID) @@ -98,6 +106,45 @@ namespace test Assert::AreEqual(1, (int)write_buffer[5]); } + TEST_METHOD(Test_Display_833kHz) + { + // set rotation switch to SW_COM_2 position + unsigned char buffer[4] = { 0x02,0,0,0 }; + test_hid_set_read_data(buffer, sizeof(buffer)); + std::this_thread::sleep_for(150ms); + + test_flight_loop(device); + std::this_thread::sleep_for(150ms); + + unsigned char write_buffer[23]; + test_hid_get_write_data(write_buffer, sizeof(write_buffer)); + Assert::AreEqual(1, (int)write_buffer[1]); + Assert::AreEqual(2, (int)write_buffer[2]); + Assert::AreEqual(0, (int)write_buffer[3]); + Assert::AreEqual(3, (int)write_buffer[4]); + Assert::AreEqual(7, (int)write_buffer[5] & 0x0F); // the digit at last position + Assert::AreEqual(0xD0, (int)write_buffer[5] & 0xF0); // the period after the last digit + } + + TEST_METHOD(Test_4_digit_display) + { + // set rotation switch to XPDR position + unsigned char buffer[4] = { 0x40,0,0,0 }; + test_hid_set_read_data(buffer, sizeof(buffer)); + std::this_thread::sleep_for(150ms); + + test_flight_loop(device); + std::this_thread::sleep_for(150ms); + + unsigned char write_buffer[23]; + test_hid_get_write_data(write_buffer, sizeof(write_buffer)); + Assert::AreEqual(255, (int)write_buffer[1]); + Assert::AreEqual(7, (int)write_buffer[2]); + Assert::AreEqual(0, (int)write_buffer[3]); + Assert::AreEqual(0, (int)write_buffer[4]); + Assert::AreEqual(1, (int)write_buffer[5]); + } + TEST_METHOD(Test_Const_Value) { // set rotation switch to SW_UP_ADF position From 245a75905b6259b54010a716364381799e4207dd Mon Sep 17 00:00:00 2001 From: Norbert Takacs Date: Sun, 6 Jul 2025 17:57:45 +0200 Subject: [PATCH 2/2] Doc: Add description about automatic truncation on displays Signed-off-by: Norbert Takacs --- doc/documentation.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/documentation.md b/doc/documentation.md index f744054..6ecb4ed 100644 --- a/doc/documentation.md +++ b/doc/documentation.md @@ -526,6 +526,20 @@ Here the ```dot_position``` option is an index starting at the most right positi | ------| -------------- | -------------- | -------------- | | 12345 | 12345. | 1234.5 | 123.45 | +### Display Value Truncation +#### Overview +When displaying values on hardware panels with limited character capacity, XPanel automatically handles cases where the data exceeds the available display space. + +#### Truncation Behavior +If a display value is wider than the available characters on the hardware display, XPanel will truncate the value and append a period (`.`) character at the end to indicate that the value has been shortened. + +**Example:** +- **Full value**: `120.375` (8.33kHz radio frequency) +- **Saitek Radio Panel display** (5 characters): `12037.` +- The period at the end indicates that the complete value cannot be displayed + +#### Configuration +The truncation behavior is automatically applied and does not require any configuration. The feature ensures that users are always aware when displayed values are incomplete due to hardware limitations. ### 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).