fix(osd): upgrades incld position format and versioned layout

10.3.x-maintenance
nathan 2016-09-22 23:57:43 -07:00
parent 019197c103
commit 99afb42a59
2 changed files with 124 additions and 45 deletions

View File

@ -304,6 +304,18 @@
margin: 0;
}
.tab-osd .char.mouseover {
background: rgba(255,255,255,0.4);
}
.tab-osd .char.dragging {
background: rgba(255,255,255,0.4);
}
.tab-osd .char-label.mouseover {
background: rgba(255,255,255,0.4);
}
.tab-osd .preview .char[draggable="true"] {
cursor: move;
}
@ -345,11 +357,17 @@ button {
}
.tab-osd .display-field {
padding-bottom: 4px;
padding-top: 4px;
padding: .3em;
border: 1px solid transparent;
border-bottom: 1px solid #ddd;
}
.tab-osd .display-field.mouseover {
background: #fff;
border: 1px solid #ccc;
font-weight: 800;
}
.tab-osd .display-field input {
float: right;
width: 50px;

View File

@ -214,6 +214,7 @@ OSD.initData = function() {
OSD.initData();
OSD.constants = {
VISIBLE: 0x0800,
VIDEO_TYPES: [
'AUTO',
'PAL',
@ -323,7 +324,7 @@ OSD.constants = {
default_position: 62,
positionable: true,
preview: function(osd_data) {
return '13.7' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE)
return '399.7' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE)
}
},
ONTIME: {
@ -342,7 +343,7 @@ OSD.constants = {
name: 'FLYMODE',
default_position: -1,
positionable: true,
preview: 'AIR'
preview: 'STAB'
},
GPS_SPEED: {
name: 'GPS_SPEED',
@ -354,7 +355,7 @@ OSD.constants = {
name: 'GPS_SATS',
default_position: -1,
positionable: true,
preview: FONT.symbol(SYM.GPS_SAT) + '3'
preview: FONT.symbol(SYM.GPS_SAT) + '14'
}
}
};
@ -410,56 +411,100 @@ OSD.updateDisplaySize = function() {
}
// compute the size
OSD.data.display_size = {
x: 30,
x: FONT.constants.SIZES.LINE,
y: OSD.constants.VIDEO_LINES[video_type],
total: null
};
};
OSD.msp = {
/**
* Note, unsigned 16 bit int for position ispacked:
* 0: unused
* v: visible flag
* b: blink flag
* y: y coordinate
* x: x coordinate
* 0000 vbyy yyyx xxxx
*/
helpers: {
unpack: {
position: function(bits, c) {
var display_item = {};
if (semver.gte(CONFIG.flightControllerVersion, "3.0.1")) {
// size * y + x
display_item.position = FONT.constants.SIZES.LINE * ((bits >> 5) & 0x001F) + (bits & 0x001F);
display_item.isVisible = (bits & OSD.constants.VISIBLE) != 0;
} else {
display_item.position = (bits === -1) ? c.default_position : bits;
display_item.isVisible = bits !== -1;
}
return display_item;
}
},
pack: {
position: function(display_item) {
var isVisible = display_item.isVisible;
var position = display_item.position;
if (semver.gte(CONFIG.flightControllerVersion, "3.0.1")) {
return (isVisible ? 0x0800 : 0) | (((position / FONT.constants.SIZES.LINE) & 0x001F) << 5) | (position % FONT.constants.SIZES.LINE);
} else {
return isVisible ? (position == -1 ? 0 : position): -1;
}
}
}
},
encodeOther: function() {
var result = [-1, OSD.data.video_system];
if (semver.gte(CONFIG.flightControllerVersion, "3.0.1")) {
result.push(OSD.data.unit_mode);
result.push8(OSD.data.unit_mode);
// watch out, order matters! match the firmware
result.push8(OSD.data.alarms.rssi.value);
result.push16(OSD.data.alarms.cap.value);
result.push16(OSD.data.alarms.time.value);
result.push16(OSD.data.alarms.alt.value);
}
return result;
},
encode: function(display_item) {
return [
display_item.index,
specificByte(display_item.position, 0),
specificByte(display_item.position, 1)
];
var buffer = [];
buffer.push8(display_item.index);
buffer.push16(this.helpers.pack.position(display_item));
return buffer;
},
// Currently only parses MSP_MAX_OSD responses, add a switch on payload.code if more codes are handled
decode: function(payload) {
var view = payload.data;
var d = OSD.data;
var i = 2;
d.compiled_in = view.readU8();
d.video_system = view.readU8();
if (semver.gte(CONFIG.flightControllerVersion, "3.0.1")) {
d.unit_mode = view.readU8();
d.alarms = [];
d.alarms.push({name: 'rssi', display_name: 'Rssi', value: view.readU8()});
d.alarms.push({name: 'cap', display_name: 'Capacity', value: view.readU16()});
d.alarms.push({name: 'time', display_name: 'Minutes', value: view.readU16()});
i += 6;
d.alarms = {};
d.alarms['rssi'] = { display_name: 'Rssi', value: view.readU8() };
d.alarms['cap']= { display_name: 'Capacity', value: view.readU16() };
d.alarms['time'] = { display_name: 'Minutes', value: view.readU16() };
d.alarms['alt'] = { display_name: 'Altitude', value: view.readU16() };
}
d.display_items = [];
// start at the offset from the other fields
for (; i < view.byteLength; i = i + 2) {
var v = view.readU16()
while (view.offset < view.byteLength) {
var v = null;
if (semver.gte(CONFIG.flightControllerVersion, "3.0.1")) {
v = view.readU16();
} else {
v = view.read16();
}
var j = d.display_items.length;
var c = OSD.constants.DISPLAY_FIELDS[j];
d.display_items.push({
d.display_items.push($.extend({
name: c.name,
index: j,
position: v,
positionable: c.positionable,
preview: typeof(c.preview) === 'function' ? c.preview(d) : c.preview
});
}, this.helpers.unpack.position(v, c)));
}
OSD.updateDisplaySize();
}
@ -467,9 +512,17 @@ OSD.msp = {
OSD.GUI = {};
OSD.GUI.preview = {
onMouseEnter: function() {
if (!$(this).data('field')) { return; }
$('.field-'+$(this).data('field').index).addClass('mouseover')
},
onMouseLeave: function() {
if (!$(this).data('field')) { return; }
$('.field-'+$(this).data('field').index).removeClass('mouseover')
},
onDragStart: function(e) {
var ev = e.originalEvent;
ev.dataTransfer.setData("text/plain", ev.target.id);
ev.dataTransfer.setData("text/plain", $(ev.target).data('field').index);
ev.dataTransfer.setDragImage($(this).data('field').preview_img, 6, 9);
},
onDragOver: function(e) {
@ -487,14 +540,18 @@ OSD.GUI.preview = {
onDrop: function(e) {
var ev = e.originalEvent;
var position = $(this).removeAttr('style').data('position');
var field_id = parseInt(ev.dataTransfer.getData('text').split('field-')[1])
var field_id = parseInt(ev.dataTransfer.getData('text'))
var display_item = OSD.data.display_items[field_id];
var overflows_line = FONT.constants.SIZES.LINE - ((position % FONT.constants.SIZES.LINE) + display_item.preview.length);
if (overflows_line < 0) {
position += overflows_line;
}
if (position > OSD.data.display_size.total/2) {
position = position - OSD.data.display_size.total;
if (semver.gte(CONFIG.flightControllerVersion, "3.0.1")) {
// unsigned now
} else {
if (position > OSD.data.display_size.total/2) {
position = position - OSD.data.display_size.total;
}
}
$('input.'+field_id+'.position').val(position).change();
},
@ -529,9 +586,7 @@ TABS.osd.initialize = function (callback) {
// ask for the OSD config data
MSP.promise(MSPCodes.MSP_OSD_CONFIG)
.then(function(info) {
if (!('DISPLAY_FIELDS' in OSD.constants)) {
OSD.chooseFields();
}
OSD.chooseFields();
if (!info.length) {
$('.unsupported').fadeIn();
return;
@ -592,8 +647,8 @@ TABS.osd.initialize = function (callback) {
// alarms
$('.alarms-container').show();
var $alarms = $('.alarms').empty();
for (var i = 0; i < OSD.data.alarms.length; i++) {
var alarm = OSD.data.alarms[i];
for (let k in OSD.data.alarms) {
var alarm = OSD.data.alarms[k];
var $input = $('<label/>').append(
$('<input name="alarm" type="number"/>'+alarm.display_name+'</label>')
.val(alarm.value)
@ -608,23 +663,20 @@ TABS.osd.initialize = function (callback) {
// versioning related, if the field doesn't exist at the current flight controller version, just skip it
if (!field.name) { continue; }
var checked = (-1 != field.position) ? 'checked' : '';
var $field = $('<div class="display-field"/>');
var checked = field.isVisible ? 'checked' : '';
var $field = $('<div class="display-field field-'+field.index+'"/>');
$field.append(
$('<input type="checkbox" name="'+field.name+'" class="togglesmall"></input>')
.data('field', field)
.attr('checked', field.position != -1)
.attr('checked', field.isVisible)
.change(function(e) {
var field = $(this).data('field');
var $position = $(this).parent().find('.position.'+field.name);
if (field.position == -1) {
field.isVisible = !field.isVisible;
if (field.isVisible) {
$position.show();
field.position = OSD.data.last_positions[field.name]
}
else {
} else {
$position.hide();
OSD.data.last_positions[field.name] = field.position
field.position = -1
}
MSP.promise(MSPCodes.MSP_SET_OSD_CONFIG, OSD.msp.encode(field))
.then(function() {
@ -632,8 +684,8 @@ TABS.osd.initialize = function (callback) {
});
})
);
$field.append('<label for="'+field.name+'">'+inflection.titleize(field.name)+'</label>');
if (field.positionable && field.position != -1) {
$field.append('<label for="'+field.name+'" class="char-label">'+inflection.titleize(field.name)+'</label>');
if (field.positionable && field.isVisible) {
$field.append(
$('<input type="number" class="'+field.index+' position"></input>')
.data('field', field)
@ -655,6 +707,12 @@ TABS.osd.initialize = function (callback) {
// buffer the preview
OSD.data.preview = [];
OSD.data.display_size.total = OSD.data.display_size.x * OSD.data.display_size.y;
for(let field of OSD.data.display_items) {
// reset fields that somehow end up off the screen
if (field.position > OSD.data.display_size.total) {
field.position = 0;
}
}
// clear the buffer
for(var i = 0; i < OSD.data.display_size.total; i++) {
OSD.data.preview.push([null, ' '.charCodeAt(0)]);
@ -669,7 +727,7 @@ TABS.osd.initialize = function (callback) {
}
// draw all the displayed items and the drag and drop preview images
for(let field of OSD.data.display_items) {
if (!field.preview || field.position == -1) { continue; }
if (!field.preview || !field.isVisible) { continue; }
var j = (field.position >= 0) ? field.position : field.position + OSD.data.display_size.total;
// create the preview image
field.preview_img = new Image();
@ -718,13 +776,16 @@ TABS.osd.initialize = function (callback) {
var charCode = OSD.data.preview[i][1];
}
var $img = $('<div class="char"><img src='+FONT.draw(charCode)+'></img></div>')
.on('mouseenter', OSD.GUI.preview.onMouseEnter)
.on('mouseleave', OSD.GUI.preview.onMouseLeave)
.on('dragover', OSD.GUI.preview.onDragOver)
.on('dragleave', OSD.GUI.preview.onDragLeave)
.on('drop', OSD.GUI.preview.onDrop)
.data('field', field)
.data('position', i);
if (field && field.positionable) {
$img
.attr('id', 'field-'+field.index)
.addClass('field-'+field.index)
.data('field', field)
.prop('draggable', true)
.on('dragstart', OSD.GUI.preview.onDragStart);