diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 55970dee2..6e1a30394 100755
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -3606,6 +3606,12 @@
"osdSettingCRSF_LQ_FORMAT_HELP": {
"message": "TYPE1 shows LQ% as used by TBS hardware. TYPE2 shows RF Profile Modes (2=150Hz, 1=50Hz, 0=4Hz update rates) and LQ % [0..100%]. Tracer shows RFMode 1 (1=250Hz) and LQ % [0..100%]."
},
+ "osd_video_show_guides": {
+ "message": "Show preview guides"
+ },
+ "osd_video_HELP": {
+ "message": "For HD: red lines show 4:3 screen, HDZero: keep within the blue box for a higher refresh rate, AUTO/PAL: green line is NTSC limit."
+ },
"osd_dji_HD_FPV": {
"message" : "DJI HD FPV"
},
diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js
index 01b5789d0..ec9b976d8 100644
--- a/js/msp/MSPHelper.js
+++ b/js/msp/MSPHelper.js
@@ -477,9 +477,9 @@ var mspHelper = (function (gui) {
data.getInt8(i + 13)
));
}
- }
+ }
break;
-
+
case MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE:
LOGIC_CONDITIONS.put(new LogicCondition(
data.getInt8(0),
@@ -788,7 +788,7 @@ var mspHelper = (function (gui) {
}
CONFIG.target = targetName;
}
-
+
break;
case MSPCodes.MSP_SET_CHANNEL_FORWARDING:
@@ -2282,8 +2282,8 @@ var mspHelper = (function (gui) {
}
};
- self.loadLogicConditions = function (callback) {
- if (semver.gte(CONFIG.flightControllerVersion, "5.0.0")) {
+ self.loadLogicConditions = function (callback) {
+ if (semver.gte(CONFIG.flightControllerVersion, "5.0.0")) {
LOGIC_CONDITIONS.flush();
let idx = 0;
MSP.send_message(MSPCodes.MSP2_INAV_LOGIC_CONDITIONS_SINGLE, [idx], false, nextLogicCondition);
diff --git a/src/css/tabs/osd.css b/src/css/tabs/osd.css
index 89db9aeff..58eab9d1d 100644
--- a/src/css/tabs/osd.css
+++ b/src/css/tabs/osd.css
@@ -430,29 +430,92 @@ button {
left: calc(50% - 197px);
}
-.tab-osd .preview_hd {
+.tab-osd .preview_hdzero {
width: 600px !important;
left: calc(50% - 317px) !important;
}
-.tab-osd .hd_43_left {
- border-left: 1px solid red;
+.tab-osd .hdzero_43_left {
+ border-left: 2px solid red;
position: absolute;
left: 60px;
height: calc(100% - 27px);
}
-.tab-osd .hd_43_right {
- border-right: 1px solid red;
+.tab-osd .hdzero_43_right {
+ border-right: 2px solid red;
position: absolute;
right: 60px;
height: calc(100% - 27px);
}
-.tab-osd .preview_hd_side {
+.tab-osd .preview_hdzero_side {
width: calc(50% - 317px) !important;
}
+.tab-osd .preview_dji_hd {
+ width: 720px !important;
+ left: calc(50% - 377px) !important;
+}
+
+.tab-osd .dji_hd_43_left {
+ border-left: 2px solid red;
+ position: absolute;
+ left: 84px;
+ height: calc(100% - 27px);
+}
+
+.tab-osd .dji_hd_43_right {
+ border-right: 2px solid red;
+ position: absolute;
+ right: 84px;
+ height: calc(100% - 27px);
+}
+
+.tab-osd .preview_dji_hd_side {
+ width: calc(50% - 377px) !important;
+}
+
+.tab-osd .hd_3016_top {
+ border-top: 2px solid blue;
+ position: absolute;
+ top: 46px;
+ left: 120px;
+ width: 360px;
+}
+
+.tab-osd .hd_3016_bottom {
+ border-bottom: 2px solid blue;
+ position: absolute;
+ bottom: 18px;
+ left: 120px;
+ width: 360px;
+}
+
+.tab-osd .hd_3016_left {
+ border-left: 2px solid blue;
+ position: absolute;
+ top: 46px;
+ left: 120px;
+ height: 288px;
+}
+
+.tab-osd .hd_3016_right {
+ border-right: 2px solid blue;
+ position: absolute;
+ top: 46px;
+ right: 120px;
+ height: 288px;
+}
+
+.tab-osd .ntsc_bottom {
+ border-bottom: 2px solid green;
+ position: absolute;
+ bottom: 54px;
+ left: 0px;
+ width: 100%;
+}
+
.tab-osd .preview {
/* please don't copy the generic background image from another project
* and replace the one that @nathantsoi took :)
@@ -538,7 +601,7 @@ button {
}
.tab-osd .settings select,
-.tab-osd .settings input,
+.tab-osd .settings input,
.tab-osd .osd_settings .switchery,
.tab-osd .unit_wrapper {
vertical-align: top;
diff --git a/tabs/osd.html b/tabs/osd.html
index 389ded66b..a11ab3da3 100644
--- a/tabs/osd.html
+++ b/tabs/osd.html
@@ -31,10 +31,14 @@
diff --git a/tabs/osd.js b/tabs/osd.js
index 44bd89d38..97f12a797 100644
--- a/tabs/osd.js
+++ b/tabs/osd.js
@@ -469,7 +469,8 @@ OSD.initData = function () {
items: [],
groups: {},
preview: [],
- isDjiHdFpv: false
+ isDjiHdFpv: false,
+ isMspDisplay: false
};
};
@@ -532,22 +533,26 @@ OSD.constants = {
'AUTO',
'PAL',
'NTSC',
- 'HD'
+ 'HDZERO',
+ 'DJIWTF'
],
VIDEO_LINES: {
PAL: 16,
NTSC: 13,
- HD: 18
+ HDZERO: 18,
+ DJIWTF: 22
},
VIDEO_COLS: {
PAL: 30,
NTSC: 30,
- HD: 50
+ HDZERO: 50,
+ DJIWTF: 60
},
VIDEO_BUFFER_CHARS: {
PAL: 480,
NTSC: 390,
- HD: 900
+ HDZERO: 900,
+ DJIWTF: 1320
},
UNIT_TYPES: [
{name: 'osdUnitImperial', value: 0},
@@ -1986,6 +1991,9 @@ OSD.reload = function(callback) {
if(port.functions.includes('DJI_FPV')) {
OSD.data.isDjiHdFpv = true;
}
+ if(port.functions.includes('MSP_DISPLAYPORT')) {
+ OSD.data.isMspDisplay = true;
+ }
});
});
@@ -2041,7 +2049,6 @@ OSD.updateDisplaySize = function () {
// set the new video type and cols per line
FONT.constants.SIZES.LINE = OSD.constants.VIDEO_COLS[video_type];
- OSD.constants.VIDEO_TYPES[OSD.data.video_system] = video_type;
// set the new display size
OSD.data.display_size = {
@@ -2063,12 +2070,16 @@ OSD.updateDisplaySize = function () {
}
}
+ // set the preview size if dji wtf
+ $('.third_left').toggleClass('preview_dji_hd_side', video_type == 'DJIWTF')
+ $('.preview').toggleClass('preview_dji_hd cut43_left', video_type == 'DJIWTF')
+ $('.third_right').toggleClass('preview_dji_hd_side', video_type == 'DJIWTF')
+
// set the preview size based on the video type
- $('.third_left').toggleClass('preview_hd_side', (video_type == 'HD'))
- $('.preview').toggleClass('preview_hd cut43_left', (video_type == 'HD'))
- $('.third_right').toggleClass('preview_hd_side', (video_type == 'HD'))
- $('.left_43_margin').toggleClass('hd_43_left', (video_type == 'HD'))
- $('.right_43_margin').toggleClass('hd_43_right', (video_type == 'HD'))
+ $('.third_left').toggleClass('preview_hdzero_side', (video_type == 'HDZERO'))
+ $('.preview').toggleClass('preview_hdzero cut43_left', (video_type == 'HDZERO'))
+ $('.third_right').toggleClass('preview_hdzero_side', (video_type == 'HDZERO'))
+ OSD.GUI.updateGuidesView($('#videoGuides').find('input').is(':checked'));
};
OSD.saveAlarms = function(callback) {
@@ -2351,18 +2362,57 @@ OSD.GUI.checkAndProcessSymbolPosition = function(pos, charCode) {
}
};
+const mspVideoSystem = [1,3,4]; // indexes of PAL, HDZERO, & DJIWTF
+const analogVideoSystem = [0,1,2]; // indexes of AUTO, PAL, & NTSC
+
OSD.GUI.updateVideoMode = function() {
// video mode
var $videoTypes = $('.video-types').empty();
- for (var i = 0; i < OSD.constants.VIDEO_TYPES.length; i++) {
-
- $videoTypes.append(
- $('')
- .append($('' + OSD.constants.VIDEO_TYPES[i] + '')
- .prop('checked', i === OSD.data.preferences.video_system)
- .data('type', i)
- )
- );
+
+ if (!OSD.data.isDjiHdFpv) {
+ $('#dji_settings').hide();
+ }
+
+ if (OSD.data.isMspDisplay) {
+ if (mspVideoSystem.includes(OSD.data.preferences.video_system) == false) {
+ OSD.data.preferences.video_system = OSD.constants.VIDEO_TYPES.indexOf('HDZERO');
+ OSD.updateDisplaySize();
+ OSD.GUI.saveConfig();
+ }
+ } else {
+ if (analogVideoSystem.includes(OSD.data.preferences.video_system) == false) {
+ OSD.data.preferences.video_system = OSD.constants.VIDEO_TYPES.indexOf('AUTO')
+ OSD.updateDisplaySize();
+ OSD.GUI.saveConfig();
+ }
+ }
+
+ if (OSD.data.isMspDisplay) {
+ for (var i = 0; i < OSD.constants.VIDEO_TYPES.length; i++) {
+ if (mspVideoSystem.includes(i))
+ {
+ $videoTypes.append(
+ $('')
+ .append($('' + OSD.constants.VIDEO_TYPES[i] + '')
+ .prop('checked', i === OSD.data.preferences.video_system)
+ .data('type', i)
+ )
+ );
+ }
+ }
+ } else {
+ for (var i = 0; i < OSD.constants.VIDEO_TYPES.length; i++) {
+ if (analogVideoSystem.includes(i))
+ {
+ $videoTypes.append(
+ $('')
+ .append($('' + OSD.constants.VIDEO_TYPES[i] + '')
+ .prop('checked', i === OSD.data.preferences.video_system)
+ .data('type', i)
+ )
+ );
+ }
+ }
}
$videoTypes.find(':radio').click(function () {
@@ -2502,6 +2552,7 @@ OSD.GUI.updateFields = function() {
// Ensure the element is inside the viewport, at least partially.
// In that case move it to the very first row/col, otherwise there's
// no way to reposition items that are outside the viewport.
+ OSD.msp.helpers.calculate.coords(itemData);
if (itemData.x > OSD.data.display_size.x || itemData.y > OSD.data.display_size.y) {
itemData.x = itemData.y = itemData.position = 0;
}
@@ -2536,10 +2587,21 @@ OSD.GUI.updateFields = function() {
}
}
+ if ($('#videoGuidesToggle').length == false) {
+ $('#videoGuides').prepend(
+ $('')
+ .attr('checked', false)
+ .on('change', function () {
+ OSD.GUI.updateGuidesView(this.checked);
+ OSD.GUI.updatePreviews();
+ })
+ );
+ }
+
if ($('#djiUnsupportedElementsToggle').length == false) {
$('#djiUnsupportedElements').prepend(
$('')
- .attr('checked', OSD.data.isDjiHdFpv)
+ .attr('checked', OSD.data.isDjiHdFpv && !OSD.data.isMspDisplay)
.on('change', function () {
OSD.GUI.updateDjiView(this.checked);
OSD.GUI.updatePreviews();
@@ -2594,6 +2656,23 @@ OSD.GUI.updateDjiMessageElements = function(on) {
OSD.GUI.removeBottomLines();
};
+OSD.GUI.updateGuidesView = function(on) {
+ isHdZero = OSD.constants.VIDEO_TYPES[OSD.data.preferences.video_system] == 'HDZERO';
+ $('.hd_43_margin_left').toggleClass('hdzero_43_left', (isHdZero && on))
+ $('.hd_43_margin_right').toggleClass('hdzero_43_right', (isHdZero && on))
+ $('.hd_3016_box_top').toggleClass('hd_3016_top', (isHdZero && on))
+ $('.hd_3016_box_bottom').toggleClass('hd_3016_bottom', (isHdZero && on))
+ $('.hd_3016_box_left').toggleClass('hd_3016_left', (isHdZero && on))
+ $('.hd_3016_box_right').toggleClass('hd_3016_right', (isHdZero && on))
+
+ isDJIWTF = OSD.constants.VIDEO_TYPES[OSD.data.preferences.video_system] == 'DJIWTF';
+ $('.hd_43_margin_left').toggleClass('dji_hd_43_left', (isDJIWTF && on))
+ $('.hd_43_margin_right').toggleClass('dji_hd_43_right', (isDJIWTF && on))
+
+ isPAL = OSD.constants.VIDEO_TYPES[OSD.data.preferences.video_system] == 'PAL' || OSD.constants.VIDEO_TYPES[OSD.data.preferences.video_system] == 'AUTO';
+ $('.pal_ntsc_box_bottom').toggleClass('ntsc_bottom', (isPAL && on))
+};
+
OSD.GUI.updateDjiView = function(on) {
if (on) {
$(OSD.DjiElements.emptyGroups).each(function(index, groupName) {
@@ -2845,6 +2924,7 @@ OSD.GUI.updateAll = function() {
layouts.on('change', function() {
OSD.updateSelectedLayout(parseInt(layouts.val()));
OSD.GUI.updateFields();
+ OSD.GUI.updateGuidesView($('#videoGuides').find('input').is(':checked'));
OSD.GUI.updateDjiView($('#djiUnsupportedElements').find('input').is(':checked'));
OSD.GUI.updatePreviews();
});
@@ -2860,7 +2940,8 @@ OSD.GUI.updateAll = function() {
OSD.GUI.updateUnits();
OSD.GUI.updateFields();
OSD.GUI.updatePreviews();
- OSD.GUI.updateDjiView(OSD.data.isDjiHdFpv);
+ OSD.GUI.updateGuidesView(false);
+ OSD.GUI.updateDjiView(OSD.data.isDjiHdFpv && !OSD.data.isMspDisplay);
};
OSD.GUI.update = function() {
diff --git a/tabs/ports.js b/tabs/ports.js
index f6320ed99..b17966f4d 100644
--- a/tabs/ports.js
+++ b/tabs/ports.js
@@ -67,7 +67,7 @@ TABS.ports.initialize = function (callback) {
name: 'VTX_FFPV',
groups: ['peripherals'],
maxPorts: 1 }
- );
+ );
functionRules.push({
name: 'OPFLOW',
@@ -335,7 +335,7 @@ TABS.ports.initialize = function (callback) {
});
MSP.send_message(MSPCodes.MSP2_SET_CF_SERIAL_CONFIG, mspHelper.crunch(MSPCodes.MSP2_SET_CF_SERIAL_CONFIG), false, save_to_eeprom);
-
+
function save_to_eeprom() {
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, on_saved_handler);
}