-
Notifications
You must be signed in to change notification settings - Fork 3
/
gfx.c
134 lines (121 loc) · 3.02 KB
/
gfx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "gfx.h"
#include "font.h"
#include "auxiliary.h"
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#define STRIDE 12
uint8_t buffers[2][7*STRIDE];
uint8_t *work_buf = buffers[0];
void GFX_init()
{
DISPLAY_init();
DISPLAY_set_viewport(work_buf, STRIDE);
}
void GFX_swap()
{
static uint8_t b = 0;
DISPLAY_set_viewport(work_buf, STRIDE);
++b;
work_buf = buffers[b & 1];
/* clear buffer */
for (uint8_t i = 0; i < 7*STRIDE; ++i)
work_buf[i] = 0;
}
void GFX_putpixel(uint8_t x, uint8_t y, uint8_t color)
{
uint8_t * const buf = work_buf + y*STRIDE + x/2;
*buf |= color << (4 * (x&1));
}
uint8_t GFX_getpixel(uint8_t x, uint8_t y)
{
const uint8_t * const pix = work_buf + y*STRIDE + x/2;
return (*pix >> (4*(x&1))) & 0x0f;
}
void GFX_fill(struct rect bbox, uint8_t color)
{
for (uint8_t i = bbox.y; i < bbox.y + bbox.h; ++i)
for (uint8_t j = bbox.x; j < bbox.x + bbox.w; ++j)
GFX_putpixel(j, i, color);
}
void GFX_put_text(struct rect bbox, int x, int y,
uint8_t src, const uint8_t *t, int16_t len, uint8_t fg, uint8_t bg)
{
int8_t col = 0;
int8_t firstbit = 0;
int8_t height = bbox.h;
int8_t width = bbox.w;
if (x >= bbox.w || x <= -len*6) {
return;
} else if (x > 0) {
bbox.x += x;
width -= x;
} else {
t += (-x) / 6;
len -= (-x) / 6;
col = (-x) % 6;
}
if (y >= bbox.h || y <= -7) {
return;
} else if (y > 0) {
bbox.y += y;
height -= y;
} else {
firstbit = -y;
height += y;
}
for (int x = bbox.x, i = 0; i < len && x < bbox.x + width; ++x) {
if (col < 5) {
uint8_t byte = 0;
switch(src) {
case TEXT_RAM:
byte = *t; break;
case TEXT_PGM:
byte = pgm_read_byte(t); break;
case TEXT_EEP:
byte = eeprom_read_byte(t); break;
}
uint8_t letter = pgm_read_byte(&font[5*(byte) + col]);
letter >>= firstbit;
for (int y = bbox.y; y < bbox.y + height; ++y, letter >>= 1)
GFX_putpixel(x, y, (letter & 1) ? fg : bg);
++col;
} else {
for (int y = bbox.y; y < bbox.y + height; ++y)
GFX_putpixel(x, y, bg);
col = 0;
++t; ++i;
}
}
}
void GFX_blit_progmem(struct rect bbox, const uint8_t *fbuffer,
uint8_t stride, uint8_t _x, uint8_t _y)
{
uint8_t old_x = _x;
for (uint8_t y = bbox.y; y < bbox.y+bbox.h; ++y, ++_y) {
_x = old_x;
for (uint8_t x = bbox.x; x < bbox.x+bbox.w; ++x, ++_x) {
const uint8_t * const pix = fbuffer + _y*stride + _x/2;
const uint8_t val = (pgm_read_byte(pix) >> (4*(_x&1))) & 0x0f;
GFX_putpixel(x, y, val);
}
}
}
void GFX_draw_bitmap(struct rect bbox, uint8_t fg, uint8_t bg, const uint8_t *bbuffer,
uint8_t stride, uint8_t _x, uint8_t _y)
{
const uint8_t *last_addr = NULL;
uint8_t last_read = 0;
for (uint8_t y = bbox.y; y < bbox.y+bbox.h; ++y) {
for (uint8_t x = bbox.x; x < bbox.x+bbox.w; ++x) {
const uint8_t rx = _x + x - bbox.x;
const uint8_t ry = _y + y - bbox.y;
const uint8_t *addr = bbuffer + ry*stride + rx/8;
if (addr != last_addr) {
last_read = pgm_read_byte(addr);
last_addr = addr;
}
GFX_putpixel(x, y, (last_read & (0x80 >> (rx%8))) ? fg : bg);
}
}
}