Blame | Last modification | View Log | Download | RSS feed
#include "maindefs.h"#include "Adafruit_GFX.h"#include "glcdfont.c"#include "oled_ssd1306.h"#include "oled_ssd1331.h"#include <string.h>#include <stdio.h>static GFX_DATA gfx_data;void GFX_Init(int w, int h) {gfx_data._width = gfx_data.WIDTH = w;gfx_data._height = gfx_data.HEIGHT = h;gfx_data.rotation = 0;gfx_data.cursor_x = gfx_data.cursor_y = 0;gfx_data.textsize = 1;gfx_data.textcolor = gfx_data.textbgcolor = 0xFFFF;gfx_data.wrap = 1;}int GFX_Abs(int i) {if (i < 0)return -i;elsereturn i;}void GFX_Swap(int *a, int *b) {int tmp = *a;*a = *b;*b = tmp;}void GFX_drawLine(int x0, int y0, int x1, int y1, unsigned int color) {#ifdef GFX_SSD1306int dx, dy, err, ystep;int steep = GFX_Abs(y1 - y0) > GFX_Abs(x1 - x0);if (steep) {GFX_Swap(&x0, &y0);GFX_Swap(&x1, &y1);}if (x0 > x1) {GFX_Swap(&x0, &x1);GFX_Swap(&y0, &y1);}dx = x1 - x0;dy = GFX_Abs(y1 - y0);err = dx / 2;if (y0 < y1) {ystep = 1;} else {ystep = -1;}for (; x0 <= x1; x0++) {if (steep) {SSD1306_Draw_Pixel(y0, x0, color);} else {SSD1306_Draw_Pixel(x0, y0, color);}err -= dy;if (err < 0) {y0 += ystep;err += dx;}}#endif#ifdef GFX_SSD1331SSD1331_Draw_Line(x0, y0, x1, y1, color);#endif}void GFX_drawFastVLine(int x, int y, int h, unsigned int color) {GFX_drawLine(x, y, x, y + h - 1, color);}void GFX_drawFastHLine(int x, int y, int w, unsigned int color) {GFX_drawLine(x, y, x + w - 1, y, color);}void GFX_drawRect(int x, int y, int w, int h, unsigned int color) {#ifdef GFX_SSD1306GFX_drawFastHLine(x, y, w, color);GFX_drawFastHLine(x, y + h, w, color);GFX_drawFastVLine(x, y, h, color);GFX_drawFastVLine(x + w, y, h, color);#endif#ifdef GFX_SSD1331SSD1331_Draw_Rect(x, y, x + w, y + h, color);#endif}void GFX_fillRect(int x, int y, int w, int h, unsigned int color) {#ifdef GFX_SSD1306int i;for (i = x; i < x + w; i++) {GFX_drawFastVLine(i, y, h, color);}#endif#ifdef GFX_SSD1331SSD1331_Fill_Rect(x, y, x + w, y + h, color);#endif}void GFX_fillScreen(unsigned int color) {GFX_fillRect(0, 0, gfx_data._width, gfx_data._height, color);}void GFX_clearScreen() {#ifdef GFX_SSD1306GFX_fillScreen(SSD1306_BLACK);#endif#ifdef GFX_SSD1331SSD1331_Clear_Display();#endif}void GFX_drawCircle(int x0, int y0, int r, unsigned int color) {int f = 1 - r;int ddF_x = 1;int ddF_y = -2 * r;int x = 0;int y = r;#ifdef GFX_SSD1306SSD1306_Draw_Pixel(x0, y0 + r, color);SSD1306_Draw_Pixel(x0, y0 - r, color);SSD1306_Draw_Pixel(x0 + r, y0, color);SSD1306_Draw_Pixel(x0 - r, y0, color);#endif#ifdef GFX_SSD1331SSD1331_Draw_Pixel(x0, y0 + r, color);SSD1331_Draw_Pixel(x0, y0 - r, color);SSD1331_Draw_Pixel(x0 + r, y0, color);SSD1331_Draw_Pixel(x0 - r, y0, color);#endifwhile (x < y) {if (f >= 0) {y--;ddF_y += 2;f += ddF_y;}x++;ddF_x += 2;f += ddF_x;#ifdef GFX_SSD1306SSD1306_Draw_Pixel(x0 + x, y0 + y, color);SSD1306_Draw_Pixel(x0 - x, y0 + y, color);SSD1306_Draw_Pixel(x0 + x, y0 - y, color);SSD1306_Draw_Pixel(x0 - x, y0 - y, color);SSD1306_Draw_Pixel(x0 + y, y0 + x, color);SSD1306_Draw_Pixel(x0 - y, y0 + x, color);SSD1306_Draw_Pixel(x0 + y, y0 - x, color);SSD1306_Draw_Pixel(x0 - y, y0 - x, color);#endif#ifdef GFX_SSD1331SSD1331_Draw_Pixel(x0 + x, y0 + y, color);SSD1331_Draw_Pixel(x0 - x, y0 + y, color);SSD1331_Draw_Pixel(x0 + x, y0 - y, color);SSD1331_Draw_Pixel(x0 - x, y0 - y, color);SSD1331_Draw_Pixel(x0 + y, y0 + x, color);SSD1331_Draw_Pixel(x0 - y, y0 + x, color);SSD1331_Draw_Pixel(x0 + y, y0 - x, color);SSD1331_Draw_Pixel(x0 - y, y0 - x, color);#endif}}void GFX_drawCircleHelper(int x0, int y0, int r, unsigned char cornername, unsigned int color) {int f = 1 - r;int ddF_x = 1;int ddF_y = -2 * r;int x = 0;int y = r;while (x < y) {if (f >= 0) {y--;ddF_y += 2;f += ddF_y;}x++;ddF_x += 2;f += ddF_x;#ifdef GFX_SSD1306if (cornername & 0x4) {SSD1306_Draw_Pixel(x0 + x, y0 + y, color);SSD1306_Draw_Pixel(x0 + y, y0 + x, color);}if (cornername & 0x2) {SSD1306_Draw_Pixel(x0 + x, y0 - y, color);SSD1306_Draw_Pixel(x0 + y, y0 - x, color);}if (cornername & 0x8) {SSD1306_Draw_Pixel(x0 - y, y0 + x, color);SSD1306_Draw_Pixel(x0 - x, y0 + y, color);}if (cornername & 0x1) {SSD1306_Draw_Pixel(x0 - y, y0 - x, color);SSD1306_Draw_Pixel(x0 - x, y0 - y, color);}#endif#ifdef GFX_SSD1331if (cornername & 0x4) {SSD1331_Draw_Pixel(x0 + x, y0 + y, color);SSD1331_Draw_Pixel(x0 + y, y0 + x, color);}if (cornername & 0x2) {SSD1331_Draw_Pixel(x0 + x, y0 - y, color);SSD1331_Draw_Pixel(x0 + y, y0 - x, color);}if (cornername & 0x8) {SSD1331_Draw_Pixel(x0 - y, y0 + x, color);SSD1331_Draw_Pixel(x0 - x, y0 + y, color);}if (cornername & 0x1) {SSD1331_Draw_Pixel(x0 - y, y0 - x, color);SSD1331_Draw_Pixel(x0 - x, y0 - y, color);}#endif}}void GFX_fillCircle(int x0, int y0, int r, unsigned int color) {GFX_drawFastVLine(x0, y0 - r, 2 * r + 1, color);GFX_fillCircleHelper(x0, y0, r, 3, 0, color);}void GFX_fillCircleHelper(int x0, int y0, int r, unsigned char cornername, int delta, unsigned int color) {int f = 1 - r;int ddF_x = 1;int ddF_y = -2 * r;int x = 0;int y = r;while (x < y) {if (f >= 0) {y--;ddF_y += 2;f += ddF_y;}x++;ddF_x += 2;f += ddF_x;if (cornername & 0x1) {GFX_drawFastVLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);GFX_drawFastVLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);}if (cornername & 0x2) {GFX_drawFastVLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);GFX_drawFastVLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);}}}void GFX_drawTriangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {GFX_drawLine(x0, y0, x1, y1, color);GFX_drawLine(x1, y1, x2, y2, color);GFX_drawLine(x2, y2, x0, y0, color);}void GFX_fillTriangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {int a, b, y, last;int dx01 = x1 - x0;int dy01 = y1 - y0;int dx02 = x2 - x0;int dy02 = y2 - y0;int dx12 = x2 - x1;int dy12 = y2 - y1;int sa = 0;int sb = 0;// Sort coordinates by Y order (y2 >= y1 >= y0)if (y0 > y1) {GFX_Swap(&y0, &y1);GFX_Swap(&x0, &x1);}if (y1 > y2) {GFX_Swap(&y2, &y1);GFX_Swap(&x2, &x1);}if (y0 > y1) {GFX_Swap(&y0, &y1);GFX_Swap(&x0, &x1);}if (y0 == y2) { // Handle awkward all-on-same-line case as its own thinga = b = x0;if (x1 < a) a = x1;else if (x1 > b) b = x1;if (x2 < a) a = x2;else if (x2 > b) b = x2;GFX_drawFastHLine(a, y0, b - a + 1, color);return;}// For upper part of triangle, find scanline crossings for segments// 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1// is included here (and second loop will be skipped, avoiding a /0// error there), otherwise scanline y1 is skipped here and handled// in the second loop...which also avoids a /0 error here if y0=y1// (flat-topped triangle).if (y1 == y2) last = y1; // Include y1 scanlineelse last = y1 - 1; // Skip itfor (y = y0; y <= last; y++) {a = x0 + sa / dy01;b = x0 + sb / dy02;sa += dx01;sb += dx02;/* longhand:a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);*/if (a > b) GFX_Swap(&a, &b);GFX_drawFastHLine(a, y, b - a + 1, color);}// For lower part of triangle, find scanline crossings for segments// 0-2 and 1-2. This loop is skipped if y1=y2.sa = dx12 * (y - y1);sb = dx02 * (y - y0);for (; y <= y2; y++) {a = x1 + sa / dy12;b = x0 + sb / dy02;sa += dx12;sb += dx02;/* longhand:a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);*/if (a > b) GFX_Swap(&a, &b);GFX_drawFastHLine(a, y, b - a + 1, color);}}void GFX_drawRoundRect(int x, int y, int w, int h, int r, unsigned int color) {// smarter versionGFX_drawFastHLine(x + r, y, w - 2 * r, color); // TopGFX_drawFastHLine(x + r, y + h - 1, w - 2 * r, color); // BottomGFX_drawFastVLine(x, y + r, h - 2 * r, color); // LeftGFX_drawFastVLine(x + w - 1, y + r, h - 2 * r, color); // Right// draw four cornersGFX_drawCircleHelper(x + r, y + r, r, 1, color);GFX_drawCircleHelper(x + w - r - 1, y + r, r, 2, color);GFX_drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color);GFX_drawCircleHelper(x + r, y + h - r - 1, r, 8, color);}void GFX_fillRoundRect(int x, int y, int w, int h, int r, unsigned int color) {// smarter versionGFX_fillRect(x + r, y, w - 2 * r, h, color);// draw four cornersGFX_fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);GFX_fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1, color);}void GFX_drawBitmap(int x, int y, const unsigned char* bitmap, int w, int h, unsigned int color) {int i, j;for (j = 0; j < h; j++) {for (i = 0; i < w; i++) {if (bitmap[i + (j / 8) * w] & (j % 8)) {#ifdef GFX_SSD1306SSD1306_Draw_Pixel(x + i, y + j, color);#endif#ifdef GFX_SSD1331SSD1331_Draw_Pixel(x + i, y + j, color);#endif}}}}void GFX_drawChar(int x, int y, unsigned char c, unsigned int color, unsigned int bg, unsigned char size) {int i, j;unsigned int line;if ((x >= gfx_data._width) || // Clip right(y >= gfx_data._height) || // Clip bottom((x + 5 * size - 1) < 0) || // Clip left((y + 8 * size - 1) < 0)) // Clip topreturn;for (i = 0; i < 6; i++) {if (i == 5)line = 0x0;elseline = font[(c * 5) + i];for (j = 0; j < 8; j++) {if (line & 0x1) {if (size == 1) {// default size#ifdef GFX_SSD1306SSD1306_Draw_Pixel(x + i, y + j, color);#endif#ifdef GFX_SSD1331SSD1331_Draw_Pixel(x + i, y + j, color);#endif} else { // big sizeGFX_fillRect(x + (i * size), y + (j * size), size, size, color);}} else if (bg != color) {if (size == 1) { // default size#ifdef GFX_SSD1306SSD1306_Draw_Pixel(x + i, y + j, bg);#endif#ifdef GFX_SSD1331SSD1331_Draw_Pixel(x + i, y + j, bg);#endif} else { // big sizeGFX_fillRect(x + i*size, y + j*size, size, size, bg);}}line >>= 1;}}}void GFX_write(unsigned char c) {if (c == '\n') {gfx_data.cursor_y += gfx_data.textsize * 8;gfx_data.cursor_x = 0;} else if (c == '\r') {// skip em} else {GFX_drawChar(gfx_data.cursor_x, gfx_data.cursor_y, c, gfx_data.textcolor, gfx_data.textbgcolor, gfx_data.textsize);gfx_data.cursor_x += gfx_data.textsize * 6;if (gfx_data.wrap && (gfx_data.cursor_x > (gfx_data._width - gfx_data.textsize * 6))) {gfx_data.cursor_y += gfx_data.textsize * 8;gfx_data.cursor_x = 0;}}}void GFX_writeString(const rom char *fmt, ...) {unsigned char i, len;va_list args;va_start(args, fmt);vsprintf((char *) gfx_data.buffer, fmt, args);va_end(args);len = strlen((char *) gfx_data.buffer);for (i = 0; i < len; i++) {GFX_write(gfx_data.buffer[i]);}}void GFX_setCursor(int x, int y) {gfx_data.cursor_x = x;gfx_data.cursor_y = y;}void GFX_setTextColor(unsigned int c) {// for 'transparent' background, we'll set the bg// to the same as fg instead of using a flaggfx_data.textcolor = c;gfx_data.textbgcolor = c;}void GFX_setTextColorBG(unsigned int c, unsigned int bg) {gfx_data.textcolor = c;gfx_data.textbgcolor = bg;}void GFX_setTextSize(unsigned char s) {gfx_data.textsize = (s > 0) ? s : 1;}void GFX_setTextWrap(unsigned char w) {gfx_data.wrap = w;}void GFX_setRotation(unsigned char x) {x %= 4; // cant be higher than 3gfx_data.rotation = x;switch (x) {case 0:case 2:gfx_data._width = gfx_data.WIDTH;gfx_data._height = gfx_data.HEIGHT;break;case 1:case 3:gfx_data._width = gfx_data.HEIGHT;gfx_data._height = gfx_data.WIDTH;break;}}unsigned char GFX_getRotation() {gfx_data.rotation %= 4;return gfx_data.rotation;}int GFX_height() {return gfx_data._height;}int GFX_width() {return gfx_data._width;}