-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathILI9341.cpp
176 lines (140 loc) · 5.31 KB
/
ILI9341.cpp
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include <cstdlib>
#include <cstdio>
#include "SDL.h"
#include <fstream>
#include <iostream>
#include "ILI9341.h"
#include "metadata.h"
#include "utils.h"
using namespace std;
#define WINDOW_SCALE 3
#define WINDOW_HEIGHT 241 // y
#define WINDOW_WIDTH 320 // x
SDL_Renderer *renderer;
SDL_Window *window;
uint32_t ILI9341_SPICounter = 0;
uint32_t screen[WINDOW_HEIGHT][WINDOW_WIDTH]; // simulator only, for hitbox display
bool changed[WINDOW_HEIGHT][WINDOW_WIDTH]; // simulator only, is true if hitbox is displayed
void LCD_startLCD() {
SDL_CreateWindowAndRenderer(WINDOW_WIDTH*WINDOW_SCALE, WINDOW_HEIGHT*WINDOW_SCALE,
0, &window, &renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
void ILI9341_drawColors(uint32_t x, uint32_t y, int32_t *rgbArr, uint16_t totalPixels) {
for(uint32_t i = 0; i < totalPixels; i++) {
uint32_t rgb = rgbArr[i];
LCD_drawPixel(x+i, y, rgb, false);
}
ILI9341_SPICounter += 11 + 3 * totalPixels;
}
void ILI9341_fillScreen(uint32_t rgb) {
for(int r = 0; r < 241; r++) {
for(int c = 0; c < 321; c++) {
LCD_drawPixel(c, r, rgb, false);
}
}
}
// simulator only
void LCD_drawOverlayCircle(double doublex, double doubley, uint8_t radius, uint32_t colorSub) {
double cx = (double) doublex;
double cy = (double) doubley;
double radius_sq = radius * radius;
for(int16_t y = cy + radius; y >= cy - radius; y--) {
if(y < 0 || y >= WINDOW_HEIGHT) continue;
for(int16_t x = cx - radius; x <= cx + radius; x++) {
if(x < 0 || x >= WINDOW_WIDTH) continue;
double distance_sq = (x-cx)*(x-cx) + (y-cy)*(y-cy);
if(radius_sq >= distance_sq) {
uint32_t oldColor = screen[y][x];
uint16_t oldRed = (oldColor >> 16u) & 0xFF;
uint16_t oldGreen = (oldColor >> 8u) & 0xFF;
uint16_t oldBlue = oldColor & 0xFF;
uint16_t overlayRed = (colorSub >> 16u) & 0xFF;
uint16_t overlayGreen = (colorSub >> 8u) & 0xFF;
uint16_t overlayBlue = colorSub & 0xFF;
int16_t newRed = oldRed - overlayRed;
int16_t newGreen = oldGreen - overlayGreen;
int16_t newBlue = oldBlue - overlayBlue;
if(newRed < 0) newRed = 0;
if(newGreen < 0) newGreen = 0;
if(newBlue < 0) newBlue = 0;
// if(newRed > 255) newRed = 255;
// if(newGreen > 255) newGreen = 255;
// if(newBlue > 255) newBlue = 255;
uint32_t newRGB = ((newRed & 0xFF) << 16) + ((newGreen & 0xFF) << 8) + (newBlue & 0xFF);
changed[y][x] = true;
LCD_drawPixel(x, y, newRGB, true);
}
}
}
}
// simulator only
void LCD_drawOverlayRectangle(double doublex, double doubley,
uint8_t width, uint8_t height, uint32_t colorSub) {
int16_t cx = (uint16_t) doublex;
int16_t cy = (uint16_t) doubley;
for(int16_t y = cy + height/2; y >= cy - height/2; y--) {
if(y < 0 || y >= WINDOW_HEIGHT) continue;
for(int16_t x = cx - width/2; x <= cx + width/2; x++) {
if(x < 0 || x >= WINDOW_WIDTH) continue;
uint32_t oldColor = screen[y][x];
uint16_t oldRed = (oldColor >> 16u) & 0xFF;
uint16_t oldGreen = (oldColor >> 8u) & 0xFF;
uint16_t oldBlue = oldColor & 0xFF;
uint16_t overlayRed = (colorSub >> 16u) & 0xFF;
uint16_t overlayGreen = (colorSub >> 8u) & 0xFF;
uint16_t overlayBlue = colorSub & 0xFF;
int16_t newRed = oldRed - overlayRed;
int16_t newGreen = oldGreen - overlayGreen;
int16_t newBlue = oldBlue - overlayBlue;
if(newRed < 0) newRed = 0;
if(newGreen < 0) newGreen = 0;
if(newBlue < 0) newBlue = 0;
if(newRed > 255) newRed = 255;
if(newGreen > 255) newGreen = 255;
if(newBlue > 255) newBlue = 255;
uint32_t newRGB = ((newRed & 0xFF) << 16) + ((newGreen & 0xFF) << 8) + (newBlue & 0xFF);
changed[y][x] = true;
LCD_drawPixel(x, y, newRGB, true);
}
}
}
void LCD_clearOverlay() {
for(int r = 0; r < WINDOW_HEIGHT; r++) {
for(int c = 0; c < WINDOW_WIDTH; c++) {
if(changed[r][c]) {
changed[r][c] = false;
LCD_drawPixel(c, r, screen[r][c], false);
}
}
}
}
void LCD_drawPixel(uint16_t x, uint16_t y, uint32_t rgb, bool isOverlay) {
if(x >= WINDOW_WIDTH || y >= WINDOW_HEIGHT) {
return;
}
if(!isOverlay) screen[y][x] = rgb;
y = WINDOW_HEIGHT - 1 - y;
SDL_SetRenderDrawColor(renderer, rgb>>16, rgb>>8, rgb, 255);
for(int i = x*WINDOW_SCALE; i < x*WINDOW_SCALE+WINDOW_SCALE; i++) {
for(int j = y * WINDOW_SCALE; j < y*WINDOW_SCALE+WINDOW_SCALE; j++) {
SDL_RenderDrawPoint(renderer, i, j);
}
}
}
void LCD_update() {
SDL_RenderPresent(renderer);
}
void stopSDL2() {
// cleanup SDL
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
void ILI9341_init() {
// ILI9341_fillScreen(0);
// LCD_update();
// for(int i = 0; i < 99999999; i++) {}
}