};
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;
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)
{
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");
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
* -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:
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;
}
}
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;
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) {
* 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 */
* 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;
}
}
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE -1
+#endif
+
static void allocate_lense(void)
{
int i, j;
/* 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++) {
2*radius+speed+2, 2*radius+speed+2);
}
+/* generate an XImage from the reflect algoritm submitted by
+ * Randy Zack <randy@acucorp.com>
+ * 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
{
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);
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)) { */
"*magnify: False",
"*swamp: False",
"*bounce: False",
+ "*reflect: False",
"*blackhole: False",
#ifdef HAVE_XSHM_EXTENSION
"*useSHM: False", /* xshm turns out not to help. */
{ "-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" },
draw(k);
}
- XSync(dpy, True);
+ XSync(dpy, False);
+ screenhack_handle_events (dpy);
if (delay) usleep(delay);
}