-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory_color.cpp
398 lines (335 loc) · 12.1 KB
/
memory_color.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
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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
//all arduino libs require this
#include <Arduino.h>
#include "memory_color.h"
//empty color constructor for arrays and such.
Color::Color(){
};
//Here is a constructor that takes 3 ints for red, green and blue.
Color::Color(int red_in, int green_in, int blue_in){
red = red_in;
green = green_in;
blue = blue_in;
};
//these three color routines are used for getting the integer values out
//These integers are used in calculations and to feed the array.
//return the red color
int Color::getRed(){
return red;
};
//return the green color
int Color::getGreen(){
return green;
};
//return the blue color
int Color::getBlue(){
return blue;
};
//debugging printing
void Color::printColor(){
Serial.print(" red = ");
Serial.print(red);
Serial.print(" green = ");
Serial.print(green);
Serial.print(" blue = ");
Serial.print(blue);
};
//this lets you move a fraction of the way from one color to another
Color Color::progressColor(Color oldColor, Color newColor, float fraction){
red = oldColor.red - ((oldColor.red - newColor.red) * fraction);
green = oldColor.green - ((oldColor.green - newColor.green) * fraction);
blue = oldColor.blue - ((oldColor.blue - newColor.blue) * fraction);
return Color(red,green,blue);
};
//This is the constructor for the color list, a list of colors to cycle through
ColorList::ColorList(prog_int16_t* listPointer, int sizeOfList){
//array pointer to the start of the list
_listPointer = listPointer;
//size of the list for bounds checking and wrap arround
_sizeOfList = sizeOfList;
long totalDelay = 0;
for(int color = 0;color < getNumberOfElements();color ++){
totalDelay = totalDelay + getDelay(color);
};
//tally up the total number of miliseconds in the list and stuff it in totalTime
totalTime = totalDelay;
};
int ColorList::getNumberOfElements(){
//returns the size of the color list for purposes of modulating total delays
return _sizeOfList;
};
//this returns the delay for the color list, wrapping around to the beginning if it overflows the list.
int ColorList::getDelay(int address){
if (address != address % _sizeOfList){
address = address % _sizeOfList;
}
int colorDelay = pgm_read_word_near(_listPointer + address * 4 + 3);
return colorDelay;
};
//This moves to the next color in the list, wrapping around to the beginning.
int ColorList::incrementAddress(int address){
address++;
if (address != address % _sizeOfList){
address = address % _sizeOfList;
}
if (address < 0){
address = _sizeOfList - 1;
}
return address;
}
//This moves to the last color in the list, wrapping around to the end.
int ColorList::decrementAddress(int address){
address--;
if (address != address % _sizeOfList){
address = address % _sizeOfList;
}
if (address < 0){
address = _sizeOfList - 1;
}
return address;
};
//This retuns the colors for a given in list address
Color ColorList::getCurrentColor(int address){
if (address != address % _sizeOfList){
address = address % _sizeOfList;
}
int red = pgm_read_word_near(_listPointer + address * 4);
int green = pgm_read_word_near(_listPointer + address * 4 + 1);
int blue = pgm_read_word_near(_listPointer + address * 4 + 2);
return Color(red,green,blue);
};
//This gets the previos color at a list wise address, wrapping around the bottom to the top.
Color ColorList::getLastColor(int address){
address--;
if (address != address % _sizeOfList){
address = address % _sizeOfList;
}
if (address < 0){
address+=_sizeOfList;
}
int red = pgm_read_word_near(_listPointer + address * 4);
int green = pgm_read_word_near(_listPointer + address * 4 + 1);
int blue = pgm_read_word_near(_listPointer + address * 4 + 2);
return Color(red,green,blue);
};
//This gets the next color in the list, wrapping around to the bottom from the top.
Color ColorList::getNextColor(int address){
address++;
if (address != address % _sizeOfList){
address = address % _sizeOfList;
}
int red = pgm_read_word_near(_listPointer + address * 4);
int green = pgm_read_word_near(_listPointer + address * 4 + 1);
int blue = pgm_read_word_near(_listPointer + address * 4 + 2);
return Color(red,green,blue);
};
//This gets the color delaytime + current time of the way along the color list
Color MasterColorList::getColorNow(int delayTime){
long currentTime = (millis() + delayTime) % getTotalTime();
int color;
for(color = 0;color < getNumberOfElements();color ++){
if(currentTime < getDelay(color)){
break;
};
currentTime = currentTime - getDelay(color);
};
Color colorAverage;
colorAverage.progressColor(getLastColor(color), getCurrentColor(color), float(currentTime) / float(getDelay(color)));
return colorAverage;
};
//This gets the color delaytime + current time of the way along the color list for the previous color list
Color MasterColorList::getLastColorNow(int delayTime){
long currentTime = (millis() + delayTime) % getLastTotalTime();
int color;
for(color = 0;color < getLastNumberOfElements();color ++){
if(currentTime < getLastDelay(color)){
break;
};
currentTime = currentTime - getLastDelay(color);
};
Color colorAverage;
colorAverage.progressColor(getLastLastColor(color), getLastCurrentColor(color), float(currentTime) / float(getLastDelay(color)));
return colorAverage;
};
/*
Color MasterColorList::getAverageTotalTime(){
return getTotalTime() * transitionRatio + getLastTotalTime() * (1 - transitionRatio);
};
*/
//This takes the last color (above) and the current color (above) offset for time and uses the transition to smoothly fade them
Color MasterColorList::getSmoothColorNow(int delayTime){
if(transitionRatio() == 1){
return getColorNow(delayTime);
}
Color colorAverage;
colorAverage.progressColor(getLastColorNow(delayTime), getColorNow(delayTime), transitionRatio());
return colorAverage;
};
//This returns the total time for the current color list
long MasterColorList::getTotalTime(){
return _listOfColorListsPointer[_currentList].totalTime;
};
//This returns the total time for the last color list
long MasterColorList::getLastTotalTime(){
return _listOfColorListsPointer[_lastList].totalTime;
};
//Here we have a big blog of flash data for the various lists.
//These each have red,green,blue and a delay per line
//They are then wrapped in Colorlists using sizeof for the size of the array.
PROGMEM prog_int16_t devilish_color_list[] = {
1023,0,0,2367,
1023,200,0,2367,
0,0,0,2367,
};
ColorList devilish_color(devilish_color_list,sizeof(devilish_color_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t minty_color_list[] = {
0,1023,1023,2367,
0,1023,0,2367,
0,0,1023,2367,
};
ColorList minty_color(minty_color_list,sizeof(minty_color_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t fire_color_list[] = {
1023,0,0,2367,
1023,300,0,2367,
1023,500,700,2367,
1023,0,300,2367,
};
ColorList fire_color(fire_color_list,sizeof(fire_color_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t ocean_color_list[] = {
0,1023,1023,2367,
0,1023,0,2367,
500,1023,0,2367,
0,0,1023,2367,
};
ColorList ocean_color(ocean_color_list,sizeof(ocean_color_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t cruise_color_list[] = {
1023,1023,0,2367,
1023,1023,1023,2367,
0,1023,1023,2367,
};
ColorList cruise_color(cruise_color_list,sizeof(cruise_color_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t slow_red_list[] = {
0,0,0,3187,
0,0,0,3187,
0,0,0,3187,
1023,0,0,3187,
1023,500,20,3187,
};
ColorList slow_red_color(slow_red_list,sizeof(slow_red_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t flamey_purple_list[] = {
1023,0,0,529,
0,0,0,529,
1023,0,529,
};
ColorList flamey_purple_color(flamey_purple_list,sizeof(flamey_purple_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t rave_bow_list[] = {
1023,0,0,11,
0,1023,0,11,
0,0,1023,11,
};
ColorList rave_bow_color(rave_bow_list,sizeof(rave_bow_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t glitter_list[] = {
1023,0,0,11,
0,0,0,1432,
0,0,0,1432,
0,0,0,1432,
1023,600,0,11,
0,0,0,1432,
0,0,0,1432,
0,0,0,1432,
600,0,1023,11,
0,0,0,1432,
0,0,0,1432,
0,0,0,1432,
};
ColorList glitter_color(glitter_list,sizeof(glitter_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t flash_list[] = {
1023,1023,1023,1,
0,0,0,1432,
0,0,0,1432,
0,0,0,1432,
};
ColorList flash_color(flash_list,sizeof(flash_list) / (sizeof(prog_int16_t) * 4));
PROGMEM prog_int16_t white_blink_list[] = {
1023,1023,1023,100,
0,0,0,100,
};
ColorList white_blink_color(white_blink_list,sizeof(white_blink_list) / (sizeof(prog_int16_t) * 4));
ColorList listOfColorLists[] = {devilish_color,minty_color,fire_color,ocean_color,cruise_color,slow_red_color, flamey_purple_color, rave_bow_color, glitter_color, white_blink_color};
//ColorList listOfColorLists[] = {devilish_color,flamey_purple_color,fire_color,slow_red_color};
//ColorList listOfColorLists[] = {fire_color,devilish_color,flamey_purple_color,flash_color};
//This is the object for the list of color lists.
MasterColorList::MasterColorList(int numberOfColorLists,ColorList* listOfColorListsPointer){
//This is how long it fades between color schemes
transitionTime = 1000;
//This keeps track of which color list we are on
_currentList = 0;
//This is the number of the last color list in the list of lists.
_lastList = numberOfColorLists - 1;
//This is the pointer to the list of lists.
_listOfColorListsPointer = listOfColorListsPointer;
//This is the total number of color lists.
_numberOfColorLists = numberOfColorLists;
};
//This gets the current delay returned by the current list at address
int MasterColorList::getDelay(int address){
return _listOfColorListsPointer[_currentList].getDelay(address);
};
//This gets the current delay returned by the previous list at address
int MasterColorList::getLastDelay(int address){
return _listOfColorListsPointer[_lastList].getDelay(address);
};
//This moves to the next color list, also starting the fading loop
//The fading loop works by setting transitionBegan
int MasterColorList::incrementList(){
_lastList = _currentList;
_currentList++;
if (_currentList >= _numberOfColorLists){
_currentList = 0;
}
transitionBegan = millis();
return _currentList;
};
int MasterColorList::pickList(int listIndex){
_lastList = _currentList;
_currentList = listIndex % _numberOfColorLists;
transitionBegan = millis();
return _currentList;
};
//This calculates how far along we are between color lists.
float MasterColorList::transitionRatio(){
long timeInTransition = millis() - transitionBegan;
float transitionRatio = float(timeInTransition) / float(transitionTime);
if(transitionRatio > 1){
transitionRatio = 1;
}
if(transitionRatio < 0){
transitionRatio = 0;
}
return transitionRatio;
};
//This returns the color for the current list at address
Color MasterColorList::getCurrentColor(int address){
return _listOfColorListsPointer[_currentList].getCurrentColor(address);
};
//This returns the color for the last list at address
Color MasterColorList::getLastColor(int address){
return _listOfColorListsPointer[_currentList].getLastColor(address);
};
//This gest the number of elements in the current list
int MasterColorList::getNumberOfElements(){
return _listOfColorListsPointer[_currentList].getNumberOfElements();
};
//This gets the current color at address for the last list in the masterlist list.
Color MasterColorList::getLastCurrentColor(int address){
return _listOfColorListsPointer[_lastList].getCurrentColor(address);
};
//This gets the last color at address for the last list in the masterlist list.
Color MasterColorList::getLastLastColor(int address){
return _listOfColorListsPointer[_lastList].getLastColor(address);
};
//This returns the number of elements in the previous color list.
int MasterColorList::getLastNumberOfElements(){
return _listOfColorListsPointer[_lastList].getNumberOfElements();
};
//This is the master color list, encapsulated in the master color list object.
MasterColorList masterColorList(sizeof(listOfColorLists) / sizeof(ColorList),listOfColorLists);