Skip to content

Commit 0eb068f

Browse files
committed
first
0 parents  commit 0eb068f

16 files changed

+2036
-0
lines changed

.vscode/c_cpp_properties.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"configurations": [
3+
{
4+
"name": "Linux",
5+
"includePath": [
6+
"${workspaceFolder}/**",
7+
"${vcpkgRoot}/x64-linux/include",
8+
"/usr/include/SDL",
9+
"/usr/include/SDL2"
10+
],
11+
"defines": [],
12+
"compilerPath": "/usr/bin/clang-11",
13+
"cStandard": "c17",
14+
"cppStandard": "c++14",
15+
"intelliSenseMode": "linux-clang-x64"
16+
}
17+
],
18+
"version": 4
19+
}

Arduino/COLOR.h

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#pragma once
2+
3+
#include "stdint.h"
4+
5+
// unsigned char reverse(unsigned char b) {
6+
// b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
7+
// b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
8+
// b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
9+
// return b;
10+
// }
11+
12+
// static const uint16_t EGA565[] = {
13+
// 0x0000,
14+
// 0x0014,
15+
// 0x0540,
16+
// 0x0554,
17+
// 0xA000,
18+
// 0xA014,
19+
// 0xA2A0,
20+
// 0xA554,
21+
// 0x52AA,
22+
// 0x52BF,
23+
// 0x57EA,
24+
// 0x57FF,
25+
// 0xFAAA,
26+
// 0xFABF,
27+
// 0xFFEA,
28+
// 0xFFFF,
29+
// };
30+
31+
static const uint16_t EGAILI[] = {
32+
0x0000,
33+
0x0014,
34+
0x0540,
35+
0x0554,
36+
0xA000,
37+
0xA014,
38+
0xA2A0,
39+
0x8210, // 1000001000010000 = 0x8210 // (BLUE: 00000-000000-11111 = 0x001F),// (GREEN: 00000-111111-00000 = 0x07E0), // 0xA554,
40+
0x5550, // 0x52AA,
41+
0x52BF,
42+
0x57EA,
43+
0x57FF,
44+
0xFAAA,
45+
0xFABF,
46+
0xFFEA,
47+
0xFFFF,
48+
};
49+
50+
// static const uint16_t EGA565[] = {
51+
// 0x0000, 0x0014, 0x0540, 0x0555,
52+
// 0xA800, 0xA815, 0xAAA0, 0xAD55,
53+
// 0x52AA, 0x52BF, 0x57EA, 0x57FF,
54+
// 0xFAAA, 0xFABF, 0xFFEA, 0xFFFF
55+
// };
56+
57+
void egargb(uint8_t ega, uint8_t& red, uint8_t& green, uint8_t& blue) {
58+
red = 85 * (((ega >> 1) & 2) | (ega >> 5) & 1);
59+
green = 85 * (( ega & 2) | (ega >> 4) & 1);
60+
blue = 85 * (((ega << 1) & 2) | (ega >> 3) & 1);
61+
}
62+
63+
// uint16_t RGB565(uint8_t red, uint8_t green, uint8_t blue) {
64+
// return ((red & 0b11111000) << 8) | ((green & 0b11111100) << 3) | (blue >> 3);
65+
// }
66+
67+
// static const uint32_t EGARGB[] = {
68+
// 0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
69+
// 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
70+
// 0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
71+
// 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
72+
// };
73+
74+
// uint16_t fixed_color565(int index) {
75+
// uint8_t r, g, b;
76+
// egargb(index, r, g, b);
77+
// return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
78+
// // return ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3);
79+
// // return ((r & 0xF8) << 8) | ((g & 0xF8) << 2) | (b >> 3);
80+
// }
81+
82+
#define Color uint16_t // RGB565
83+
84+
// #define COLOR(index) (fixed_color565(index))
85+
#define COLOR(index) (EGAILI[index])
86+
// Color COLOR(int index) {
87+
// int red, green, blue;
88+
// EGARGB(index, red, green, blue);
89+
// return RGB565(red, green, blue);
90+
// }

Arduino/Graphics.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#pragma once
2+
3+
#include <Adafruit_GFX.h>
4+
5+
// TODO: implement Graphics on Arduino (based on ADAFRUIT_gfx)
6+
class Graphics {
7+
protected:
8+
Adafruit_GFX& GFX;
9+
public:
10+
Graphics(Adafruit_GFX& GFX): GFX(GFX) {}
11+
void vline(int x, int y, int l, Color c) {
12+
GFX.writeFastVLine(x, y, l, c);
13+
}
14+
void hline(int x, int y, int l, Color c) {
15+
GFX.writeFastHLine(x, y, l, c);
16+
}
17+
void borders(int x, int y, int w, int h, Color ctop, Color cleft, Color cright, Color cbottom) {
18+
hline(x, y, w, ctop);
19+
hline(x, y+h, w, cbottom);
20+
vline(x, y, h, cleft);
21+
vline(x+w, y, h, cright);
22+
}
23+
void fillRect(int x, int y, int w, int h, Color c) {
24+
GFX.fillRect(x, y, w, h, c);
25+
}
26+
void text(const String& txt, int x, int y, int size, Color c) {
27+
GFX.setTextColor(c);
28+
GFX.setTextSize(size);
29+
GFX.setCursor(x, y);
30+
GFX.print(txt);
31+
}
32+
void getTextBounds(const String& txt, int size, uint16_t &w, uint16_t &h) {
33+
// TODO: works only with 6x8 monospace
34+
w = txt.length()*size * 6;
35+
h = size * 8;
36+
37+
// GFX.getTextBounds(txt, x,y, x1, y1, w_, h_);
38+
}
39+
void fillScreen(Color c) {
40+
GFX.fillScreen(c);
41+
}
42+
};

Arduino/Touch.h

+235
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
#pragma once
2+
3+
#include <TouchScreen.h>
4+
5+
// TODO: implement Touch on Arduino (based on TouchScreen)
6+
7+
// TODO add into a config?
8+
#ifndef SCREEN_DEFAULT_CLK_ALPHA
9+
#define SCREEN_DEFAULT_CLK_ALPHA 10
10+
#endif
11+
12+
#ifndef SCREEN_DEFAULT_CLK_MAX
13+
#define SCREEN_DEFAULT_CLK_MAX 150
14+
#endif
15+
16+
#ifndef SCREEN_DEFAULT_CLK_MIN
17+
#define SCREEN_DEFAULT_CLK_MIN 30
18+
#endif
19+
20+
struct Size {
21+
int width = SCREEN_THEME_WIDTH;
22+
int height = SCREEN_THEME_HEIGHT;
23+
bool operator==(const Size& other) const {
24+
return
25+
width == other.width &&
26+
height == other.height;
27+
}
28+
bool operator!=(const Size& other) const {
29+
return !(*this == other);
30+
}
31+
};
32+
33+
class Touch {
34+
public:
35+
36+
struct Calibration {
37+
unsigned int tsMinX;
38+
unsigned int tsMinY;
39+
unsigned int tsMaxX;
40+
unsigned int tsMaxY;
41+
42+
// touch
43+
double alpha;
44+
double cmax;
45+
double cmin;
46+
};
47+
48+
protected:
49+
Graphics& graphics;
50+
TouchScreen& TS;
51+
const uint8_t& yp;
52+
const uint8_t& xm;
53+
int rotation;
54+
55+
Size size;
56+
Calibration calibration;
57+
int calibrating = 0;
58+
mutable double clkz = 0;
59+
60+
TSPoint p;
61+
void read() {
62+
prevState = state;
63+
64+
p = TS.getPoint();
65+
pinMode(xm, OUTPUT);
66+
pinMode(yp, OUTPUT);
67+
68+
// smooth EMA on sensor value
69+
clkz = (clkz * calibration.alpha + (double)p.z) / (calibration.alpha + 1);
70+
if (clkz > calibration.cmax) clkz = calibration.cmax;
71+
if (clkz < calibration.cmin) clkz = 0;
72+
state.z = clkz;
73+
74+
switch (state.event) {
75+
case EVENT_IDLE:
76+
if (clkz >= calibration.cmax) state.event = EVENT_TOUCH;
77+
break;
78+
case EVENT_TOUCH:
79+
state.event = EVENT_MOVE;
80+
break;
81+
case EVENT_MOVE:
82+
if (clkz <= calibration.cmin) state.event = EVENT_RELEASE;
83+
break;
84+
case EVENT_RELEASE:
85+
state.event = EVENT_IDLE;
86+
break;
87+
88+
default:
89+
state.event = EVENT_IDLE;
90+
break;
91+
}
92+
93+
94+
if (state.event == EVENT_TOUCH || (EVENT_MOVE && state.z == calibration.cmax)) {
95+
switch (rotation) {
96+
default:
97+
case 0:
98+
state.x = p.x;
99+
state.y = p.y;
100+
break;
101+
case 1:
102+
state.x = p.y;
103+
state.y = p.x;
104+
break;
105+
case 2:
106+
state.x = size.width - p.x;
107+
state.y = p.y;
108+
break;
109+
case 3:
110+
state.x = p.x;
111+
state.y = size.height - p.y;
112+
break;
113+
case 4:
114+
state.x = size.width - p.x;
115+
state.y = size.height - p.y;
116+
break;
117+
case 5:
118+
state.x = size.width - p.y;
119+
state.y = p.x;
120+
break;
121+
case 6:
122+
state.x = p.y;
123+
state.y = size.height - p.x;
124+
break;
125+
case 7:
126+
state.x = size.width - p.y;
127+
state.y = size.height - p.x;
128+
break;
129+
}
130+
if (!calibrating) {
131+
state.x = map(state.x, calibration.tsMaxX, calibration.tsMinX, size.width, 0);
132+
state.y = map(state.y, calibration.tsMaxY, calibration.tsMinY, size.height, 0);
133+
}
134+
}
135+
136+
}
137+
138+
public:
139+
struct State {
140+
int event;
141+
int x;
142+
int y;
143+
int z;
144+
};
145+
protected:
146+
State state, prevState;
147+
public:
148+
Touch(TouchScreen& TS, const uint8_t& yp, const uint8_t& xm, const int rotation = 0): TS(TS), yp(yp), xm(xm), rotation(rotation) {
149+
150+
state.event = EVENT_IDLE;
151+
state.x = -1;
152+
state.y = -1;
153+
}
154+
155+
// TODO: add on desktop?
156+
void begin(
157+
int width, int height, unsigned int tsMinX, unsigned int tsMinY, unsigned int tsMaxX, unsigned int tsMaxY,
158+
const double alpha = SCREEN_DEFAULT_CLK_ALPHA, const double cmax = SCREEN_DEFAULT_CLK_MAX, const double cmin = SCREEN_DEFAULT_CLK_MIN
159+
) {
160+
size.width = width;
161+
size.height = height;
162+
calibration.tsMinX = tsMinX;
163+
calibration.tsMinY = tsMinY;
164+
calibration.tsMaxX = tsMaxX;
165+
calibration.tsMaxY = tsMaxY;
166+
calibration.alpha = alpha;
167+
calibration.cmax = cmax;
168+
calibration.cmin = cmin;
169+
calibrating = 0;
170+
}
171+
172+
Calibration& begin(
173+
int width, int height, Graphics& graphics,
174+
const double alpha = SCREEN_DEFAULT_CLK_ALPHA, const double cmax = SCREEN_DEFAULT_CLK_MAX, const double cmin = SCREEN_DEFAULT_CLK_MIN
175+
) {
176+
size.width = width;
177+
size.height = height;
178+
calibrating = 1;
179+
calibration.alpha = alpha;
180+
calibration.cmax = cmax;
181+
calibration.cmin = cmin;
182+
183+
Color textcolor = COLOR(EGA_WHITE);
184+
const char* text = "Calibration...";
185+
186+
while(calibrating) {
187+
read();
188+
switch (calibrating) {
189+
case 1:
190+
graphics.fillScreen(EGA_BLACK);
191+
// const char* s = "Calibration...";
192+
graphics.text(text, 0, 40, 2, textcolor);
193+
graphics.text("X <- Press here", 1, 1, 2, textcolor);
194+
calibrating = 2;
195+
break;
196+
case 2:
197+
// waiting for first point...
198+
if (state.event == EVENT_TOUCH) {
199+
calibration.tsMinX = state.x;
200+
calibration.tsMinY = state.y;
201+
202+
graphics.fillScreen(EGA_BLACK);
203+
graphics.text(text, 0, 0, 2, textcolor);
204+
uint16_t w,h;
205+
const char* txt = "Press here -> X";
206+
graphics.getTextBounds(txt, 2, w, h);
207+
graphics.text(txt, width-w, height-h, 2, textcolor);
208+
209+
calibrating = 3;
210+
}
211+
break;
212+
213+
case 3:
214+
// waiting for second point...
215+
if (state.event == EVENT_TOUCH) {
216+
calibration.tsMaxX = state.x;
217+
calibration.tsMaxY = state.y;
218+
calibrating = 0;
219+
}
220+
break;
221+
default:
222+
calibrating = 0;
223+
break;
224+
}
225+
}
226+
227+
graphics.fillScreen(COLOR(EGA_BLACK));
228+
return calibration;
229+
}
230+
231+
State& getState() {
232+
read();
233+
return state;
234+
}
235+
};

0 commit comments

Comments
 (0)