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:
parent
f20290451a
commit
266d5f445d
8 changed files with 271 additions and 70 deletions
|
@ -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"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 |
|
@ -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,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue