Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
121 Kevin 1
#include "maindefs.h"
2
#include "Adafruit_GFX.h"
3
#include "glcdfont.c"
4
#include "oled_ssd1306.h"
5
#include "oled_ssd1331.h"
6
#include <string.h>
7
#include <stdio.h>
8
 
9
static GFX_DATA gfx_data;
10
 
11
void GFX_Init(int w, int h) {
12
    gfx_data._width = gfx_data.WIDTH = w;
13
    gfx_data._height = gfx_data.HEIGHT = h;
14
    gfx_data.rotation = 0;
15
    gfx_data.cursor_x = gfx_data.cursor_y = 0;
16
    gfx_data.textsize = 1;
17
    gfx_data.textcolor = gfx_data.textbgcolor = 0xFFFF;
18
    gfx_data.wrap = 1;
19
}
20
 
21
int GFX_Abs(int i) {
22
    if (i < 0)
23
        return -i;
24
    else
25
        return i;
26
}
27
 
28
void GFX_Swap(int *a, int *b) {
29
    int tmp = *a;
30
    *a = *b;
31
    *b = tmp;
32
}
33
 
34
void GFX_drawLine(int x0, int y0, int x1, int y1, unsigned int color) {
35
#ifdef GFX_SSD1306
36
    int dx, dy, err, ystep;
37
    int steep = GFX_Abs(y1 - y0) > GFX_Abs(x1 - x0);
38
    if (steep) {
39
        GFX_Swap(&x0, &y0);
40
        GFX_Swap(&x1, &y1);
41
    }
42
 
43
    if (x0 > x1) {
44
        GFX_Swap(&x0, &x1);
45
        GFX_Swap(&y0, &y1);
46
    }
47
 
48
    dx = x1 - x0;
49
    dy = GFX_Abs(y1 - y0);
50
 
51
    err = dx / 2;
52
 
53
    if (y0 < y1) {
54
        ystep = 1;
55
    } else {
56
        ystep = -1;
57
    }
58
 
59
    for (; x0 <= x1; x0++) {
60
 
61
        if (steep) {
62
            SSD1306_Draw_Pixel(y0, x0, color);
63
        } else {
64
            SSD1306_Draw_Pixel(x0, y0, color);
65
        }
66
        err -= dy;
67
        if (err < 0) {
68
            y0 += ystep;
69
            err += dx;
70
        }
71
    }
72
#endif
73
#ifdef GFX_SSD1331
74
    SSD1331_Draw_Line(x0, y0, x1, y1, color);
75
#endif
76
}
77
 
78
void GFX_drawFastVLine(int x, int y, int h, unsigned int color) {
79
    GFX_drawLine(x, y, x, y + h - 1, color);
80
}
81
 
82
void GFX_drawFastHLine(int x, int y, int w, unsigned int color) {
83
    GFX_drawLine(x, y, x + w - 1, y, color);
84
}
85
 
86
void GFX_drawRect(int x, int y, int w, int h, unsigned int color) {
87
#ifdef GFX_SSD1306
88
    GFX_drawFastHLine(x, y, w, color);
89
    GFX_drawFastHLine(x, y + h, w, color);
90
    GFX_drawFastVLine(x, y, h, color);
91
    GFX_drawFastVLine(x + w, y, h, color);
92
#endif
93
#ifdef GFX_SSD1331
94
    SSD1331_Draw_Rect(x, y, x + w, y + h, color);
95
#endif
96
}
97
 
98
void GFX_fillRect(int x, int y, int w, int h, unsigned int color) {
99
#ifdef GFX_SSD1306
100
    int i;
101
    for (i = x; i < x + w; i++) {
102
        GFX_drawFastVLine(i, y, h, color);
103
    }
104
#endif
105
#ifdef GFX_SSD1331
106
    SSD1331_Fill_Rect(x, y, x + w, y + h, color);
107
#endif
108
}
109
 
110
void GFX_fillScreen(unsigned int color) {
111
    GFX_fillRect(0, 0, gfx_data._width, gfx_data._height, color);
112
}
113
 
114
void GFX_clearScreen() {
115
#ifdef GFX_SSD1306
116
    GFX_fillScreen(SSD1306_BLACK);
117
#endif
118
#ifdef GFX_SSD1331
119
    SSD1331_Clear_Display();
120
#endif
121
}
122
 
123
void GFX_drawCircle(int x0, int y0, int r, unsigned int color) {
124
    int f = 1 - r;
125
    int ddF_x = 1;
126
    int ddF_y = -2 * r;
127
    int x = 0;
128
    int y = r;
129
 
130
#ifdef GFX_SSD1306
131
    SSD1306_Draw_Pixel(x0, y0 + r, color);
132
    SSD1306_Draw_Pixel(x0, y0 - r, color);
133
    SSD1306_Draw_Pixel(x0 + r, y0, color);
134
    SSD1306_Draw_Pixel(x0 - r, y0, color);
135
#endif
136
#ifdef GFX_SSD1331
137
    SSD1331_Draw_Pixel(x0, y0 + r, color);
138
    SSD1331_Draw_Pixel(x0, y0 - r, color);
139
    SSD1331_Draw_Pixel(x0 + r, y0, color);
140
    SSD1331_Draw_Pixel(x0 - r, y0, color);
141
#endif
142
 
143
    while (x < y) {
144
        if (f >= 0) {
145
            y--;
146
            ddF_y += 2;
147
            f += ddF_y;
148
        }
149
        x++;
150
        ddF_x += 2;
151
        f += ddF_x;
152
 
153
#ifdef GFX_SSD1306
154
        SSD1306_Draw_Pixel(x0 + x, y0 + y, color);
155
        SSD1306_Draw_Pixel(x0 - x, y0 + y, color);
156
        SSD1306_Draw_Pixel(x0 + x, y0 - y, color);
157
        SSD1306_Draw_Pixel(x0 - x, y0 - y, color);
158
        SSD1306_Draw_Pixel(x0 + y, y0 + x, color);
159
        SSD1306_Draw_Pixel(x0 - y, y0 + x, color);
160
        SSD1306_Draw_Pixel(x0 + y, y0 - x, color);
161
        SSD1306_Draw_Pixel(x0 - y, y0 - x, color);
162
#endif
163
#ifdef GFX_SSD1331
164
        SSD1331_Draw_Pixel(x0 + x, y0 + y, color);
165
        SSD1331_Draw_Pixel(x0 - x, y0 + y, color);
166
        SSD1331_Draw_Pixel(x0 + x, y0 - y, color);
167
        SSD1331_Draw_Pixel(x0 - x, y0 - y, color);
168
        SSD1331_Draw_Pixel(x0 + y, y0 + x, color);
169
        SSD1331_Draw_Pixel(x0 - y, y0 + x, color);
170
        SSD1331_Draw_Pixel(x0 + y, y0 - x, color);
171
        SSD1331_Draw_Pixel(x0 - y, y0 - x, color);
172
#endif
173
    }
174
}
175
 
176
void GFX_drawCircleHelper(int x0, int y0, int r, unsigned char cornername, unsigned int color) {
177
    int f = 1 - r;
178
    int ddF_x = 1;
179
    int ddF_y = -2 * r;
180
    int x = 0;
181
    int y = r;
182
 
183
    while (x < y) {
184
        if (f >= 0) {
185
            y--;
186
            ddF_y += 2;
187
            f += ddF_y;
188
        }
189
        x++;
190
        ddF_x += 2;
191
        f += ddF_x;
192
#ifdef GFX_SSD1306
193
        if (cornername & 0x4) {
194
            SSD1306_Draw_Pixel(x0 + x, y0 + y, color);
195
            SSD1306_Draw_Pixel(x0 + y, y0 + x, color);
196
        }
197
        if (cornername & 0x2) {
198
            SSD1306_Draw_Pixel(x0 + x, y0 - y, color);
199
            SSD1306_Draw_Pixel(x0 + y, y0 - x, color);
200
        }
201
        if (cornername & 0x8) {
202
            SSD1306_Draw_Pixel(x0 - y, y0 + x, color);
203
            SSD1306_Draw_Pixel(x0 - x, y0 + y, color);
204
        }
205
        if (cornername & 0x1) {
206
            SSD1306_Draw_Pixel(x0 - y, y0 - x, color);
207
            SSD1306_Draw_Pixel(x0 - x, y0 - y, color);
208
        }
209
#endif
210
#ifdef GFX_SSD1331
211
        if (cornername & 0x4) {
212
            SSD1331_Draw_Pixel(x0 + x, y0 + y, color);
213
            SSD1331_Draw_Pixel(x0 + y, y0 + x, color);
214
        }
215
        if (cornername & 0x2) {
216
            SSD1331_Draw_Pixel(x0 + x, y0 - y, color);
217
            SSD1331_Draw_Pixel(x0 + y, y0 - x, color);
218
        }
219
        if (cornername & 0x8) {
220
            SSD1331_Draw_Pixel(x0 - y, y0 + x, color);
221
            SSD1331_Draw_Pixel(x0 - x, y0 + y, color);
222
        }
223
        if (cornername & 0x1) {
224
            SSD1331_Draw_Pixel(x0 - y, y0 - x, color);
225
            SSD1331_Draw_Pixel(x0 - x, y0 - y, color);
226
        }
227
#endif
228
    }
229
}
230
 
231
void GFX_fillCircle(int x0, int y0, int r, unsigned int color) {
232
    GFX_drawFastVLine(x0, y0 - r, 2 * r + 1, color);
233
    GFX_fillCircleHelper(x0, y0, r, 3, 0, color);
234
}
235
 
236
void GFX_fillCircleHelper(int x0, int y0, int r, unsigned char cornername, int delta, unsigned int color) {
237
    int f = 1 - r;
238
    int ddF_x = 1;
239
    int ddF_y = -2 * r;
240
    int x = 0;
241
    int y = r;
242
 
243
    while (x < y) {
244
        if (f >= 0) {
245
            y--;
246
            ddF_y += 2;
247
            f += ddF_y;
248
        }
249
        x++;
250
        ddF_x += 2;
251
        f += ddF_x;
252
 
253
        if (cornername & 0x1) {
254
            GFX_drawFastVLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);
255
            GFX_drawFastVLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);
256
        }
257
        if (cornername & 0x2) {
258
            GFX_drawFastVLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);
259
            GFX_drawFastVLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);
260
        }
261
    }
262
}
263
 
264
void GFX_drawTriangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
265
    GFX_drawLine(x0, y0, x1, y1, color);
266
    GFX_drawLine(x1, y1, x2, y2, color);
267
    GFX_drawLine(x2, y2, x0, y0, color);
268
}
269
 
270
void GFX_fillTriangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
271
    int a, b, y, last;
272
    int dx01 = x1 - x0;
273
    int dy01 = y1 - y0;
274
    int dx02 = x2 - x0;
275
    int dy02 = y2 - y0;
276
    int dx12 = x2 - x1;
277
    int dy12 = y2 - y1;
278
    int sa = 0;
279
    int sb = 0;
280
 
281
    // Sort coordinates by Y order (y2 >= y1 >= y0)
282
    if (y0 > y1) {
283
        GFX_Swap(&y0, &y1);
284
        GFX_Swap(&x0, &x1);
285
    }
286
    if (y1 > y2) {
287
        GFX_Swap(&y2, &y1);
288
        GFX_Swap(&x2, &x1);
289
    }
290
    if (y0 > y1) {
291
        GFX_Swap(&y0, &y1);
292
        GFX_Swap(&x0, &x1);
293
    }
294
 
295
    if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
296
        a = b = x0;
297
        if (x1 < a) a = x1;
298
        else if (x1 > b) b = x1;
299
        if (x2 < a) a = x2;
300
        else if (x2 > b) b = x2;
301
        GFX_drawFastHLine(a, y0, b - a + 1, color);
302
        return;
303
    }
304
 
305
    // For upper part of triangle, find scanline crossings for segments
306
    // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
307
    // is included here (and second loop will be skipped, avoiding a /0
308
    // error there), otherwise scanline y1 is skipped here and handled
309
    // in the second loop...which also avoids a /0 error here if y0=y1
310
    // (flat-topped triangle).
311
    if (y1 == y2) last = y1; // Include y1 scanline
312
    else last = y1 - 1; // Skip it
313
 
314
    for (y = y0; y <= last; y++) {
315
        a = x0 + sa / dy01;
316
        b = x0 + sb / dy02;
317
        sa += dx01;
318
        sb += dx02;
319
        /* longhand:
320
        a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
321
        b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
322
         */
323
        if (a > b) GFX_Swap(&a, &b);
324
        GFX_drawFastHLine(a, y, b - a + 1, color);
325
    }
326
 
327
    // For lower part of triangle, find scanline crossings for segments
328
    // 0-2 and 1-2.  This loop is skipped if y1=y2.
329
    sa = dx12 * (y - y1);
330
    sb = dx02 * (y - y0);
331
    for (; y <= y2; y++) {
332
        a = x1 + sa / dy12;
333
        b = x0 + sb / dy02;
334
        sa += dx12;
335
        sb += dx02;
336
        /* longhand:
337
        a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
338
        b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
339
         */
340
        if (a > b) GFX_Swap(&a, &b);
341
        GFX_drawFastHLine(a, y, b - a + 1, color);
342
    }
343
}
344
 
345
void GFX_drawRoundRect(int x, int y, int w, int h, int r, unsigned int color) {
346
    // smarter version
347
    GFX_drawFastHLine(x + r, y, w - 2 * r, color); // Top
348
    GFX_drawFastHLine(x + r, y + h - 1, w - 2 * r, color); // Bottom
349
    GFX_drawFastVLine(x, y + r, h - 2 * r, color); // Left
350
    GFX_drawFastVLine(x + w - 1, y + r, h - 2 * r, color); // Right
351
 
352
    // draw four corners
353
    GFX_drawCircleHelper(x + r, y + r, r, 1, color);
354
    GFX_drawCircleHelper(x + w - r - 1, y + r, r, 2, color);
355
    GFX_drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color);
356
    GFX_drawCircleHelper(x + r, y + h - r - 1, r, 8, color);
357
}
358
 
359
void GFX_fillRoundRect(int x, int y, int w, int h, int r, unsigned int color) {
360
    // smarter version
361
    GFX_fillRect(x + r, y, w - 2 * r, h, color);
362
 
363
    // draw four corners
364
    GFX_fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
365
    GFX_fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1, color);
366
}
367
 
368
void GFX_drawBitmap(int x, int y, const unsigned char* bitmap, int w, int h, unsigned int color) {
369
    int i, j;
370
    for (j = 0; j < h; j++) {
371
        for (i = 0; i < w; i++) {
372
            if (bitmap[i + (j / 8) * w] & (j % 8)) {
373
#ifdef GFX_SSD1306
374
                SSD1306_Draw_Pixel(x + i, y + j, color);
375
#endif
376
#ifdef GFX_SSD1331
377
                SSD1331_Draw_Pixel(x + i, y + j, color);
378
#endif
379
            }
380
        }
381
    }
382
}
383
 
384
void GFX_drawChar(int x, int y, unsigned char c, unsigned int color, unsigned int bg, unsigned char size) {
385
    int i, j;
386
    unsigned int line;
387
 
388
    if ((x >= gfx_data._width) || // Clip right
389
            (y >= gfx_data._height) || // Clip bottom
390
            ((x + 5 * size - 1) < 0) || // Clip left
391
            ((y + 8 * size - 1) < 0)) // Clip top
392
        return;
393
 
394
    for (i = 0; i < 6; i++) {
395
        if (i == 5)
396
            line = 0x0;
397
        else
398
            line = font[(c * 5) + i];
399
        for (j = 0; j < 8; j++) {
400
            if (line & 0x1) {
401
                if (size == 1) {// default size
402
#ifdef GFX_SSD1306
403
                    SSD1306_Draw_Pixel(x + i, y + j, color);
404
#endif
405
#ifdef GFX_SSD1331
406
                    SSD1331_Draw_Pixel(x + i, y + j, color);
407
#endif
408
                } else { // big size
409
                    GFX_fillRect(x + (i * size), y + (j * size), size, size, color);
410
                }
411
            } else if (bg != color) {
412
                if (size == 1) { // default size
413
#ifdef GFX_SSD1306
414
                    SSD1306_Draw_Pixel(x + i, y + j, bg);
415
#endif
416
#ifdef GFX_SSD1331
417
                    SSD1331_Draw_Pixel(x + i, y + j, bg);
418
#endif
419
                } else { // big size
420
                    GFX_fillRect(x + i*size, y + j*size, size, size, bg);
421
                }
422
            }
423
            line >>= 1;
424
        }
425
    }
426
}
427
 
428
void GFX_write(unsigned char c) {
429
    if (c == '\n') {
430
        gfx_data.cursor_y += gfx_data.textsize * 8;
431
        gfx_data.cursor_x = 0;
432
    } else if (c == '\r') {
433
        // skip em
434
    } else {
435
        GFX_drawChar(gfx_data.cursor_x, gfx_data.cursor_y, c, gfx_data.textcolor, gfx_data.textbgcolor, gfx_data.textsize);
436
        gfx_data.cursor_x += gfx_data.textsize * 6;
437
        if (gfx_data.wrap && (gfx_data.cursor_x > (gfx_data._width - gfx_data.textsize * 6))) {
438
            gfx_data.cursor_y += gfx_data.textsize * 8;
439
            gfx_data.cursor_x = 0;
440
        }
441
    }
442
}
443
 
444
void GFX_writeString(const rom char *fmt, ...) {
445
    unsigned char i, len;
446
    va_list args;
447
    va_start(args, fmt);
448
    vsprintf((char *) gfx_data.buffer, fmt, args);
449
    va_end(args);
450
    len = strlen((char *) gfx_data.buffer);
451
    for (i = 0; i < len; i++) {
452
        GFX_write(gfx_data.buffer[i]);
453
    }
454
}
455
 
456
void GFX_setCursor(int x, int y) {
457
    gfx_data.cursor_x = x;
458
    gfx_data.cursor_y = y;
459
}
460
 
461
void GFX_setTextColor(unsigned int c) {
462
    // for 'transparent' background, we'll set the bg
463
    // to the same as fg instead of using a flag
464
    gfx_data.textcolor = c;
465
    gfx_data.textbgcolor = c;
466
}
467
 
468
void GFX_setTextColorBG(unsigned int c, unsigned int bg) {
469
    gfx_data.textcolor = c;
470
    gfx_data.textbgcolor = bg;
471
}
472
 
473
void GFX_setTextSize(unsigned char s) {
474
    gfx_data.textsize = (s > 0) ? s : 1;
475
}
476
 
477
void GFX_setTextWrap(unsigned char w) {
478
    gfx_data.wrap = w;
479
}
480
 
481
void GFX_setRotation(unsigned char x) {
482
    x %= 4; // cant be higher than 3
483
    gfx_data.rotation = x;
484
    switch (x) {
485
        case 0:
486
        case 2:
487
            gfx_data._width = gfx_data.WIDTH;
488
            gfx_data._height = gfx_data.HEIGHT;
489
            break;
490
        case 1:
491
        case 3:
492
            gfx_data._width = gfx_data.HEIGHT;
493
            gfx_data._height = gfx_data.WIDTH;
494
            break;
495
    }
496
}
497
 
498
unsigned char GFX_getRotation() {
499
    gfx_data.rotation %= 4;
500
    return gfx_data.rotation;
501
}
502
 
503
int GFX_height() {
504
    return gfx_data._height;
505
}
506
 
507
int GFX_width() {
508
    return gfx_data._width;
509
}