Add GRITTY mode
This commit is contained in:
parent
f37e0a1a63
commit
0c463c87bf
3 changed files with 2245 additions and 28 deletions
|
|
@ -6,12 +6,12 @@
|
||||||
#include <Adafruit_ST7735.h>
|
#include <Adafruit_ST7735.h>
|
||||||
#include <Adafruit_ZeroDMA.h>
|
#include <Adafruit_ZeroDMA.h>
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
//#include "gritty.h"
|
||||||
|
|
||||||
#define G_SCALE 40.0 // Accel scale; no science, just looks good
|
#define G_SCALE 40.0 // Accel scale; no science, just looks good
|
||||||
#define ELASTICITY 0.80 // Edge-bounce coefficient (MUST be <1.0!)
|
#define ELASTICITY 0.80 // Edge-bounce coefficient (MUST be <1.0!)
|
||||||
#define DRAG 0.996 // Dampens motion slightly
|
#define DRAG 0.996 // Dampens motion slightly
|
||||||
|
|
||||||
#define EYE_RADIUS 64.0 // Radius of eye, floating-point pixel units
|
|
||||||
#define PUPIL_RADIUS (PUPIL_SIZE / 2.0) // Radius of pupil, same units
|
#define PUPIL_RADIUS (PUPIL_SIZE / 2.0) // Radius of pupil, same units
|
||||||
// Pupil motion is computed as a single point constrained within a circle
|
// Pupil motion is computed as a single point constrained within a circle
|
||||||
// whose radius is the eye radius minus the pupil radius.
|
// whose radius is the eye radius minus the pupil radius.
|
||||||
|
|
@ -61,7 +61,6 @@ void setup(void) {
|
||||||
tft.fillScreen(0);
|
tft.fillScreen(0);
|
||||||
|
|
||||||
pinMode(TFT_BACKLIGHT, OUTPUT);
|
pinMode(TFT_BACKLIGHT, OUTPUT);
|
||||||
analogWriteResolution(8);
|
|
||||||
|
|
||||||
if(accel.begin(0x18) || accel.begin(0x19)) {
|
if(accel.begin(0x18) || accel.begin(0x19)) {
|
||||||
accel.setRange(LIS3DH_RANGE_8_G);
|
accel.setRange(LIS3DH_RANGE_8_G);
|
||||||
|
|
@ -112,7 +111,7 @@ void setup(void) {
|
||||||
false); // increment dest addr?
|
false); // increment dest addr?
|
||||||
dma.setCallback(dma_callback);
|
dma.setCallback(dma_callback);
|
||||||
|
|
||||||
analogWrite(TFT_BACKLIGHT, 255);
|
digitalWrite(TFT_BACKLIGHT, HIGH);
|
||||||
lastTime = micros();
|
lastTime = micros();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,11 +233,11 @@ void loop(void) {
|
||||||
vyNew = ry * mag1;
|
vyNew = ry * mag1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x1, y1, x2, y2, // Bounding rect of screen update area
|
int x1, y1, x2, y2, // Bounding rect of screen update area
|
||||||
px1 = 64 + (int)xNew - 24, // Bounding rect of new pupil pos. only
|
px1 = 64 + (int)xNew - PUPIL_SIZE / 2, // Bounding rect of new pupil pos. only
|
||||||
px2 = 64 + (int)xNew + 23,
|
px2 = 64 + (int)xNew + PUPIL_SIZE / 2 - 1,
|
||||||
py1 = 64 - (int)yNew - 24,
|
py1 = 64 - (int)yNew - PUPIL_SIZE / 2,
|
||||||
py2 = 64 - (int)yNew + 23;
|
py2 = 64 - (int)yNew + PUPIL_SIZE / 2 - 1;
|
||||||
|
|
||||||
if(firstFrame) {
|
if(firstFrame) {
|
||||||
x1 = y1 = 0;
|
x1 = y1 = 0;
|
||||||
|
|
@ -246,18 +245,18 @@ void loop(void) {
|
||||||
firstFrame = false;
|
firstFrame = false;
|
||||||
} else {
|
} else {
|
||||||
if(xNew >= x) { // Moving right
|
if(xNew >= x) { // Moving right
|
||||||
x1 = 64 + (int)x - 24;
|
x1 = 64 + (int)x - PUPIL_SIZE / 2;
|
||||||
x2 = 64 + (int)xNew + 23;
|
x2 = 64 + (int)xNew + PUPIL_SIZE / 2 - 1;
|
||||||
} else { // Moving left
|
} else { // Moving left
|
||||||
x1 = 64 + (int)xNew - 24;
|
x1 = 64 + (int)xNew - PUPIL_SIZE / 2;
|
||||||
x2 = 64 + (int)x + 23;
|
x2 = 64 + (int)x + PUPIL_SIZE / 2 - 1;
|
||||||
}
|
}
|
||||||
if(yNew >= y) { // Moving up (still using +Y Cartesian coords)
|
if(yNew >= y) { // Moving up (still using +Y Cartesian coords)
|
||||||
y1 = 64 - (int)yNew - 24;
|
y1 = 64 - (int)yNew - PUPIL_SIZE / 2;
|
||||||
y2 = 64 - (int)y + 23;
|
y2 = 64 - (int)y + PUPIL_SIZE / 2 - 1;
|
||||||
} else { // Moving down
|
} else { // Moving down
|
||||||
y1 = 64 - (int)y - 24;
|
y1 = 64 - (int)y - PUPIL_SIZE / 2;
|
||||||
y2 = 64 - (int)yNew + 23;
|
y2 = 64 - (int)yNew + PUPIL_SIZE / 2 - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,15 +279,74 @@ void loop(void) {
|
||||||
digitalWrite(TFT_DC, HIGH); // Data mode...
|
digitalWrite(TFT_DC, HIGH); // Data mode...
|
||||||
|
|
||||||
uint16_t *dmaPtr; // Pointer into DMA output buffer (16 bits/pixel)
|
uint16_t *dmaPtr; // Pointer into DMA output buffer (16 bits/pixel)
|
||||||
uint8_t *srcPtr1, // Pointer into eye background bitmap (8bpp)
|
uint8_t col, row; // X,Y pixel counters
|
||||||
*srcPtr2, // Pointer into pupil bitmap (8bpp)
|
|
||||||
b, // Resulting pixel brightness (0-255)
|
|
||||||
col, row; // X,Y pixel counters
|
|
||||||
uint16_t result, // Expanded 16-bit pixel color
|
uint16_t result, // Expanded 16-bit pixel color
|
||||||
nBytes; // Size of DMA transfer
|
nBytes; // Size of DMA transfer
|
||||||
|
|
||||||
descriptor->BTCNT.reg = nBytes = (x2 - x1 + 1) * 2;
|
descriptor->BTCNT.reg = nBytes = (x2 - x1 + 1) * 2;
|
||||||
|
|
||||||
|
#ifdef COLOR_EYE
|
||||||
|
uint16_t *srcPtr1, // Pointer into eye background bitmap (16bpp)
|
||||||
|
*srcPtr2, // Pointer into pupil bitmap (16bpp)
|
||||||
|
rgb1, rgb2; // Colors of above
|
||||||
|
uint8_t red1, green1, blue1, // Color components
|
||||||
|
red2, green2, blue2;
|
||||||
|
|
||||||
|
// Process rows ABOVE pupil
|
||||||
|
for(row=y1; row<py1; row++) {
|
||||||
|
dmaPtr = &dmaBuf[dmaIdx][0];
|
||||||
|
srcPtr1 = (uint16_t *)&borderData[row][x1];
|
||||||
|
for(col=x1; col<=x2; col++) {
|
||||||
|
*dmaPtr++ = __builtin_bswap16(*srcPtr1++);
|
||||||
|
}
|
||||||
|
dmaXfer(nBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process rows WITH pupil
|
||||||
|
for(; row<=py2; row++) {
|
||||||
|
dmaPtr = &dmaBuf[dmaIdx][0]; // Output to start of DMA buf
|
||||||
|
srcPtr1 = (uint16_t *)&borderData[row][x1]; // Initial byte of eye border
|
||||||
|
srcPtr2 = (uint16_t *)&pupilData[row-py1][0]; // Initial byte of pupil
|
||||||
|
for(col=x1; col<px1; col++) { // LEFT of pupil
|
||||||
|
*dmaPtr++ = __builtin_bswap16(*srcPtr1++);
|
||||||
|
}
|
||||||
|
for(; col<=px2; col++) { // Overlap pupil
|
||||||
|
rgb1 = *srcPtr1++;
|
||||||
|
rgb2 = *srcPtr2++;
|
||||||
|
red1 = rgb1 >> 11; // 5 bits red
|
||||||
|
green1 = (rgb1 >> 5) & 0x3F; // 6 bits green
|
||||||
|
blue1 = rgb1 & 0x1F; // 5 bits blue
|
||||||
|
red2 = rgb2 >> 11;
|
||||||
|
green2 = (rgb2 >> 5) & 0x3F;
|
||||||
|
blue2 = rgb2 & 0x1F;
|
||||||
|
red1 = (red1 * (red2 + 1)) / 32; // Multiply each
|
||||||
|
green1 = (green1 * (green2 + 1)) / 64;
|
||||||
|
blue1 = (blue1 * (blue2 + 1)) / 32;
|
||||||
|
rgb1 = ((uint16_t)red1 << 11) | ((uint16_t)green1 << 5) | blue1;
|
||||||
|
*dmaPtr++ = __builtin_bswap16(rgb1);
|
||||||
|
}
|
||||||
|
for(; col<=x2; col++) { // RIGHT of pupil
|
||||||
|
*dmaPtr++ = __builtin_bswap16(*srcPtr1++);
|
||||||
|
}
|
||||||
|
dmaXfer(nBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process rows BELOW pupil
|
||||||
|
for(; row<=y2; row++) {
|
||||||
|
dmaPtr = &dmaBuf[dmaIdx][0];
|
||||||
|
srcPtr1 = (uint16_t *)&borderData[row][x1];
|
||||||
|
for(col=x1; col<=x2; col++) {
|
||||||
|
*dmaPtr++ = __builtin_bswap16(*srcPtr1++);
|
||||||
|
}
|
||||||
|
dmaXfer(nBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // Grayscale eye
|
||||||
|
|
||||||
|
uint8_t *srcPtr1, // Pointer into eye background bitmap (8bpp)
|
||||||
|
*srcPtr2, // Pointer into pupil bitmap (8bpp)
|
||||||
|
b; // Resulting pixel brightness (0-255)
|
||||||
|
|
||||||
// Macro converts 8-bit grayscale to 16-bit '565' RGB value
|
// Macro converts 8-bit grayscale to 16-bit '565' RGB value
|
||||||
#define STORE565(x) \
|
#define STORE565(x) \
|
||||||
result = (((x * 0x801) >> 3) & 0xF81F) | ((x & 0xFC) << 3); \
|
result = (((x * 0x801) >> 3) & 0xF81F) | ((x & 0xFC) << 3); \
|
||||||
|
|
@ -297,7 +355,7 @@ void loop(void) {
|
||||||
// Process rows ABOVE pupil
|
// Process rows ABOVE pupil
|
||||||
for(row=y1; row<py1; row++) {
|
for(row=y1; row<py1; row++) {
|
||||||
dmaPtr = &dmaBuf[dmaIdx][0];
|
dmaPtr = &dmaBuf[dmaIdx][0];
|
||||||
srcPtr1 = &borderData[row][x1];
|
srcPtr1 = (uint8_t *)&borderData[row][x1];
|
||||||
for(col=x1; col<=x2; col++) {
|
for(col=x1; col<=x2; col++) {
|
||||||
b = *srcPtr1++;
|
b = *srcPtr1++;
|
||||||
STORE565(b)
|
STORE565(b)
|
||||||
|
|
@ -307,10 +365,10 @@ void loop(void) {
|
||||||
|
|
||||||
// Process rows WITH pupil
|
// Process rows WITH pupil
|
||||||
for(; row<=py2; row++) {
|
for(; row<=py2; row++) {
|
||||||
dmaPtr = &dmaBuf[dmaIdx][0]; // Output to start of DMA buf
|
dmaPtr = &dmaBuf[dmaIdx][0]; // Output to start of DMA buf
|
||||||
srcPtr1 = &borderData[row][x1]; // Initial byte of eye border
|
srcPtr1 = (uint8_t *)&borderData[row][x1]; // Initial byte of eye border
|
||||||
srcPtr2 = &pupilData[row-py1][0]; // Initial byte of pupil
|
srcPtr2 = (uint8_t *)&pupilData[row-py1][0]; // Initial byte of pupil
|
||||||
for(col=x1; col<px1; col++) { // LEFT of pupil
|
for(col=x1; col<px1; col++) { // LEFT of pupil
|
||||||
b = *srcPtr1++;
|
b = *srcPtr1++;
|
||||||
STORE565(b)
|
STORE565(b)
|
||||||
}
|
}
|
||||||
|
|
@ -328,7 +386,7 @@ void loop(void) {
|
||||||
// Process rows BELOW pupil
|
// Process rows BELOW pupil
|
||||||
for(; row<=y2; row++) {
|
for(; row<=y2; row++) {
|
||||||
dmaPtr = &dmaBuf[dmaIdx][0];
|
dmaPtr = &dmaBuf[dmaIdx][0];
|
||||||
srcPtr1 = &borderData[row][x1];
|
srcPtr1 = (uint8_t *)&borderData[row][x1];
|
||||||
for(col=x1; col<=x2; col++) {
|
for(col=x1; col<=x2; col++) {
|
||||||
b = *srcPtr1++;
|
b = *srcPtr1++;
|
||||||
STORE565(b)
|
STORE565(b)
|
||||||
|
|
@ -336,6 +394,8 @@ void loop(void) {
|
||||||
dmaXfer(nBytes);
|
dmaXfer(nBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // !COLOR_EYE
|
||||||
|
|
||||||
while(dma_busy); // Wait for last DMA transfer to complete
|
while(dma_busy); // Wait for last DMA transfer to complete
|
||||||
digitalWrite(TFT_CS, HIGH); // Deselect
|
digitalWrite(TFT_CS, HIGH); // Deselect
|
||||||
SPI.endTransaction(); // SPI done
|
SPI.endTransaction(); // SPI done
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
uint8_t borderData[128][128] = {
|
#define EYE_RADIUS 64.0 // Radius of eye, floating-point pixel units
|
||||||
|
|
||||||
|
const uint8_t borderData[128][128] = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
@ -1368,7 +1370,7 @@ uint8_t borderData[128][128] = {
|
||||||
|
|
||||||
#define PUPIL_SIZE 48
|
#define PUPIL_SIZE 48
|
||||||
|
|
||||||
uint8_t pupilData[PUPIL_SIZE][PUPIL_SIZE] = {
|
const uint8_t pupilData[PUPIL_SIZE][PUPIL_SIZE] = {
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x9E, 0x72, 0x4C, 0x2E, 0x16, 0x07,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x9E, 0x72, 0x4C, 0x2E, 0x16, 0x07,
|
||||||
0x07, 0x16, 0x2E, 0x4C, 0x72, 0x9E, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x07, 0x16, 0x2E, 0x4C, 0x72, 0x9E, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
|
|
||||||
2155
Hallowing_Googly_Eye/gritty.h
Normal file
2155
Hallowing_Googly_Eye/gritty.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue