-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcube.hpp
154 lines (119 loc) · 3.68 KB
/
cube.hpp
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
#ifndef CUBE_H
#define CUBE_H
#include <stdint.h>
#include "Arduino.h"
#include "Adafruit_NeoTrellis.h"
#define REFRESH_DELAY 100
#define INT_PIN 10
class Face {
private:
bool is_init;
int rotation;
Adafruit_NeoTrellis * trellis;
friend class Cube;
public:
bool refresh_needed;
Face();
void init(int addr, int rotation);
// Set one pixel to the rgb color
void set_pixel(uint8_t row, uint8_t col, uint8_t r, uint8_t g, uint8_t b);
// Get the rgb colors of one pixel
void get_pixel(uint8_t row, uint8_t col, uint8_t & r, uint8_t & g, uint8_t & b);
// Add the rgb colors to the current colors of a pixel. ie: for each color max between the current value and the value added.
void add_pixel_color(uint8_t row, uint8_t col, uint8_t r, uint8_t g, uint8_t b);
// Rm the rgb colors to the current colors of a pixel. ie: for each color min between the current value and the value added.
void rm_pixel_color(uint8_t row, uint8_t col, uint8_t r, uint8_t g, uint8_t b);
void show();
void reset_leds();
void see_idx(int idx);
void activate_btn(uint8_t row, uint8_t col, uint8_t event);
void deactivate_btn(uint8_t row, uint8_t col, uint8_t event);
void bind_btn_callback(uint8_t row, uint8_t col, TrellisCallback cb);
void unbind_btn_callback(uint8_t row, uint8_t col);
};
class Cube {
public:
Face faces[6];
Cube();
void init();
void read(bool pooling);
void show();
void reset_leds();
};
class Coordinates {
public:
uint8_t compact_coords;
Coordinates() {
this->compact_coords = 0xFF;
}
Coordinates(uint8_t compacted_coords) {
this->compact_coords = compacted_coords;
}
Coordinates(uint8_t face, uint8_t row, uint8_t col) {
this->compact_coords = ((face & 0b111) << 4) | ((row & 0b11) << 2) | (col & 0b11);
}
Coordinates(uint8_t * coords) {
this->compact_coords = ((coords[0] & 0b111) << 4) | ((coords[1] & 0b11) << 2) | (coords[2] & 0b11);
}
Coordinates(Coordinates & c) {
this->compact_coords = c.compact_coords;
}
uint8_t face() { return this->compact_coords >> 4; }
uint8_t row() { return (this->compact_coords >> 2) & 0b11; }
uint8_t col() { return this->compact_coords & 0b11; }
/** Given the coordinates and direction, return the next coordinates.
* The values are stored in the input variables.
*
* @param face face index [min: 0 ; max: 5] (1st coordinate)
* @param row row index [min: 0 ; max: 3] (2nd coordinate)
* @param col column index [min: 0 ; max: 3] (3rd coordinate)
* @param direction direction index [min: 0 ; max: 3]. 0 means north, 1 west, 2 south and 3 east.
*/
static void next_coord(Coordinates & coord, int direction) {
int8_t face = coord.face();
int8_t row = coord.row();
int8_t col = coord.col();
switch (direction) {
case 0:
row -= 1;
// Overflow
if (row == -1) {
face = 3 * (face / 3) + ((face + 1) % 3);
row = col;
col = 0;
}
break;
case 1:
col -= 1;
// Overflow
if (col == -1) {
face = 3 * (face / 3) + ((face + 2) % 3);
col = row;
row = 0;
}
break;
case 2:
row += 1;
// Overflow
if (row == 4) {
// Face triplet change + opposite face
face = ((face / 3 + 1) % 2) * 3 + 2 - (face + 1) % 3;
col = 3 - col;
row = 3;
}
break;
case 3:
col += 1;
// Overflow
if (col == 4) {
// Face triplet change + opposite face
face = ((face / 3 + 1) % 2) * 3 + 2 - (face + 2) % 3;
col = 3;
row = 3 - row;
}
break;
}
coord.compact_coords = ((face & 0b111) << 4) | ((row & 0b11) << 2) | (col & 0b11);
}
};
#endif