X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fdistort.c;h=7eed6281c8b9c4d3ecef180c77956506ae080fd9;hb=c31d10b6605cd8dc1a7b61fef4256f06198767e5;hp=a18df51bc598dd5948957b6fa4538b8ce8543293;hpb=ce3185de9d9705e259f2b60dd4b5509007fa17d4;p=xscreensaver diff --git a/hacks/distort.c b/hacks/distort.c index a18df51b..7eed6281 100644 --- a/hacks/distort.c +++ b/hacks/distort.c @@ -41,11 +41,12 @@ struct coo { }; static struct coo xy_coo[10]; -static int delay, radius, speed, number, blackhole, vortex, magnify; +static int delay, radius, speed, number, blackhole, vortex, magnify, reflect; static XWindowAttributes xgwa; static GC gc; static Window g_window; -static Display *g_dpy; +static Display *g_dpy; +static unsigned long black_pixel; static XImage *orig_map, *buffer_map; @@ -56,6 +57,9 @@ static void move_lense(int); static void swamp_thing(int); static void new_rnd_coo(int); static void init_round_lense(void); +static void (*draw) (int) = NULL; +static void reflect_draw(int); +static void plain_draw(int); static void init_distort(Display *dpy, Window window) { @@ -66,10 +70,10 @@ static void init_distort(Display *dpy, Window window) g_window=window; g_dpy=dpy; - delay = get_integer_resource ("delay", "Integer"); - radius = get_integer_resource ("radius", "Integer"); - speed = get_integer_resource ("speed", "Integer"); - number = get_integer_resource ("number", "Integer"); + delay = get_integer_resource("delay", "Integer"); + radius = get_integer_resource("radius", "Integer"); + speed = get_integer_resource("speed", "Integer"); + number = get_integer_resource("number", "Integer"); #ifdef HAVE_XSHM_EXTENSION use_shm = get_boolean_resource("useSHM", "Boolean"); @@ -78,14 +82,15 @@ static void init_distort(Display *dpy, Window window) blackhole = get_boolean_resource("blackhole", "Boolean"); vortex = get_boolean_resource("vortex", "Boolean"); magnify = get_boolean_resource("magnify", "Boolean"); + reflect = get_boolean_resource("reflect", "Boolean"); - if (get_boolean_resource ("swamp", "Boolean")) + if (get_boolean_resource("swamp", "Boolean")) effect = &swamp_thing; - if (get_boolean_resource ("bounce", "Boolean")) + if (get_boolean_resource("bounce", "Boolean")) effect = &move_lense; if (effect == NULL && radius == 0 && speed == 0 && number == 0 - && !blackhole && !vortex && !magnify) { + && !blackhole && !vortex && !magnify && !reflect) { /* if no cmdline options are given, randomly choose one of: * -radius 50 -number 4 -speed 1 -bounce * -radius 50 -number 4 -speed 1 -blackhole @@ -102,9 +107,13 @@ static void init_distort(Display *dpy, Window window) * -radius 50 -number 4 -speed 2 -swamp -vortex * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify * -radius 50 -number 4 -speed 2 -swamp -vortex -magnify -blackhole + * -radius 80 -number 1 -speed 2 -reflect + * -radius 50 -number 3 -speed 2 -reflect */ - i = (random() % 15); + i = (random() % 17); + + draw = &plain_draw; switch (i) { case 0: @@ -149,9 +158,15 @@ static void init_distort(Display *dpy, Window window) case 13: radius=50;number=4;speed=2;vortex=1;magnify=1; effect=&swamp_thing;break; - case 14: default: + case 14: radius=50;number=4;speed=2;vortex=1;magnify=1;blackhole=1; effect=&swamp_thing;break; + case 15: + radius=80;number=1;speed=2;reflect=1; + draw = &reflect_draw;effect = &move_lense;break; + case 16: default: + radius=50;number=4;speed=2;reflect=1; + draw = &reflect_draw;effect = &move_lense;break; } } @@ -168,8 +183,15 @@ static void init_distort(Display *dpy, Window window) number=1; if (effect == NULL) effect = &move_lense; + if (reflect) { + draw = &reflect_draw; + effect = &move_lense; + } + if (draw == NULL) + draw = &plain_draw; XGetWindowAttributes (dpy, window, &xgwa); + black_pixel = BlackPixelOfScreen( xgwa.screen ); gcv.function = GXcopy; gcv.subwindow_mode = IncludeInferiors; @@ -245,7 +267,10 @@ static void make_round_lense(int radius, int loop) for(j = 0; j < 2*radius+speed+2; j++) { double r, d; r = sqrt ((i-radius)*(i-radius)+(j-radius)*(j-radius)); - d=r/loop; + if (loop == 0) + d=0.0; + else + d=r/loop; if (r < loop-1) { @@ -256,13 +281,18 @@ static void make_round_lense(int radius, int loop) * Copyright (C) 1996 Federico Mena Quintero */ /* 2.5 is just a constant used because it looks good :) */ - angle = 2.5*(1-r/loop)*(1-r/loop); - - from[i][j][0] = radius + cos(angle - - atan2(radius-j,-(radius-i)))*r; - from[i][j][1] = radius + sin(angle - - atan2(radius-j,-(radius-i)))*r; - + angle = 2.5*(1-d)*(1-d); + + /* Avoid atan2: DOMAIN error message */ + if ((radius-j) == 0.0 && (radius-i) == 0.0) { + from[i][j][0] = radius + cos(angle)*r; + from[i][j][1] = radius + sin(angle)*r; + } else { + from[i][j][0] = radius + + cos(angle - atan2(radius-j, -(radius-i)))*r; + from[i][j][1] = radius + + sin(angle - atan2(radius-j, -(radius-i)))*r; + } if (magnify) { r = sin(d*M_PI_2); if (blackhole && r != 0) /* blackhole effect */ @@ -277,7 +307,7 @@ static void make_round_lense(int radius, int loop) * distortion, a negative value sucks everything into a black hole */ /* r = r*r; */ - if (blackhole) /* blackhole effect */ + if (blackhole && r != 0) /* blackhole effect */ r = 1/r; /* bubble effect (and blackhole) */ from[i][j][0] = radius + (i-radius)*r; @@ -291,6 +321,10 @@ static void make_round_lense(int radius, int loop) } } +#ifndef EXIT_FAILURE +# define EXIT_FAILURE -1 +#endif + static void allocate_lense(void) { int i, j; @@ -343,7 +377,7 @@ static void init_round_lense(void) /* generate an XImage of from[][][] and draw it on the screen */ -void draw(int k) +void plain_draw(int k) { int i, j; for(i = 0 ; i < 2*radius+speed+2; i++) { @@ -363,6 +397,55 @@ void draw(int k) 2*radius+speed+2, 2*radius+speed+2); } +/* generate an XImage from the reflect algoritm submitted by + * Randy Zack + * draw really got too big and ugly so I split it up + * it should be possible to use the from[][] to speed it up + * (once I figure out the algorithm used :) + */ +void reflect_draw(int k) +{ + int i, j; + int cx, cy; + int ly, lysq, lx, ny, dist, rsq = radius * radius; + + cx = cy = radius; + if (xy_coo[k].ymove > 0) + cy += speed; + if (xy_coo[k].xmove > 0) + cx += speed; + + for(i = 0 ; i < 2*radius+speed+2; i++) { + ly = i - cy; + lysq = ly * ly; + ny = xy_coo[k].y + i; + for(j = 0 ; j < 2*radius+speed+2 ; j++) { + lx = j - cx; + dist = lx * lx + lysq; + if (dist > rsq || + ly < -radius || ly > radius || + lx < -radius || lx > radius) + XPutPixel( buffer_map, j, i, + XGetPixel( orig_map, xy_coo[k].x + j, ny )); + else if (dist == 0) + XPutPixel( buffer_map, j, i, black_pixel ); + else { + int x = xy_coo[k].x + cx + (lx * rsq / dist); + int y = xy_coo[k].y + cy + (ly * rsq / dist); + if (x < 0 || x > xgwa.width || + y < 0 || y > xgwa.height) + XPutPixel( buffer_map, j, i, black_pixel ); + else + XPutPixel( buffer_map, j, i, + XGetPixel( orig_map, x, y )); + } + } + } + + XPutImage(g_dpy, g_window, gc, buffer_map, 0, 0, xy_coo[k].x, xy_coo[k].y, + 2*radius+speed+2, 2*radius+speed+2); +} + /* create a new, random coordinate, that won't interfer with any other * coordinates, as the drawing routines would be significantly slowed * down if they were to handle serveral layers of distortions @@ -391,11 +474,11 @@ static void move_lense(int k) { int i; - if (xy_coo[k].x + 4*radius/2 >= xgwa.width) + if (xy_coo[k].x + 2*radius + speed + 2 >= xgwa.width) xy_coo[k].xmove = -abs(xy_coo[k].xmove); if (xy_coo[k].x <= speed) xy_coo[k].xmove = abs(xy_coo[k].xmove); - if (xy_coo[k].y + 4*radius/2 >= xgwa.height) + if (xy_coo[k].y + 2*radius + speed + 2 >= xgwa.height) xy_coo[k].ymove = -abs(xy_coo[k].ymove); if (xy_coo[k].y <= speed) xy_coo[k].ymove = abs(xy_coo[k].ymove); @@ -406,7 +489,7 @@ static void move_lense(int k) for (i = 0; i < number; i++) { if ((i != k) -/* This commented test is for rectangular lenses (not presently used) and +/* This commented test is for rectangular lenses (not currently used) and * the one used is for circular ones && (abs(xy_coo[k].x - xy_coo[i].x) <= 2*radius) && (abs(xy_coo[k].y - xy_coo[i].y) <= 2*radius)) { */ @@ -471,6 +554,7 @@ char *defaults [] = { "*magnify: False", "*swamp: False", "*bounce: False", + "*reflect: False", "*blackhole: False", #ifdef HAVE_XSHM_EXTENSION "*useSHM: False", /* xshm turns out not to help. */ @@ -485,6 +569,7 @@ XrmOptionDescRec options [] = { { "-number", ".number", XrmoptionSepArg, 0 }, { "-swamp", ".swamp", XrmoptionNoArg, "True" }, { "-bounce", ".bounce", XrmoptionNoArg, "True" }, + { "-reflect", ".reflect", XrmoptionNoArg, "True" }, { "-vortex", ".vortex", XrmoptionNoArg, "True" }, { "-magnify", ".magnify", XrmoptionNoArg, "True" }, { "-blackhole", ".blackhole", XrmoptionNoArg, "True" },