#include #include #include #include #include #include #include #include "hsluv.h" #define MIN(a,b) ((a)<=(b)?(a):(b)) #define MAX(a,b) ((a)>=(b)?(a):(b)) #define D2C(x) (int)MAX(0, MIN(0xff, x*256.0)) static int nothread = 0; static int noalpha = 1; static int pause; static QLock lck; static u16int s[256][2]; static ulong rgba2u(double *rgba) { return D2C(rgba[0])<<24 | D2C(rgba[1])<<16 | D2C(rgba[2])<<8 | D2C(rgba[3]); } static void reader(void *) { for(;;){ qlock(&lck); if(readn(0, s, sizeof(s)) < 0) sysfatal("%r"); qunlock(&lck); if(write(1, s, sizeof(s)) != sizeof(s)) sysfatal("%r"); } } static void redraw(void) { Rectangle r; int i, z, xoff, yoff; static ulong j, rgb, oldrgb; static float oldk, oldx, oldy, diff; static char t; Image *color; float k, x, y; j++; if(pause) return; if(nothread){ if(readn(0, s, sizeof(s)) < 0) sysfatal("%r"); if(write(1, s, sizeof(s)) != sizeof(s)) sysfatal("%r"); }else{ qlock(&lck); } k = 0; for(i = 0; i < nelem(s); i++){ k += abs(s[i][0])+abs(s[i][1]); } if(!nothread) qunlock(&lck); k /= 440*64.0; if(k < 1) k = 1; k = (oldk*7+k)/8; x = k - oldk; oldk = k; diff += MIN(1.0, x/10); float w = 1.0 + sin(0.1*diff); double RGB[3]; hsluv2rgb(MAX(0.0, MIN(360.0, 180.0*(w * fabs(cos(0.001*j))))), 50.0+30*w, MIN(100.0, 25+25*w), &RGB[0], &RGB[1], &RGB[2]); k = x*3; static double oRGB[3]; for(i = 0; i < 3; i++) RGB[i] = (oRGB[i]*3+RGB[i])/4.0; memmove(oRGB, RGB, sizeof(RGB)); rgb = rgba2u(RGB); if(!noalpha) rgb = setalpha(rgb, 40+w*127); color = allocimage(display, Rect(0,0,1,1), noalpha ? RGB24 : RGBA32, 1, rgb); t = '0'; //draw(screen, screen->r, display->white, nil, ZP); for(i = 0; i < nelem(s); i++){ x = s[i][0]; y = s[i][1]; x /= 64.0; y /= 64.0; z = sin(0.01*(x+y-oldx-oldy))*(cos(0.01*k))*256.0; x = (oldx*63+x)/64; y = (oldy*63+y)/64; oldx = x; oldy = y; x /= 4096/k + i/16+1; y /= 4096/k + i/16+1; t += (z/32)&7; t &= 0x7f; r = screen->r; r.min.x += Dx(r)/2 + 20*sin(nrand(MAX(1, j))); r.min.y += Dy(r)/2 + 20*cos(nrand(MAX(1, j))); icossin(0.01*j, &xoff, &yoff); if(k == 0.0) break; xoff *= sin(0.001*(sin(0.001*j)*z+k)); yoff *= cos(0.001*(sin(0.001*j)*z+k)); x += 10*sin(nrand(MAX(1, i))); y += 10*cos(nrand(MAX(1, i))); /* this is all absolutely random stuff that doesn't make any sense */ stringn(screen, addpt(r.min, Pt(k*sin(0.01*sin(0.001*(k+z))*(j+z))+x*(sin(yoff*0.01)+cos(xoff*0.04)), k*cos(0.01*cos(0.001*(k+j))*(j+z))+y*(sin(xoff*0.01)+cos(yoff*0.04)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*cos(0.02*cos(0.002*(k+z))*(j+z))+x*(cos(yoff*0.02)+sin(xoff*0.03)), k*sin(0.02*sin(0.002*(k+j))*(j+z))+y*(cos(xoff*0.02)+sin(yoff*0.03)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*cos(0.03*sin(0.003*(k+z))*(j+z))+x*(cos(yoff*0.03)+sin(xoff*0.02)), k*cos(0.03*sin(0.003*(k+j))*(j+z))+y*(cos(xoff*0.03)+sin(yoff*0.02)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*sin(0.04*cos(0.004*(k+z))*(j+z))+x*(cos(yoff*0.04)+sin(xoff*0.01)), k*sin(0.04*cos(0.004*(k+j))*(j+z))+y*(cos(xoff*0.04)+sin(yoff*0.01)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*sin(0.01*sin(0.001*(k+z))*(j+z))+x*(sin(yoff*0.01)+cos(xoff*0.04)), k*cos(0.01*cos(0.001*(k+j))*(j+z))+y*(sin(xoff*0.01)+cos(yoff*0.04)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*cos(0.02*cos(0.002*(k+z))*(j+z))+x*(cos(yoff*0.02)+sin(xoff*0.03)), k*sin(0.02*sin(0.002*(k+j))*(j+z))+y*(cos(xoff*0.02)+sin(yoff*0.03)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*cos(0.03*sin(0.003*(k+z))*(j+z))+x*(cos(yoff*0.03)+sin(xoff*0.02)), k*cos(0.03*sin(0.003*(k+j))*(j+z))+y*(cos(xoff*0.03)+sin(yoff*0.02)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*sin(0.04*cos(0.004*(k+z))*(j+z))+x*(cos(yoff*0.04)+sin(xoff*0.01)), k*sin(0.04*cos(0.004*(k+j))*(j+z))+y*(cos(xoff*0.04)+sin(yoff*0.01)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*sin(0.01*sin(0.001*(k+z))*(j+z))+x*(sin(yoff*0.01)+cos(xoff*0.04)), k*cos(0.01*cos(0.001*(k+j))*(j+z))+y*(sin(xoff*0.01)+cos(yoff*0.04)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*cos(0.02*cos(0.002*(k+z))*(j+z))+x*(cos(yoff*0.02)+sin(xoff*0.03)), k*sin(0.02*sin(0.002*(k+j))*(j+z))+y*(cos(xoff*0.02)+sin(yoff*0.03)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*sin(0.01*sin(0.001*(k+z))*(j+z))+x*(sin(yoff*0.01)+cos(xoff*0.04)), k*cos(0.01*cos(0.001*(k+j))*(j+z))+y*(sin(xoff*0.01)+cos(yoff*0.04)))), color, ZP, display->defaultfont, &t, 1); t++; stringn(screen, addpt(r.min, Pt(k*cos(0.02*cos(0.002*(k+z))*(j+z))+x*(cos(yoff*0.02)+sin(xoff*0.03)), k*sin(0.02*sin(0.002*(k+j))*(j+z))+y*(cos(xoff*0.02)+sin(yoff*0.03)))), color, ZP, display->defaultfont, &t, 1); t++; j = -j; } freeimage(color); flushimage(display, 1); } void threadmain(int argc, char **argv) { Mousectl *mctl; Keyboardctl *kctl; Mouse m; Rune key; Alt a[] = { { nil, &m, CHANRCV }, { nil, nil, CHANRCV }, { nil, &key, CHANRCV }, { nil, nil, CHANNOBLK }, }; USED(argc); USED(argv); setfcr(FPPDBL|FPRNR); if (initdraw(nil, nil, "glitch") < 0) sysfatal("initdraw: %r"); if ((mctl = initmouse(nil, screen)) == nil) sysfatal("initmouse: %r"); if ((kctl = initkeyboard(nil)) == nil) sysfatal("initkeyboard: %r"); a[0].c = mctl->c; a[1].c = mctl->resizec; a[2].c = kctl->c; if(!nothread) proccreate(reader, nil, 4096); pause = 0; for (;;) { redraw(); switch (alt(a)) { case 0: /* mouse */ break; case 1: /* resize */ getwindow(display, Refnone); break; case 2: /* keyboard */ switch (key) { case 'q': case Kdel: goto end; case 'p': pause = !pause; break; } break; } } end: threadexitsall(nil); }