/*
    bomb - automatic interactive visual stimulation
    Copyright (C) 1995  Scott Draves <spot@cs.cmu.edu>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "defs.h"


#define R8b (random_byte())

int
random_byte()
{
    static int stage = 0;
    static unsigned int savebits;
    int r;

    if (0 == stage) {
       savebits = random();
       stage = 3;
    }
    r = savebits & 0xff;
    savebits = savebits >> 8;
    stage--;
    return r;
}

int
quantize(d)
   double d;
{
  int i = floor(d);
  double f = d - i;
  if (R8b < f*0xff)
    i++;
  return i;
}


void
step_rule_slip(int frame, rule_t *p, image8_t *fb) {
   int i, j, k;
   board_t *sboard, *dboard;
   u_char *lp;
   int ib;

#define bsize 30

   for (ib = 0; ib < 50; ib++) {
      int dx, dy;
      int x = R%(fb->width - bsize);
      int y = R%(fb->height - bsize);
      double t, tx, ty, s1, s2;

      switch (iclamp(p->drift, 6)) {
       case 0:
	 tx = 2 * x / (double) fb->width - 1;
	 ty = 2 * y / (double) fb->height - 1;
	 s2 = tx + ty;
	 s1 = tx - ty;
       q:

	 /* multiply by matrix here */

	 dx = quantize(s1);
	 dy = quantize(s2);
	 break;
       case 1:
	 dx = R8b%3 - 1;
	 dy = R8b%3 - 1;
	 break;
       case 2:
	 tx = 2 * x / (double) fb->width - 1;
	 ty = 2 * y / (double) fb->height - 1;
	 s1 = -ty;
	 s2 = tx;
	 goto q;
       case 3:
       case 4:
	 tx = 2 * x / (double) fb->width - 1;
	 ty = 2 * y / (double) fb->height - 1;

	 if (ty < 0) {
	    ty = ty + 0.05;
	    if (ty > 0)
	       ty = 0.0;
	 }
	 if (ty > 0) {
	    ty = ty - 0.05;
	    if (ty < 0)
	       ty = 0.0;
	 }
      
	 t = tx * tx + ty * ty + 1e-5;
	 s1 = 2 * tx * tx / t - 1;
	 s2 = 2 * tx * ty / t;
	 s1 *= 2;
	 s2 *= 2;
	 goto q;
       case 5:
	 tx = 2 * x / (double) fb->width - 1;
	 ty = 2 * y / (double) fb->height - 1;
	 s1 = tx;
	 s2 = ty;
	 goto q;
      }

      if (1) {
	 u_char *line_base, *p;
	 int blit_offset, ix, iy;
	 
	 blit_offset = fb->stride * dy + dx;
	 line_base = fb->p + x + (y * fb->stride);

	 if (dx > 0) {
	    ix = -1;
	    line_base += bsize - 1;
	 } else
	    ix = 1;
	 if (dy > 0) {
	    iy = -fb->stride;
	    line_base += fb->stride * (bsize - 1);
	 } else
	    iy = fb->stride;
	 for (j = 0; j < bsize; j++) {
	    p = line_base;
	    for (i = 0; i < bsize; i++) {
	       p[blit_offset] = *p;
	       p += ix;
	    }
	    line_base += iy;
	 }
      }
   }
}
