summaryrefslogtreecommitdiffstats
path: root/hacks/binaryring.c
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/binaryring.c')
-rw-r--r--hacks/binaryring.c589
1 files changed, 0 insertions, 589 deletions
diff --git a/hacks/binaryring.c b/hacks/binaryring.c
deleted file mode 100644
index 755a1b4..0000000
--- a/hacks/binaryring.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Binary Ring
- * Copyright (c) 2006-2014 Emilio Del Tessandoro <emilio.deltessa@gmail.com>
- *
- * Directly ported code from complexification.net Binary Ring art
- * http://www.complexification.net/gallery/machines/binaryRing/appletm/BinaryRing_m.pde
- *
- * Binary Ring code:
- * j.tarbell June, 2004
- * Albuquerque, New Mexico
- * complexification.net
- *
- * Directly based the hacks of:
- *
- * xscreensaver, Copyright (c) 1997, 1998, 2002 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-
-#include "screenhack.h"
-#include "colors.h"
-#include "hsv.h"
-
-#define ANTIALIAS 1
-#define BLACK 0
-#define WHITE 1
-
-#define swap(a, b) do { __typeof__(a) tmp; tmp = a; a = b; b = tmp; } while(0)
-#define frand1() ((((int) random() ) << 1) * 4.65661287524579692411E-10)
-#define min(a,b) ((a)<(b)?(a):(b))
-#define max(a,b) ((a)>(b)?(a):(b))
-
-/* better if signed */
-typedef unsigned long pixel_t;
-
-
-typedef struct {
- float x, y;
- float xx, yy;
- float vx, vy;
- float color;
- int age; /* age from 0 to ageMax */
-} particle_t;
-
-
-struct state {
- int epoch;
- int growth_delay;
- int ring_radius;
- int max_age;
- float curliness;
- int particles_number;
- particle_t* particles;
-
-
- Display *display; /* variables for the X stuff */
- Window window;
- GC gc;
- XGCValues gcv;
- Visual* visual;
- int depth;
-
- int width;
- int height;
-
- Pixmap pix; /* for reshape */
- XImage* buf; /* buffer */
- pixel_t* buffer;
- pixel_t colors[2];
-
- Bool color;
-};
-
-
-
-static void point2rgb(int depth, pixel_t c, int *r, int *g, int *b)
-{
- switch(depth) {
- case 32:
- case 24:
-#ifdef HAVE_JWXYZ
- /* This program idiotically does not go through a color map, so
- we have to hardcode in knowledge of how jwxyz.a packs pixels!
- Fix it to go through st->colors[st->ncolors] instead!
- */
- *r = (c & 0x00ff0000) >> 16;
- *g = (c & 0x0000ffff) >> 8;
- *b = (c & 0x000000ff);
-#else
- *g = (c & 0xff00) >> 8;
- *r = (c & 0xff0000) >> 16;
- *b = c & 0xff;
-#endif
- break;
- case 16:
- *g = ((c >> 5) & 0x3f) << 2;
- *r = ((c >> 11) & 0x1f) << 3;
- *b = (c & 0x1f) << 3;
- break;
- case 15:
- *g = ((c >> 5) & 0x1f) << 3;
- *r = ((c >> 10) & 0x1f) << 3;
- *b = (c & 0x1f) << 3;
- break;
- }
-}
-
-static pixel_t rgb2point(int depth, int r, int g, int b)
-{
- pixel_t ret = 0;
-
- switch(depth) {
- case 32:
- case 24:
-#ifdef HAVE_JWXYZ
- /* This program idiotically does not go through a color map, so
- we have to hardcode in knowledge of how jwxyz.a packs pixels!
- Fix it to go through st->colors[st->ncolors] instead!
- */
- ret = 0xFF000000 | (r << 16) | (g << 8) | b;
-#else
- ret |= (r << 16) | (g << 8) | b;
-#endif
- break;
- case 16:
- ret = ((r>>3) << 11) | ((g>>2)<<5) | (b>>3);
- break;
- case 15:
- ret = ((r>>3) << 10) | ((g>>3)<<5) | (b>>3);
- break;
- }
-
- return ret;
-}
-
-void print_color ( struct state* st, pixel_t color );
-/* alpha blended point drawing -- this is Not Right and will likely fail on
- * non-intel platforms as it is now, needs fixing
- */
-
-static
-void draw_point ( struct state* st,
- int x, int y, pixel_t myc, float a ) {
-
- int or = 0, og = 0, ob = 0;
- int r = 0, g = 0, b = 0;
- int nr, ng, nb;
- register pixel_t c;
-
- /*or = st->buffer[ 3 * ( y * st->width + x ) + 0 ];
- og = st->buffer[ 3 * ( y * st->width + x ) + 1 ];
- ob = st->buffer[ 3 * ( y * st->width + x ) + 2 ];*/
-
- c = st->buffer[ y * st->width + x ];
- point2rgb( st->depth, c, &or, &og, &ob );
- point2rgb( st->depth, myc, &r, &g, &b );
-
- nr = or + (r - or) * a;
- ng = og + (g - og) * a;
- nb = ob + (b - ob) * a;
-
- /*st->buffer[ 3 * ( y * st->width + x ) + 0 ] = nr;
- st->buffer[ 3 * ( y * st->width + x ) + 1 ] = ng;
- st->buffer[ 3 * ( y * st->width + x ) + 2 ] = nb;*/
- c = rgb2point(st->depth, nr, ng, nb);
- st->buffer[ y * st->width + x ] = c;
-
- XPutPixel( st->buf, x, y, c );
-}
-
-
-
-
-void print_color ( struct state* st, pixel_t color ) {
- int r=0, g=0, b=0;
- point2rgb(st->depth, color, &r, &g, &b);
- printf( "%d %d %d\n", r, g, b);
-}
-
-
-
-#if ANTIALIAS
-#define plot_(X,Y,D) do{ \
- _dla_plot(st, (X), (Y), color, (D) * alpha); }while(0)
-
-static
-void _dla_plot(struct state* st, int x, int y, pixel_t col, float br)
-{
- if ( ( x >= 0 && x < st->width ) && ( y >= 0 && y < st->height ) ) {
- if ( br > 1.0f ) br = 1.0f;
- draw_point( st, x, y, col, br );
- }
-}
-
-#define ipart_(X) ((int)(X))
-#define round_(X) ((int)(((float)(X))+0.5))
-#define fpart_(X) (((float)(X))-(float)ipart_(X))
-#define rfpart_(X) (1.0-fpart_(X))
-
-static
-void draw_line_antialias(
- struct state* st,
- int x1, int y1,
- int x2, int y2,
- pixel_t color, float alpha )
-{
- float dx = (float)x2 - (float)x1;
- float dy = (float)y2 - (float)y1;
- float gradient;
- float xend;
- float yend;
- float xgap;
- float ygap;
- int xpxl1;
- int ypxl1;
- float intery;
- float interx;
- int xpxl2;
- int ypxl2;
- int x;
- int y;
-
- /* hard clipping, because this routine has some problems with negative coordinates */
- /* TODO: fix the alpha for that boundary cases. Using fabs() could solve? */
- if ( ( x1 < 0 || x1 > st->width ) ||
- ( x2 < 0 || x2 > st->width ) ||
- ( y1 < 0 || y1 > st->height ) ||
- ( y2 < 0 || y2 > st->height ) )
- return;
-
- if ( fabs(dx) > fabs(dy) ) {
- if ( x2 < x1 ) {
- swap(x1, x2);
- swap(y1, y2);
- }
- gradient = dy / dx;
- xend = round_(x1);
- yend = y1 + gradient*(xend - x1);
- xgap = rfpart_(x1 + 0.5);
- xpxl1 = xend;
- ypxl1 = ipart_(yend);
- plot_(xpxl1, ypxl1, rfpart_(yend)*xgap);
- plot_(xpxl1, ypxl1+1, fpart_(yend)*xgap);
- intery = yend + gradient;
-
- xend = round_(x2);
- yend = y2 + gradient*(xend - x2);
- xgap = fpart_(x2+0.5);
- xpxl2 = xend;
- ypxl2 = ipart_(yend);
- plot_(xpxl2, ypxl2, rfpart_(yend) * xgap);
- plot_(xpxl2, ypxl2 + 1, fpart_(yend) * xgap);
-
- /*if ( rfpart_(yend) * xgap < 0 || fpart_(yend) * xgap < 0)
- printf("%f %f\n", rfpart_(yend) * xgap, fpart_(yend) * xgap);*/
- for(x=xpxl1+1; x <= (xpxl2-1); x++) {
- plot_(x, ipart_(intery), rfpart_(intery));
- plot_(x, ipart_(intery) + 1, fpart_(intery));
- /*if ( rfpart_(intery) < 0 || fpart_(intery) < 0)
- printf("%f %f\n", rfpart_(intery), fpart_(intery));*/
- intery += gradient;
- }
- } else {
- if ( y2 < y1 ) {
- swap(x1, x2);
- swap(y1, y2);
- }
- gradient = dx / dy;
- yend = round_(y1);
- xend = x1 + gradient*(yend - y1);
- ygap = rfpart_(y1 + 0.5);
- ypxl1 = yend;
- xpxl1 = ipart_(xend);
- plot_(xpxl1, ypxl1, rfpart_(xend)*ygap);
- plot_(xpxl1, ypxl1+1, fpart_(xend)*ygap);
- interx = xend + gradient;
-
- yend = round_(y2);
- xend = x2 + gradient*(yend - y2);
- ygap = fpart_(y2+0.5);
- ypxl2 = yend;
- xpxl2 = ipart_(xend);
- plot_(xpxl2, ypxl2, rfpart_(xend) * ygap);
- plot_(xpxl2, ypxl2 + 1, fpart_(xend) * ygap);
-
- for(y=ypxl1+1; y <= (ypxl2-1); y++) {
- plot_(ipart_(interx), y, rfpart_(interx));
- plot_(ipart_(interx) + 1, y, fpart_(interx));
- interx += gradient;
- }
- }
-}
-#undef plot_
-#undef ipart_
-#undef fpart_
-#undef round_
-#undef rfpart_
-
-#else
-
-static
-void draw_line ( struct state* st, int x0, int y0, int x1, int y1, int color, float a ) {
- register int steep;
- register int deltax;
- register int deltay;
- register int error;
- register int ystep;
- register int y;
- register int x;
-
-
- steep = abs ( y1 - y0 ) > abs ( x1 - x0 );
- if ( steep ) { swap(x0,y0); swap(x1,y1); }
- if ( x0 > x1 ) { swap(x0,x1); swap(y0,y1); }
- deltax = x1 - x0;
- deltay = abs(y1-y0);
- error = 0;
- y = y0;
- ystep = y0 < y1 ? 1 : -1;
- if ( a > 1.0f ) a = 1.0f;
-
- for ( x = x0; x < x1; x++ ) {
- if ( steep ) {
- if ( ( y >= 0 && y < st->width ) && ( x >= 0 && x < st->height ) )
- draw_point( st, y, x, color, a );
- } else {
- if ( ( x >= 0 && x < st->width ) && ( y >= 0 && y < st->height ) )
- draw_point( st, x, y, color, a );
- }
- error += deltay;
- if ( ( error << 1 ) > deltax ) {
- y += ystep;
- error -= deltax;
- }
- }
-}
-#endif
-
-static void create_buffers ( struct state* st, Display* display, Screen* screen, Window window, GC gc ) {
-
- XWindowAttributes xgwa;
- XGetWindowAttributes( display, window, &xgwa );
-
- /* Initialize the pixmap */
- if ( st->buf != NULL ) XFreePixmap( display, st->pix );
-
- XSetForeground( display, gc, st->colors[BLACK] );
- st->pix = XCreatePixmap( display, window, st->width, st->height,
- xgwa.depth );
- XFillRectangle( display, st->pix, gc, 0, 0, st->width, st->height);
-
- /* Initialize the bitmap */
- if ( st->buf != NULL ) XDestroyImage ( st->buf );
- st->buf = XGetImage( display, st->pix, 0, 0, st->width, st->height, visual_depth(screen, st->visual), ZPixmap );
- st->buffer = (pixel_t*) calloc(sizeof(pixel_t), st->width * st->height);
- /*int i;
- for ( i = 0; i < st->width * st->height; ++i ) st->buffer[i] = st->colors[BLACK];*/
-}
-
-static void init_particle ( particle_t* p, float dx, float dy, float direction, int color, int max_age ) {
- float max_initial_velocity = 2.0f;
- p->x = -dx;
- p->y = -dy;
- p->xx = 0;
- p->yy = 0;
- p->vx = max_initial_velocity * cos(direction);
- p->vy = max_initial_velocity * sin(direction);
-
- p->age = random() % max_age;
-
- p->color = color;
-}
-
-static void clamp ( int* value, int l, int h ) {
- if ( *value < l ) *value = l;
- if ( *value > h ) *value = h;
-}
-
-static pixel_t next_color ( struct state* st, pixel_t current ) {
- int r=0, g=0, b=0;
-
- point2rgb(st->depth, current, &r, &g, &b);
- r += random() % 5 - 2;
- g += random() % 5 - 2;
- b += random() % 5 - 2;
- clamp(&r, 0, 255);
- clamp(&g, 0, 255);
- clamp(&b, 0, 255);
-
- return rgb2point( st->depth, r, g, b );
-}
-
-
-static void create_particles ( struct state* st ) {
- int i;
- float emitx, emity;
- float direction;
-
- for ( i = 0; i < st->particles_number; i++ ) {
- emitx = ( st->ring_radius * sinf( M_PI * 2 * ( (float) i / st->particles_number ) ) );
- emity = ( st->ring_radius * cosf( M_PI * 2 * ( (float) i / st->particles_number ) ) );
- direction = (M_PI * i) / st->particles_number;
-
- if ( st->epoch == WHITE && st->color )
- st->colors[WHITE] = next_color(st, st->colors[WHITE]);
-
- init_particle(st->particles + i, emitx, emity, direction, st->colors[WHITE], st->max_age);
- }
-}
-
-
-/* randomly move one particle and draw it */
-static void move ( particle_t* p, struct state * st ) {
- int w = st->width / 2;
- int h = st->height / 2;
- float max_dv = 1.0f;
-
- p->xx = p->x;
- p->yy = p->y;
- p->x += p->vx;
- p->y += p->vy;
- p->vx += frand1() * st->curliness * max_dv;
- p->vy += frand1() * st->curliness * max_dv;
-
-
-#if ANTIALIAS
- draw_line_antialias( st,
- w+p->xx, h+p->yy, w+p->x, h+p->y, p->color, 0.15 );
- draw_line_antialias( st,
- w-p->xx, h+p->yy, w-p->x, h+p->y, p->color, 0.15 );
-#else
- draw_line( st, w+p->xx, h+p->yy, w+p->x, h+p->y, p->color, 0.15 );
- draw_line( st, w-p->xx, h+p->yy, w-p->x, h+p->y, p->color, 0.15 );
-#endif
-
- p->age++;
- /* if this is too old, die and reborn */
- if ( p->age > st->max_age ) {
- float dir = frand1() * 2 * M_PI;
- p->x = st->ring_radius * sin(dir);
- p->y = st->ring_radius * cos(dir);
- p->xx = p->yy = p->vx = p->vy = 0;
- p->age = 0;
-
- if ( st->epoch == WHITE && st->color )
- st->colors[WHITE] = next_color(st, st->colors[WHITE] );
-
- p->color = st->colors[st->epoch];
- }
-}
-
-
-
-
-/* Initialize Everything */
-static void* binaryring_init ( Display* display, Window window ) {
- XWindowAttributes xgwa;
-
- struct state *st = ( struct state* ) calloc ( 1, sizeof( *st ) );
-
- XGetWindowAttributes( display, window, &xgwa );
-
- st->epoch = WHITE;
- st->display = display;
- st->window = window;
- st->particles_number = (get_integer_resource(st->display, "particles_number", "Integer"));
- st->growth_delay = (get_integer_resource(st->display, "growth_delay", "Integer"));
- st->ring_radius = (get_integer_resource(st->display, "ring_radius", "Integer"));
- st->max_age = (get_integer_resource(st->display, "max_age", "Integer"));
- st->color = get_boolean_resource(st->display, "color", "Boolean");
- st->height = xgwa.height;
- st->width = xgwa.width;
- st->visual = xgwa.visual;
- st->curliness = 0.5;
-
-
- st->depth = visual_depth(xgwa.screen, st->visual);
- st->colors[0] = rgb2point(st->depth, 0, 0, 0);
- st->colors[1] = rgb2point(st->depth, 255, 255, 255);
-
- /*describe_visual (stdout, xgwa.screen, xgwa.visual, False);*/
-
- st->particles = malloc (st->particles_number * sizeof( particle_t ) );
- create_particles ( st );
-
- st->gc = XCreateGC( st->display, st->window, 0, &st->gcv );
- create_buffers ( st, display, xgwa.screen, window, st->gc );
-
-
- return st;
-}
-
-
-static unsigned long binaryring_draw ( Display* display, Window win, void *closure ) {
- struct state *st = (struct state *) closure;
- int i;
-
- for ( i = 0; i < st->particles_number; i++ )
- move( &(st->particles[i]), st );
-
- /* draw the XImage in the Pixmap and the put the Pixmap on the screen */
- XPutImage( display, st->pix, st->gc, st->buf, 0, 0, 0, 0, st->width, st->height);
- XCopyArea( display, st->pix, win, st->gc, 0, 0, st->width, st->height, 0, 0 );
-
- /* randomly switch ageColor periods */
- if ( random() % 10000 > 9950 )
- st->epoch = (st->epoch == WHITE) ? BLACK : WHITE;
-
- return st->growth_delay;
-}
-
-
-
-static void binaryring_reshape ( Display* display, Window win, void *closure, unsigned int w, unsigned int h ) {
- struct state *st = (struct state *) closure;
-
- XWindowAttributes tmp;
- XGetWindowAttributes(display, win, &tmp);
-
- if ( tmp.height != st->height || tmp.width != st->width ) {
- st->height = tmp.height;
- st->width = tmp.width;
-
-
- st->epoch = WHITE;
- create_particles ( st );
-
- create_buffers ( st, display, tmp.screen, win, st->gc );
- }
-}
-
-
-/* if someone press a key switch the color */
-static Bool binaryring_event ( Display* display, Window win, void *closure, XEvent* event ) {
- struct state *st = (struct state *) closure;
-
- if ( (*event).xany.type == KeyPress ) {
- st->epoch = (st->epoch == WHITE) ? BLACK : WHITE;
- }
-
- return False;
-}
-
-
-/* delete everything */
-static void binaryring_free ( Display* display, Window win, void *closure ) {
- struct state *st = (struct state *) closure;
- XWindowAttributes tmp;
- XGetWindowAttributes(display, win, &tmp);
-
- if (st->gc) XFreeGC (display, st->gc);
- if (st->pix) XFreePixmap (display, st->pix);
- if (st->buf) XDestroyImage (st->buf);
- free (st->buffer);
- free (st->particles);
- free (st);
-}
-
-
-/* Default resources of the program */
-static const char* binaryring_defaults [] = {
- ".background: black",
- ".foreground: white",
- "*growth_delay: 10000",
- "*particles_number: 5000",
- "*ring_radius: 40",
- "*max_age: 400",
- "*color: True",
- "*ignoreRotation: True",
- 0
-};
-
-static XrmOptionDescRec binaryring_options [] = {
- { "-particles-number", ".particles_number", XrmoptionSepArg, 0 },
- { "-growth-delay", ".growth_delay", XrmoptionSepArg, 0 },
- { "-ring-radius", ".ring_radius", XrmoptionSepArg, 0 },
- { "-max-age", ".max_age", XrmoptionSepArg, 0 },
- { "-color", ".color", XrmoptionNoArg, "True" },
- { "-no-color", ".color", XrmoptionNoArg, "False" },
- { 0, 0, 0, 0}
-};
-
-XSCREENSAVER_MODULE("BinaryRing", binaryring)