1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-15 20:35:23 +03:00

Add HD OSD support (#3071)

* Add HD OSD mode

* Update src/js/tabs/osd.js

Co-authored-by: Jan Post <Rm2k-Freak@web.de>

Co-authored-by: Jan Post <Rm2k-Freak@web.de>
This commit is contained in:
Steve Evans 2022-11-20 17:42:52 +00:00 committed by GitHub
parent f20290451a
commit 266d5f445d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 271 additions and 70 deletions

View file

@ -4790,6 +4790,10 @@
"message": "NTSC", "message": "NTSC",
"description": "Option for the video format in the OSD" "description": "Option for the video format in the OSD"
}, },
"osdSetupVideoFormatOptionHd": {
"message": "HD",
"description": "Option for the video format in the OSD"
},
"osdSetupUnitsTitle": { "osdSetupUnitsTitle": {
"message": "Units" "message": "Units"
}, },
@ -5020,6 +5024,83 @@
"message": "Aux value", "message": "Aux value",
"description": "One of the elements of the OSD" "description": "One of the elements of the OSD"
}, },
"osdTextElementSysGoggleVoltage": {
"message": "Goggle voltage",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysGoggleVoltage": {
"message": "Goggle voltage rendered by the goggles"
},
"osdTextElementSysVtxVoltage": {
"message": "VTX voltage",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysVtxVoltage": {
"message": "VTX voltage rendered by the goggles"
},
"osdTextElementSysBitrate": {
"message": "VTX bitrate",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysBitrate": {
"message": "Video bitrate rendered by the goggles"
},
"osdTextElementSysDelay": {
"message": "VTX delay",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysDelay": {
"message": "Video delay rendered by the goggles"
},
"osdTextElementSysDistance": {
"message": "VTX distance",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysDistance": {
"message": "Video transmission distance rendered by the goggles"
},
"osdTextElementSysLQ": {
"message": "Goggle link quality",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysLQ": {
"message": "Video link quality rendered by the goggles"
},
"osdTextElementSysGoggleDVR": {
"message": "Goggle DVR status",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysGoggleDVR": {
"message": "Goggle DVR status rendered by the goggles"
},
"osdTextElementSysVtxDVR": {
"message": "VTX DVR status",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysVtxDVR": {
"message": "VTX DVR status rendered by the goggles"
},
"osdTextElementSysWarnings": {
"message": "Goggle system warnings",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysWarnings": {
"message": "Video system warnings rendered by the goggles"
},
"osdTextElementSysVtxTemp": {
"message": "VTX temperature",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysVtxTemp": {
"message": "VTX temperature rendered by the goggles"
},
"osdTextElementSysFanSpeed": {
"message": "Goggle fan speed",
"description": "One of the system elements of the OSD"
},
"osdDescElementSysFanSpeed": {
"message": "Goggle fan speed rendered by the goggles"
},
"osdTextElementCraftName": { "osdTextElementCraftName": {
"message": "Craft name", "message": "Craft name",
"description": "One of the elements of the OSD" "description": "One of the elements of the OSD"

View file

@ -534,10 +534,6 @@ progress[value] {
.preview { .preview {
background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), url(../images/osd-bg-1.jpg); background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), url(../images/osd-bg-1.jpg);
background-size: cover; background-size: cover;
&:active {
background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), url(../../images/osd-bg-1-grid.png), url(../../images/osd-bg-1.jpg);
background-size: cover;
}
} }
input[type='checkbox'] { input[type='checkbox'] {
&:after { &:after {

View file

@ -214,6 +214,7 @@
margin: 0; margin: 0;
flex: 1 1 auto; flex: 1 1 auto;
flex-wrap: nowrap; flex-wrap: nowrap;
border: 1px solid transparent;
img { img {
flex: 1 1 auto; flex: 1 1 auto;
} }
@ -221,6 +222,12 @@
.char[draggable="true"] { .char[draggable="true"] {
cursor: move; cursor: move;
} }
&:active {
.char {
border: 1px dashed rgba(55, 55, 55, 0.5) ;
}
}
} }
.char.mouseover { .char.mouseover {
background: rgba(255,255,255,0.4); background: rgba(255,255,255,0.4);
@ -307,24 +314,7 @@
select.osd-variant { select.osd-variant {
max-width: 100%; max-width: 100%;
} }
.video-pal {
.preview {
&:active {
background: url(../../images/osd-bg-1-grid-pal.png), url(../../images/osd-bg-1.jpg);
background-size: 100% 100%, cover;
background-repeat: no-repeat;
}
}
}
.video-ntsc {
.preview {
&:active {
background: url(../../images/osd-bg-1-grid-ntsc.png), url(../../images/osd-bg-1.jpg);
background-size: 100% 100%, cover;
background-repeat: no-repeat;
}
}
}
.alarms { .alarms {
label { label {
display: block; display: block;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

View file

@ -138,6 +138,9 @@ const MSPCodes = {
MSP_BEEPER_CONFIG: 184, MSP_BEEPER_CONFIG: 184,
MSP_SET_BEEPER_CONFIG: 185, MSP_SET_BEEPER_CONFIG: 185,
MSP_SET_OSD_CANVAS: 188,
MSP_OSD_CANVAS: 189,
MSP_SET_RAW_RC: 200, MSP_SET_RAW_RC: 200,
MSP_SET_RAW_GPS: 201, // Not used MSP_SET_RAW_GPS: 201, // Not used
MSP_SET_PID: 202, MSP_SET_PID: 202,

View file

@ -1694,6 +1694,12 @@ MspHelper.prototype.process_data = function(dataHandler) {
case MSPCodes.MSP_SET_FAILSAFE_CONFIG: case MSPCodes.MSP_SET_FAILSAFE_CONFIG:
console.log('Failsafe config saved'); console.log('Failsafe config saved');
break; break;
case MSPCodes.MSP_OSD_CANVAS:
OSD.data.VIDEO_COLS['HD'] = data.readU8();
OSD.data.VIDEO_ROWS['HD'] = data.readU8();
OSD.data.VIDEO_BUFFER_CHARS['HD'] = OSD.data.VIDEO_COLS['HD'] * OSD.data.VIDEO_ROWS['HD'];
console.log(`Canvas ${OSD.data.VIDEO_COLS['HD']} x ${OSD.data.VIDEO_ROWS['HD']}`);
break;
case MSPCodes.MSP_OSD_CONFIG: case MSPCodes.MSP_OSD_CONFIG:
break; break;
case MSPCodes.MSP_SET_OSD_CONFIG: case MSPCodes.MSP_SET_OSD_CONFIG:

View file

@ -45,6 +45,7 @@ SYM.loadSymbols = function() {
SYM.ARROW_SOUTH = 0x60; SYM.ARROW_SOUTH = 0x60;
SYM.ARROW_EAST = 0x64; SYM.ARROW_EAST = 0x64;
SYM.ARROW_SMALL_UP = 0x75; SYM.ARROW_SMALL_UP = 0x75;
SYM.ARROW_SMALL_RIGHT = 0x77;
SYM.HEADING_LINE = 0x1D; SYM.HEADING_LINE = 0x1D;
SYM.HEADING_DIVIDED_LINE = 0x1C; SYM.HEADING_DIVIDED_LINE = 0x1C;
SYM.HEADING_N = 0x18; SYM.HEADING_N = 0x18;
@ -106,7 +107,6 @@ FONT.constants = {
MAX_NVM_FONT_CHAR_FIELD_SIZE: 64, MAX_NVM_FONT_CHAR_FIELD_SIZE: 64,
CHAR_HEIGHT: 18, CHAR_HEIGHT: 18,
CHAR_WIDTH: 12, CHAR_WIDTH: 12,
LINE: 30,
}, },
COLORS: { COLORS: {
// black // black
@ -292,6 +292,21 @@ OSD.initData = function() {
preview: [], preview: [],
tooltips: [], tooltips: [],
osd_profiles: {}, osd_profiles: {},
VIDEO_COLS: {
PAL: 30,
NTSC: 30,
HD: 53,
},
VIDEO_ROWS: {
PAL: 16,
NTSC: 13,
HD: 20,
},
VIDEO_BUFFER_CHARS: {
PAL: 480,
NTSC: 390,
HD: 1590,
},
}; };
}; };
OSD.initData(); OSD.initData();
@ -542,6 +557,8 @@ OSD.formatPidsPreview = function(axis) {
OSD.loadDisplayFields = function() { OSD.loadDisplayFields = function() {
let videoType = OSD.constants.VIDEO_TYPES[OSD.data.video_system];
// All display fields, from every version, do not remove elements, only add! // All display fields, from every version, do not remove elements, only add!
OSD.ALL_DISPLAY_FIELDS = { OSD.ALL_DISPLAY_FIELDS = {
MAIN_BATT_VOLTAGE: { MAIN_BATT_VOLTAGE: {
@ -632,11 +649,7 @@ OSD.loadDisplayFields = function() {
text: 'osdTextElementCrosshairs', text: 'osdTextElementCrosshairs',
desc: 'osdDescElementCrosshairs', desc: 'osdDescElementCrosshairs',
defaultPosition() { defaultPosition() {
let position = 193; return (OSD.data.VIDEO_COLS[videoType] >> 1) + ((OSD.data.VIDEO_ROWS[videoType] >> 1) - 2) * OSD.data.VIDEO_COLS[videoType] - 2;
if (OSD.constants.VIDEO_TYPES[OSD.data.video_system] !== 'NTSC') {
position += FONT.constants.SIZES.LINE;
}
return position;
}, },
draw_order: 40, draw_order: 40,
positionable() { positionable() {
@ -651,11 +664,7 @@ OSD.loadDisplayFields = function() {
text: 'osdTextElementArtificialHorizon', text: 'osdTextElementArtificialHorizon',
desc: 'osdDescElementArtificialHorizon', desc: 'osdDescElementArtificialHorizon',
defaultPosition() { defaultPosition() {
let position = 74; return (OSD.data.VIDEO_COLS[videoType] >> 1) + ((OSD.data.VIDEO_ROWS[videoType] >> 1) - 5) * OSD.data.VIDEO_COLS[videoType] - 1;
if (OSD.constants.VIDEO_TYPES[OSD.data.video_system] !== 'NTSC') {
position += FONT.constants.SIZES.LINE;
}
return position;
}, },
draw_order: 10, draw_order: 10,
positionable() { positionable() {
@ -688,11 +697,7 @@ OSD.loadDisplayFields = function() {
text: 'osdTextElementHorizonSidebars', text: 'osdTextElementHorizonSidebars',
desc: 'osdDescElementHorizonSidebars', desc: 'osdDescElementHorizonSidebars',
defaultPosition() { defaultPosition() {
let position = 194; return (OSD.data.VIDEO_COLS[videoType] >> 1) + ((OSD.data.VIDEO_ROWS[videoType] >> 1) - 2) * OSD.data.VIDEO_COLS[videoType] - 1;
if (OSD.constants.VIDEO_TYPES[OSD.data.video_system] !== 'NTSC') {
position += FONT.constants.SIZES.LINE;
}
return position;
}, },
draw_order: 50, draw_order: 50,
positionable() { positionable() {
@ -1369,6 +1374,107 @@ OSD.loadDisplayFields = function() {
positionable: true, positionable: true,
preview: 'AUX', preview: 'AUX',
}, },
SYS_GOGGLE_VOLTAGE: {
name: 'SYS_GOGGLE_VOLTAGE',
text: 'osdTextElementSysGoggleVoltage',
desc: 'osdDescElementSysGoggleVoltage',
defaultPosition: -1,
draw_order: 485,
positionable: true,
preview: 'G 16.8V',
},
SYS_VTX_VOLTAGE: {
name: 'SYS_VTX_VOLTAGE',
text: 'osdTextElementSysVtxVoltage',
desc: 'osdDescElementSysVtxVoltage',
defaultPosition: -1,
draw_order: 490,
positionable: true,
preview: 'A 12.6V',
},
SYS_BITRATE: {
name: 'SYS_BITRATE',
text: 'osdTextElementSysBitrate',
desc: 'osdDescElementSysBitrate',
defaultPosition: -1,
draw_order: 495,
positionable: true,
preview: '50MBPS',
},
SYS_DELAY: {
name: 'SYS_DELAY',
text: 'osdTextElementSysDelay',
desc: 'osdDescElementSysDelay',
defaultPosition: -1,
draw_order: 500,
positionable: true,
preview: '24.5MS',
},
SYS_DISTANCE: {
name: 'SYS_DISTANCE',
text: 'osdTextElementSysDistance',
desc: 'osdDescElementSysDistance',
defaultPosition: -1,
draw_order: 505,
positionable: true,
preview: `10${FONT.symbol(SYM.METRE)}`,
},
SYS_LQ: {
name: 'SYS_LQ',
text: 'osdTextElementSysLQ',
desc: 'osdDescElementSysLQ',
defaultPosition: -1,
draw_order: 510,
positionable: true,
preview: `G${FONT.symbol(SYM.LINK_QUALITY)}100`,
},
SYS_GOGGLE_DVR: {
name: 'SYS_GOGGLE_DVR',
text: 'osdTextElementSysGoggleDVR',
desc: 'osdDescElementSysGoggleDVR',
defaultPosition: -1,
draw_order: 515,
positionable: true,
preview: `${FONT.symbol(SYM.ARROW_SMALL_RIGHT)}G DVR 8.4G`,
},
SYS_VTX_DVR: {
name: 'SYS_VTX_DVR',
text: 'osdTextElementSysVtxDVR',
desc: 'osdDescElementSysVtxDVR',
defaultPosition: -1,
draw_order: 520,
positionable: true,
preview: `${FONT.symbol(SYM.ARROW_SMALL_RIGHT)}A DVR 1.6G`,
},
SYS_WARNINGS: {
name: 'SYS_WARNINGS',
text: 'osdTextElementSysWarnings',
desc: 'osdDescElementSysWarnings',
defaultPosition: -1,
draw_order: 525,
positionable: true,
preview: 'VTX WARNINGS',
},
SYS_VTX_TEMP: {
name: 'SYS_VTX_TEMP',
text: 'osdTextElementSysVtxTemp',
desc: 'osdDescElementSysVtxTemp',
defaultPosition: -1,
draw_order: 530,
positionable: true,
preview(osdData) {
return `V${OSD.generateTemperaturePreview(osdData, 45)}`;
},
},
SYS_FAN_SPEED: {
name: 'SYS_FAN_SPEED',
text: 'osdTextElementSysFanSpeed',
desc: 'osdDescElementSysFanSpeed',
defaultPosition: -1,
draw_order: 535,
positionable: true,
preview: `F${FONT.symbol(SYM.TEMPERATURE)}5`,
},
}; };
}; };
@ -1379,15 +1485,8 @@ OSD.constants = {
'AUTO', 'AUTO',
'PAL', 'PAL',
'NTSC', 'NTSC',
'HD',
], ],
VIDEO_LINES: {
PAL: 16,
NTSC: 13,
},
VIDEO_BUFFER_CHARS: {
PAL: 480,
NTSC: 390,
},
UNIT_TYPES: [ UNIT_TYPES: [
'IMPERIAL', 'IMPERIAL',
'METRIC', 'METRIC',
@ -1805,6 +1904,17 @@ OSD.chooseFields = function() {
F.WH_DRAWN, F.WH_DRAWN,
F.AUX_VALUE, F.AUX_VALUE,
F.READY_MODE, F.READY_MODE,
F.SYS_GOGGLE_VOLTAGE,
F.SYS_VTX_VOLTAGE,
F.SYS_BITRATE,
F.SYS_DELAY,
F.SYS_DISTANCE,
F.SYS_LQ,
F.SYS_GOGGLE_DVR,
F.SYS_VTX_DVR,
F.SYS_WARNINGS,
F.SYS_VTX_TEMP,
F.SYS_FAN_SPEED,
]); ]);
} }
} }
@ -1968,15 +2078,13 @@ OSD.updateDisplaySize = function() {
if (videoType === 'AUTO') { if (videoType === 'AUTO') {
videoType = 'PAL'; videoType = 'PAL';
} }
// compute the size // compute the size
OSD.data.displaySize = { OSD.data.displaySize = {
x: FONT.constants.SIZES.LINE, x: OSD.data.VIDEO_COLS[videoType],
y: OSD.constants.VIDEO_LINES[videoType], y: OSD.data.VIDEO_ROWS[videoType],
total: null, total: null,
}; };
// Adjust css background grid
const previewLayoutElement = $(".tab-osd .display-layout");
videoType === 'PAL' ? previewLayoutElement.addClass('video-pal').removeClass('video-ntsc') : previewLayoutElement.addClass('video-ntsc').removeClass('video-pal');
}; };
OSD.drawByOrder = function(selectedPosition, field, charCode, x, y) { OSD.drawByOrder = function(selectedPosition, field, charCode, x, y) {
@ -2017,9 +2125,15 @@ OSD.msp = {
const defaultPosition = typeof (c.defaultPosition) === 'function' ? c.defaultPosition() : c.defaultPosition; const defaultPosition = typeof (c.defaultPosition) === 'function' ? c.defaultPosition() : c.defaultPosition;
displayItem.positionable = positionable; displayItem.positionable = positionable;
OSD.updateDisplaySize();
if (semver.gte(FC.CONFIG.apiVersion, "1.21.0")) { if (semver.gte(FC.CONFIG.apiVersion, "1.21.0")) {
// size * y + x // size * y + x
displayItem.position = positionable ? FONT.constants.SIZES.LINE * ((bits >> 5) & 0x001F) + (bits & 0x001F) : defaultPosition; const xpos = ((bits >> 5) & 0x0020) | (bits & 0x001F);
const ypos = (bits >> 5) & 0x001F;
displayItem.position = positionable ? OSD.data.displaySize.x * ypos + xpos : defaultPosition;
displayItem.isVisible = []; displayItem.isVisible = [];
for (let osd_profile = 0; osd_profile < OSD.getNumberOfProfiles(); osd_profile++) { for (let osd_profile = 0; osd_profile < OSD.getNumberOfProfiles(); osd_profile++) {
@ -2056,8 +2170,10 @@ OSD.msp = {
packed_visible |= isVisible[osd_profile] ? OSD.constants.VISIBLE << osd_profile : 0; packed_visible |= isVisible[osd_profile] ? OSD.constants.VISIBLE << osd_profile : 0;
} }
const variantSelected = (variant << 14); const variantSelected = (variant << 14);
const xpos = position % OSD.data.displaySize.x;
const ypos = (position - xpos) / OSD.data.displaySize.x;
return packed_visible | variantSelected | (((position / FONT.constants.SIZES.LINE) & 0x001F) << 5) | (position % FONT.constants.SIZES.LINE); return packed_visible | variantSelected | ((ypos & 0x001F) << 5) | ((xpos & 0x0020) << 5) | (xpos & 0x001F);
} else { } else {
const realPosition = position === -1 ? 0 : position; const realPosition = position === -1 ? 0 : position;
return isVisible[0] ? realPosition : -1; return isVisible[0] ? realPosition : -1;
@ -2483,7 +2599,9 @@ OSD.GUI.preview = {
const displayItem = OSD.data.displayItems[fieldId]; const displayItem = OSD.data.displayItems[fieldId];
let position = $(this).removeAttr('style').data('position'); let position = $(this).removeAttr('style').data('position');
const cursor = position; const cursor = position;
const cursorX = cursor % FONT.constants.SIZES.LINE; const cursorX = cursor % OSD.data.displaySize.x;
console.log(`cursorX=${cursorX}`);
if (displayItem.preview.constructor === Array) { if (displayItem.preview.constructor === Array) {
console.log(`Initial Drop Position: ${position}`); console.log(`Initial Drop Position: ${position}`);
@ -2491,14 +2609,14 @@ OSD.GUI.preview = {
const y = parseInt(ev.dataTransfer.getData('y')); const y = parseInt(ev.dataTransfer.getData('y'));
console.log(`XY Co-ords: ${x}-${y}`); console.log(`XY Co-ords: ${x}-${y}`);
position -= x; position -= x;
position -= (y * FONT.constants.SIZES.LINE); position -= (y * OSD.data.displaySize.x);
console.log(`Calculated Position: ${position}`); console.log(`Calculated Position: ${position}`);
} }
if (!displayItem.ignoreSize) { if (!displayItem.ignoreSize) {
if (displayItem.preview.constructor !== Array) { if (displayItem.preview.constructor !== Array) {
// Standard preview, string type // Standard preview, string type
const overflowsLine = FONT.constants.SIZES.LINE - ((position % FONT.constants.SIZES.LINE) + displayItem.preview.length); const overflowsLine = OSD.data.displaySize.x - ((position % OSD.data.displaySize.x) + displayItem.preview.length);
if (overflowsLine < 0) { if (overflowsLine < 0) {
position += overflowsLine; position += overflowsLine;
} }
@ -2506,34 +2624,34 @@ OSD.GUI.preview = {
// Advanced preview, array type // Advanced preview, array type
const arrayElements = displayItem.preview; const arrayElements = displayItem.preview;
const limits = OSD.searchLimitsElement(arrayElements); const limits = OSD.searchLimitsElement(arrayElements);
const selectedPositionX = position % FONT.constants.SIZES.LINE; const selectedPositionX = position % OSD.data.displaySize.x;
let selectedPositionY = Math.trunc(position / FONT.constants.SIZES.LINE); let selectedPositionY = Math.trunc(position / OSD.data.displaySize.x);
if (arrayElements[0].constructor === String) { if (arrayElements[0].constructor === String) {
if (position < 0 ) { if (position < 0 ) {
return; return;
} }
if (selectedPositionX > cursorX) { // TRUE -> Detected wrap around if (selectedPositionX > cursorX) { // TRUE -> Detected wrap around
position += FONT.constants.SIZES.LINE - selectedPositionX; position += OSD.data.displaySize.x - selectedPositionX;
selectedPositionY++; selectedPositionY++;
} else if (selectedPositionX + limits.maxX > FONT.constants.SIZES.LINE) { // TRUE -> right border of the element went beyond left edge of screen. } else if (selectedPositionX + limits.maxX > OSD.data.displaySize.x) { // TRUE -> right border of the element went beyond left edge of screen.
position -= selectedPositionX + limits.maxX - FONT.constants.SIZES.LINE; position -= selectedPositionX + limits.maxX - OSD.data.displaySize.x;
} }
if (selectedPositionY < 0 ) { if (selectedPositionY < 0 ) {
position += Math.abs(selectedPositionY) * FONT.constants.SIZES.LINE; position += Math.abs(selectedPositionY) * OSD.data.displaySize.x;
} else if ((selectedPositionY + limits.maxY ) > OSD.data.displaySize.y) { } else if ((selectedPositionY + limits.maxY ) > OSD.data.displaySize.y) {
position -= (selectedPositionY + limits.maxY - OSD.data.displaySize.y) * FONT.constants.SIZES.LINE; position -= (selectedPositionY + limits.maxY - OSD.data.displaySize.y) * OSD.data.displaySize.x;
} }
} else { } else {
if ((limits.minX < 0) && ((selectedPositionX + limits.minX) < 0)) { if ((limits.minX < 0) && ((selectedPositionX + limits.minX) < 0)) {
position += Math.abs(selectedPositionX + limits.minX); position += Math.abs(selectedPositionX + limits.minX);
} else if ((limits.maxX > 0) && ((selectedPositionX + limits.maxX) >= FONT.constants.SIZES.LINE)) { } else if ((limits.maxX > 0) && ((selectedPositionX + limits.maxX) >= OSD.data.displaySize.x)) {
position -= (selectedPositionX + limits.maxX + 1) - FONT.constants.SIZES.LINE; position -= (selectedPositionX + limits.maxX + 1) - OSD.data.displaySize.x;
} }
if ((limits.minY < 0) && ((selectedPositionY + limits.minY) < 0)) { if ((limits.minY < 0) && ((selectedPositionY + limits.minY) < 0)) {
position += Math.abs(selectedPositionY + limits.minY) * FONT.constants.SIZES.LINE; position += Math.abs(selectedPositionY + limits.minY) * OSD.data.displaySize.x;
} else if ((limits.maxY > 0) && ((selectedPositionY + limits.maxY) >= OSD.data.displaySize.y)) { } else if ((limits.maxY > 0) && ((selectedPositionY + limits.maxY) >= OSD.data.displaySize.y)) {
position -= (selectedPositionY + limits.maxY - OSD.data.displaySize.y + 1) * FONT.constants.SIZES.LINE; position -= (selectedPositionY + limits.maxY - OSD.data.displaySize.y + 1) * OSD.data.displaySize.x;
} }
} }
} }
@ -2550,6 +2668,11 @@ OSD.GUI.preview = {
}, },
}; };
async function getCanvas() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45)) {
return MSP.promise(MSPCodes.MSP_OSD_CANVAS);
}
}
const osd = { const osd = {
analyticsChanges: {}, analyticsChanges: {},
@ -2648,6 +2771,9 @@ osd.initialize = function(callback) {
// 2 way binding... sorta // 2 way binding... sorta
function updateOsdView() { function updateOsdView() {
// ask for the OSD canvas data
getCanvas();
// ask for the OSD config data // ask for the OSD config data
MSP.promise(MSPCodes.MSP_OSD_CONFIG) MSP.promise(MSPCodes.MSP_OSD_CONFIG)
.then(function(info) { .then(function(info) {
@ -3077,7 +3203,6 @@ osd.initialize = function(callback) {
// Insert in alphabetical order, with unknown fields at the end // Insert in alphabetical order, with unknown fields at the end
$field.name = field.name; $field.name = field.name;
insertOrdered($displayFields, $field); insertOrdered($displayFields, $field);
} }
GUI.switchery(); GUI.switchery();
@ -3144,7 +3269,7 @@ osd.initialize = function(callback) {
ctx.drawImage(img, j * 12, i * 18); ctx.drawImage(img, j * 12, i * 18);
} }
} }
selectedPosition = selectedPosition - element.length + FONT.constants.SIZES.LINE; selectedPosition = selectedPosition - element.length + OSD.data.displaySize.x;
} else { } else {
const limits = OSD.searchLimitsElement(arrayElements); const limits = OSD.searchLimitsElement(arrayElements);
let offsetX = 0; let offsetX = 0;
@ -3157,7 +3282,7 @@ osd.initialize = function(callback) {
} }
// Add the character to the preview // Add the character to the preview
const charCode = element.sym; const charCode = element.sym;
OSD.drawByOrder(selectedPosition + element.x + element.y * FONT.constants.SIZES.LINE, field, charCode, element.x, element.y); OSD.drawByOrder(selectedPosition + element.x + element.y * OSD.data.displaySize.x, field, charCode, element.x, element.y);
// Image used when "dragging" the element // Image used when "dragging" the element
if (field.positionable) { if (field.positionable) {
const img = new Image(); const img = new Image();