/* from oneMobeIdea as...
I lost the random rotating R code
so. Randomly select a color and an orientation. render an R. delay. repeat.
*/
# define RMODE false // just show R on every mobe
// pin 12 - kluydgey "global" direction input
// now for a switch between any two of the LFSRs
const byte gDirection = 12;
# include <Adafruit_NeoPixel.h>
void advanceDB() {}
//void checkButtons(void);
unsigned char xIdx = 0;
// unsigned char transer MapIndex = 0; // which of thirty odd sprays. now hard wired, it only makes sense to display one mobe 'm'
# define SIXTYFOUR 64
unsigned char bits[SIXTYFOUR];
unsigned char result[SIXTYFOUR];
# define THIRTYODD 41 // 0..40
extern const unsigned char qTransMap[THIRTYODD][16];
//unsigned char qTransMap[2000][16] = {
/* kludge support */
/* always delay by anim, add pattern at phase 0 */
# define RATE 111 /* ten frames per second, defines quantum of speed */
# define NSPEEDS 5
struct {
int anim, pattern;
} speeds[5] = {
{333, 333},
{50, 280},
{0, 330}, {0, 220},
{400, 0},
};
/*
unsigned long standardColors[9] = {
0x000000, // 0 off-ish
0x000040, // 1 blue
0x400000, // 2 red
0x100018, // 3 magenta blued darken
0x004000, // 4 green
0x004040, // 5 cyan
0x404000, // 6 yellow
0x404040, // 7 whiter
0x060606,
};
unsigned long standardBackgroundColors[9] = {
0x000000, // 0 off-ish
0x000008, // 1 blue
0x080000, // 2 red
0x010002, // 3 magenta blued darken
0x002000, // 4 green
0x002020, // 5 cyan
0x202000, // 6 yellow
0x0404040, // 7 whiter
0x010101,
};
*/
unsigned long standardColors[9] = {
0x000000, // 0 off-ish
0x0000ff, // 1 blue
0xff0000, // 2 red
0x8000ff, // 3 magenta blued darken
0x00ff00, // 4 green
0x00ffff, // 5 cyan
0xffff00, // 6 yellow
0x808080, // 7 grey
0xe0e0e0, // 8 whiter
};
unsigned long standardBackgroundColors[9] = {
0x000000, // 0 off-ish
0x000008, // 1 blue
0x080000, // 2 red
0x010002, // 3 magenta blued darken
0x002000, // 4 green
0x002020, // 5 cyan
0x202000, // 6 yellow
0x0404040, // 7 whiter
0x010101,
};
typedef struct {
unsigned int shiftRegister; // initial contents
unsigned char qxform; // computed! Use xform 0 .. 7 and quadrant 0 .. 3 CCW NOT YET, just selected from a giant array
unsigned char color;
unsigned char xform, quadrant;
unsigned char speed;
unsigned char direction; // advance or reverse
} mobe;
//# define NMOBES 1
//# define ANMOBES 4
mobe theMobes[] = {
/*
{ 0x0020, 99, 8, 0, 0, 0, 1,},
{ 0x0020, 99, 8, 1, 1, 0, 1,},
{ 0x0020, 99, 8, 2, 2, 0, 1,},
{ 0x0020, 99, 8, 3, 3, 0, 1,},
{ 0x0020, 99, 8, 7, 0, 0, 1,},
{ 0x0020, 99, 8, 3, 1, 0, 1,},
{ 0x0020, 99, 8, 4, 2, 0, 1,},
{ 0x0020, 99, 8, 0, 3, 0, 1,},
{ 0x0020, 99, 2, 4, 0, 0, 0,},
{ 0x0020, 99, 2, 6, 1, 0, 0,},
{ 0x0020, 99, 2, 5, 2, 0, 0,},
{ 0x0020, 99, 2, 7, 3, 0, 0,},
*/
{ 0x0020, 99, 2, 1, 0, 0, 0,},
{ 0x0020, 99, 2, 0, 1, 0, 0,},
{ 0x0020, 99, 2, 3, 2, 0, 0,},
{ 0x0020, 99, 2, 2, 3, 0, 0,},
// { 0x0020, 38, 4, 0, 0, 0, 0,},
// { 0x0200, 37, 3,},
// { 0x0200, 35, 3,},
// { 0xaaaa, 10, 2,},
// { 0xaaaa, 17, 2,},
// { 0xaaaa, 15, 2,},
// { 0xaaaa, 29, 1,},
// { 0xaaaa, 29, 0, 0, 1,},
};
/*
mobe theMobes[NMOBES] = {
{ 0xaaaa, 0, 2,},
{ 0xaaaa, 29, 1,},
{ 0xaaaa, 18, 6,},
{ 0xaaaa, 15, 5,},
// { 0xaaaa, 29, 1,},
// { 0xaaaa, 29, 0, 0, 1,},
};
*/
const byte NMOBES = sizeof theMobes / sizeof *theMobes;
const byte ANMOBES = NMOBES;
unsigned char speedIndex;
bool kDirection; // true is forward
// unsigned int lamp; - sign propagation in shift NOT!
unsigned int lamp;
unsigned char nextBit; /* kludge for bit15 "next" value */
unsigned char animPhase; /* 0..3 */
unsigned char havent; /* kludge to slow animation at phase 0 */
unsigned char x4LEDs[68] = { /* 68 becuase we ran off/over impossible 16 2x2 LED clusters */
0, 1, 8, 9, 2, 3, 10, 11,
4, 5, 12, 13, 6, 7, 14, 15,
16, 17, 24, 25, 18, 19, 26, 27,
20, 21, 28, 29, 22, 23, 30, 31,
32, 33, 40, 41, 34, 35, 42, 43,
36, 37, 44, 45, 38, 39, 46, 47,
48, 49, 56, 57, 50, 51, 58, 59,
52, 53, 60, 61, 54, 55, 62, 63, 64, 64, 64, 64,
};
unsigned char fixedLamps[69] = { /* just so we can write bbbeyond the array */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1, 0, 1,
};
const unsigned char devMap[SIXTYFOUR] = {
0, 1, 2, 3, 16, 17, 18, 19,
7, 6, 5, 4, 23, 22, 21, 20,
8, 9, 10, 11, 24, 25, 26, 27,
15, 14, 13, 12, 31, 30, 29, 28,
32, 33, 34, 35, 48, 49, 50, 51,
39, 38, 37, 36, 55, 54, 53, 52,
40, 41, 42, 43, 56, 57, 58, 59,
47, 46, 45, 44, 63, 62, 61, 60,
};
extern const unsigned char transMap[8][64];
/*
const unsigned char rPentamino[64] = {
1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 0, 0, 1, 1, 1,
1, 1, 1, 0, 0, 1, 1, 1,
1, 1, 1, 0, 0, 1, 1, 1,
};
const unsigned char rPentamino[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 0, 0, 0,
0, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
*/
// this is a nice 5x7 'R'
const unsigned char r5X7[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 1, 1, 1, 0, 0, 0,
0, 1, 0, 1, 0, 0, 0, 0,
0, 1, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
};
// this is a nice 5x7 'F'
const unsigned char f5X7[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
};
/*
const unsigned char rPentamino[64] = {
0, 1, 1, 1, 1, 1, 0, 0,
0, 1, 1, 0, 0, 1, 1, 0,
0, 1, 1, 0, 0, 1, 1, 0,
0, 1, 1, 1, 1, 1, 0, 0,
0, 1, 1, 0, 1, 1, 0, 0,
0, 1, 1, 0, 0, 1, 1, 0,
0, 1, 1, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
*/
const unsigned char rPentamino[64];
unsigned char quadMap[16] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27,};
/* total shift and spray test */
/* 0 - four copies at same (no) flip or rotation */
void moberly0()
{
unsigned char ii;
int tLamp;
//... ad vance();
tLamp = lamp;
for (ii = 0; ii < 16; ii++) {
fixedLamps[quadMap[ii]] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 4] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 32] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 36] = tLamp & 0x1;
tLamp >>= 1;
}
}
void moberlyKk()
{
unsigned char ii;
int tLamp;
//... ad vance();
tLamp = lamp;
for (ii = 0; ii < 64; ii += 4) {
fixedLamps[x4LEDs[ii]] = tLamp & 0x1; // tLamp & 0x80;
fixedLamps[x4LEDs[ii + 1]] = tLamp & 0x1; // tLamp & 0x80;
fixedLamps[x4LEDs[ii + 2]] = tLamp & 0x1; // tLamp & 0x80;
fixedLamps[x4LEDs[ii + 3]] = tLamp & 0x1; // tLamp & 0x80;
tLamp >>= 1;
}
}
void moberlyID()
{
unsigned char ik;
static unsigned char did = 0;
if (!did) {
xform(rPentamino, fixedLamps, transMap[0]);
did = 1;
}
/* that's all folks, just a shape we can track */
}
/* gack! gigundakludge */
void moberly()
{
animPhase++; animPhase &= 0x3;
if (kDirection) moberlyF();
else moberlyR();
}
void moberlyF()
{
unsigned char ik, ii;
unsigned int tLamp;
// some one else does so
//(gDirection; animPhase &= 0x3;
if (!animPhase) advance();
tLamp = lamp;
for (ik = 0; ik <= 15; ik++, tLamp <<= 1) {
ii = (ik << 2) + animPhase;
fixedLamps[x4LEDs[ii]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 1]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 2]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 3]] = (tLamp & 0x8000) ? 1 : 0;
}
/* now fix up animPhase number of lamps into 2x2 pixel 0 */
switch (animPhase) {
case 3 :
fixedLamps[x4LEDs[2]] = nextBit;
case 2 :
fixedLamps[x4LEDs[1]] = nextBit;
case 1 :
fixedLamps[x4LEDs[0]] = nextBit;
case 0:
break;
}
}
void moberlyR()
{
unsigned char ik, ii;
unsigned int tLamp;
// some one else does so
// (gDirection; animPhase &= 0x3;
if (!animPhase) advance();
tLamp = lamp;
for (ik = 15; !(ik & 0x80); ik--, tLamp >>= 1) { /* not OK with ik 0, must fix */
ii = (ik << 2) + 3 - animPhase;
fixedLamps[x4LEDs[ii]] = (tLamp & 0x1) ? 1 : 0;
if (ii == 0) break;
fixedLamps[x4LEDs[ii - 1]] = (tLamp & 0x1) ? 1 : 0;
if ((ii - 1) == 0) break;
fixedLamps[x4LEDs[ii - 2]] = (tLamp & 0x1) ? 1 : 0;
if ((ii - 2) == 0) break;
fixedLamps[x4LEDs[ii - 3]] = (tLamp & 0x1) ? 1 : 0;
}
// nextBit = 1;
/* now fix up animPhase number of lamps into 2x2 pixel 15 */
switch (animPhase) {
case 3 :
fixedLamps[x4LEDs[61]] = nextBit;
case 2 :
fixedLamps[x4LEDs[62]] = nextBit;
case 1 :
fixedLamps[x4LEDs[63]] = nextBit;
case 0:
break;
}
}
void moberlyUK()
{
unsigned char ik, ii;
unsigned int tLamp;
// if (!animPhase)
//... ad vance();
tLamp = lamp;
for (ik = 0; ik <= 15; ik++, tLamp <<= 1) {
ii = (ik << 2);// + animPhase;
fixedLamps[x4LEDs[ii]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 1]] = 0;
fixedLamps[x4LEDs[ii + 2]] = 0;
fixedLamps[x4LEDs[ii + 3]] = 0;
/* fixedLamps[x4LEDs[ii + 1]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 2]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 3]] = (tLamp & 0x8000) ? 1 : 0;
*/
}
/* now fix up animPhase number of lamps into 2x2 pixel 0 */
/* switch (animPhase) {
case 3 :
fixedLamps[x4LEDs[2]] = nextBit;
case 2 :
fixedLamps[x4LEDs[1]] = nextBit;
case 1 :
fixedLamps[x4LEDs[0]] = nextBit;
case 0:
break;
}
*/
}
void moberlyDB()
{
unsigned char ik, ii;
unsigned int tLamp;
if (!animPhase);//... ad vance();
tLamp = lamp;
Serial.print(animPhase); Serial.println(" <- phase");
for (ik = 1; ik <= 15; ik++, tLamp <<= 1) {
ii = (ik << 2) + animPhase;
Serial.print(ik); Serial.print(" ik, so ");
Serial.print(ii); Serial.print(" filling "); Serial.println((tLamp & 0x8000) ? 1 : 0);
fixedLamps[x4LEDs[ii]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 1]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 2]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 3]] = (tLamp & 0x8000) ? 1 : 0;
}
fixedLamps[x4LEDs[animPhase]] = nextBit;
fixedLamps[x4LEDs[animPhase + 1]] = nextBit;
fixedLamps[x4LEDs[animPhase + 2]] = nextBit;
fixedLamps[x4LEDs[animPhase + 3]] = nextBit;
}
// void process() -> xform
void xform(unsigned char *from, unsigned char *to, unsigned char *map)
{
unsigned char ii;
ii = SIXTYFOUR;
do {
ii--;
to[map[ii]] = from[ii];
} while (ii);
}
# define PIN 6 /* my Hz pin */
# define NPIN 7 /* neopixel pin */
Adafruit_NeoPixel strip = Adafruit_NeoPixel(SIXTYFOUR, NPIN, NEO_GRB + NEO_KHZ800);
unsigned long roller;
unsigned char tog, uu;
void setup() {
Serial.begin(115200); Serial.println("rpentamino all in one QQ");
// mySerial.begin(9600);
smartLampSetup();
pinMode(PIN, OUTPUT);
roller = millis();
tog = 0;
uu = 0;
animPhase = 0; /* if we don't use it, it better is zero */
havent = 0;
speedIndex = 0;
lamp = 0x1840; /* well not zero pair, single anim test */
// lamp = 0x800; /* well not zero pair, single anim test */
kDirection = true; /* forward */
if (0) {
unsigned long tt = millis();
for (long int ii = 0; ii < 32767; ii++) {
//Serial.print('*');
//... ad vance();
}
tt = millis() - tt;
Serial.println(tt);
}
pinMode(gDirection, INPUT_PULLUP);
}
void smartLampSetup() {
strip.begin();
strip.setPixelColor(0, 0xff0000);
strip.setPixelColor(1, 0x00ff00);
strip.setPixelColor(2, 0x0000ff);
strip.setPixelColor(SIXTYFOUR - 1, 0x808080);
strip.show();
strip.clear();
delay(1777);
for (byte ii = 0; ii < SIXTYFOUR; ii++) strip.setPixelColor(ii, 0x030303);
}
const unsigned char uiTable[8][4] = {
{4, 2, 1, 7},
{5, 3, 0, 6},
{6, 0, 3, 5},
{7, 1, 2, 4},
{3, 5, 6, 0},
{2, 4, 7, 1},
{1, 7, 4, 2},
{0, 6, 5, 3}
};
void loop() {
static bool once;
if (!once) {
lamp = 0x4000;
once = true;
}
// mobesLoop();
checkButtons();
moberly();
xform(fixedLamps, result, transMap[xIdx]);
for (int ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, result[ik] ? 0xff0008 : 0x0);
strip.show();
int dFactor = potPeriod();
if (!animPhase) delay(dFactor);
else delay(75);
}
int potPeriod()
{
float t = analogRead(A0) / 1023.0;
float bpmx = 20.0 * pow(600.0 / 20.0, t);
float period_ms = 60000.0 / bpmx;
return period_ms + 0.5 - 2;;
}
void mobesLoop()
{
static unsigned long lastTick;
static int bpm;
unsigned long now = millis();
{
static bool once;
if (!once) once = initMobes();
}
if (lamp == 0x0c00) Serial.println(" 0x0c00");
// one chatGPT idea
float t = analogRead(A0) / 1023.0;
float bpmx = 20.0 * pow(600.0 / 20.0, t);
float period_ms = 60000.0 / bpmx;
bpm = period_ms + 0.5 - 2;
if (now - lastTick < bpm) return;
lastTick = now;
checkButtons();
displayMobes();
// delay(300); // kludge 4 now
}
// simple UI test
void loop_UITest()
{
/*
static unsigned long lastTime;
unsigned long tempTime;
if ((tempTime = millis()) - lastTime < RATE) return;
lastTime = tempTime;
*/
uiLoop(); /* charlie never returns */
checkButtons();
}
/* called at RATE, see? */
void realLoop()
{
static unsigned int counter;
unsigned long tempTime;
checkButtons();
displayMobes();
/*
Serial.print(counter); counter++;
Serial.print(" ");
Serial.print(theMobes[0].shiftRegister);
Serial.print(" ");
tempTime = micros();
Serial.print(micros() - tempTime);
Serial.println("");
*/
}
/*
void loopAint() {
/ moberlyID();
xform(fixedLamps, result, transMap[xIdx]);
for (int ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, result[ik] ? 0x040008 : 0x0);
strip.show();
/
checkButtons();
// uiLoop();
loopIS();
// delay(100);
}
*/
void loopIS()/*was*/
{
unsigned char ik;
static unsigned char fork = 17;
digitalWrite(PIN, HIGH);
gDirection; animPhase &= 0x3;
// animPhase = 0;
moberlyUK(); // or whatever advancmenter
//moberly0();
/* final transform and disply */
xform(fixedLamps, result, transMap[xIdx]);
for (ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, result[ik] ? 0x480000 : 0x0);
strip.show();
// delay(166); /* kludge */
if (!animPhase) delay(88); /* kludge */
else delay(8);
if (!animPhase && !--fork) {
delay(2600);
fork = 13;
}
/* for RTOS */
digitalWrite(PIN, LOW);
}
void loopRPenta()
{
static unsigned char kfactor = 0;
digitalWrite(PIN, HIGH);
/* final transform and disply */
// xIdx = random(8);
unsigned long fgv = standardColors[random(9)];
unsigned long bgv = standardBackgroundColors[random(9)];
xform(rPentamino, result, transMap[xIdx]);
for (unsigned char ik = 0; ik < 64; ik++) {
switch (kfactor) {
case 0 :
strip.setPixelColor(ik, result[ik] ? 0xff0000 : 0);
break;
case 1 :
strip.setPixelColor(ik, result[ik] ? 0 : 0xff0000);
break;
case 2 :
strip.setPixelColor(ik, result[ik] ? 0x0000ff : 0);
break;
case 3 :
strip.setPixelColor(ik, result[ik] ? 0 : 0x0000ff);
break;
}
}
kfactor++; kfactor &= 0x3;
strip.show();
delay(1450); /* kludge */
xIdx++; xIdx &= 0x7; /* next transformation */
/* for RTOS */
digitalWrite(PIN, LOW);
}
// strip.setPixelColor(ik, result[ik] ? fgv : bgv); // : 0); // 0x122008);
// switch (random(1024) & 0x3) {
void loopRPenta0()
{
digitalWrite(PIN, HIGH);
/* final transform and disply */
xIdx = random(8);
unsigned long fgv = standardColors[random(9)];
unsigned long bgv = standardBackgroundColors[random(9)];
xform(rPentamino, result, transMap[xIdx]);
for (unsigned char ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, result[ik] ? fgv : bgv); // : 0); // 0x122008);
strip.show();
delay(1450); /* kludge */
xIdx++; xIdx &= 0x7; /* next transformation */
/* for RTOS */
digitalWrite(PIN, LOW);
}
/* first cut at a <G>UI */
void uiLoop()
{
unsigned char ik;
static unsigned long timer;
unsigned long temp;
if ((temp = millis()) - timer < 50) return;
timer = temp;
digitalWrite(PIN, HIGH);
xform(kDirection ? f5X7 : r5X7, result, transMap[xIdx]);
for (ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, result[ik] ? 0xc00060 : 0x0);
strip.show();
/* for RTOS */
digitalWrite(PIN, LOW);
}
/* advance with (attempted)real reverse */
/* waht about the IFM505s? */
/* UGH! */
void advance() {
// advanceDB();
advanceNORM();
}
void advanceNORM() // NewWIP()
{
if (kDirection) { // forward
lamp >>= 1;
if (lamp & 1)
if (lamp & 2) lamp &= 0x7fff;
else lamp |= 0x8000;
else if (lamp & 2) lamp |= 0x8000;
else lamp &= 0x7fff;
/* precalculate next bit for anim fixup */
if (lamp & 2)
if (lamp & 4) nextBit = 0;
else nextBit = 1;
else if (lamp & 4) nextBit = 1;
else nextBit = 0;
}
else { // reverse
lamp <<= 1; lamp &= 0xffff;
// Serial.println("true reverse");
if (lamp & 0x8000)
if (lamp & 2) lamp &= ~1;
else lamp |= 1;
else if (lamp & 2) lamp |= 1;
else lamp &= ~1;
/* precalculate next bit for anim fixup */
if (lamp & 0x4000)
if (lamp & 1) nextBit = 0;
else nextBit = 1;
else if (lamp & 1) nextBit = 1;
else nextBit = 0;
}
}
void advanceMobe(unsigned char mobeIdx)
{
unsigned int lamp;
Serial.println(" advancing...");
// UI test. Just draw the r pentamino in the grid
if (RMODE) {
theMobes[mobeIdx].shiftRegister = 0x6c4;
return;
}
lamp = theMobes[mobeIdx].shiftRegister;
// if (digitalRead(gDirection) == HIGH) lamp = advanceK16(lamp);
// else lamp = reverseK16(lamp);
kDirection = digitalRead(gDirection) == HIGH;
advanceNORM(); // 15 bit; true <-> ?
/*
if (digitalRead(gDirection) == HIGH)
lamp = advance16_2(lamp);
else // reverse or alternate LFSR
lamp = advanceB(lamp);
*/
theMobes[mobeIdx].shiftRegister = lamp;
}
bool initMobes()
{
for (unsigned char ii = 0; ii < NMOBES; ii++)
theMobes[ii].qxform = (theMobes[ii].xform << 2) + theMobes[ii].quadrant;
return true;
}
/* transfer a 4x4 onto the 8x8 display array, now indexing color transMap[*/
void injectMobe(unsigned char mobeIdx)
{
unsigned int lamp = theMobes[mobeIdx].shiftRegister;
// hard core, will be proper one map demo / dev
for (int ii = 0; ii < 16; ii++, lamp <<= 1)
result[qTransMap[ theMobes[mobeIdx].qxform ][ii]] = lamp & 0x8000 ? theMobes[mobeIdx].color : 0x305030;
// result[qTransMap[ transer MapIndex ][ii]] = lamp & 0x8000 ? theMobes[mobeIdx].color : 0x305030;
}
void displayMobes()
{
for (unsigned char ii = 0; ii < NMOBES; ii++)
injectMobe(ii);
for (unsigned char ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, standardColors[result[ik]]);
/* just now, advance them here */
for (unsigned char ii = 0; ii < NMOBES; ii++)
advanceMobe(ii);
strip.show();
}
unsigned int advance16_2(unsigned int it)
{
bool msb = it & (1ul << 15);
it <<= 1;
if (msb)
it ^= 0x002Du;
return it;
}
unsigned int advanceB(unsigned int it)
{
bool msb = it & (1 << 14);
it <<= 1;
if (msb)
it ^= 0x3;
return it;
}
/*
if (0) {
static int counter;
Serial.print(counter + 1000); Serial.print(" ");
counter++;
unsigned int the = it & 0xffff;
Serial.println(the, HEX);
}
}
*/
// GLOBAL LAMP DOH
void mobe16()
{
if (digitalRead(gDirection) == HIGH) lamp = advanceK16(lamp);
else lamp = reverseK16(lamp);
}
unsigned int advanceK16(unsigned int it)
{
unsigned int bits = it & 0xb400;
bool parity = false;
while (bits) {
bits &= bits - 1;
parity = !parity;
}
it <<= 1;
if (parity) it |= 0x1;
return it;
}
unsigned int reverseK16(unsigned int it)
{
unsigned int bits = it & 0x5a1;
bool parity = false;
while (bits) {
bits &= bits - 1;
parity = !parity;
}
it >>= 1;
if (parity) it |= 0x8000;
return it;
}
void checkButtons()
{
int theChar;
/*
if (Serial.available())
theChar = Serial.read();
else if (!mySerial.available()) return;
else theChar = mySerial.read();
*/
if (!Serial.available()) return;
theChar = Serial.read();
bool disposed = true;
/* kludge to slow action down, real kludge. make it a better,er, kludge */
// delay(70);
switch (theChar) {
case '1' : case 'a' :
Serial.println(" clock ");
xIdx = uiTable[xIdx][0];
break;
case '2' : case 'b' :
Serial.println(" horizontal ");
xIdx = uiTable[xIdx][1];
break;
case '3' : case 'c' :
Serial.println(" vertical ");
xIdx = uiTable[xIdx][2];
break;
case '4' : case 'd' :
Serial.println(" anti-clock ");
xIdx = uiTable[xIdx][3];
break;
case '6' : case 'r' :
Serial.println(" reset ");
lamp = 0x100; /* one pixel in the middle */
//theMobes[0].shiftRegister = 0x0200; //... sue me
kDirection = true; /* in the traditional forward mode */
break;
case '5' : case 's' :
Serial.println(" speed ");
if (++speedIndex >= NSPEEDS) speedIndex = 0;
break;
case '0' :
Serial.println(" + ");
xIdx += 1; xIdx &= 0x7;
break;
case '7' :
Serial.println(" direction ");
kDirection = !kDirection;
break;
case '9' :
Serial.println(" - ");
xIdx -= 1; xIdx &= 0x7;
break;
/*
case 'm' :
transer MapIndex++;
if (transer MapIndex >= THIRTYODD) transer MapIndex = 0;
for (byte ii = 0; ii < SIXTYFOUR; ii++) strip.setPixelColor(ii, 0x030303);
for (byte ii = 0; ii < SIXTYFOUR; ii++) result[ii] = 0;
theMobes[0].shiftRegister = 0x0200;
break;
case 'n' :
if (transer MapIndex > 0) transer MapIndex--;
else transer MapIndex = THIRTYODD - 1;
// can't? missed deleting this if (transer MapIndex >= THIRTYODD) transer MapIndex = 0;
for (byte ii = 0; ii < SIXTYFOUR; ii++) strip.setPixelColor(ii, 0x030303);
for (byte ii = 0; ii < SIXTYFOUR; ii++) result[ii] = 0;
theMobes[0].shiftRegister = 0x0200;
break;
*/
default :
//Serial.println(" ? ");
disposed = false; // right? so no need to say more
break;
}
if (disposed) {
Serial.print("Transform "); Serial.println(xIdx);
Serial.print(xIdx & 0x4 ? "rotate " : " ");
Serial.print(xIdx & 0x2 ? "h-flip " : " ");
Serial.print(xIdx & 0x1 ? "v-flip " : " ");
// Serial.print(""); Serial.println(transer MapIndex);
Serial.println(""); Serial.println("");
}
}
const unsigned char qTransMap[THIRTYODD][16] = {
// 0. X0 is
{
0, 1, 2, 3,
8, 9, 10, 11,
16, 17, 18, 19,
24, 25, 26, 27,
},
// 1. X1 is
{
32, 33, 34, 35,
40, 41, 42, 43,
48, 49, 50, 51,
56, 57, 58, 59,
},
// 2. X2 is
{
4, 5, 6, 7,
12, 13, 14, 15,
20, 21, 22, 23,
28, 29, 30, 31,
},
// 3. X3 is
{
36, 37, 38, 39,
44, 45, 46, 47,
52, 53, 54, 55,
60, 61, 62, 63,
},
// 4. vX0 is
{
24, 25, 26, 27,
16, 17, 18, 19,
8, 9, 10, 11,
0, 1, 2, 3,
},
// 5. vX1 is
{
56, 57, 58, 59,
48, 49, 50, 51,
40, 41, 42, 43,
32, 33, 34, 35,
},
// 6. vX2 is
{
28, 29, 30, 31,
20, 21, 22, 23,
12, 13, 14, 15,
4, 5, 6, 7,
},
// 7. vX3 is
{
60, 61, 62, 63,
52, 53, 54, 55,
44, 45, 46, 47,
36, 37, 38, 39,
},
// 8. hX0 is
{
3, 2, 1, 0,
11, 10, 9, 8,
19, 18, 17, 16,
27, 26, 25, 24,
},
// 9. hX1 is
{
35, 34, 33, 32,
43, 42, 41, 40,
51, 50, 49, 48,
59, 58, 57, 56,
},
// 10. hX2 is
{
7, 6, 5, 4,
15, 14, 13, 12,
23, 22, 21, 20,
31, 30, 29, 28,
},
// 11. hX3 is
{
39, 38, 37, 36,
47, 46, 45, 44,
55, 54, 53, 52,
63, 62, 61, 60,
},
// 12. vhX0 is
{
27, 26, 25, 24,
19, 18, 17, 16,
11, 10, 9, 8,
3, 2, 1, 0,
},
// 13. vhX1 is
{
59, 58, 57, 56,
51, 50, 49, 48,
43, 42, 41, 40,
35, 34, 33, 32,
},
// 14. vhX2 is
{
31, 30, 29, 28,
23, 22, 21, 20,
15, 14, 13, 12,
7, 6, 5, 4,
},
// 15. vhX3 is
{
63, 62, 61, 60,
55, 54, 53, 52,
47, 46, 45, 44,
39, 38, 37, 36,
},
// 16. rX0 is
{
3, 11, 19, 27,
2, 10, 18, 26,
1, 9, 17, 25,
0, 8, 16, 24,
},
// 17. rX1 is
{
35, 43, 51, 59,
34, 42, 50, 58,
33, 41, 49, 57,
32, 40, 48, 56,
},
// 18. rX2 is
{
7, 15, 23, 31,
6, 14, 22, 30,
5, 13, 21, 29,
4, 12, 20, 28,
},
// 19. rX3 is
{
39, 47, 55, 63,
38, 46, 54, 62,
37, 45, 53, 61,
36, 44, 52, 60,
},
// 20. vrX0 is
{
0, 8, 16, 24,
1, 9, 17, 25,
2, 10, 18, 26,
3, 11, 19, 27,
},
// 21. vrX1 is
{
32, 40, 48, 56,
33, 41, 49, 57,
34, 42, 50, 58,
35, 43, 51, 59,
},
// 22. vrX2 is
{
4, 12, 20, 28,
5, 13, 21, 29,
6, 14, 22, 30,
7, 15, 23, 31,
},
// 23. vrX3 is
{
36, 44, 52, 60,
37, 45, 53, 61,
38, 46, 54, 62,
39, 47, 55, 63,
},
// 24. hrX0 is
{
27, 19, 11, 3,
26, 18, 10, 2,
25, 17, 9, 1,
24, 16, 8, 0,
},
// 25. hrX1 is
{
59, 51, 43, 35,
58, 50, 42, 34,
57, 49, 41, 33,
56, 48, 40, 32,
},
// 26. hrX2 is
{
31, 23, 15, 7,
30, 22, 14, 6,
29, 21, 13, 5,
28, 20, 12, 4,
},
// 27. hrX3 is
{
63, 55, 47, 39,
62, 54, 46, 38,
61, 53, 45, 37,
60, 52, 44, 36,
},
// 28. vhrX0 is
{
24, 16, 8, 0,
25, 17, 9, 1,
26, 18, 10, 2,
27, 19, 11, 3,
},
// 29. vhrX1 is
{
56, 48, 40, 32,
57, 49, 41, 33,
58, 50, 42, 34,
59, 51, 43, 35,
},
// 30. vhrX2 is
{
28, 20, 12, 4,
29, 21, 13, 5,
30, 22, 14, 6,
31, 23, 15, 7,
},
// 31. vhrX3 is
{
60, 52, 44, 36,
61, 53, 45, 37,
62, 54, 46, 38,
63, 55, 47, 39,
},
// 32. WILD ONE OFFS
{
27, 28, 36, 35, 34, 26, 18, 19, 20, 21, 29, 37, 45, 44, 43, 42,
},
// 33. WILD ONE OFFS
{
0, 1, 9, 8, 6, 7, 15, 14, 48, 49, 57, 56, 54, 55, 63, 62,
},
// 34. WILD ONE OFFS
{
2, 3, 4, 5, 10, 11, 12, 13, 50, 51, 52, 53, 58, 59, 60, 61,
},
// 35. WILD ONE OFFS
{
16, 24, 32, 40, 17, 25, 33, 41, 22, 30, 38, 46, 23, 31, 39, 47
},
// these are all 0..63 into 4 random 16 LED packs
{ 2, 11, 26, 28, 32, 34, 38, 40, 41, 43, 51, 53, 54, 55, 56, 62,}, // 36
{ 3, 4, 7, 12, 13, 15, 16, 23, 25, 30, 33, 35, 42, 44, 45, 49,}, // 37
{ 1, 6, 8, 9, 21, 22, 29, 36, 37, 39, 46, 47, 59, 60, 61, 63,}, // 38
{0, 5, 10, 14, 17, 18, 19, 20, 24, 27, 31, 48, 50, 52, 57, 58,}, // 39
// 40. just stretch a 4x4 onto the 8x8
{9, 11, 13, 15, 25, 27, 29, 31, 41, 43, 45, 47, 57, 59, 61, 63,},
};
const unsigned char transMap[8][64] = {
{
0, 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,
},
{
56, 57, 58, 59, 60, 61, 62, 63,
48, 49, 50, 51, 52, 53, 54, 55,
40, 41, 42, 43, 44, 45, 46, 47,
32, 33, 34, 35, 36, 37, 38, 39,
24, 25, 26, 27, 28, 29, 30, 31,
16, 17, 18, 19, 20, 21, 22, 23,
8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7,
},
{
7, 6, 5, 4, 3, 2, 1, 0,
15, 14, 13, 12, 11, 10, 9, 8,
23, 22, 21, 20, 19, 18, 17, 16,
31, 30, 29, 28, 27, 26, 25, 24,
39, 38, 37, 36, 35, 34, 33, 32,
47, 46, 45, 44, 43, 42, 41, 40,
55, 54, 53, 52, 51, 50, 49, 48,
63, 62, 61, 60, 59, 58, 57, 56,
},
{
63, 62, 61, 60, 59, 58, 57, 56,
55, 54, 53, 52, 51, 50, 49, 48,
47, 46, 45, 44, 43, 42, 41, 40,
39, 38, 37, 36, 35, 34, 33, 32,
31, 30, 29, 28, 27, 26, 25, 24,
23, 22, 21, 20, 19, 18, 17, 16,
15, 14, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1, 0,
},
{
7, 15, 23, 31, 39, 47, 55, 63,
6, 14, 22, 30, 38, 46, 54, 62,
5, 13, 21, 29, 37, 45, 53, 61,
4, 12, 20, 28, 36, 44, 52, 60,
3, 11, 19, 27, 35, 43, 51, 59,
2, 10, 18, 26, 34, 42, 50, 58,
1, 9, 17, 25, 33, 41, 49, 57,
0, 8, 16, 24, 32, 40, 48, 56,
},
{
0, 8, 16, 24, 32, 40, 48, 56,
1, 9, 17, 25, 33, 41, 49, 57,
2, 10, 18, 26, 34, 42, 50, 58,
3, 11, 19, 27, 35, 43, 51, 59,
4, 12, 20, 28, 36, 44, 52, 60,
5, 13, 21, 29, 37, 45, 53, 61,
6, 14, 22, 30, 38, 46, 54, 62,
7, 15, 23, 31, 39, 47, 55, 63,
},
{
63, 55, 47, 39, 31, 23, 15, 7,
62, 54, 46, 38, 30, 22, 14, 6,
61, 53, 45, 37, 29, 21, 13, 5,
60, 52, 44, 36, 28, 20, 12, 4,
59, 51, 43, 35, 27, 19, 11, 3,
58, 50, 42, 34, 26, 18, 10, 2,
57, 49, 41, 33, 25, 17, 9, 1,
56, 48, 40, 32, 24, 16, 8, 0,
},
{
56, 48, 40, 32, 24, 16, 8, 0,
57, 49, 41, 33, 25, 17, 9, 1,
58, 50, 42, 34, 26, 18, 10, 2,
59, 51, 43, 35, 27, 19, 11, 3,
60, 52, 44, 36, 28, 20, 12, 4,
61, 53, 45, 37, 29, 21, 13, 5,
62, 54, 46, 38, 30, 22, 14, 6,
63, 55, 47, 39, 31, 23, 15, 7,
},
};