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");
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") || reflect)
+ if (get_boolean_resource("bounce", "Boolean"))
effect = &move_lense;
if (effect == NULL && radius == 0 && speed == 0 && number == 0
* -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 );
static void make_round_lense(int radius, int loop)
{
int i, j;
- double theta;
for (i = 0; i < 2*radius+speed+2; i++) {
for(j = 0; j < 2*radius+speed+2; j++) {
/* 2.5 is just a constant used because it looks good :) */
angle = 2.5*(1-d)*(1-d);
-
/* Avoid atan2: DOMAIN error message */
- if ((radius-j) == 0.0 && (radius-i) == 0.0)
- theta = 0.0;
- else
- theta = atan2(radius-j, radius-i);
- from[i][j][0] = radius +
- cos(angle - theta)*r;
- from[i][j][1] = radius +
- sin(angle - theta)*r;
-
+ 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;
/* 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++) {
+ for(j = 0 ; j < 2*radius+speed+2 ; j++) {
+ if (xy_coo[k].x+from[i][j][0] >= 0 &&
+ xy_coo[k].x+from[i][j][0] < xgwa.width &&
+ xy_coo[k].y+from[i][j][1] >= 0 &&
+ xy_coo[k].y+from[i][j][1] < xgwa.height)
+ XPutPixel(buffer_map, i, j,
+ XGetPixel(orig_map,
+ xy_coo[k].x+from[i][j][0],
+ xy_coo[k].y+from[i][j][1]));
+ }
+ }
+
+ 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);
+}
+
+/* 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;
- if (reflect) {
- cx = cy = radius;
- if (xy_coo[k].ymove > 0)
- cy += speed;
- if (xy_coo[k].xmove > 0)
- cx += speed;
- }
+
+ 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++) {
- if (reflect) {
- ly = i - cy;
- lysq = ly * ly;
- ny = xy_coo[k].y + i;
- }
+ ly = i - cy;
+ lysq = ly * ly;
+ ny = xy_coo[k].y + i;
for(j = 0 ; j < 2*radius+speed+2 ; j++) {
- if (reflect) {
- 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)
+ 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 {
- 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 ));
- }
- } else if (xy_coo[k].x+from[i][j][0] >= 0 &&
- xy_coo[k].x+from[i][j][0] < xgwa.width &&
- xy_coo[k].y+from[i][j][1] >= 0 &&
- xy_coo[k].y+from[i][j][1] < xgwa.height) {
- XPutPixel(buffer_map, i, j,
- XGetPixel(orig_map,
- xy_coo[k].x+from[i][j][0],
- xy_coo[k].y+from[i][j][1]));
+ else
+ XPutPixel( buffer_map, j, i,
+ XGetPixel( orig_map, x, y ));
}
}
}
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)) { */
draw(k);
}
- XSync(dpy, True);
+ XSync(dpy, False);
+ screenhack_handle_events (dpy);
if (delay) usleep(delay);
}