mirror of https://github.com/ArduPilot/ardupilot
AP_OSD: allow for loading fonts from sdcard
user can put fontN.bin on their sdcard and it will replace the font in romfs. This makes for easy font development, and allows for multiple languages This replaces #15668
This commit is contained in:
parent
773517a473
commit
a2d86eac6d
|
@ -51,3 +51,26 @@ void AP_OSD_Backend::write(uint8_t x, uint8_t y, bool blink, const char *fmt, ..
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
load a font from sdcard or ROMFS
|
||||||
|
*/
|
||||||
|
FileData *AP_OSD_Backend::load_font_data(uint8_t font_num)
|
||||||
|
{
|
||||||
|
FileData *fd;
|
||||||
|
|
||||||
|
// first try from microSD
|
||||||
|
char fontname[] = "font0.bin";
|
||||||
|
fontname[4] = font_num + '0';
|
||||||
|
|
||||||
|
fd = AP::FS().load_file(fontname);
|
||||||
|
if (fd == nullptr) {
|
||||||
|
char fontname_romfs[] = "@ROMFS/font0.bin";
|
||||||
|
fontname_romfs[7+4] = font_num + '0';
|
||||||
|
fd = AP::FS().load_file(fontname_romfs);
|
||||||
|
}
|
||||||
|
if (fd == nullptr) {
|
||||||
|
GCS_SEND_TEXT(MAV_SEVERITY_ERROR, "OSD: Failed to load font %u", font_num);
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <AP_HAL/HAL.h>
|
#include <AP_HAL/HAL.h>
|
||||||
#include <AP_OSD/AP_OSD.h>
|
#include <AP_OSD/AP_OSD.h>
|
||||||
|
#include <AP_Filesystem/AP_Filesystem.h>
|
||||||
|
|
||||||
|
|
||||||
class AP_OSD_Backend
|
class AP_OSD_Backend
|
||||||
|
@ -72,6 +73,9 @@ protected:
|
||||||
return (_osd.options & option) != 0;
|
return (_osd.options & option) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load a font from sdcard or ROMFS
|
||||||
|
FileData *load_font_data(uint8_t font_num);
|
||||||
|
|
||||||
int8_t blink_phase;
|
int8_t blink_phase;
|
||||||
|
|
||||||
enum vid_format {
|
enum vid_format {
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
#include <AP_HAL/Util.h>
|
#include <AP_HAL/Util.h>
|
||||||
#include <AP_HAL/Semaphores.h>
|
#include <AP_HAL/Semaphores.h>
|
||||||
#include <AP_HAL/Scheduler.h>
|
#include <AP_HAL/Scheduler.h>
|
||||||
#include <AP_ROMFS/AP_ROMFS.h>
|
#include <AP_Filesystem/AP_Filesystem.h>
|
||||||
|
#include <GCS_MAVLink/GCS.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -157,13 +158,19 @@ bool AP_OSD_MAX7456::init()
|
||||||
|
|
||||||
bool AP_OSD_MAX7456::update_font()
|
bool AP_OSD_MAX7456::update_font()
|
||||||
{
|
{
|
||||||
uint32_t font_size;
|
|
||||||
uint8_t updated_chars = 0;
|
uint8_t updated_chars = 0;
|
||||||
char fontname[] = "font0.bin";
|
|
||||||
last_font = get_font_num();
|
last_font = get_font_num();
|
||||||
fontname[4] = last_font + '0';
|
FileData *fd = load_font_data(last_font);
|
||||||
const uint8_t *font_data = AP_ROMFS::find_decompress(fontname, font_size);
|
|
||||||
if (font_data == nullptr || font_size != NVM_RAM_SIZE * 256) {
|
if (fd == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *font_data = fd->data;
|
||||||
|
uint32_t font_size = fd->length;
|
||||||
|
if (font_size != NVM_RAM_SIZE * 256) {
|
||||||
|
GCS_SEND_TEXT(MAV_SEVERITY_ERROR, "AP_OSD: bad font size %u\n", unsigned(font_size));
|
||||||
|
delete fd;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,18 +180,13 @@ bool AP_OSD_MAX7456::update_font()
|
||||||
if (!check_font_char(chr, chr_font_data)) {
|
if (!check_font_char(chr, chr_font_data)) {
|
||||||
//update char inside max7456 NVM
|
//update char inside max7456 NVM
|
||||||
if (!update_font_char(chr, chr_font_data)) {
|
if (!update_font_char(chr, chr_font_data)) {
|
||||||
hal.console->printf("AP_OSD: error during font char update\n");
|
delete fd;
|
||||||
AP_ROMFS::free(font_data);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
updated_chars++;
|
updated_chars++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updated_chars > 0) {
|
delete fd;
|
||||||
hal.console->printf("AP_OSD: updated %d symbols.\n", updated_chars);
|
|
||||||
}
|
|
||||||
hal.console->printf("AP_OSD: osd font is up to date.\n");
|
|
||||||
AP_ROMFS::free(font_data);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,21 +43,13 @@ extern const AP_HAL::HAL &hal;
|
||||||
*/
|
*/
|
||||||
void AP_OSD_SITL::load_font(void)
|
void AP_OSD_SITL::load_font(void)
|
||||||
{
|
{
|
||||||
uint32_t font_size;
|
|
||||||
char fontname[] = "font0.bin";
|
|
||||||
last_font = get_font_num();
|
last_font = get_font_num();
|
||||||
fontname[4] = last_font + '0';
|
FileData *fd = load_font_data(last_font);
|
||||||
const uint8_t *font_data = AP_ROMFS::find_decompress(fontname, font_size);
|
if (fd == nullptr || fd->length != 54 * 256) {
|
||||||
if (font_data == nullptr && last_font != 0) {
|
|
||||||
last_font = 0;
|
|
||||||
fontname[4] = last_font + '0';
|
|
||||||
font_data = AP_ROMFS::find_decompress(fontname, font_size);
|
|
||||||
}
|
|
||||||
if (font_data == nullptr || font_size != 54 * 256) {
|
|
||||||
AP_HAL::panic("Bad font file");
|
AP_HAL::panic("Bad font file");
|
||||||
}
|
}
|
||||||
for (uint16_t i=0; i<256; i++) {
|
for (uint16_t i=0; i<256; i++) {
|
||||||
const uint8_t *c = &font_data[i*54];
|
const uint8_t *c = &fd->data[i*54];
|
||||||
// each pixel is 4 bytes, RGBA
|
// each pixel is 4 bytes, RGBA
|
||||||
sf::Uint8 *pixels = new sf::Uint8[char_width * char_height * 4];
|
sf::Uint8 *pixels = new sf::Uint8[char_width * char_height * 4];
|
||||||
if (!font[i].create(char_width, char_height)) {
|
if (!font[i].create(char_width, char_height)) {
|
||||||
|
@ -97,7 +89,7 @@ void AP_OSD_SITL::load_font(void)
|
||||||
}
|
}
|
||||||
font[i].update(pixels);
|
font[i].update(pixels);
|
||||||
}
|
}
|
||||||
AP_ROMFS::free(font_data);
|
delete fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_OSD_SITL::write(uint8_t x, uint8_t y, const char* text)
|
void AP_OSD_SITL::write(uint8_t x, uint8_t y, const char* text)
|
||||||
|
|
|
@ -1777,17 +1777,15 @@ void AP_OSD_Screen::draw_callsign(uint8_t x, uint8_t y)
|
||||||
#if HAVE_FILESYSTEM_SUPPORT
|
#if HAVE_FILESYSTEM_SUPPORT
|
||||||
if (!callsign_data.load_attempted) {
|
if (!callsign_data.load_attempted) {
|
||||||
callsign_data.load_attempted = true;
|
callsign_data.load_attempted = true;
|
||||||
int fd = AP::FS().open("callsign.txt", O_RDONLY);
|
FileData *fd = AP::FS().load_file("callsign.txt");
|
||||||
if (fd != -1) {
|
if (fd != nullptr) {
|
||||||
char s[20] {};
|
uint32_t len = fd->length;
|
||||||
int32_t len = AP::FS().read(fd, s, sizeof(s)-1);
|
|
||||||
// trim off whitespace
|
// trim off whitespace
|
||||||
while (len > 0 && isspace(s[len-1])) {
|
while (len > 0 && isspace(fd->data[len-1])) {
|
||||||
s[len-1] = 0;
|
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
AP::FS().close(fd);
|
callsign_data.str = strndup((const char *)fd->data, len);
|
||||||
callsign_data.str = strdup(s);
|
delete fd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (callsign_data.str != nullptr) {
|
if (callsign_data.str != nullptr) {
|
||||||
|
|
Loading…
Reference in New Issue