- static int x, y, xmove=0, ymove=0;
- int i,j;
-
- move_lens (&x, &y, &xmove, &ymove);
-
- XCopyArea(dpy, orig_map, buffer_map, gc,
- x-radius/2 - xmove, y-radius/2 - ymove,
- 2*radius + abs(xmove), 2*radius + abs(ymove),
- 0,0);
-
- /* it's possible to lower the number of loop iterations by a factor
- * of 4, but since it's the XCopyArea's which eat resources, and
- * I've only supplied one distortion routine (which is circular),
- * here's a check-if-inside circle variation of this for loop.
- * Using both optimizations turns the matrix rendering into one
- * ugly mess... I'm counting on gcc optimization ;)
- */
+ int k;
+
+ if (effect == &swamp_thing) {
+ from_array = (int ****)malloc((radius+1)*sizeof(int ***));
+ for (k=0; k <= radius; k++) {
+ allocate_lense();
+ make_round_lense(radius, k);
+ from_array[k] = from;
+ }
+ } else { /* just allocate one from[][][] */
+ allocate_lense();
+ make_round_lense(radius,radius);
+ }
+}
+
+/* If fast_draw_8, fast_draw_16 or fast_draw_32 are to be used, the following properties
+ * of the src and dest XImages must hold (otherwise the generic, slooow, method provided
+ * by X is to be used):
+ * src->byte_order == dest->byte_order
+ * src->format == ZPixmap && dest->format == ZPixmap
+ * src->depth == dest->depth == the depth the function in question asumes
+ * x and y is the coordinates in src from where to cut out the image from,
+ * distort_matrix is a precalculated array of how to distort the matrix
+ */
+
+static void fast_draw_8(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ CARD8 *u = (CARD8 *)dest->data;
+ CARD8 *t = (CARD8 *)src->data + x + y*src->bytes_per_line/sizeof(CARD8);
+
+ while (u < (CARD8 *)(dest->data + sizeof(CARD8)*dest->height
+ *dest->bytes_per_line/sizeof(CARD8))) {
+ *u++ = t[*distort_matrix++];
+ }
+}
+
+static void fast_draw_16(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ CARD16 *u = (CARD16 *)dest->data;
+ CARD16 *t = (CARD16 *)src->data + x + y*src->bytes_per_line/sizeof(CARD16);
+
+ while (u < (CARD16 *)(dest->data + sizeof(CARD16)*dest->height
+ *dest->bytes_per_line/sizeof(CARD16))) {
+ *u++ = t[*distort_matrix++];
+ }
+}
+
+static void fast_draw_32(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ CARD32 *u = (CARD32 *)dest->data;
+ CARD32 *t = (CARD32 *)src->data + x + y*src->bytes_per_line/sizeof(CARD32);
+
+ while (u < (CARD32 *)(dest->data + sizeof(CARD32)*dest->height
+ *dest->bytes_per_line/sizeof(CARD32))) {
+ *u++ = t[*distort_matrix++];
+ }
+}
+
+static void generic_draw(XImage *src, XImage *dest, int x, int y, int *distort_matrix) {
+ int i, j;
+ for (i = 0; i < dest->width; i++)
+ for (j = 0; j < dest->height; j++)
+ if (from[i][j][0] + x >= 0 &&
+ from[i][j][0] + x < src->width &&
+ from[i][j][1] + y >= 0 &&
+ from[i][j][1] + y < src->height)
+ XPutPixel(dest, i, j,
+ XGetPixel(src,
+ from[i][j][0] + x,
+ from[i][j][1] + y));
+}
+
+/* generate an XImage of from[][][] and draw it on the screen */
+static void plain_draw(int k)
+{
+ if (xy_coo[k].x+2*radius+speed+2 > orig_map->width ||
+ xy_coo[k].y+2*radius+speed+2 > orig_map->height)
+ return;
+
+ draw_routine(orig_map, buffer_map, xy_coo[k].x, xy_coo[k].y, fast_from);
+
+# ifdef HAVE_XSHM_EXTENSION
+ if (use_shm)
+ XShmPutImage(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, False);
+ else
+
+ if (!use_shm)
+# endif
+ 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 :)
+ */
+static 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;