40 #include "physical_constants.h"
44 #include "gpsposition.h"
45 #include "homelocation.h"
49 #if defined(PIOS_VIDEO_SPLITBUFFER)
52 extern uint8_t *disp_buffer_level;
53 extern uint8_t *disp_buffer_mask;
62 #if defined(PIOS_VIDEO_SPLITBUFFER)
72 #if defined(PIOS_VIDEO_SPLITBUFFER)
74 uint8_t byte_width = image->
width / 8;
75 uint8_t pixel_offset = x % 8;
79 if (pixel_offset > 0) {
80 for (uint8_t
i = 0;
i<pixel_offset;
i++) {
86 for (uint16_t yp = 0; yp < image->
height; yp++) {
87 for (uint16_t xp = 0; xp < image->
width / 8; xp++) {
90 if (pixel_offset > 0) {
100 uint8_t byte_width = image->
width / 4;
101 uint8_t pixel_offset = 2 * (x % 4);
102 uint8_t mask1 = 0xFF;
103 uint8_t mask2 = 0x00;
105 if (pixel_offset > 0) {
106 for (uint8_t
i = 0;
i<pixel_offset;
i++) {
112 for (uint16_t yp = 0; yp < image->
height; yp++) {
113 for (uint16_t xp = 0; xp < byte_width; xp++) {
115 if (pixel_offset > 0) {
152 void ellipse(
int centerX,
int centerY,
int horizontalRadius,
int verticalRadius)
154 int64_t doubleHorizontalRadius = horizontalRadius * horizontalRadius;
155 int64_t doubleVerticalRadius = verticalRadius * verticalRadius;
157 int64_t
error = doubleVerticalRadius - doubleHorizontalRadius * verticalRadius + (doubleVerticalRadius >> 2);
160 int y = verticalRadius;
162 int deltaY = (doubleHorizontalRadius << 1) * y;
166 while (deltaY >= deltaX) {
168 deltaX += (doubleVerticalRadius << 1);
170 error += deltaX + doubleVerticalRadius;
174 deltaY -= (doubleHorizontalRadius << 1);
181 error = (int64_t)(doubleVerticalRadius * (x + 1 / 2.0
f) * (x + 1 / 2.0f) + doubleHorizontalRadius * (y - 1) * (y - 1) - doubleHorizontalRadius * doubleVerticalRadius);
184 error += doubleHorizontalRadius;
186 deltaY -= (doubleHorizontalRadius << 1);
191 deltaX += (doubleVerticalRadius << 1);
199 void drawArrow(uint16_t x, uint16_t y, uint16_t angle, uint16_t size_quarter)
201 float sin_angle = sinf(angle * (
float)(M_PI / 180));
202 float cos_angle = cosf(angle * (
float)(M_PI / 180));
203 int16_t peak_x = (int16_t)(sin_angle * size_quarter * 2);
204 int16_t peak_y = (int16_t)(cos_angle * size_quarter * 2);
205 int16_t d_end_x = (int16_t)(cos_angle * size_quarter);
206 int16_t d_end_y = (int16_t)(sin_angle * size_quarter);
208 write_line_lm(x + peak_x, y - peak_y, x - peak_x - d_end_x, y + peak_y - d_end_y, 1, 1);
209 write_line_lm(x + peak_x, y - peak_y, x - peak_x + d_end_x, y + peak_y + d_end_y, 1, 1);
210 write_line_lm(x, y, x - peak_x - d_end_x, y + peak_y - d_end_y, 1, 1);
211 write_line_lm(x, y, x - peak_x + d_end_x, y + peak_y + d_end_y, 1, 1);
214 void drawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
222 #if defined(PIOS_VIDEO_SPLITBUFFER)
268 #if defined(PIOS_VIDEO_SPLITBUFFER)
286 #if defined(PIOS_VIDEO_SPLITBUFFER)
304 int mask, mask_l, mask_r,
i;
307 if (addr0 == addr1) {
317 for (i = addr0 + 1; i <= addr1 - 1; i++) {
341 int mask, mask_l, mask_r,
i;
344 if (addr0 == addr1) {
354 for (i = addr0 + 1; i <= addr1 - 1; i++) {
374 #if defined(PIOS_VIDEO_SPLITBUFFER)
423 #if defined(PIOS_VIDEO_SPLITBUFFER)
424 void write_vline(uint8_t *buff,
int x,
int y0,
int y1,
int mode)
485 #if defined(PIOS_VIDEO_SPLITBUFFER)
539 #if defined(PIOS_VIDEO_SPLITBUFFER)
542 int yy, addr0_old, addr1_old;
546 if (width <= 0 || height <= 0) {
555 int mask, mask_l, mask_r,
i;
557 if (addr0 == addr1) {
571 while (yy < height) {
582 while (yy < height) {
583 for (i = addr0 + 1; i <= addr1 - 1; i++) {
596 int yy, addr0_old, addr1_old;
600 if (width <= 0 || height <= 0) {
609 int mask, mask_l, mask_r,
i;
611 if (addr0 == addr1) {
625 while (yy < height) {
636 while (yy < height) {
637 for (i = addr0 + 1; i <= addr1 - 1; i++) {
661 #if defined(PIOS_VIDEO_SPLITBUFFER)
689 #if defined(PIOS_VIDEO_SPLITBUFFER)
701 void write_circle(uint8_t *buff,
int cx,
int cy,
int r,
int dashp,
int mode)
704 int error = -r, x = r, y = 0;
706 if (dashp == 0 || (y % dashp) < (dashp / 2)) {
709 error += (y * 2) + 1;
737 int error = -r, x = r, y = 0;
739 if (dashp == 0 || (y % dashp) < (dashp / 2)) {
755 error += (y * 2) + 1;
766 if (dashp == 0 || (y % dashp) < (dashp / 2)) {
770 error += (y * 2) + 1;
788 void write_circle_filled(uint8_t *buff,
int cx,
int cy,
int r,
int mode)
791 int error = -r, x = r, y = 0, xch = 0;
803 if (mode != 2 || (mode == 2 && xch && (cx - x) != (cx - y))) {
809 error += (y * 2) + 1;
834 #if defined(PIOS_VIDEO_SPLITBUFFER)
835 void write_line(uint8_t *buff,
int x0,
int y0,
int x1,
int y1,
int mode)
838 int steep = abs(y1 - y0) > abs(x1 - x0);
848 int deltax = x1 - x0;
849 int deltay = abs(y1 - y0);
850 int error = deltax / 2;
859 for (x = x0; x < x1; x++) {
876 int steep = abs(y1 - y0) > abs(x1 - x0);
886 int deltax = x1 - x0;
887 int deltay = abs(y1 - y0);
888 int error = deltax / 2;
897 for (x = x0; x < x1; x++) {
924 #if defined(PIOS_VIDEO_SPLITBUFFER)
960 int steep = abs(y1 - y0) > abs(x1 - x0);
969 int deltax = x1 - x0;
970 int deltay = abs(y1 - y0);
971 int error = deltax / 2;
981 for (x = x0; x < x1; x++) {
1002 for (x = x0; x < x1; x++) {
1031 int mode,
int mmode,
int dots)
1044 int steep = abs(y1 - y0) > abs(x1 - x0);
1053 int deltax = x1 - x0;
1054 int deltay = abs(y1 - y0);
1055 int error = deltax / 2;
1067 for (x = x0; x < x1; x++) {
1068 if (dots && !(dot_cnt++ % dots)) {
1095 for (x = x0; x < x1; x++) {
1096 if (dots && !(dot_cnt++ % dots)) {
1131 uint16_t firstmask = word >> xoff;
1132 uint16_t lastmask = word << (16 - xoff);
1158 uint16_t firstmask = word >> xoff;
1159 uint16_t lastmask = word << (16 - xoff);
1185 uint16_t firstword = (word >> xoff);
1186 uint16_t lastword = word << (16 - xoff);
1187 uint16_t firstmask = (mask >> xoff);
1188 uint16_t lastmask = mask << (16 - xoff);
1190 WRITE_WORD(buff, addr + 1, firstmask & 0x00ff, firstword & 0x00ff);
1191 WRITE_WORD(buff, addr, (firstmask & 0xff00) >> 8, (firstword & 0xff00) >> 8);
1193 WRITE_WORD(buff, addr + 2, (lastmask & 0xff00) >> 8, (lastword & 0xff00) >> 8);
1209 #if defined(PIOS_VIDEO_SPLITBUFFER)
1216 ch = font_info->
lookup[ch];
1230 row = ch * font_info->
height;
1232 if (font_info->
width > 8) {
1234 for (yy = y; yy < y + font_info->
height; yy++) {
1236 data = ((uint32_t*)font_info->
data)[row];
1237 #if defined(PIOS_VIDEO_SPLITBUFFER)
1238 mask = data & 0xFFFF;
1239 levels = (data >> 16) & 0xFFFF;
1244 mask = (mask & levels);
1247 data16 = (data & 0xFFFF0000) >> 16;
1248 mask = data16 | (data16 << 1);
1250 data16 = (data & 0x0000FFFF);
1251 mask = data16 | (data16 << 1);
1261 for (yy = y; yy < y + font_info->
height; yy++) {
1263 data = font_info->
data[row];
1264 #if defined(PIOS_VIDEO_SPLITBUFFER)
1265 levels = data & 0xFF00;
1266 mask = (data & 0x00FF) << 8;
1271 mask = (mask & levels);
1274 mask = data | (data << 1);
1310 int max_length = 0, line_length = 0, lines = 1;
1314 if (*str ==
'\n' || *str ==
'\r') {
1315 if (line_length > max_length) {
1316 max_length = line_length;
1323 if (line_length > max_length) {
1324 max_length = line_length;
1326 dim->
width = max_length * (font->
width + xs);
1346 int xx = 0, yy = 0, xx_original = 0;
1358 yy = y - (dim.
height / 2) + 1;
1370 xx = x - (dim.
width / 2);
1379 if (*str ==
'\n' || *str ==
'\r') {
1380 yy += ys + font_info->height;
1386 xx += font_info->width + xs;
1396 void draw_polygon(int16_t x, int16_t y,
float angle,
const point_t * points, uint8_t n_points,
int mode,
int mmode)
1398 float sin_angle, cos_angle;
1399 int16_t x1, y1, x2, y2;
1401 sin_angle = sinf(angle * (
float)(M_PI / 180));
1402 cos_angle = cosf(angle * (
float)(M_PI / 180));
1404 x1 = roundf(cos_angle * points[0].x - sin_angle * points[0].y);
1405 y1 = roundf(sin_angle * points[0].x + cos_angle * points[0].y);
1409 for (
int i=0; i<n_points-1; i++)
1411 x2 = roundf(cos_angle * points[i + 1].x - sin_angle * points[i + 1].y);
1412 y2 = roundf(sin_angle * points[i + 1].x + cos_angle * points[i + 1].y);
1419 x1 = roundf(cos_angle * points[0].x - sin_angle * points[0].y);
1420 y1 = roundf(sin_angle * points[0].x + cos_angle * points[0].y);
1423 for (
int i=0; i<n_points-1; i++)
1425 x2 = roundf(cos_angle * points[i + 1].x - sin_angle * points[i + 1].y);
1426 y2 = roundf(sin_angle * points[i + 1].x + cos_angle * points[i + 1].y);
1433 x1 = roundf(cos_angle * points[0].x - sin_angle * points[0].y);
1434 y1 = roundf(sin_angle * points[0].x + cos_angle * points[0].y);
1453 HomeLocationGet(&homeLocation);
1455 GPSPositionData gpsPosition;
1456 GPSPositionGet(&gpsPosition);
1458 float lat = lattitude / 10.0e6f * DEG2RAD;
1461 T[0] = altitude + 6.378137E6f;
1462 T[1] = cosf(lat) * (altitude + 6.378137E6f);
1465 float dL[3] = {(lattitude - homeLocation.Latitude) / 10.0e6f * DEG2RAD,
1466 (longitude - homeLocation.Longitude) / 10.0e6f * DEG2RAD,
1467 (altitude + gpsPosition.GeoidSeparation - homeLocation.Altitude)};
1469 NED[0] = T[0] * dL[0];
1470 NED[1] = T[1] * dL[1];
1471 NED[2] = T[2] * dL[2];
#define GRAPHICS_WIDTH_REAL
void write_string(char *str, int x, int y, int xs, int ys, int va, int ha, int flags, int font)
void write_circle_outlined(int cx, int cy, int r, int dashp, int bmode, int mode, int mmode)
void draw_polygon(int16_t x, int16_t y, float angle, const point_t *points, uint8_t n_points, int mode, int mmode)
void write_vline_lm(int x, int y0, int y1, int lmode, int mmode)
#define DRAW_ENDCAP_VLINE(e, x, y, s, f, l)
void write_vline_outlined(int x, int y0, int y1, int endcap0, int endcap1, int mode, int mmode)
#define COMPUTE_HLINE_ISLAND_MASK(b0, b1)
#define CALC_BIT0_IN_WORD(x)
void write_char(uint8_t ch, int x, int y, const struct FontEntry *font_info)
void draw_image(uint16_t x, uint16_t y, const struct Image *image)
OSD gen module, handles OSD draw. Parts from CL-OSD and SUPEROSD projects.
#define CIRCLE_PLOT_8(buff, cx, cy, x, y, mode)
void write_line(int x0, int y0, int x1, int y1, uint8_t value)
void write_rectangle_outlined(int x, int y, int width, int height, int mode, int mmode)
void write_line_outlined_dashed(int x0, int y0, int x1, int y1, __attribute__((unused)) int endcap0, __attribute__((unused)) int endcap1, int mode, int mmode, int dots)
void write_word_misaligned_OR(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff)
#define COMPUTE_HLINE_EDGE_R_MASK(b)
#define CALC_BUFF_ADDR(x, y)
void write_line_outlined(int x0, int y0, int x1, int y1, __attribute__((unused)) int endcap0, __attribute__((unused)) int endcap1, int mode, int mmode)
void write_filled_rectangle(int x, int y, int width, int height, uint8_t value)
static float T[3]
Scales used in NED transform (local tangent plane approx).
uint8_t data[XFER_BYTES_PER_PACKET]
void calc_text_dimensions(char *str, const struct FontEntry *font, int xs, int ys, struct FontDimensions *dim)
uint8_t * draw_buffer_level
#define WRITE_WORD_NAND(buff, addr, mask)
void write_line_lm(int x0, int y0, int x1, int y1, int mmode, int lmode)
#define WRITE_WORD_MODE(buff, addr, mask, mode)
#define WRITE_WORD_OR(buff, addr, mask)
void write_word_misaligned_MASKED(uint8_t *buff, uint16_t word, uint16_t mask, unsigned int addr, unsigned int xoff)
void plotFourQuadrants(int32_t centerX, int32_t centerY, int32_t deltaX, int32_t deltaY)
static HomeLocationData homeLocation
#define PACK_BITS(mask, level)
uint8_t * draw_buffer_mask
void write_hline_outlined(int x0, int x1, int y, int endcap0, int endcap1, int mode, int mmode)
void write_word_misaligned_NAND(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff)
void write_vline(int x, int y0, int y1, uint8_t value)
#define WRITE_WORD(buff, addr, mask, value)
#define CALC_BIT1_IN_WORD(x)
void drawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
const struct FontEntry * get_font_info(int font)
Includes PiOS and core architecture components.
#define DRAW_ENDCAP_HLINE(e, x, y, s, f, l)
void ellipse(int centerX, int centerY, int horizontalRadius, int verticalRadius)
void drawArrow(uint16_t x, uint16_t y, uint16_t angle, uint16_t size_quarter)
void write_hline_lm(int x0, int x1, int y, int lmode, int mmode)
#define COMPUTE_HLINE_EDGE_L_MASK(b)
#define SETUP_STROKE_FILL(stroke, fill, mode)
void write_filled_rectangle_lm(int x, int y, int width, int height, int lmode, int mmode)
void lla_to_ned(int32_t lat, int32_t lon, float alt, float *NED)
void write_pixel(int x, int y, uint8_t value)
struct FontEntry * fonts[NUM_FONTS]
void write_hline(int x0, int x1, int y, uint8_t value)
void write_pixel_lm(int x, int y, int mmode, int lmode)
#define CHECK_COORDS(x, y)
#define CALC_BIT_IN_WORD(x)