|
|
@ -63,13 +63,13 @@ static int32_t m_gpsLon=0;
|
|
|
|
static float m_gpsAlt=0;
|
|
|
|
static float m_gpsAlt=0;
|
|
|
|
static float m_gpsSpd=0;
|
|
|
|
static float m_gpsSpd=0;
|
|
|
|
|
|
|
|
|
|
|
|
extern uint8_t *draw_buffer_level;
|
|
|
|
extern uint8_t *draw_buffer_level;
|
|
|
|
extern uint8_t *draw_buffer_mask;
|
|
|
|
extern uint8_t *draw_buffer_mask;
|
|
|
|
extern uint8_t *disp_buffer_level;
|
|
|
|
extern uint8_t *disp_buffer_level;
|
|
|
|
extern uint8_t *disp_buffer_mask;
|
|
|
|
extern uint8_t *disp_buffer_mask;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TTime time;
|
|
|
|
TTime timex;
|
|
|
|
|
|
|
|
|
|
|
|
// ****************
|
|
|
|
// ****************
|
|
|
|
// Private functions
|
|
|
|
// Private functions
|
|
|
@ -94,8 +94,8 @@ static xTaskHandle osdgenTaskHandle;
|
|
|
|
struct splashEntry
|
|
|
|
struct splashEntry
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned int width, height;
|
|
|
|
unsigned int width, height;
|
|
|
|
uint8_t *level;
|
|
|
|
uint8_t *level;
|
|
|
|
uint8_t *mask;
|
|
|
|
uint8_t *mask;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct splashEntry splash[3] = {
|
|
|
|
struct splashEntry splash[3] = {
|
|
|
@ -114,100 +114,43 @@ struct splashEntry splash[3] = {
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// simple routines
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
uint8_t getCharData(uint16_t charPos) {
|
|
|
|
|
|
|
|
if (charPos >= CHAR_ARRAY_OFFSET && charPos < CHAR_ARRAY_MAX) {
|
|
|
|
|
|
|
|
return (oem6x8[charPos - CHAR_ARRAY_OFFSET]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
return 0x00;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// prints text into draw_buffer_level, 8x2
|
|
|
|
|
|
|
|
/*uint8_t printTextFB(uint16_t x, uint16_t y, const char* str) {
|
|
|
|
|
|
|
|
uint8_t length = strlen(str);
|
|
|
|
|
|
|
|
if (x + length >= TEXT_LINE_MAX_CHARS) {
|
|
|
|
|
|
|
|
length = TEXT_LINE_MAX_CHARS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uint8_t i = 0; i < TEXT_CHAR_HEIGHT; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint8_t c=0;
|
|
|
|
|
|
|
|
uint16_t charPos;
|
|
|
|
|
|
|
|
for(int j=0; j<length; j+=2)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint16_t word=0;
|
|
|
|
|
|
|
|
charPos = str[j] * TEXT_CHAR_HEIGHT + i;
|
|
|
|
|
|
|
|
word = getCharData(charPos)<<8;
|
|
|
|
|
|
|
|
charPos = str[j+1] * TEXT_CHAR_HEIGHT + i;
|
|
|
|
|
|
|
|
word |= getCharData(charPos);
|
|
|
|
|
|
|
|
draw_buffer_level[((y+i)*GRAPHICS_WIDTH)+(x + c)] = word;
|
|
|
|
|
|
|
|
c++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return length;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t printText16(uint16_t x, uint16_t y, const char* str) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t length = strlen(str);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int j=0; j<length; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
write_char16(str[j],12*j+x,y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return length;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t printCharFB(uint16_t ch, uint16_t x, uint16_t y) {
|
|
|
|
|
|
|
|
for(uint8_t i = 0; i < 18; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint8_t c=0;
|
|
|
|
|
|
|
|
draw_buffer_level[((y+i)*GRAPHICS_WIDTH)+(x+c)] = font_frame16x18[ch*18+i];
|
|
|
|
|
|
|
|
draw_buffer_mask[((y+i)*GRAPHICS_WIDTH)+(x+c)] = font_mask16x18[ch*18+i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t mirror(uint16_t source)
|
|
|
|
uint16_t mirror(uint16_t source)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int result = ((source & 0x8000) >> 7) | ((source & 0x4000) >> 5) |
|
|
|
|
int result = ((source & 0x8000) >> 7) | ((source & 0x4000) >> 5) |
|
|
|
|
((source & 0x2000) >> 3) | ((source & 0x1000) >> 1) |
|
|
|
|
((source & 0x2000) >> 3) | ((source & 0x1000) >> 1) |
|
|
|
|
((source & 0x0800) << 1) | ((source & 0x0400) << 3) |
|
|
|
|
((source & 0x0800) << 1) | ((source & 0x0400) << 3) |
|
|
|
|
((source & 0x0200) << 5) | ((source & 0x0100) << 7) |
|
|
|
|
((source & 0x0200) << 5) | ((source & 0x0100) << 7) |
|
|
|
|
((source & 0x0080) >> 7) | ((source & 0x0040) >> 5) |
|
|
|
|
((source & 0x0080) >> 7) | ((source & 0x0040) >> 5) |
|
|
|
|
((source & 0x0020) >> 3) | ((source & 0x0010) >> 1) |
|
|
|
|
((source & 0x0020) >> 3) | ((source & 0x0010) >> 1) |
|
|
|
|
((source & 0x0008) << 1) | ((source & 0x0004) << 3) |
|
|
|
|
((source & 0x0008) << 1) | ((source & 0x0004) << 3) |
|
|
|
|
((source & 0x0002) << 5) | ((source & 0x0001) << 7);
|
|
|
|
((source & 0x0002) << 5) | ((source & 0x0001) << 7);
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void clearGraphics() {
|
|
|
|
void clearGraphics() {
|
|
|
|
memset((uint8_t *) draw_buffer_mask, 0, GRAPHICS_WIDTH * GRAPHICS_HEIGHT);
|
|
|
|
memset((uint8_t *) draw_buffer_mask, 0, GRAPHICS_WIDTH * GRAPHICS_HEIGHT);
|
|
|
|
memset((uint8_t *) draw_buffer_level, 0, GRAPHICS_WIDTH * GRAPHICS_HEIGHT);
|
|
|
|
memset((uint8_t *) draw_buffer_level, 0, GRAPHICS_WIDTH * GRAPHICS_HEIGHT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void copyimage(uint16_t offsetx, uint16_t offsety, int image) {
|
|
|
|
void copyimage(uint16_t offsetx, uint16_t offsety, int image) {
|
|
|
|
|
|
|
|
//check top/left position
|
|
|
|
|
|
|
|
if (!validPos(offsetx, offsety)) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
struct splashEntry splash_info;
|
|
|
|
struct splashEntry splash_info;
|
|
|
|
splash_info = splash[image];
|
|
|
|
splash_info = splash[image];
|
|
|
|
offsetx=offsetx/8;
|
|
|
|
offsetx=offsetx/8;
|
|
|
|
for (uint16_t y = offsety; y < ((splash_info.height)+offsety); y++) {
|
|
|
|
for (uint16_t y = offsety; y < ((splash_info.height)+offsety); y++) {
|
|
|
|
for (uint16_t x = offsetx; x < (((splash_info.width)/8)+offsetx); x++) {
|
|
|
|
for (uint16_t x = offsetx; x < (((splash_info.width)/8)+offsetx); x++) {
|
|
|
|
draw_buffer_level[y*GRAPHICS_WIDTH+x] = mirror(splash_info.level[(y-offsety)*((splash_info.width)/8)+(x-offsetx)]);
|
|
|
|
draw_buffer_level[y*GRAPHICS_WIDTH+x] = mirror(splash_info.level[(y-offsety)*((splash_info.width)/8)+(x-offsetx)]);
|
|
|
|
draw_buffer_mask[y*GRAPHICS_WIDTH+x] = mirror(splash_info.mask[(y-offsety)*((splash_info.width)/8)+(x-offsetx)]);
|
|
|
|
draw_buffer_mask[y*GRAPHICS_WIDTH+x] = mirror(splash_info.mask[(y-offsety)*((splash_info.width)/8)+(x-offsetx)]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t validPos(uint16_t x, uint16_t y) {
|
|
|
|
uint8_t validPos(uint16_t x, uint16_t y) {
|
|
|
|
if (x >= GRAPHICS_WIDTH_REAL || y >= GRAPHICS_HEIGHT) {
|
|
|
|
if ( x < GRAPHICS_HDEADBAND || x >= GRAPHICS_WIDTH_REAL || y >= GRAPHICS_HEIGHT_REAL) {
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
@ -217,9 +160,9 @@ void setPixel(uint16_t x, uint16_t y, uint8_t state) {
|
|
|
|
if (!validPos(x, y)) {
|
|
|
|
if (!validPos(x, y)) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uint8_t bitPos = 7-(x%8);
|
|
|
|
uint8_t bitPos = 7-(x%8);
|
|
|
|
uint16_t tempf = draw_buffer_level[y*GRAPHICS_WIDTH+x/8];
|
|
|
|
uint16_t tempf = draw_buffer_level[y*GRAPHICS_WIDTH+x/8];
|
|
|
|
uint16_t tempm = draw_buffer_mask[y*GRAPHICS_WIDTH+x/8];
|
|
|
|
uint16_t tempm = draw_buffer_mask[y*GRAPHICS_WIDTH+x/8];
|
|
|
|
if (state == 0) {
|
|
|
|
if (state == 0) {
|
|
|
|
tempf &= ~(1<<bitPos);
|
|
|
|
tempf &= ~(1<<bitPos);
|
|
|
|
tempm &= ~(1<<bitPos);
|
|
|
|
tempm &= ~(1<<bitPos);
|
|
|
@ -232,8 +175,8 @@ void setPixel(uint16_t x, uint16_t y, uint8_t state) {
|
|
|
|
tempf ^= (1<<bitPos);
|
|
|
|
tempf ^= (1<<bitPos);
|
|
|
|
tempm ^= (1<<bitPos);
|
|
|
|
tempm ^= (1<<bitPos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
draw_buffer_level[y*GRAPHICS_WIDTH+x/8] = tempf;
|
|
|
|
draw_buffer_level[y*GRAPHICS_WIDTH+x/8] = tempf;
|
|
|
|
draw_buffer_mask[y*GRAPHICS_WIDTH+x/8] = tempm;
|
|
|
|
draw_buffer_mask[y*GRAPHICS_WIDTH+x/8] = tempm;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Credit for this one goes to wikipedia! :-)
|
|
|
|
// Credit for this one goes to wikipedia! :-)
|
|
|
@ -478,16 +421,16 @@ void drawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
|
|
|
* @param y y coordinate
|
|
|
|
* @param y y coordinate
|
|
|
|
* @param mode 0 = clear bit, 1 = set bit, 2 = toggle bit
|
|
|
|
* @param mode 0 = clear bit, 1 = set bit, 2 = toggle bit
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_pixel(uint8_t *buff, unsigned int x, unsigned int y, int mode)
|
|
|
|
void write_pixel(uint8_t *buff, unsigned int x, unsigned int y, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CHECK_COORDS(x, y);
|
|
|
|
CHECK_COORDS(x, y);
|
|
|
|
// Determine the bit in the word to be set and the word
|
|
|
|
// Determine the bit in the word to be set and the word
|
|
|
|
// index to set it in.
|
|
|
|
// index to set it in.
|
|
|
|
int bitnum = CALC_BIT_IN_WORD(x);
|
|
|
|
int bitnum = CALC_BIT_IN_WORD(x);
|
|
|
|
int wordnum = CALC_BUFF_ADDR(x, y);
|
|
|
|
int wordnum = CALC_BUFF_ADDR(x, y);
|
|
|
|
// Apply a mask.
|
|
|
|
// Apply a mask.
|
|
|
|
uint16_t mask = 1 << (7 - bitnum);
|
|
|
|
uint16_t mask = 1 << (7 - bitnum);
|
|
|
|
WRITE_WORD_MODE(buff, wordnum, mask, mode);
|
|
|
|
WRITE_WORD_MODE(buff, wordnum, mask, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -501,15 +444,15 @@ void write_pixel(uint8_t *buff, unsigned int x, unsigned int y, int mode)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_pixel_lm(unsigned int x, unsigned int y, int mmode, int lmode)
|
|
|
|
void write_pixel_lm(unsigned int x, unsigned int y, int mmode, int lmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CHECK_COORDS(x, y);
|
|
|
|
CHECK_COORDS(x, y);
|
|
|
|
// Determine the bit in the word to be set and the word
|
|
|
|
// Determine the bit in the word to be set and the word
|
|
|
|
// index to set it in.
|
|
|
|
// index to set it in.
|
|
|
|
int bitnum = CALC_BIT_IN_WORD(x);
|
|
|
|
int bitnum = CALC_BIT_IN_WORD(x);
|
|
|
|
int wordnum = CALC_BUFF_ADDR(x, y);
|
|
|
|
int wordnum = CALC_BUFF_ADDR(x, y);
|
|
|
|
// Apply the masks.
|
|
|
|
// Apply the masks.
|
|
|
|
uint16_t mask = 1 << (7 - bitnum);
|
|
|
|
uint16_t mask = 1 << (7 - bitnum);
|
|
|
|
WRITE_WORD_MODE(draw_buffer_mask, wordnum, mask, mmode);
|
|
|
|
WRITE_WORD_MODE(draw_buffer_mask, wordnum, mask, mmode);
|
|
|
|
WRITE_WORD_MODE(draw_buffer_level, wordnum, mask, lmode);
|
|
|
|
WRITE_WORD_MODE(draw_buffer_level, wordnum, mask, lmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -522,42 +465,42 @@ void write_pixel_lm(unsigned int x, unsigned int y, int mmode, int lmode)
|
|
|
|
* @param y y coordinate
|
|
|
|
* @param y y coordinate
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_hline(uint8_t *buff, unsigned int x0, unsigned int x1, unsigned int y, int mode)
|
|
|
|
void write_hline(uint8_t *buff, unsigned int x0, unsigned int x1, unsigned int y, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CLIP_COORDS(x0, y);
|
|
|
|
CLIP_COORDS(x0, y);
|
|
|
|
CLIP_COORDS(x1, y);
|
|
|
|
CLIP_COORDS(x1, y);
|
|
|
|
if(x0 > x1)
|
|
|
|
if(x0 > x1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(x0, x1);
|
|
|
|
SWAP(x0, x1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(x0 == x1) return;
|
|
|
|
if(x0 == x1) return;
|
|
|
|
/* This is an optimised algorithm for writing horizontal lines.
|
|
|
|
/* This is an optimised algorithm for writing horizontal lines.
|
|
|
|
* We begin by finding the addresses of the x0 and x1 points. */
|
|
|
|
* We begin by finding the addresses of the x0 and x1 points. */
|
|
|
|
int addr0 = CALC_BUFF_ADDR(x0, y);
|
|
|
|
int addr0 = CALC_BUFF_ADDR(x0, y);
|
|
|
|
int addr1 = CALC_BUFF_ADDR(x1, y);
|
|
|
|
int addr1 = CALC_BUFF_ADDR(x1, y);
|
|
|
|
int addr0_bit = CALC_BIT_IN_WORD(x0);
|
|
|
|
int addr0_bit = CALC_BIT_IN_WORD(x0);
|
|
|
|
int addr1_bit = CALC_BIT_IN_WORD(x1);
|
|
|
|
int addr1_bit = CALC_BIT_IN_WORD(x1);
|
|
|
|
int mask, mask_l, mask_r, i;
|
|
|
|
int mask, mask_l, mask_r, i;
|
|
|
|
/* If the addresses are equal, we only need to write one word
|
|
|
|
/* If the addresses are equal, we only need to write one word
|
|
|
|
* which is an island. */
|
|
|
|
* which is an island. */
|
|
|
|
if(addr0 == addr1)
|
|
|
|
if(addr0 == addr1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mask = COMPUTE_HLINE_ISLAND_MASK(addr0_bit, addr1_bit);
|
|
|
|
mask = COMPUTE_HLINE_ISLAND_MASK(addr0_bit, addr1_bit);
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Otherwise we need to write the edges and then the middle. */
|
|
|
|
/* Otherwise we need to write the edges and then the middle. */
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mask_l = COMPUTE_HLINE_EDGE_L_MASK(addr0_bit);
|
|
|
|
mask_l = COMPUTE_HLINE_EDGE_L_MASK(addr0_bit);
|
|
|
|
mask_r = COMPUTE_HLINE_EDGE_R_MASK(addr1_bit);
|
|
|
|
mask_r = COMPUTE_HLINE_EDGE_R_MASK(addr1_bit);
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask_l, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask_l, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr1, mask_r, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr1, mask_r, mode);
|
|
|
|
// Now write 0xffff words from start+1 to end-1.
|
|
|
|
// Now write 0xffff words from start+1 to end-1.
|
|
|
|
for(i = addr0 + 1; i <= addr1 - 1; i++)
|
|
|
|
for(i = addr0 + 1; i <= addr1 - 1; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WRITE_WORD_MODE(buff, i, 0xff, mode);
|
|
|
|
WRITE_WORD_MODE(buff, i, 0xff, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -571,10 +514,10 @@ void write_hline(uint8_t *buff, unsigned int x0, unsigned int x1, unsigned int y
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_hline_lm(unsigned int x0, unsigned int x1, unsigned int y, int lmode, int mmode)
|
|
|
|
void write_hline_lm(unsigned int x0, unsigned int x1, unsigned int y, int lmode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// TODO: an optimisation would compute the masks and apply to
|
|
|
|
// TODO: an optimisation would compute the masks and apply to
|
|
|
|
// both buffers simultaneously.
|
|
|
|
// both buffers simultaneously.
|
|
|
|
write_hline(draw_buffer_level, x0, x1, y, lmode);
|
|
|
|
write_hline(draw_buffer_level, x0, x1, y, lmode);
|
|
|
|
write_hline(draw_buffer_mask, x0, x1, y, mmode);
|
|
|
|
write_hline(draw_buffer_mask, x0, x1, y, mmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -591,19 +534,19 @@ void write_hline_lm(unsigned int x0, unsigned int x1, unsigned int y, int lmode,
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_hline_outlined(unsigned int x0, unsigned int x1, unsigned int y, int endcap0, int endcap1, int mode, int mmode)
|
|
|
|
void write_hline_outlined(unsigned int x0, unsigned int x1, unsigned int y, int endcap0, int endcap1, int mode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int stroke, fill;
|
|
|
|
int stroke, fill;
|
|
|
|
SETUP_STROKE_FILL(stroke, fill, mode)
|
|
|
|
SETUP_STROKE_FILL(stroke, fill, mode)
|
|
|
|
if(x0 > x1)
|
|
|
|
if(x0 > x1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(x0, x1);
|
|
|
|
SWAP(x0, x1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw the main body of the line.
|
|
|
|
// Draw the main body of the line.
|
|
|
|
write_hline_lm(x0 + 1, x1 - 1, y - 1, stroke, mmode);
|
|
|
|
write_hline_lm(x0 + 1, x1 - 1, y - 1, stroke, mmode);
|
|
|
|
write_hline_lm(x0 + 1, x1 - 1, y + 1, stroke, mmode);
|
|
|
|
write_hline_lm(x0 + 1, x1 - 1, y + 1, stroke, mmode);
|
|
|
|
write_hline_lm(x0 + 1, x1 - 1, y, fill, mmode);
|
|
|
|
write_hline_lm(x0 + 1, x1 - 1, y, fill, mmode);
|
|
|
|
// Draw the endcaps, if any.
|
|
|
|
// Draw the endcaps, if any.
|
|
|
|
DRAW_ENDCAP_HLINE(endcap0, x0, y, stroke, fill, mmode);
|
|
|
|
DRAW_ENDCAP_HLINE(endcap0, x0, y, stroke, fill, mmode);
|
|
|
|
DRAW_ENDCAP_HLINE(endcap1, x1, y, stroke, fill, mmode);
|
|
|
|
DRAW_ENDCAP_HLINE(endcap1, x1, y, stroke, fill, mmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -615,29 +558,29 @@ void write_hline_outlined(unsigned int x0, unsigned int x1, unsigned int y, int
|
|
|
|
* @param y1 y1 coordinate
|
|
|
|
* @param y1 y1 coordinate
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_vline(uint8_t *buff, unsigned int x, unsigned int y0, unsigned int y1, int mode)
|
|
|
|
void write_vline(uint8_t *buff, unsigned int x, unsigned int y0, unsigned int y1, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned int a;
|
|
|
|
unsigned int a;
|
|
|
|
CLIP_COORDS(x, y0);
|
|
|
|
CLIP_COORDS(x, y0);
|
|
|
|
CLIP_COORDS(x, y1);
|
|
|
|
CLIP_COORDS(x, y1);
|
|
|
|
if(y0 > y1)
|
|
|
|
if(y0 > y1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(y0, y1);
|
|
|
|
SWAP(y0, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(y0 == y1) return;
|
|
|
|
if(y0 == y1) return;
|
|
|
|
/* This is an optimised algorithm for writing vertical lines.
|
|
|
|
/* This is an optimised algorithm for writing vertical lines.
|
|
|
|
* We begin by finding the addresses of the x,y0 and x,y1 points. */
|
|
|
|
* We begin by finding the addresses of the x,y0 and x,y1 points. */
|
|
|
|
int addr0 = CALC_BUFF_ADDR(x, y0);
|
|
|
|
int addr0 = CALC_BUFF_ADDR(x, y0);
|
|
|
|
int addr1 = CALC_BUFF_ADDR(x, y1);
|
|
|
|
int addr1 = CALC_BUFF_ADDR(x, y1);
|
|
|
|
/* Then we calculate the pixel data to be written. */
|
|
|
|
/* Then we calculate the pixel data to be written. */
|
|
|
|
int bitnum = CALC_BIT_IN_WORD(x);
|
|
|
|
int bitnum = CALC_BIT_IN_WORD(x);
|
|
|
|
uint16_t mask = 1 << (7 - bitnum);
|
|
|
|
uint16_t mask = 1 << (7 - bitnum);
|
|
|
|
/* Run from addr0 to addr1 placing pixels. Increment by the number
|
|
|
|
/* Run from addr0 to addr1 placing pixels. Increment by the number
|
|
|
|
* of words n each graphics line. */
|
|
|
|
* of words n each graphics line. */
|
|
|
|
for(a = addr0; a <= addr1; a += DISP_WIDTH / 8)
|
|
|
|
for(a = addr0; a <= addr1; a += GRAPHICS_WIDTH_REAL / 8)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WRITE_WORD_MODE(buff, a, mask, mode);
|
|
|
|
WRITE_WORD_MODE(buff, a, mask, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -651,10 +594,10 @@ void write_vline(uint8_t *buff, unsigned int x, unsigned int y0, unsigned int y1
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_vline_lm(unsigned int x, unsigned int y0, unsigned int y1, int lmode, int mmode)
|
|
|
|
void write_vline_lm(unsigned int x, unsigned int y0, unsigned int y1, int lmode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// TODO: an optimisation would compute the masks and apply to
|
|
|
|
// TODO: an optimisation would compute the masks and apply to
|
|
|
|
// both buffers simultaneously.
|
|
|
|
// both buffers simultaneously.
|
|
|
|
write_vline(draw_buffer_level, x, y0, y1, lmode);
|
|
|
|
write_vline(draw_buffer_level, x, y0, y1, lmode);
|
|
|
|
write_vline(draw_buffer_mask, x, y0, y1, mmode);
|
|
|
|
write_vline(draw_buffer_mask, x, y0, y1, mmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -671,19 +614,19 @@ void write_vline_lm(unsigned int x, unsigned int y0, unsigned int y1, int lmode,
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_vline_outlined(unsigned int x, unsigned int y0, unsigned int y1, int endcap0, int endcap1, int mode, int mmode)
|
|
|
|
void write_vline_outlined(unsigned int x, unsigned int y0, unsigned int y1, int endcap0, int endcap1, int mode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int stroke, fill;
|
|
|
|
int stroke, fill;
|
|
|
|
if(y0 > y1)
|
|
|
|
if(y0 > y1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(y0, y1);
|
|
|
|
SWAP(y0, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SETUP_STROKE_FILL(stroke, fill, mode);
|
|
|
|
SETUP_STROKE_FILL(stroke, fill, mode);
|
|
|
|
// Draw the main body of the line.
|
|
|
|
// Draw the main body of the line.
|
|
|
|
write_vline_lm(x - 1, y0 + 1, y1 - 1, stroke, mmode);
|
|
|
|
write_vline_lm(x - 1, y0 + 1, y1 - 1, stroke, mmode);
|
|
|
|
write_vline_lm(x + 1, y0 + 1, y1 - 1, stroke, mmode);
|
|
|
|
write_vline_lm(x + 1, y0 + 1, y1 - 1, stroke, mmode);
|
|
|
|
write_vline_lm(x, y0 + 1, y1 - 1, fill, mmode);
|
|
|
|
write_vline_lm(x, y0 + 1, y1 - 1, fill, mmode);
|
|
|
|
// Draw the endcaps, if any.
|
|
|
|
// Draw the endcaps, if any.
|
|
|
|
DRAW_ENDCAP_VLINE(endcap0, x, y0, stroke, fill, mmode);
|
|
|
|
DRAW_ENDCAP_VLINE(endcap0, x, y0, stroke, fill, mmode);
|
|
|
|
DRAW_ENDCAP_VLINE(endcap1, x, y1, stroke, fill, mmode);
|
|
|
|
DRAW_ENDCAP_VLINE(endcap1, x, y1, stroke, fill, mmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -700,7 +643,7 @@ void write_vline_outlined(unsigned int x, unsigned int y0, unsigned int y1, int
|
|
|
|
* @param height rectangle height
|
|
|
|
* @param height rectangle height
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_filled_rectangle(uint8_t *buff, unsigned int x, unsigned int y, unsigned int width, unsigned int height, int mode)
|
|
|
|
void write_filled_rectangle(uint8_t *buff, unsigned int x, unsigned int y, unsigned int width, unsigned int height, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int yy, addr0_old, addr1_old;
|
|
|
|
int yy, addr0_old, addr1_old;
|
|
|
|
CHECK_COORDS(x, y);
|
|
|
|
CHECK_COORDS(x, y);
|
|
|
@ -721,7 +664,7 @@ void write_filled_rectangle(uint8_t *buff, unsigned int x, unsigned int y, unsig
|
|
|
|
while(height--)
|
|
|
|
while(height--)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask, mode);
|
|
|
|
addr0 += DISP_WIDTH / 8;
|
|
|
|
addr0 += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Otherwise we need to write the edges and then the middle repeatedly.
|
|
|
|
// Otherwise we need to write the edges and then the middle repeatedly.
|
|
|
@ -737,8 +680,8 @@ void write_filled_rectangle(uint8_t *buff, unsigned int x, unsigned int y, unsig
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask_l, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr0, mask_l, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr1, mask_r, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr1, mask_r, mode);
|
|
|
|
addr0 += DISP_WIDTH / 8;
|
|
|
|
addr0 += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
addr1 += DISP_WIDTH / 8;
|
|
|
|
addr1 += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
yy++;
|
|
|
|
yy++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Now write 0xffff words from start+1 to end-1 for each row.
|
|
|
|
// Now write 0xffff words from start+1 to end-1 for each row.
|
|
|
@ -749,10 +692,10 @@ void write_filled_rectangle(uint8_t *buff, unsigned int x, unsigned int y, unsig
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for(i = addr0 + 1; i <= addr1 - 1; i++)
|
|
|
|
for(i = addr0 + 1; i <= addr1 - 1; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WRITE_WORD_MODE(buff, i, 0xff, mode);
|
|
|
|
WRITE_WORD_MODE(buff, i, 0xff, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
addr0 += DISP_WIDTH / 8;
|
|
|
|
addr0 += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
addr1 += DISP_WIDTH / 8;
|
|
|
|
addr1 += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
yy++;
|
|
|
|
yy++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -787,14 +730,14 @@ void write_filled_rectangle_lm(unsigned int x, unsigned int y, unsigned int widt
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_rectangle_outlined(unsigned int x, unsigned int y, int width, int height, int mode, int mmode)
|
|
|
|
void write_rectangle_outlined(unsigned int x, unsigned int y, int width, int height, int mode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//CHECK_COORDS(x, y);
|
|
|
|
//CHECK_COORDS(x, y);
|
|
|
|
//CHECK_COORDS(x + width, y + height);
|
|
|
|
//CHECK_COORDS(x + width, y + height);
|
|
|
|
//if((x + width) > DISP_WIDTH) width = DISP_WIDTH - x;
|
|
|
|
//if((x + width) > DISP_WIDTH) width = DISP_WIDTH - x;
|
|
|
|
//if((y + height) > DISP_HEIGHT) height = DISP_HEIGHT - y;
|
|
|
|
//if((y + height) > DISP_HEIGHT) height = DISP_HEIGHT - y;
|
|
|
|
write_hline_outlined(x, x + width, y, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
write_hline_outlined(x, x + width, y, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
write_hline_outlined(x, x + width, y + height, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
write_hline_outlined(x, x + width, y + height, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
write_vline_outlined(x, y, y + height, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
write_vline_outlined(x, y, y + height, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
write_vline_outlined(x + width, y, y + height, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
write_vline_outlined(x + width, y, y + height, ENDCAP_ROUND, ENDCAP_ROUND, mode, mmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -808,24 +751,24 @@ void write_rectangle_outlined(unsigned int x, unsigned int y, int width, int hei
|
|
|
|
* @param dashp dash period (pixels) - zero for no dash
|
|
|
|
* @param dashp dash period (pixels) - zero for no dash
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_circle(uint8_t *buff, unsigned int cx, unsigned int cy, unsigned int r, unsigned int dashp, int mode)
|
|
|
|
void write_circle(uint8_t *buff, unsigned int cx, unsigned int cy, unsigned int r, unsigned int dashp, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CHECK_COORDS(cx, cy);
|
|
|
|
CHECK_COORDS(cx, cy);
|
|
|
|
int error = -r, x = r, y = 0;
|
|
|
|
int error = -r, x = r, y = 0;
|
|
|
|
while(x >= y)
|
|
|
|
while(x >= y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(dashp == 0 || (y % dashp) < (dashp / 2))
|
|
|
|
if(dashp == 0 || (y % dashp) < (dashp / 2))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CIRCLE_PLOT_8(buff, cx, cy, x, y, mode);
|
|
|
|
CIRCLE_PLOT_8(buff, cx, cy, x, y, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
y++;
|
|
|
|
y++;
|
|
|
|
if(error >= 0)
|
|
|
|
if(error >= 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
--x;
|
|
|
|
--x;
|
|
|
|
error -= x * 2;
|
|
|
|
error -= x * 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -841,58 +784,58 @@ void write_circle(uint8_t *buff, unsigned int cx, unsigned int cy, unsigned int
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_circle_outlined(unsigned int cx, unsigned int cy, unsigned int r, unsigned int dashp, int bmode, int mode, int mmode)
|
|
|
|
void write_circle_outlined(unsigned int cx, unsigned int cy, unsigned int r, unsigned int dashp, int bmode, int mode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int stroke, fill;
|
|
|
|
int stroke, fill;
|
|
|
|
CHECK_COORDS(cx, cy);
|
|
|
|
CHECK_COORDS(cx, cy);
|
|
|
|
SETUP_STROKE_FILL(stroke, fill, mode);
|
|
|
|
SETUP_STROKE_FILL(stroke, fill, mode);
|
|
|
|
// This is a two step procedure. First, we draw the outline of the
|
|
|
|
// This is a two step procedure. First, we draw the outline of the
|
|
|
|
// circle, then we draw the inner part.
|
|
|
|
// circle, then we draw the inner part.
|
|
|
|
int error = -r, x = r, y = 0;
|
|
|
|
int error = -r, x = r, y = 0;
|
|
|
|
while(x >= y)
|
|
|
|
while(x >= y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(dashp == 0 || (y % dashp) < (dashp / 2))
|
|
|
|
if(dashp == 0 || (y % dashp) < (dashp / 2))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x + 1, y, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x + 1, y, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x + 1, y, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x + 1, y, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x, y + 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x, y + 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x, y + 1, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x, y + 1, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x - 1, y, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x - 1, y, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x - 1, y, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x - 1, y, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x, y - 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x, y - 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x, y - 1, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x, y - 1, stroke);
|
|
|
|
if(bmode == 1)
|
|
|
|
if(bmode == 1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x + 1, y + 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x + 1, y + 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x + 1, y + 1, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x + 1, y + 1, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x - 1, y - 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x - 1, y - 1, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x - 1, y - 1, stroke);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x - 1, y - 1, stroke);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
y++;
|
|
|
|
y++;
|
|
|
|
if(error >= 0)
|
|
|
|
if(error >= 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
--x;
|
|
|
|
--x;
|
|
|
|
error -= x * 2;
|
|
|
|
error -= x * 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error = -r;
|
|
|
|
error = -r;
|
|
|
|
x = r;
|
|
|
|
x = r;
|
|
|
|
y = 0;
|
|
|
|
y = 0;
|
|
|
|
while(x >= y)
|
|
|
|
while(x >= y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(dashp == 0 || (y % dashp) < (dashp / 2))
|
|
|
|
if(dashp == 0 || (y % dashp) < (dashp / 2))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x, y, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_mask, cx, cy, x, y, mmode);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x, y, fill);
|
|
|
|
CIRCLE_PLOT_8(draw_buffer_level, cx, cy, x, y, fill);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
y++;
|
|
|
|
y++;
|
|
|
|
if(error >= 0)
|
|
|
|
if(error >= 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
--x;
|
|
|
|
--x;
|
|
|
|
error -= x * 2;
|
|
|
|
error -= x * 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -904,44 +847,44 @@ void write_circle_outlined(unsigned int cx, unsigned int cy, unsigned int r, uns
|
|
|
|
* @param r radius
|
|
|
|
* @param r radius
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_circle_filled(uint8_t *buff, unsigned int cx, unsigned int cy, unsigned int r, int mode)
|
|
|
|
void write_circle_filled(uint8_t *buff, unsigned int cx, unsigned int cy, unsigned int r, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CHECK_COORDS(cx, cy);
|
|
|
|
CHECK_COORDS(cx, cy);
|
|
|
|
int error = -r, x = r, y = 0, xch = 0;
|
|
|
|
int error = -r, x = r, y = 0, xch = 0;
|
|
|
|
// It turns out that filled circles can take advantage of the midpoint
|
|
|
|
// It turns out that filled circles can take advantage of the midpoint
|
|
|
|
// circle algorithm. We simply draw very fast horizontal lines across each
|
|
|
|
// circle algorithm. We simply draw very fast horizontal lines across each
|
|
|
|
// pair of X,Y coordinates. In some cases, this can even be faster than
|
|
|
|
// pair of X,Y coordinates. In some cases, this can even be faster than
|
|
|
|
// drawing an outlined circle!
|
|
|
|
// drawing an outlined circle!
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Due to multiple writes to each set of pixels, we have a special exception
|
|
|
|
// Due to multiple writes to each set of pixels, we have a special exception
|
|
|
|
// for when using the toggling draw mode.
|
|
|
|
// for when using the toggling draw mode.
|
|
|
|
while(x >= y)
|
|
|
|
while(x >= y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(y != 0)
|
|
|
|
if(y != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_hline(buff, cx - x, cx + x, cy + y, mode);
|
|
|
|
write_hline(buff, cx - x, cx + x, cy + y, mode);
|
|
|
|
write_hline(buff, cx - x, cx + x, cy - y, mode);
|
|
|
|
write_hline(buff, cx - x, cx + x, cy - y, mode);
|
|
|
|
if(mode != 2 || (mode == 2 && xch && (cx - x) != (cx - y)))
|
|
|
|
if(mode != 2 || (mode == 2 && xch && (cx - x) != (cx - y)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_hline(buff, cx - y, cx + y, cy + x, mode);
|
|
|
|
write_hline(buff, cx - y, cx + y, cy + x, mode);
|
|
|
|
write_hline(buff, cx - y, cx + y, cy - x, mode);
|
|
|
|
write_hline(buff, cx - y, cx + y, cy - x, mode);
|
|
|
|
xch = 0;
|
|
|
|
xch = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
error += (y * 2) + 1;
|
|
|
|
y++;
|
|
|
|
y++;
|
|
|
|
if(error >= 0)
|
|
|
|
if(error >= 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
--x;
|
|
|
|
--x;
|
|
|
|
xch = 1;
|
|
|
|
xch = 1;
|
|
|
|
error -= x * 2;
|
|
|
|
error -= x * 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Handle toggle mode.
|
|
|
|
// Handle toggle mode.
|
|
|
|
if(mode == 2)
|
|
|
|
if(mode == 2)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_hline(buff, cx - r, cx + r, cy, mode);
|
|
|
|
write_hline(buff, cx - r, cx + r, cy, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -954,66 +897,66 @@ void write_circle_filled(uint8_t *buff, unsigned int cx, unsigned int cy, unsign
|
|
|
|
* @param y1 second y coordinate
|
|
|
|
* @param y1 second y coordinate
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_line(uint8_t *buff, unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int mode)
|
|
|
|
void write_line(uint8_t *buff, unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Based on http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
|
|
|
// Based on http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
|
|
|
int steep = abs(y1 - y0) > abs(x1 - x0);
|
|
|
|
int steep = abs(y1 - y0) > abs(x1 - x0);
|
|
|
|
if(steep)
|
|
|
|
if(steep)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(x0, y0);
|
|
|
|
SWAP(x0, y0);
|
|
|
|
SWAP(x1, y1);
|
|
|
|
SWAP(x1, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(x0 > x1)
|
|
|
|
if(x0 > x1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(x0, x1);
|
|
|
|
SWAP(x0, x1);
|
|
|
|
SWAP(y0, y1);
|
|
|
|
SWAP(y0, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int deltax = x1 - x0;
|
|
|
|
int deltax = x1 - x0;
|
|
|
|
int deltay = abs(y1 - y0);
|
|
|
|
int deltay = abs(y1 - y0);
|
|
|
|
int error = deltax / 2;
|
|
|
|
int error = deltax / 2;
|
|
|
|
int ystep;
|
|
|
|
int ystep;
|
|
|
|
int y = y0;
|
|
|
|
int y = y0;
|
|
|
|
int x, lasty = y, stox = 0;
|
|
|
|
int x, lasty = y, stox = 0;
|
|
|
|
if(y0 < y1)
|
|
|
|
if(y0 < y1)
|
|
|
|
ystep = 1;
|
|
|
|
ystep = 1;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
ystep = -1;
|
|
|
|
ystep = -1;
|
|
|
|
for(x = x0; x < x1; x++)
|
|
|
|
for(x = x0; x < x1; x++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(steep)
|
|
|
|
if(steep)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(lasty != y)
|
|
|
|
if(lasty != y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(x > lasty)
|
|
|
|
if(x > lasty)
|
|
|
|
write_vline(buff, stox, y, lasty, mode);
|
|
|
|
write_vline(buff, stox, y, lasty, mode);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
write_vline(buff, stox, lasty, y, mode);
|
|
|
|
write_vline(buff, stox, lasty, y, mode);
|
|
|
|
lasty = y;
|
|
|
|
lasty = y;
|
|
|
|
stox = x;
|
|
|
|
stox = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//write_pixel(buff, x, y, mode);
|
|
|
|
//write_pixel(buff, x, y, mode);
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
if(lasty != y)
|
|
|
|
if(lasty != y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(y > lasty)
|
|
|
|
if(y > lasty)
|
|
|
|
write_vline(buff, stox, y, lasty, mode);
|
|
|
|
write_vline(buff, stox, y, lasty, mode);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
write_vline(buff, stox, lasty, y, mode);
|
|
|
|
write_vline(buff, stox, lasty, y, mode);
|
|
|
|
lasty = y;
|
|
|
|
lasty = y;
|
|
|
|
stox = x;
|
|
|
|
stox = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error -= deltay;
|
|
|
|
error -= deltay;
|
|
|
|
if(error < 0)
|
|
|
|
if(error < 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
y += ystep;
|
|
|
|
y += ystep;
|
|
|
|
error += deltax;
|
|
|
|
error += deltax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1028,8 +971,8 @@ void write_line(uint8_t *buff, unsigned int x0, unsigned int y0, unsigned int x1
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_line_lm(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int mmode, int lmode)
|
|
|
|
void write_line_lm(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int mmode, int lmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_line(draw_buffer_mask, x0, y0, x1, y1, mmode);
|
|
|
|
write_line(draw_buffer_mask, x0, y0, x1, y1, mmode);
|
|
|
|
write_line(draw_buffer_level, x0, y0, x1, y1, lmode);
|
|
|
|
write_line(draw_buffer_level, x0, y0, x1, y1, lmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1047,84 +990,84 @@ void write_line_lm(unsigned int x0, unsigned int y0, unsigned int x1, unsigned i
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_line_outlined(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int endcap0, int endcap1, int mode, int mmode)
|
|
|
|
void write_line_outlined(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, int endcap0, int endcap1, int mode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Based on http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
|
|
|
// Based on http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
|
|
|
// This could be improved for speed.
|
|
|
|
// This could be improved for speed.
|
|
|
|
int omode, imode;
|
|
|
|
int omode, imode;
|
|
|
|
if(mode == 0)
|
|
|
|
if(mode == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
omode = 0;
|
|
|
|
omode = 0;
|
|
|
|
imode = 1;
|
|
|
|
imode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
omode = 1;
|
|
|
|
omode = 1;
|
|
|
|
imode = 0;
|
|
|
|
imode = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int steep = abs(y1 - y0) > abs(x1 - x0);
|
|
|
|
int steep = abs(y1 - y0) > abs(x1 - x0);
|
|
|
|
if(steep)
|
|
|
|
if(steep)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(x0, y0);
|
|
|
|
SWAP(x0, y0);
|
|
|
|
SWAP(x1, y1);
|
|
|
|
SWAP(x1, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(x0 > x1)
|
|
|
|
if(x0 > x1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SWAP(x0, x1);
|
|
|
|
SWAP(x0, x1);
|
|
|
|
SWAP(y0, y1);
|
|
|
|
SWAP(y0, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int deltax = x1 - x0;
|
|
|
|
int deltax = x1 - x0;
|
|
|
|
int deltay = abs(y1 - y0);
|
|
|
|
int deltay = abs(y1 - y0);
|
|
|
|
int error = deltax / 2;
|
|
|
|
int error = deltax / 2;
|
|
|
|
int ystep;
|
|
|
|
int ystep;
|
|
|
|
int y = y0;
|
|
|
|
int y = y0;
|
|
|
|
int x;
|
|
|
|
int x;
|
|
|
|
if(y0 < y1)
|
|
|
|
if(y0 < y1)
|
|
|
|
ystep = 1;
|
|
|
|
ystep = 1;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
ystep = -1;
|
|
|
|
ystep = -1;
|
|
|
|
// Draw the outline.
|
|
|
|
// Draw the outline.
|
|
|
|
for(x = x0; x < x1; x++)
|
|
|
|
for(x = x0; x < x1; x++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(steep)
|
|
|
|
if(steep)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_pixel_lm(y - 1, x, mmode, omode);
|
|
|
|
write_pixel_lm(y - 1, x, mmode, omode);
|
|
|
|
write_pixel_lm(y + 1, x, mmode, omode);
|
|
|
|
write_pixel_lm(y + 1, x, mmode, omode);
|
|
|
|
write_pixel_lm(y, x - 1, mmode, omode);
|
|
|
|
write_pixel_lm(y, x - 1, mmode, omode);
|
|
|
|
write_pixel_lm(y, x + 1, mmode, omode);
|
|
|
|
write_pixel_lm(y, x + 1, mmode, omode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_pixel_lm(x - 1, y, mmode, omode);
|
|
|
|
write_pixel_lm(x - 1, y, mmode, omode);
|
|
|
|
write_pixel_lm(x + 1, y, mmode, omode);
|
|
|
|
write_pixel_lm(x + 1, y, mmode, omode);
|
|
|
|
write_pixel_lm(x, y - 1, mmode, omode);
|
|
|
|
write_pixel_lm(x, y - 1, mmode, omode);
|
|
|
|
write_pixel_lm(x, y + 1, mmode, omode);
|
|
|
|
write_pixel_lm(x, y + 1, mmode, omode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error -= deltay;
|
|
|
|
error -= deltay;
|
|
|
|
if(error < 0)
|
|
|
|
if(error < 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
y += ystep;
|
|
|
|
y += ystep;
|
|
|
|
error += deltax;
|
|
|
|
error += deltax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Now draw the innards.
|
|
|
|
// Now draw the innards.
|
|
|
|
error = deltax / 2;
|
|
|
|
error = deltax / 2;
|
|
|
|
y = y0;
|
|
|
|
y = y0;
|
|
|
|
for(x = x0; x < x1; x++)
|
|
|
|
for(x = x0; x < x1; x++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(steep)
|
|
|
|
if(steep)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_pixel_lm(y, x, mmode, imode);
|
|
|
|
write_pixel_lm(y, x, mmode, imode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_pixel_lm(x, y, mmode, imode);
|
|
|
|
write_pixel_lm(x, y, mmode, imode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error -= deltay;
|
|
|
|
error -= deltay;
|
|
|
|
if(error < 0)
|
|
|
|
if(error < 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
y += ystep;
|
|
|
|
y += ystep;
|
|
|
|
error += deltax;
|
|
|
|
error += deltax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1139,16 +1082,16 @@ void write_line_outlined(unsigned int x0, unsigned int y0, unsigned int x1, unsi
|
|
|
|
* @param xoff x offset (0-15)
|
|
|
|
* @param xoff x offset (0-15)
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
* @param mode 0 = clear, 1 = set, 2 = toggle
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_word_misaligned(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff, int mode)
|
|
|
|
void write_word_misaligned(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff, int mode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16_t firstmask = word >> xoff;
|
|
|
|
uint16_t firstmask = word >> xoff;
|
|
|
|
uint16_t lastmask = word << (16 - xoff);
|
|
|
|
uint16_t lastmask = word << (16 - xoff);
|
|
|
|
WRITE_WORD_MODE(buff, addr+1, firstmask && 0x00ff, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr+1, firstmask && 0x00ff, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr, (firstmask & 0xff00) >> 8, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr, (firstmask & 0xff00) >> 8, mode);
|
|
|
|
if(xoff > 0)
|
|
|
|
if(xoff > 0)
|
|
|
|
WRITE_WORD_MODE(buff, addr+3, lastmask & 0x00ff, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr+3, lastmask & 0x00ff, mode);
|
|
|
|
if(xoff > 8)
|
|
|
|
if(xoff > 8)
|
|
|
|
WRITE_WORD_MODE(buff, addr+2, (lastmask & 0xff00) >> 8, mode);
|
|
|
|
WRITE_WORD_MODE(buff, addr+2, (lastmask & 0xff00) >> 8, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1166,16 +1109,16 @@ void write_word_misaligned(uint8_t *buff, uint16_t word, unsigned int addr, unsi
|
|
|
|
* it doesn't go through a lot of switch logic which slows down text writing
|
|
|
|
* it doesn't go through a lot of switch logic which slows down text writing
|
|
|
|
* a lot.
|
|
|
|
* a lot.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_word_misaligned_NAND(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff)
|
|
|
|
void write_word_misaligned_NAND(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16_t firstmask = word >> xoff;
|
|
|
|
uint16_t firstmask = word >> xoff;
|
|
|
|
uint16_t lastmask = word << (16 - xoff);
|
|
|
|
uint16_t lastmask = word << (16 - xoff);
|
|
|
|
WRITE_WORD_NAND(buff, addr+1, firstmask & 0x00ff);
|
|
|
|
WRITE_WORD_NAND(buff, addr+1, firstmask & 0x00ff);
|
|
|
|
WRITE_WORD_NAND(buff, addr, (firstmask & 0xff00) >> 8);
|
|
|
|
WRITE_WORD_NAND(buff, addr, (firstmask & 0xff00) >> 8);
|
|
|
|
if(xoff > 0)
|
|
|
|
if(xoff > 0)
|
|
|
|
WRITE_WORD_NAND(buff, addr+3, (lastmask & 0x00ff));
|
|
|
|
WRITE_WORD_NAND(buff, addr+3, (lastmask & 0x00ff));
|
|
|
|
if (xoff > 8)
|
|
|
|
if (xoff > 8)
|
|
|
|
WRITE_WORD_NAND(buff, addr+2, (lastmask & 0xff00) >> 8);
|
|
|
|
WRITE_WORD_NAND(buff, addr+2, (lastmask & 0xff00) >> 8);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1193,17 +1136,17 @@ void write_word_misaligned_NAND(uint8_t *buff, uint16_t word, unsigned int addr,
|
|
|
|
* it doesn't go through a lot of switch logic which slows down text writing
|
|
|
|
* it doesn't go through a lot of switch logic which slows down text writing
|
|
|
|
* a lot.
|
|
|
|
* a lot.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_word_misaligned_OR(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff)
|
|
|
|
void write_word_misaligned_OR(uint8_t *buff, uint16_t word, unsigned int addr, unsigned int xoff)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16_t firstmask = word >> xoff;
|
|
|
|
uint16_t firstmask = word >> xoff;
|
|
|
|
uint16_t lastmask = word << (16 - xoff);
|
|
|
|
uint16_t lastmask = word << (16 - xoff);
|
|
|
|
WRITE_WORD_OR(buff, addr+1, firstmask & 0x00ff);
|
|
|
|
WRITE_WORD_OR(buff, addr+1, firstmask & 0x00ff);
|
|
|
|
WRITE_WORD_OR(buff, addr, (firstmask & 0xff00) >> 8);
|
|
|
|
WRITE_WORD_OR(buff, addr, (firstmask & 0xff00) >> 8);
|
|
|
|
if(xoff > 0)
|
|
|
|
if(xoff > 0)
|
|
|
|
WRITE_WORD_OR(buff, addr + 3, lastmask & 0x00ff);
|
|
|
|
WRITE_WORD_OR(buff, addr + 3, lastmask & 0x00ff);
|
|
|
|
if(xoff > 8)
|
|
|
|
if(xoff > 8)
|
|
|
|
WRITE_WORD_OR(buff, addr + 2, (lastmask & 0xff00) >> 8);
|
|
|
|
WRITE_WORD_OR(buff, addr + 2, (lastmask & 0xff00) >> 8);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1220,8 +1163,8 @@ void write_word_misaligned_OR(uint8_t *buff, uint16_t word, unsigned int addr, u
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void write_word_misaligned_lm(uint16_t wordl, uint16_t wordm, unsigned int addr, unsigned int xoff, int lmode, int mmode)
|
|
|
|
void write_word_misaligned_lm(uint16_t wordl, uint16_t wordm, unsigned int addr, unsigned int xoff, int lmode, int mmode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_word_misaligned(draw_buffer_level, wordl, addr, xoff, lmode);
|
|
|
|
write_word_misaligned(draw_buffer_level, wordl, addr, xoff, lmode);
|
|
|
|
write_word_misaligned(draw_buffer_mask, wordm, addr, xoff, mmode);
|
|
|
|
write_word_misaligned(draw_buffer_mask, wordm, addr, xoff, mmode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1232,19 +1175,19 @@ void write_word_misaligned_lm(uint16_t wordl, uint16_t wordm, unsigned int addr,
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int fetch_font_info(char ch, int font, struct FontEntry *font_info, char *lookup)
|
|
|
|
int fetch_font_info(char ch, int font, struct FontEntry *font_info, char *lookup)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// First locate the font struct.
|
|
|
|
// First locate the font struct.
|
|
|
|
if(font > SIZEOF_ARRAY(fonts))
|
|
|
|
if(font > SIZEOF_ARRAY(fonts))
|
|
|
|
return 0; // font does not exist, exit.*/
|
|
|
|
return 0; // font does not exist, exit.*/
|
|
|
|
// Load the font info; IDs are always sequential.
|
|
|
|
// Load the font info; IDs are always sequential.
|
|
|
|
*font_info = fonts[font];
|
|
|
|
*font_info = fonts[font];
|
|
|
|
// Locate character in font lookup table. (If required.)
|
|
|
|
// Locate character in font lookup table. (If required.)
|
|
|
|
if(lookup != NULL)
|
|
|
|
if(lookup != NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
*lookup = font_info->lookup[ch];
|
|
|
|
*lookup = font_info->lookup[ch];
|
|
|
|
if(*lookup == 0xff)
|
|
|
|
if(*lookup == 0xff)
|
|
|
|
return 0; // character doesn't exist, don't bother writing it.
|
|
|
|
return 0; // character doesn't exist, don't bother writing it.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1266,7 +1209,7 @@ void write_char16(char ch, unsigned int x, unsigned int y, int font)
|
|
|
|
struct FontEntry font_info;
|
|
|
|
struct FontEntry font_info;
|
|
|
|
char lookup = 0;
|
|
|
|
char lookup = 0;
|
|
|
|
fetch_font_info(0, font, &font_info, NULL);
|
|
|
|
fetch_font_info(0, font, &font_info, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
// Compute starting address (for x,y) of character.
|
|
|
|
// Compute starting address (for x,y) of character.
|
|
|
|
int addr = CALC_BUFF_ADDR(x, y);
|
|
|
|
int addr = CALC_BUFF_ADDR(x, y);
|
|
|
|
int wbit = CALC_BIT_IN_WORD(x);
|
|
|
|
int wbit = CALC_BIT_IN_WORD(x);
|
|
|
@ -1275,53 +1218,53 @@ void write_char16(char ch, unsigned int x, unsigned int y, int font)
|
|
|
|
// How big is the character? We handle characters up to 8 pixels
|
|
|
|
// How big is the character? We handle characters up to 8 pixels
|
|
|
|
// wide for now. Support for large characters may be added in future.
|
|
|
|
// wide for now. Support for large characters may be added in future.
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Ensure we don't overflow.
|
|
|
|
// Ensure we don't overflow.
|
|
|
|
if(x + wbit > DISP_WIDTH)
|
|
|
|
if(x + wbit > GRAPHICS_WIDTH_REAL)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
// Load data pointer.
|
|
|
|
// Load data pointer.
|
|
|
|
row = ch * font_info.height;
|
|
|
|
row = ch * font_info.height;
|
|
|
|
row_temp = row;
|
|
|
|
row_temp = row;
|
|
|
|
addr_temp = addr;
|
|
|
|
addr_temp = addr;
|
|
|
|
xshift = 16 - font_info.width;
|
|
|
|
xshift = 16 - font_info.width;
|
|
|
|
// We can write mask words easily.
|
|
|
|
// We can write mask words easily.
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(font==3)
|
|
|
|
if(font==3)
|
|
|
|
write_word_misaligned_OR(draw_buffer_mask, font_mask12x18[row] << xshift, addr, wbit);
|
|
|
|
write_word_misaligned_OR(draw_buffer_mask, font_mask12x18[row] << xshift, addr, wbit);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
write_word_misaligned_OR(draw_buffer_mask, font_mask8x10[row] << xshift, addr, wbit);
|
|
|
|
write_word_misaligned_OR(draw_buffer_mask, font_mask8x10[row] << xshift, addr, wbit);
|
|
|
|
addr += DISP_WIDTH / 8;
|
|
|
|
addr += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
row++;
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Level bits are more complicated. We need to set or clear
|
|
|
|
// Level bits are more complicated. We need to set or clear
|
|
|
|
// level bits, but only where the mask bit is set; otherwise,
|
|
|
|
// level bits, but only where the mask bit is set; otherwise,
|
|
|
|
// we need to leave them alone. To do this, for each word, we
|
|
|
|
// we need to leave them alone. To do this, for each word, we
|
|
|
|
// construct an AND mask and an OR mask, and apply each individually.
|
|
|
|
// construct an AND mask and an OR mask, and apply each individually.
|
|
|
|
row = row_temp;
|
|
|
|
row = row_temp;
|
|
|
|
addr = addr_temp;
|
|
|
|
addr = addr_temp;
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(font==3)
|
|
|
|
if(font==3)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
level_bits = font_frame12x18[row];
|
|
|
|
level_bits = font_frame12x18[row];
|
|
|
|
//if(!(flags & FONT_INVERT)) // data is normally inverted
|
|
|
|
//if(!(flags & FONT_INVERT)) // data is normally inverted
|
|
|
|
level_bits = ~level_bits;
|
|
|
|
level_bits = ~level_bits;
|
|
|
|
or_mask = font_mask12x18[row] << xshift;
|
|
|
|
or_mask = font_mask12x18[row] << xshift;
|
|
|
|
and_mask = (font_mask12x18[row] & level_bits) << xshift;
|
|
|
|
and_mask = (font_mask12x18[row] & level_bits) << xshift;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
level_bits = font_frame8x10[row];
|
|
|
|
level_bits = font_frame8x10[row];
|
|
|
|
//if(!(flags & FONT_INVERT)) // data is normally inverted
|
|
|
|
//if(!(flags & FONT_INVERT)) // data is normally inverted
|
|
|
|
level_bits = ~level_bits;
|
|
|
|
level_bits = ~level_bits;
|
|
|
|
or_mask = font_mask8x10[row] << xshift;
|
|
|
|
or_mask = font_mask8x10[row] << xshift;
|
|
|
|
and_mask = (font_mask8x10[row] & level_bits) << xshift;
|
|
|
|
and_mask = (font_mask8x10[row] & level_bits) << xshift;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
write_word_misaligned_OR(draw_buffer_level, or_mask, addr, wbit);
|
|
|
|
write_word_misaligned_OR(draw_buffer_level, or_mask, addr, wbit);
|
|
|
|
// If we're not bold write the AND mask.
|
|
|
|
// If we're not bold write the AND mask.
|
|
|
|
//if(!(flags & FONT_BOLD))
|
|
|
|
//if(!(flags & FONT_BOLD))
|
|
|
|
write_word_misaligned_NAND(draw_buffer_level, and_mask, addr, wbit);
|
|
|
|
write_word_misaligned_NAND(draw_buffer_level, and_mask, addr, wbit);
|
|
|
|
addr += DISP_WIDTH / 8;
|
|
|
|
addr += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
row++;
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1351,49 +1294,49 @@ void write_char(char ch, unsigned int x, unsigned int y, int flags, int font)
|
|
|
|
// If font only supports lowercase or uppercase, make the letter
|
|
|
|
// If font only supports lowercase or uppercase, make the letter
|
|
|
|
// lowercase or uppercase.
|
|
|
|
// lowercase or uppercase.
|
|
|
|
if(font_info.flags & FONT_LOWERCASE_ONLY)
|
|
|
|
if(font_info.flags & FONT_LOWERCASE_ONLY)
|
|
|
|
ch = tolower(ch);
|
|
|
|
ch = tolower(ch);
|
|
|
|
if(font_info.flags & FONT_UPPERCASE_ONLY)
|
|
|
|
if(font_info.flags & FONT_UPPERCASE_ONLY)
|
|
|
|
ch = toupper(ch);
|
|
|
|
ch = toupper(ch);
|
|
|
|
fetch_font_info(ch, font, &font_info, &lookup);
|
|
|
|
fetch_font_info(ch, font, &font_info, &lookup);
|
|
|
|
// How big is the character? We handle characters up to 8 pixels
|
|
|
|
// How big is the character? We handle characters up to 8 pixels
|
|
|
|
// wide for now. Support for large characters may be added in future.
|
|
|
|
// wide for now. Support for large characters may be added in future.
|
|
|
|
if(font_info.width <= 8)
|
|
|
|
if(font_info.width <= 8)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Ensure we don't overflow.
|
|
|
|
// Ensure we don't overflow.
|
|
|
|
if(x + wbit > DISP_WIDTH)
|
|
|
|
if(x + wbit > GRAPHICS_WIDTH_REAL)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
// Load data pointer.
|
|
|
|
// Load data pointer.
|
|
|
|
row = lookup * font_info.height * 2;
|
|
|
|
row = lookup * font_info.height * 2;
|
|
|
|
row_temp = row;
|
|
|
|
row_temp = row;
|
|
|
|
addr_temp = addr;
|
|
|
|
addr_temp = addr;
|
|
|
|
xshift = 16 - font_info.width;
|
|
|
|
xshift = 16 - font_info.width;
|
|
|
|
// We can write mask words easily.
|
|
|
|
// We can write mask words easily.
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
write_word_misaligned_OR(draw_buffer_mask, font_info.data[row] << xshift, addr, wbit);
|
|
|
|
write_word_misaligned_OR(draw_buffer_mask, font_info.data[row] << xshift, addr, wbit);
|
|
|
|
addr += DISP_WIDTH / 8;
|
|
|
|
addr += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
row++;
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Level bits are more complicated. We need to set or clear
|
|
|
|
// Level bits are more complicated. We need to set or clear
|
|
|
|
// level bits, but only where the mask bit is set; otherwise,
|
|
|
|
// level bits, but only where the mask bit is set; otherwise,
|
|
|
|
// we need to leave them alone. To do this, for each word, we
|
|
|
|
// we need to leave them alone. To do this, for each word, we
|
|
|
|
// construct an AND mask and an OR mask, and apply each individually.
|
|
|
|
// construct an AND mask and an OR mask, and apply each individually.
|
|
|
|
row = row_temp;
|
|
|
|
row = row_temp;
|
|
|
|
addr = addr_temp;
|
|
|
|
addr = addr_temp;
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
for(yy = y; yy < y + font_info.height; yy++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
level_bits = font_info.data[row + font_info.height];
|
|
|
|
level_bits = font_info.data[row + font_info.height];
|
|
|
|
if(!(flags & FONT_INVERT)) // data is normally inverted
|
|
|
|
if(!(flags & FONT_INVERT)) // data is normally inverted
|
|
|
|
level_bits = ~level_bits;
|
|
|
|
level_bits = ~level_bits;
|
|
|
|
or_mask = font_info.data[row] << xshift;
|
|
|
|
or_mask = font_info.data[row] << xshift;
|
|
|
|
and_mask = (font_info.data[row] & level_bits) << xshift;
|
|
|
|
and_mask = (font_info.data[row] & level_bits) << xshift;
|
|
|
|
write_word_misaligned_OR(draw_buffer_level, or_mask, addr, wbit);
|
|
|
|
write_word_misaligned_OR(draw_buffer_level, or_mask, addr, wbit);
|
|
|
|
// If we're not bold write the AND mask.
|
|
|
|
// If we're not bold write the AND mask.
|
|
|
|
//if(!(flags & FONT_BOLD))
|
|
|
|
//if(!(flags & FONT_BOLD))
|
|
|
|
write_word_misaligned_NAND(draw_buffer_level, and_mask, addr, wbit);
|
|
|
|
write_word_misaligned_NAND(draw_buffer_level, and_mask, addr, wbit);
|
|
|
|
addr += DISP_WIDTH / 8;
|
|
|
|
addr += GRAPHICS_WIDTH_REAL / 8;
|
|
|
|
row++;
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1413,18 +1356,18 @@ void calc_text_dimensions(char *str, struct FontEntry font, int xs, int ys, stru
|
|
|
|
int max_length = 0, line_length = 0, lines = 1;
|
|
|
|
int max_length = 0, line_length = 0, lines = 1;
|
|
|
|
while(*str != 0)
|
|
|
|
while(*str != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
line_length++;
|
|
|
|
line_length++;
|
|
|
|
if(*str == '\n' || *str == '\r')
|
|
|
|
if(*str == '\n' || *str == '\r')
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(line_length > max_length)
|
|
|
|
if(line_length > max_length)
|
|
|
|
max_length = line_length;
|
|
|
|
max_length = line_length;
|
|
|
|
line_length = 0;
|
|
|
|
line_length = 0;
|
|
|
|
lines++;
|
|
|
|
lines++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
str++;
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(line_length > max_length)
|
|
|
|
if(line_length > max_length)
|
|
|
|
max_length = line_length;
|
|
|
|
max_length = line_length;
|
|
|
|
dim->width = max_length * (font.width + xs);
|
|
|
|
dim->width = max_length * (font.width + xs);
|
|
|
|
dim->height = lines * (font.height + ys);
|
|
|
|
dim->height = lines * (font.height + ys);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1453,37 +1396,37 @@ void write_string(char *str, unsigned int x, unsigned int y, unsigned int xs, un
|
|
|
|
calc_text_dimensions(str, font_info, xs, ys, &dim);
|
|
|
|
calc_text_dimensions(str, font_info, xs, ys, &dim);
|
|
|
|
switch(va)
|
|
|
|
switch(va)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case TEXT_VA_TOP: yy = y; break;
|
|
|
|
case TEXT_VA_TOP: yy = y; break;
|
|
|
|
case TEXT_VA_MIDDLE: yy = y - (dim.height / 2); break;
|
|
|
|
case TEXT_VA_MIDDLE: yy = y - (dim.height / 2); break;
|
|
|
|
case TEXT_VA_BOTTOM: yy = y - dim.height; break;
|
|
|
|
case TEXT_VA_BOTTOM: yy = y - dim.height; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch(ha)
|
|
|
|
switch(ha)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case TEXT_HA_LEFT: xx = x; break;
|
|
|
|
case TEXT_HA_LEFT: xx = x; break;
|
|
|
|
case TEXT_HA_CENTER: xx = x - (dim.width / 2); break;
|
|
|
|
case TEXT_HA_CENTER: xx = x - (dim.width / 2); break;
|
|
|
|
case TEXT_HA_RIGHT: xx = x - dim.width; break;
|
|
|
|
case TEXT_HA_RIGHT: xx = x - dim.width; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Then write each character.
|
|
|
|
// Then write each character.
|
|
|
|
xx_original = xx;
|
|
|
|
xx_original = xx;
|
|
|
|
while(*str != 0)
|
|
|
|
while(*str != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(*str == '\n' || *str == '\r')
|
|
|
|
if(*str == '\n' || *str == '\r')
|
|
|
|
{
|
|
|
|
{
|
|
|
|
yy += ys + font_info.height;
|
|
|
|
yy += ys + font_info.height;
|
|
|
|
xx = xx_original;
|
|
|
|
xx = xx_original;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(xx >= 0 && xx < DISP_WIDTH)
|
|
|
|
if(xx >= 0 && xx < GRAPHICS_WIDTH_REAL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(font_info.id<2)
|
|
|
|
if(font_info.id<2)
|
|
|
|
write_char(*str, xx, yy, flags, font);
|
|
|
|
write_char(*str, xx, yy, flags, font);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
write_char16(*str, xx, yy, font);
|
|
|
|
write_char16(*str, xx, yy, font);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xx += font_info.width + xs;
|
|
|
|
xx += font_info.width + xs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
str++;
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1773,44 +1716,11 @@ void drawBattery(uint16_t x, uint16_t y, uint8_t battery, uint16_t size)
|
|
|
|
|
|
|
|
|
|
|
|
void printTime(uint16_t x, uint16_t y) {
|
|
|
|
void printTime(uint16_t x, uint16_t y) {
|
|
|
|
char temp[9]={0};
|
|
|
|
char temp[9]={0};
|
|
|
|
sprintf(temp,"%02d:%02d:%02d",time.hour,time.min,time.sec);
|
|
|
|
sprintf(temp,"%02d:%02d:%02d",timex.hour,timex.min,timex.sec);
|
|
|
|
//printTextFB(x,y,temp);
|
|
|
|
//printTextFB(x,y,temp);
|
|
|
|
write_string(temp, x, y, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 3);
|
|
|
|
write_string(temp, x, y, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void setAttitudeOsd(int16_t pitch, int16_t roll, int16_t yaw)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pitch=pitch;
|
|
|
|
|
|
|
|
m_roll=roll;
|
|
|
|
|
|
|
|
m_yaw=yaw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setGpsOsd(uint8_t status, int32_t lat, int32_t lon, float alt, float spd)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_gpsStatus=status;
|
|
|
|
|
|
|
|
m_gpsLat=lat;
|
|
|
|
|
|
|
|
m_gpsLon=lon;
|
|
|
|
|
|
|
|
m_gpsAlt=alt;
|
|
|
|
|
|
|
|
m_gpsSpd=spd;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void introText(){
|
|
|
|
|
|
|
|
//printTextFB((GRAPHICS_WIDTH_REAL/2 - 40)/16,GRAPHICS_HEIGHT_REAL-10,"ver 0.1");
|
|
|
|
|
|
|
|
write_string("ver 0.2", (GRAPHICS_WIDTH_REAL/2),GRAPHICS_HEIGHT_REAL-20, 0, 0, TEXT_VA_TOP, TEXT_HA_CENTER, 0, 3);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void introGraphics() {
|
|
|
|
|
|
|
|
/* logo */
|
|
|
|
|
|
|
|
int image=0;
|
|
|
|
|
|
|
|
struct splashEntry splash_info;
|
|
|
|
|
|
|
|
splash_info = splash[image];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
copyimage(GRAPHICS_WIDTH_REAL/2-(splash_info.width)/2, GRAPHICS_HEIGHT_REAL/2-(splash_info.height)/2,image);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* frame */
|
|
|
|
|
|
|
|
drawBox(0,0,GRAPHICS_WIDTH_REAL-2,GRAPHICS_HEIGHT_REAL-1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
void drawAltitude(uint16_t x, uint16_t y, int16_t alt, uint8_t dir) {
|
|
|
|
void drawAltitude(uint16_t x, uint16_t y, int16_t alt, uint8_t dir) {
|
|
|
|
|
|
|
|
|
|
|
@ -1863,12 +1773,12 @@ void hud_draw_vertical_scale(int v, int range, int halign, int x, int y, int hei
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(halign == +1)
|
|
|
|
else if(halign == +1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
majtick_start = DISP_WIDTH - x - 1;
|
|
|
|
majtick_start = GRAPHICS_WIDTH_REAL - x - 1;
|
|
|
|
majtick_end = DISP_WIDTH - x - majtick_len - 1;
|
|
|
|
majtick_end = GRAPHICS_WIDTH_REAL - x - majtick_len - 1;
|
|
|
|
mintick_start = DISP_WIDTH - x - 1;
|
|
|
|
mintick_start = GRAPHICS_WIDTH_REAL - x - 1;
|
|
|
|
mintick_end = DISP_WIDTH - x - mintick_len - 1;
|
|
|
|
mintick_end = GRAPHICS_WIDTH_REAL - x - mintick_len - 1;
|
|
|
|
boundtick_start = DISP_WIDTH - x - 1;
|
|
|
|
boundtick_start = GRAPHICS_WIDTH_REAL - x - 1;
|
|
|
|
boundtick_end = DISP_WIDTH - x - boundtick_len - 1;
|
|
|
|
boundtick_end = GRAPHICS_WIDTH_REAL - x - boundtick_len - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Retrieve width of large font (font #0); from this calculate the x spacing.
|
|
|
|
// Retrieve width of large font (font #0); from this calculate the x spacing.
|
|
|
|
fetch_font_info(0, 0, &font_info, NULL);
|
|
|
|
fetch_font_info(0, 0, &font_info, NULL);
|
|
|
@ -2075,7 +1985,45 @@ void hud_draw_linear_compass(int v, int range, int width, int x, int y, int mint
|
|
|
|
headingstr[3] = 0;
|
|
|
|
headingstr[3] = 0;
|
|
|
|
write_string(headingstr, x + 1, majtick_start + textoffset+2, 0, 0, TEXT_VA_MIDDLE, TEXT_HA_CENTER, 1, 3);
|
|
|
|
write_string(headingstr, x + 1, majtick_start + textoffset+2, 0, 0, TEXT_VA_MIDDLE, TEXT_HA_CENTER, 1, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CORE draw routines end here
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setAttitudeOsd(int16_t pitch, int16_t roll, int16_t yaw)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pitch=pitch;
|
|
|
|
|
|
|
|
m_roll=roll;
|
|
|
|
|
|
|
|
m_yaw=yaw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setGpsOsd(uint8_t status, int32_t lat, int32_t lon, float alt, float spd)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_gpsStatus=status;
|
|
|
|
|
|
|
|
m_gpsLat=lat;
|
|
|
|
|
|
|
|
m_gpsLon=lon;
|
|
|
|
|
|
|
|
m_gpsAlt=alt;
|
|
|
|
|
|
|
|
m_gpsSpd=spd;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void introText(){
|
|
|
|
|
|
|
|
write_string("ver 0.2", APPLY_HDEADBAND((GRAPHICS_RIGHT/2)),APPLY_VDEADBAND(GRAPHICS_BOTTOM-10), 0, 0, TEXT_VA_BOTTOM, TEXT_HA_CENTER, 0, 3);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void introGraphics() {
|
|
|
|
|
|
|
|
/* logo */
|
|
|
|
|
|
|
|
int image=0;
|
|
|
|
|
|
|
|
struct splashEntry splash_info;
|
|
|
|
|
|
|
|
splash_info = splash[image];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
copyimage(APPLY_HDEADBAND(GRAPHICS_RIGHT/2-(splash_info.width)/2), APPLY_VDEADBAND(GRAPHICS_BOTTOM/2-(splash_info.height)/2),image);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* frame */
|
|
|
|
|
|
|
|
drawBox(APPLY_HDEADBAND(0),APPLY_VDEADBAND(0),APPLY_HDEADBAND(GRAPHICS_RIGHT-8),APPLY_VDEADBAND(GRAPHICS_BOTTOM));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Must mask out last half-word because SPI keeps clocking it out otherwise
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < 8; i++) {
|
|
|
|
|
|
|
|
write_vline( draw_buffer_level,GRAPHICS_WIDTH_REAL-i-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
|
|
|
|
write_vline( draw_buffer_mask,GRAPHICS_WIDTH_REAL-i-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void calcHomeArrow(void)
|
|
|
|
void calcHomeArrow(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -2141,16 +2089,16 @@ void calcHomeArrow(void)
|
|
|
|
|
|
|
|
|
|
|
|
char temp[50]={0};
|
|
|
|
char temp[50]={0};
|
|
|
|
sprintf(temp,"hea:%d",(int)brng);
|
|
|
|
sprintf(temp,"hea:%d",(int)brng);
|
|
|
|
write_string(temp, 130, 5, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(GRAPHICS_RIGHT/2-30), APPLY_VDEADBAND(30), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
sprintf(temp,"ele:%d",(int)elevation);
|
|
|
|
sprintf(temp,"ele:%d",(int)elevation);
|
|
|
|
write_string(temp, 130, 5+10, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(GRAPHICS_RIGHT/2-30), APPLY_VDEADBAND(30+10), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
sprintf(temp,"dis:%d",(int)d);
|
|
|
|
sprintf(temp,"dis:%d",(int)d);
|
|
|
|
write_string(temp, 130, 5+10+10, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(GRAPHICS_RIGHT/2-30), APPLY_VDEADBAND(30+10+10), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
sprintf(temp,"u2g:%d",(int)u2g);
|
|
|
|
sprintf(temp,"u2g:%d",(int)u2g);
|
|
|
|
write_string(temp, 130, 5+10+10+10, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(GRAPHICS_RIGHT/2-30), APPLY_VDEADBAND(30+10+10+10), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(temp,"%c%c",(int)(u2g/22.5f)*2+0x90,(int)(u2g/22.5f)*2+0x91);
|
|
|
|
sprintf(temp,"%c%c",(int)(u2g/22.5f)*2+0x90,(int)(u2g/22.5f)*2+0x91);
|
|
|
|
write_string(temp,200,10+10+10, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 3);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(250), APPLY_VDEADBAND(40+10+10), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int lama=10;
|
|
|
|
int lama=10;
|
|
|
@ -2186,15 +2134,15 @@ void updateGraphics() {
|
|
|
|
GPSPositionGet(&gpsData);
|
|
|
|
GPSPositionGet(&gpsData);
|
|
|
|
HomeLocationData home;
|
|
|
|
HomeLocationData home;
|
|
|
|
HomeLocationGet(&home);
|
|
|
|
HomeLocationGet(&home);
|
|
|
|
|
|
|
|
|
|
|
|
if(home.Set == HOMELOCATION_SET_FALSE)
|
|
|
|
if(home.Set == HOMELOCATION_SET_FALSE)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char temps[20]={0};
|
|
|
|
char temps[20]={0};
|
|
|
|
sprintf(temps,"HOME NOT SET");
|
|
|
|
sprintf(temps,"HOME NOT SET");
|
|
|
|
//printTextFB(x,y,temp);
|
|
|
|
//printTextFB(x,y,temp);
|
|
|
|
write_string(temps, GRAPHICS_WIDTH_REAL/2-((12*12)/2), GRAPHICS_HEIGHT_REAL/2-18/2, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 3);
|
|
|
|
write_string(temps, APPLY_HDEADBAND(GRAPHICS_RIGHT/2), (GRAPHICS_BOTTOM/2), 0, 0, TEXT_VA_TOP, TEXT_HA_CENTER, 0, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t disp = 0;
|
|
|
|
uint32_t disp = 0;
|
|
|
|
switch (disp) {
|
|
|
|
switch (disp) {
|
|
|
|
case 0: // Dave simple
|
|
|
|
case 0: // Dave simple
|
|
|
@ -2203,35 +2151,28 @@ void updateGraphics() {
|
|
|
|
setAttitudeOsd(0,0,(int16_t)(gpsData.Heading-360));
|
|
|
|
setAttitudeOsd(0,0,(int16_t)(gpsData.Heading-360));
|
|
|
|
else
|
|
|
|
else
|
|
|
|
setAttitudeOsd(0,0,(int16_t)(gpsData.Heading));
|
|
|
|
setAttitudeOsd(0,0,(int16_t)(gpsData.Heading));
|
|
|
|
|
|
|
|
|
|
|
|
char temp[50]={0};
|
|
|
|
char temp[50]={0};
|
|
|
|
memset(temp, ' ', 40);
|
|
|
|
memset(temp, ' ', 40);
|
|
|
|
sprintf(temp,"Lat:%11.7f",gpsData.Latitude/10000000.0f);
|
|
|
|
sprintf(temp,"Lat:%11.7f",gpsData.Latitude/10000000.0f);
|
|
|
|
write_string(temp, 170, GRAPHICS_HEIGHT_REAL-30, 0, 0, TEXT_VA_BOTTOM, TEXT_HA_LEFT, 0, 3);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(20), APPLY_VDEADBAND(GRAPHICS_BOTTOM-30), 0, 0, TEXT_VA_BOTTOM, TEXT_HA_LEFT, 0, 3);
|
|
|
|
sprintf(temp,"Lon:%11.7f",gpsData.Longitude/10000000.0f);
|
|
|
|
sprintf(temp,"Lon:%11.7f",gpsData.Longitude/10000000.0f);
|
|
|
|
write_string(temp, 170, GRAPHICS_HEIGHT_REAL-10, 0, 0, TEXT_VA_BOTTOM, TEXT_HA_LEFT, 0, 3);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(20), APPLY_VDEADBAND(GRAPHICS_BOTTOM-10), 0, 0, TEXT_VA_BOTTOM, TEXT_HA_LEFT, 0, 3);
|
|
|
|
sprintf(temp,"Sat:%d",(int)gpsData.Satellites);
|
|
|
|
sprintf(temp,"Sat:%d",(int)gpsData.Satellites);
|
|
|
|
write_string(temp, GRAPHICS_WIDTH_REAL-40, 30, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(GRAPHICS_RIGHT-40), APPLY_VDEADBAND(30), 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Print ADC voltage FLIGHT*/
|
|
|
|
/* Print ADC voltage FLIGHT*/
|
|
|
|
sprintf(temp,"V:%4.2fV",(PIOS_ADC_PinGet(2)*3.0f*6.1f/4096.0f));
|
|
|
|
sprintf(temp,"V:%5.2fV",(PIOS_ADC_PinGet(2)*3*6.1f/4096));
|
|
|
|
write_string(temp, 170, 20, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 3);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(20), APPLY_VDEADBAND(20), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 3);
|
|
|
|
|
|
|
|
|
|
|
|
calcHomeArrow();
|
|
|
|
calcHomeArrow();
|
|
|
|
|
|
|
|
|
|
|
|
write_vline( draw_buffer_level,GRAPHICS_WIDTH_REAL-12,0,GRAPHICS_HEIGHT_REAL-1,1);
|
|
|
|
|
|
|
|
write_vline( draw_buffer_mask,GRAPHICS_WIDTH_REAL-12,0,GRAPHICS_HEIGHT_REAL-1,1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Last pixel
|
|
|
|
|
|
|
|
write_vline( draw_buffer_level,GRAPHICS_WIDTH_REAL-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
|
|
|
|
write_vline( draw_buffer_mask,GRAPHICS_WIDTH_REAL-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(OsdSettings.Attitude == OSDSETTINGS_ATTITUDE_ENABLED)
|
|
|
|
if(OsdSettings.Attitude == OSDSETTINGS_ATTITUDE_ENABLED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// GPS HACK
|
|
|
|
// GPS HACK
|
|
|
|
if(gpsData.Heading>180)
|
|
|
|
if(gpsData.Heading>180)
|
|
|
|
setAttitudeOsd(0,0,(int16_t)(gpsData.Heading-360));
|
|
|
|
setAttitudeOsd(0,0,(int16_t)(gpsData.Heading-360));
|
|
|
@ -2259,62 +2200,62 @@ void updateGraphics() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
angleB+=sum;
|
|
|
|
angleB+=sum;
|
|
|
|
angleC+=2;
|
|
|
|
angleC+=2;
|
|
|
|
|
|
|
|
|
|
|
|
calcHomeArrow();
|
|
|
|
calcHomeArrow();
|
|
|
|
|
|
|
|
|
|
|
|
/* Draw Attitude Indicator */
|
|
|
|
/* Draw Attitude Indicator */
|
|
|
|
//if(OsdSettings.Attitude == OSDSETTINGS_ATTITUDE_ENABLED)
|
|
|
|
//if(OsdSettings.Attitude == OSDSETTINGS_ATTITUDE_ENABLED)
|
|
|
|
if(0)
|
|
|
|
if(0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
drawAttitude(OsdSettings.AttitudeSetup[OSDSETTINGS_ATTITUDESETUP_X],OsdSettings.AttitudeSetup[OSDSETTINGS_ATTITUDESETUP_Y],attitude.Pitch,attitude.Roll,96);
|
|
|
|
drawAttitude(APPLY_HDEADBAND(OsdSettings.AttitudeSetup[OSDSETTINGS_ATTITUDESETUP_X]),APPLY_VDEADBAND(OsdSettings.AttitudeSetup[OSDSETTINGS_ATTITUDESETUP_Y]),attitude.Pitch,attitude.Roll,96);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//write_string("Hello OP-OSD", 60, 12, 1, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 0);
|
|
|
|
//write_string("Hello OP-OSD", 60, 12, 1, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 0);
|
|
|
|
//printText16( 60, 12,"Hello OP-OSD");
|
|
|
|
//printText16( 60, 12,"Hello OP-OSD");
|
|
|
|
|
|
|
|
|
|
|
|
char temp[50]={0};
|
|
|
|
char temp[50]={0};
|
|
|
|
memset(temp, ' ', 40);
|
|
|
|
memset(temp, ' ', 40);
|
|
|
|
sprintf(temp,"Lat:%11.7f",gpsData.Latitude/10000000.0f);
|
|
|
|
sprintf(temp,"Lat:%11.7f",gpsData.Latitude/10000000.0f);
|
|
|
|
write_string(temp, 5, 5, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(5), APPLY_VDEADBAND(5), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
sprintf(temp,"Lon:%11.7f",gpsData.Longitude/10000000.0f);
|
|
|
|
sprintf(temp,"Lon:%11.7f",gpsData.Longitude/10000000.0f);
|
|
|
|
write_string(temp, 5, 15, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(5), APPLY_VDEADBAND(15), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
sprintf(temp,"Fix:%d",(int)gpsData.Status);
|
|
|
|
sprintf(temp,"Fix:%d",(int)gpsData.Status);
|
|
|
|
write_string(temp, 5, 25, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(5), APPLY_VDEADBAND(25), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
sprintf(temp,"Sat:%d",(int)gpsData.Satellites);
|
|
|
|
sprintf(temp,"Sat:%d",(int)gpsData.Satellites);
|
|
|
|
write_string(temp, 5, 35, 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND(5), APPLY_VDEADBAND(35), 0, 0, TEXT_VA_TOP, TEXT_HA_LEFT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Print RTC time */
|
|
|
|
/* Print RTC time */
|
|
|
|
if(OsdSettings.Time == OSDSETTINGS_TIME_ENABLED)
|
|
|
|
if(OsdSettings.Time == OSDSETTINGS_TIME_ENABLED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
printTime(OsdSettings.TimeSetup[OSDSETTINGS_TIMESETUP_X],OsdSettings.TimeSetup[OSDSETTINGS_TIMESETUP_Y]);
|
|
|
|
printTime(APPLY_HDEADBAND(OsdSettings.TimeSetup[OSDSETTINGS_TIMESETUP_X]),APPLY_VDEADBAND(OsdSettings.TimeSetup[OSDSETTINGS_TIMESETUP_Y]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Print Number of detected video Lines */
|
|
|
|
/* Print Number of detected video Lines */
|
|
|
|
sprintf(temp,"Lines:%4d",PIOS_Video_GetOSDLines());
|
|
|
|
sprintf(temp,"Lines:%4d",PIOS_Video_GetOSDLines());
|
|
|
|
write_string(temp, (GRAPHICS_WIDTH_REAL - 2),5, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND((GRAPHICS_RIGHT - 2)),APPLY_VDEADBAND(5), 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Print ADC voltage */
|
|
|
|
/* Print ADC voltage */
|
|
|
|
//sprintf(temp,"Rssi:%4dV",(int)(PIOS_ADC_PinGet(4)*3000/4096));
|
|
|
|
//sprintf(temp,"Rssi:%4dV",(int)(PIOS_ADC_PinGet(4)*3000/4096));
|
|
|
|
//write_string(temp, (GRAPHICS_WIDTH_REAL - 2),15, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
//write_string(temp, (GRAPHICS_WIDTH_REAL - 2),15, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
sprintf(temp,"Rssi:%4.2fV",(PIOS_ADC_PinGet(4)*3.0f/4096.0f));
|
|
|
|
sprintf(temp,"Rssi:%4.2fV",(PIOS_ADC_PinGet(4)*3.0f/4096.0f));
|
|
|
|
write_string(temp, (GRAPHICS_WIDTH_REAL - 2),15, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND((GRAPHICS_RIGHT - 2)),APPLY_VDEADBAND(15), 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Print CPU temperature */
|
|
|
|
/* Print CPU temperature */
|
|
|
|
sprintf(temp,"Temp:%4.2fC",(PIOS_ADC_PinGet(6)*0.29296875f-264));
|
|
|
|
sprintf(temp,"Temp:%4.2fC",(PIOS_ADC_PinGet(6)*0.29296875f-264));
|
|
|
|
write_string(temp, (GRAPHICS_WIDTH_REAL - 2),25, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND((GRAPHICS_RIGHT - 2)),APPLY_VDEADBAND(25), 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Print ADC voltage FLIGHT*/
|
|
|
|
/* Print ADC voltage FLIGHT*/
|
|
|
|
sprintf(temp,"FltV:%4.2fV",(PIOS_ADC_PinGet(2)*3.0f*6.1f/4096.0f));
|
|
|
|
sprintf(temp,"FltV:%4.2fV",(PIOS_ADC_PinGet(2)*3.0f*6.1f/4096.0f));
|
|
|
|
write_string(temp, (GRAPHICS_WIDTH_REAL - 2),35, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND((GRAPHICS_RIGHT - 2)),APPLY_VDEADBAND(35), 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Print ADC voltage VIDEO*/
|
|
|
|
/* Print ADC voltage VIDEO*/
|
|
|
|
sprintf(temp,"VidV:%4.2fV",(PIOS_ADC_PinGet(3)*3.0f*6.1f/4096.0f));
|
|
|
|
sprintf(temp,"VidV:%4.2fV",(PIOS_ADC_PinGet(3)*3.0f*6.1f/4096.0f));
|
|
|
|
write_string(temp, (GRAPHICS_WIDTH_REAL - 2),45, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
write_string(temp, APPLY_HDEADBAND((GRAPHICS_RIGHT - 2)),APPLY_VDEADBAND(45), 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Print ADC voltage RSSI */
|
|
|
|
/* Print ADC voltage RSSI */
|
|
|
|
//sprintf(temp,"Curr:%4dA",(int)(PIOS_ADC_PinGet(0)*300*61/4096));
|
|
|
|
//sprintf(temp,"Curr:%4dA",(int)(PIOS_ADC_PinGet(0)*300*61/4096));
|
|
|
|
//write_string(temp, (GRAPHICS_WIDTH_REAL - 2),60, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
//write_string(temp, (GRAPHICS_WIDTH_REAL - 2),60, 0, 0, TEXT_VA_TOP, TEXT_HA_RIGHT, 0, 2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Draw Battery Gauge */
|
|
|
|
/* Draw Battery Gauge */
|
|
|
|
m_batt++;
|
|
|
|
m_batt++;
|
|
|
|
uint8_t dir=3;
|
|
|
|
uint8_t dir=3;
|
|
|
@ -2333,35 +2274,35 @@ void updateGraphics() {
|
|
|
|
//if(OsdSettings.Battery == OSDSETTINGS_BATTERY_ENABLED)
|
|
|
|
//if(OsdSettings.Battery == OSDSETTINGS_BATTERY_ENABLED)
|
|
|
|
if(0)
|
|
|
|
if(0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
drawBattery(OsdSettings.BatterySetup[OSDSETTINGS_BATTERYSETUP_X],OsdSettings.BatterySetup[OSDSETTINGS_BATTERYSETUP_Y],m_batt,16);
|
|
|
|
drawBattery(APPLY_HDEADBAND(OsdSettings.BatterySetup[OSDSETTINGS_BATTERYSETUP_X]),APPLY_VDEADBAND(OsdSettings.BatterySetup[OSDSETTINGS_BATTERYSETUP_Y]),m_batt,16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//drawAltitude(200,50,m_alt,dir);
|
|
|
|
//drawAltitude(200,50,m_alt,dir);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//drawArrow(96,GRAPHICS_HEIGHT_REAL/2,angleB,32);
|
|
|
|
//drawArrow(96,GRAPHICS_HEIGHT_REAL/2,angleB,32);
|
|
|
|
|
|
|
|
|
|
|
|
// Draw airspeed (left side.)
|
|
|
|
// Draw airspeed (left side.)
|
|
|
|
if(OsdSettings.Speed == OSDSETTINGS_SPEED_ENABLED)
|
|
|
|
if(OsdSettings.Speed == OSDSETTINGS_SPEED_ENABLED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
hud_draw_vertical_scale((int)m_gpsSpd, 100, -1, OsdSettings.SpeedSetup[OSDSETTINGS_SPEEDSETUP_X],
|
|
|
|
hud_draw_vertical_scale((int)m_gpsSpd, 100, -1, APPLY_HDEADBAND(OsdSettings.SpeedSetup[OSDSETTINGS_SPEEDSETUP_X]),
|
|
|
|
OsdSettings.SpeedSetup[OSDSETTINGS_SPEEDSETUP_Y], 100, 10, 20, 7, 12, 15, 1000, HUD_VSCALE_FLAG_NO_NEGATIVE);
|
|
|
|
APPLY_VDEADBAND(OsdSettings.SpeedSetup[OSDSETTINGS_SPEEDSETUP_Y]), 100, 10, 20, 7, 12, 15, 1000, HUD_VSCALE_FLAG_NO_NEGATIVE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw altimeter (right side.)
|
|
|
|
// Draw altimeter (right side.)
|
|
|
|
if(OsdSettings.Altitude == OSDSETTINGS_ALTITUDE_ENABLED)
|
|
|
|
if(OsdSettings.Altitude == OSDSETTINGS_ALTITUDE_ENABLED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
hud_draw_vertical_scale((int)m_gpsAlt, 200, +1, OsdSettings.AltitudeSetup[OSDSETTINGS_ALTITUDESETUP_X],
|
|
|
|
hud_draw_vertical_scale((int)m_gpsAlt, 200, +1, APPLY_HDEADBAND(OsdSettings.AltitudeSetup[OSDSETTINGS_ALTITUDESETUP_X]),
|
|
|
|
OsdSettings.AltitudeSetup[OSDSETTINGS_ALTITUDESETUP_Y], 100, 20, 100, 7, 12, 15, 500, 0);
|
|
|
|
APPLY_VDEADBAND(OsdSettings.AltitudeSetup[OSDSETTINGS_ALTITUDESETUP_Y]), 100, 20, 100, 7, 12, 15, 500, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw compass.
|
|
|
|
// Draw compass.
|
|
|
|
if(OsdSettings.Heading == OSDSETTINGS_HEADING_ENABLED)
|
|
|
|
if(OsdSettings.Heading == OSDSETTINGS_HEADING_ENABLED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(m_yaw<0) {
|
|
|
|
if(m_yaw<0) {
|
|
|
|
hud_draw_linear_compass(360+m_yaw, 150, 120, OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_X],
|
|
|
|
hud_draw_linear_compass(360+m_yaw, 150, 120, APPLY_HDEADBAND(OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_X]),
|
|
|
|
OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_Y], 15, 30, 7, 12, 0);
|
|
|
|
APPLY_VDEADBAND(OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_Y]), 15, 30, 7, 12, 0);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
hud_draw_linear_compass(m_yaw, 150, 120, OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_X],
|
|
|
|
hud_draw_linear_compass(m_yaw, 150, 120, APPLY_HDEADBAND(OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_X]),
|
|
|
|
OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_Y], 15, 30, 7, 12, 0);
|
|
|
|
APPLY_VDEADBAND(OsdSettings.HeadingSetup[OSDSETTINGS_HEADINGSETUP_Y]), 15, 30, 7, 12, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//write_filled_rectangle(draw_buffer_level,20,20,30,30,1);
|
|
|
|
//write_filled_rectangle(draw_buffer_level,20,20,30,30,1);
|
|
|
@ -2377,15 +2318,14 @@ void updateGraphics() {
|
|
|
|
write_vline( draw_buffer_level,16,0,GRAPHICS_HEIGHT_REAL-1,1);
|
|
|
|
write_vline( draw_buffer_level,16,0,GRAPHICS_HEIGHT_REAL-1,1);
|
|
|
|
write_vline( draw_buffer_mask,16,0,GRAPHICS_HEIGHT_REAL-1,1);
|
|
|
|
write_vline( draw_buffer_mask,16,0,GRAPHICS_HEIGHT_REAL-1,1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Must mask out last half-word because SPI keeps clocking it out otherwise
|
|
|
|
// Must mask out last half-word because SPI keeps clocking it out otherwise
|
|
|
|
for (uint32_t i = 0; i < 16; i++) {
|
|
|
|
for (uint32_t i = 0; i < 8; i++) {
|
|
|
|
write_vline( draw_buffer_level,GRAPHICS_WIDTH_REAL-i-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
write_vline( draw_buffer_level,GRAPHICS_WIDTH_REAL-i-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
write_vline( draw_buffer_mask,GRAPHICS_WIDTH_REAL-i-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
write_vline( draw_buffer_mask,GRAPHICS_WIDTH_REAL-i-1,0,GRAPHICS_HEIGHT_REAL-1,0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void updateOnceEveryFrame() {
|
|
|
|
void updateOnceEveryFrame() {
|
|
|
|
clearGraphics();
|
|
|
|
clearGraphics();
|
|
|
|
updateGraphics();
|
|
|
|
updateGraphics();
|
|
|
@ -2441,8 +2381,6 @@ MODULE_INITCALL(osdgenInitialize, osdgenStart)
|
|
|
|
static void osdgenTask(void *parameters)
|
|
|
|
static void osdgenTask(void *parameters)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
portTickType lastSysTime;
|
|
|
|
portTickType lastSysTime;
|
|
|
|
AttitudeActualData attitude;
|
|
|
|
|
|
|
|
GPSPositionData gpsData;
|
|
|
|
|
|
|
|
// Loop forever
|
|
|
|
// Loop forever
|
|
|
|
lastSysTime = xTaskGetTickCount();
|
|
|
|
lastSysTime = xTaskGetTickCount();
|
|
|
|
|
|
|
|
|
|
|
@ -2469,10 +2407,6 @@ static void osdgenTask(void *parameters)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if( xSemaphoreTake( osdSemaphore, LONG_TIME ) == pdTRUE )
|
|
|
|
if( xSemaphoreTake( osdSemaphore, LONG_TIME ) == pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
GPSPositionGet(&gpsData);
|
|
|
|
|
|
|
|
AttitudeActualGet(&attitude);
|
|
|
|
|
|
|
|
setAttitudeOsd((int16_t)attitude.Pitch,(int16_t)attitude.Roll,(int16_t)attitude.Yaw);
|
|
|
|
|
|
|
|
setGpsOsd(gpsData.Status,gpsData.Latitude,gpsData.Longitude,gpsData.Altitude,gpsData.Groundspeed);
|
|
|
|
|
|
|
|
updateOnceEveryFrame();
|
|
|
|
updateOnceEveryFrame();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//xSemaphoreTake(osdSemaphore, portMAX_DELAY);
|
|
|
|
//xSemaphoreTake(osdSemaphore, portMAX_DELAY);
|
|
|
|