-
Notifications
You must be signed in to change notification settings - Fork 0
/
canvas.c
322 lines (263 loc) · 8.76 KB
/
canvas.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
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/**
* Include Libraries & models
*/
#include <stdint.h> // Declarations of uint_32 and the like.
#include <stdbool.h> // Support for boolean
#include <stdio.h> // Used for debugging
#include "model/paddle.c"
#include "model/ball.c"
#include "model/fontBig.c"
#include "model/fontSmall.c"
#include "basicFunctions.h" // Used in production
//#include "basicFunctions.c" // Used for debugging
#include "menu.h"
#include "config.h"
/**
* Data
*/
static uint8_t canvas[DISPLAY_WIDTH][DISPLAY_HEIGHT];
/**
* Canvas Action
*
* This function is called from simpler functions.
* It takes in data and modifies the canvas.
*
* Warning: No not call this method if not via
* a simpler function such as paint and erase.
*
* @param {int} x position
* @param {int} y position
* @param {int} width in pixels
* @param {int} height in pixels
* @param {int} target value (0 or 1)
*
* @author Fridh, William
*/
void canvasAction(int x, int y, int width, int height, int val) {
for (int xx = 0; xx < width; xx++) {
for (int yy = 0; yy < height; yy++) {
canvas[x+xx][y+yy] = val;
}
}
}
/**
* Canvas Paint
*
* Paints to the canvas trough a call to canvasAction().
* This function can paint at a certain location and draw shapes.
*
* @param {int} x position
* @param {int} y position
* @param {int} width in pixels
* @param {int} height in pixels
*
* @author Fridh, William
*/
void canvasPaint(int x, int y, int width, int height) {
canvasAction(x, y, width, height, 1);
}
/**
* Canvas Erase
*
* Removes from the canvas via a call tol canvasAction().
* This function removed from the canvas at a given location
* and can do so in shapes.
*
* @param {int} x position
* @param {int} y position
* @param {int} width in pixels
* @param {int} height in pixels
*
* @author Fridh, William
*/
void canvasErase(int x, int y, int width, int height) {
canvasAction(x, y, width, height, 0);
}
/**
* Clear Canvas
*
* Clear all values in the canvas. This can be used for quickly
* clearing the display data before sending it to the display.
*
* @author Fridh, William
*/
void canvasClear() {
for (int x = 0; x < DISPLAY_WIDTH; x++) {
for (int y = 0; y < DISPLAY_HEIGHT; y++) {
canvas[x][y] = 255;
}
}
}
/**
* Check If Pixel In Location
*
* @param {int} position
* @param {int} position
*
* @return {bool} true if the pixel is in the location
*
* @author Fridh, William
*/
bool ifPixelIsFilled(int x, int y) {
if (canvas[x][y] == 1) {
return true;
} else {
return false;
}
}
/**
* Insert Model
*
* Note: Flipping the modelWidth and moderlHeight arguments results in a flipped model.
*
* @param {int} x offset
* @param {int} y offset
* @param {int} width of the model
* @param {int} height of the model
* @param {uint8_t[][]} two-dimensional array of the model
* @param {bool} boolean for deciding merging
*
* @author Fridh, William
*/
void canvasInsertModel(
int x,
int y,
int modelWidth,
int modelHeight,
uint8_t modelData[][modelHeight],
bool merge
) {
for (int xx = 0; xx < modelWidth; xx++) {
for (int yy = 0; yy < modelHeight; yy++) {
if (merge) {
if (canvas[x+xx][y+yy] == 1 || modelData[xx][yy] == 1) {
canvas[x+xx][y+yy] = 1;
}
} else {
canvas[x+xx][y+yy] = modelData[xx][yy];
}
}
}
}
/**
* Write On Canvas
*
* Note: font models are stores in a 1D array.
*
* This function takes in a string an prints it to the screen.
* It loads a font model and converts the correct data from it
* into a 2D array which is sent to canvasInsertModel.
*
* Appart from this, it also cleares the area to be printed
* beforehand, if merge is set to false.
*
* @param {char*} String to be printed on canvas
* @param {int} X position
* @param {int} Y position
* @param {bool} Determin if it should merge or not.
* @param {bool} Print big letters if true, otherwise small
*
* @author Fridh, William
*/
void canvasWrite(char *txt, int x, int y, bool merge, bool big) {
uint8_t *model_font = big ? model_font_big : model_font_small; // Determin font model
const int size = big ? 8 : 5; // Determin size
const int txt_len = getCharLen(txt); // get text length
if (!merge) {
const int textAreaWidth = size*txt_len+(txt_len-1)*LETTER_SPACING; // Calculate text area width
canvasErase(x, y, textAreaWidth, size); // Clear text area
}
for (int i = 0; i < txt_len; i++) { // Loop characters
uint8_t char_model[size][size]; // Create small model
for (int x = 0; x < size; x++) {
const int x_offset = (txt[i]-32)*size+x; // Calculate x offset for reading font
for (int i = (size-1), j = 1; i >= 0; i--, j = j*2) {
char_model[x][i] = model_font[x_offset] & j ? 1 : 0;
}
}
canvasInsertModel(x+i*size+LETTER_SPACING*i, y, size, size, char_model, merge); // Send data to canvasInsertmodel
}
}
/**
* Get Encoded Canvas Data
*
* Return: An encoded version of the canvas that can be read by the display.
*
* @return {uint8_t} An encoded version of the canvas.
*
* @author Fridh, William
*/
uint8_t* canvasGetData(void) {
static uint8_t canvas_encoded[DISPLAY_BYTES]; // Declare new array
for (int i = 0; i < DISPLAY_BYTES; i++) canvas_encoded[i] = 255; // Add placeholder data to new array
for (int i = 0, val = 1, byte_row = 0, col = 0; i < DISPLAY_BYTES; i++, val = 1, col++) { // Loop that also sets values to be used
if (col == DISPLAY_WIDTH) { // If last column is reached
col = 0; // Jump to first column again
byte_row++;
}
for (int bit = 0; bit < 8; bit++) { // Loop 8 bits to be in byte
if (canvas[col][bit+byte_row*8] == 1) canvas_encoded[i] -= val; // Decrese byte value if the canvas cell is painted (=1)
val += val; // Double val (1, 2, 4, 8, 16...)
}
}
return canvas_encoded;
}
/**
* Draw Button Description Bar
*
* A bar that describes each button for the user.
* Should be used for the menu.
*
* @param {bool} whether the left arrow should be visible
* @param {bool} whether the right arrow should be visible
* @param {bool} hether the OK text arrow should be visible
* @param {bool} whether the BACK text should be visible
*
* @author Fridh, William
*/
void drawButtonDescBar(bool left_arrow, bool right_arrow, bool ok, bool back) {
if (left_arrow) canvasWrite("<<", 5, SMALL_TEXTLINE_FOUR, false, false);
if (right_arrow) canvasWrite(">>", 35, SMALL_TEXTLINE_FOUR, false, false);
if (ok) canvasWrite("OK", 70, SMALL_TEXTLINE_FOUR, false, false);
if (back) canvasWrite("BACK", 100, SMALL_TEXTLINE_FOUR, false, false);
canvasPaint(0, 25, 128, 1);
canvasPaint(22, 26, 1, 6);
canvasPaint(57, 26, 1, 6);
canvasPaint(92, 26, 1, 6);
}
/**
* Main - For Debugging & Example
*
* @author Fridh, William
*//*
int main(void) {
char t[] = {getInputChar(0), getInputChar(1), getInputChar(2)};
canvasWrite(t, SMALL_TEXTLINE_TWO, 9, false, true);
//drawButtonDescBar(false, false, false, true);
//canvasInsertModel(0, 123, 128, 5, model_menu_navigation, false);
//canvasWrite("BOARD", 40, 9, false, true);
//canvasWrite("qwertyuiop", 0,0, false, true);
//canvasWrite("QWERTYUIOP", 0,0, false, true);
//canvasInsertModel(0, 0, 2, 4, model_paddle, false);
//canvasInsertModel(63, 0, 2, 2, model_ball, false);
for (int i = 0; i < DISPLAY_HEIGHT; i++) {
for (int j = 0; j < DISPLAY_WIDTH; j++) {
if (canvas[j][i] == 0) {
printf("%s", "-");
} else {
printf("%s", "X");
}
}
printf("\n");
}
printf("\n");
uint8_t* canvas_data = canvasGetData();
for (int i = 0, t = 0; i < DISPLAY_BYTES; i++) {
printf("%d, ", canvas_data[i]);
t++;
if (t == DISPLAY_WIDTH) {
printf("\n");
t = 0;
}
}
}*/