#include "g_main.h"
#include "dummy.h"
#include "m_main.h"
#include "vengine.h"

#include <math.h>

  int tab1[256];
  int tab2[256];

  int add1;
  int add2;

  char  *dat1;
  char  *dat2;

  int *p1;
  int *p2;

  long *buf;

void * init_dummy (void *dat,cbitmap *s, cbitmap *d,int duration)
{
  return (void *)-1;
}



void  doit_dummy (void *dat, cbitmap *s1, cbitmap *s2, cbitmap *d,int time, int duration)
{
  int i;
  if (d->x != s1->x)
    m_fatalerror ("dummy xsize is not the same");

  if (d->bpp==18 && s1->bpp==8)
     for (i=0;i<d->x*d->y;i++) ((long *)d->data)[i]=s1->pal[(unsigned long)s1->data[i]];  //8Bit pal -> 18Bit
     else
     if (d->bpp==18 && s1->bpp==18)
       for (i=0;i<d->x*d->y;i++) ((long *)d->data)[i]=((long *)s1->data)[i];  //18Bit -> 18Bit
       else
       if (d->bpp==8 && s1->bpp==8)
       {
         for (i=0;i<d->x*d->y;i++) d->data[i]=s1->data[i];  //8Bit -> 8Bit
         for (i=0;i<256;i++) d->pal[i]=s1->pal[i];
       }
       else
         m_fatalerror ("dummy donīt support true to pal");


}

void  exit_dummy (void *dat)
{
}

void  * init_rotz (void *dat,cbitmap *s, cbitmap *d,int duration)
{
  RotIn *sd=(RotIn *)dat;
  RotOut *dd=(RotOut *)m_alloc (sizeof(RotOut));

  dd->z_start=sd->z_start;
  dd->z_amplitude=sd->z_amplitude;
  dd->z_periods=sd->z_periods;

  dd->r_start=sd->r_start;
  dd->r_amplitude=sd->r_amplitude;
  dd->r_periods=sd->r_periods;

  dd->duration=duration;

  return (void *)dd;
}


void  doit_rotz (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
  RotOut *dat=(RotOut *)data;
  float px1,py1;
  float px2,py2;
  float px3,py3;
  float dx1,dy1;
  float dx2,dy2;
  long tab1[160];
  long tab2[160];
  long x,y,i;
  float winkel,zoom;
  float ut=(double)time/(double)duration;

  winkel=dat->r_start+ dat->r_amplitude*(float)cos(2*3.14*ut*dat->r_periods);
  zoom=dat->z_start+dat->z_amplitude*(float)cos(360/180*3.14*ut*dat->z_periods);

  px1=(float)cos (winkel/180*3.14)*zoom;
  py1=(float)sin (winkel/180*3.14)*zoom;

  px2=(float)cos ( (winkel+90)/180*3.14)*zoom;
  py2=(float)sin ( (winkel+90)/180*3.14)*zoom;

  px3=(float)cos ( (winkel-90)/180*3.14)*zoom;
  py3=(float)sin ( (winkel-90)/180*3.14)*zoom;


  dx1=(px2-px1)/d->x*2;
  dy1=(py2-py1)/d->x*2;

  dx2=(px3-px1)/d->y*2;
  dy2=(py3-py1)/d->y*2;


  px1+=32;
  py1+=32;

  px2=px1;
  py2=py1;


  for (i=0;i<d->x;i++)
  {
    tab1[i]=(((long)py1)&127)*128+(((long)px1)&127);
    px1+=dx1;
    py1+=dy1;

    tab2[i]=(((long)py2)&127)*128+(((long)px2)&127);
    px2+=dx2;
    py2+=dy2;
  }

  if (s1->x!=128)
      m_fatalerror ("rotzoomer source pic must be 128x128");

  if (d->bpp==18 && s1->bpp==8)
  {
    long *tmp=(long *)d->data;
    for (y=0;y<d->y;y++)
      for (x=0;x<d->x;x++)
        *tmp++=s1->pal[(unsigned char)s1->data[(tab1[x]+tab2[y])&0x3fff]];
  }
  else
  if (d->bpp==18 && s1->bpp==18)
  {
    long *tmp=(long *)d->data;
    for (y=0;y<d->y;y++)
      for (x=0;x<d->x;x++)
        *tmp++=((long *)s1->data)[(tab1[x]+tab2[y])&0x3fff];
  }
  else
  if (d->bpp==8 && s1->bpp==8)
  {
    char *tmp=(char *)d->data;
    for (y=0;y<d->y;y++)
      for (x=0;x<d->x;x++)
        *tmp++=((char *)s1->data)[(tab1[x]+tab2[y])&0x3fff];
    for (x=0;x<256;x++)
       ((long *)d->pal)[x]=((long *)s1->pal)[x];
  }
  else
      m_fatalerror ("rotzoomer donīt support true to pal");


}

void  exit_rotz (void *dat)
{
  m_free ((char *) dat);
}





void  * init_back (void *dat,cbitmap *s, cbitmap *d,int duration)
{
  BackIn *sd=(BackIn *)dat;
  BackOut *dd=(BackOut *)m_alloc (sizeof(BackOut));

  dd->z_start1=sd->z_start1;
  dd->z_end1=sd->z_end1;

  dd->z_start2=sd->z_start2;
  dd->z_end2=sd->z_end2;

  dd->amplitude=sd->amplitude;

  dd->i_start1=sd->i_start1;
  dd->i_start2=sd->i_start2;


  dd->duration=duration;
  return (void *)dd;
}


void  doit_back (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
  BackOut *dat=(BackOut *)data;
  int x,y;
  int pal1[256];
  int pal2[256];
  long *buf2;
  char ipol[64];


  float ut=(double)time/(double)duration;
  float zoom1=dat->z_start1+(dat->z_end1-dat->z_start1)*ut;
  float zoom2=dat->z_start2+(dat->z_end2-dat->z_start2)*ut;

  float px1;
  float py1;

  float px2;
  float py2;

  float dx1;
  float dy1;
  float dx2;
  float dy2;

  float itens=(dat->i_start2-dat->i_start1)*ut+dat->i_start1;

  buf=(long *)d->data;

  if (zoom1<1) zoom1=1+(1-zoom1);
  if (zoom2<1) zoom2=1+(1-zoom2);


  px1=-s1->x*zoom1+(dat->amplitude*(float)cos(6.28*ut) )*zoom1;
  py1=-s1->y*zoom1/2+(dat->amplitude*(float)sin(6.26*ut) )*zoom1;

  px2=-s2->x*zoom2+(dat->amplitude*(float)cos(6.28*ut) )*zoom2;
  py2=-s2->y*zoom2/2+(dat->amplitude*(float)sin(6.26*ut) )*zoom2;

  dx1=-(s1->x-s1->x*zoom1)/(d->x-1)*2;
  dy1=-(s1->y-s1->y*zoom1)/(d->y-1);
  dx2=-(s2->x-s2->x*zoom2)/(d->x-1)*2;
  dy2=-(s2->y-s2->y*zoom2)/(d->y-1);




  if (s1->x!=128 || s2->x!=128)
      m_fatalerror ("background source pic must be 128x128");

  for (x=0;x<64;x++)
    ipol[x]=(char) (x*ut);

 for (x=0;x<1024;x++)
 {
   ((char *)pal1)[x]=(char)(((((char *)s1->pal)[x]-ipol[ ((char *)s1->pal)[x] ]) )*itens);
   ((char *)pal2)[x]=(char)((ipol[ ((char *)s2->pal)[x] ])*itens);
 }


  for ( x=0;x<d->x;x++ )
  {
    tab1[x]=((int)px1)&127;
    px1+=dx1;
    tab2[x]=((int)px2)&127;
    px2+=dx2;

  }

  dat1=s1->data;
  dat2=s2->data;

  p1=pal1;
  p2=pal2;

  buf2=buf;

  if (d->bpp==18 && s1->bpp==8 && s2->bpp==8)
  {
    for (y=0;y<d->y;y++)
    {
      add1=(((int) py1)&127)*128;
      add2=(((int) py2)&127)*128;

 #ifndef __AMIGA68K__

      for (x=0;x<d->x;x++)
      {
        *buf2=p1[(unsigned char) dat1[ (tab1[x]+add1)&0x3fff]];
        *buf2+=p2[(unsigned char) dat2[ (tab2[x]+add2)&0x3fff]];
        buf2++;

      }
 #endif

 #ifdef __AMIGA68K__
      backasm();
 #endif

      py1+=dy1;
      py2+=dy2;

    }
  }
  else
      m_fatalerror ("back check cbitmaps");

}

void  exit_back (void *dat)
{
  m_free ((char *)dat);
}






void  * init_zoom (void *dat,cbitmap *s, cbitmap *d,int duration)
{
  ZoomIn *sd=(ZoomIn *)dat;
  ZoomOut *dd=(ZoomOut *)m_alloc (sizeof(ZoomOut));

  dd->z_start1=sd->z_start1;
  dd->z_end1=sd->z_end1;

  dd->duration=duration;
  return (void *)dd;
}


void  doit_zoom (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
  ZoomOut *dat=(ZoomOut *)data;
  int x,y;
  int tab1[256];


  float ut=(double)time/(double)duration;
  float zoom1=dat->z_start1+(dat->z_end1-dat->z_start1)*ut;

  float px1=s1->x*zoom1;
  float py1=-s1->y*zoom1/2;

  float dx1=(s1->x-s1->x*zoom1)/(d->x-1)*2;
  float dy1=-(s1->y-s1->y*zoom1)/(d->y-1);



  if (s1->x!=128)
      m_fatalerror ("background source pic must be 128x128");

  for ( x=0;x<d->x;x++ )
  {
    tab1[x]=((int)px1)&127;
    px1+=dx1;
  }

  if (d->bpp==18 && s1->bpp==8)
  {
    long *buf=(long *)d->data;

    for (y=0;y<d->y;y++)
    {
      int add1=(((int) py1)&127)*128;

      for (x=0;x<d->x;x++)
      {
        *buf++=s1->pal[(unsigned char) s1->data[ (tab1[x]+add1)&0x3fff]];
      }
      py1+=dy1;
    }
  }
  else
  if (d->bpp==8 && s1->bpp==8)
  {
    char  *buf=(char *)d->data;
    for (y=0;y<d->y;y++)
    {
      int add1=(((int) py1)&127)*128;

      for (x=0;x<d->x;x++)
      {
        *buf++=s1->data[ (tab1[x]+add1)&0x3fff];
      }
      py1+=dy1;
    }
    for (x=0;x<256;x++) d->pal[x]=s1->pal[x];
  }
  else
      m_fatalerror ("zoom check cbitmaps");

}

void  exit_zoom (void *dat)
{
  m_free ((char *)dat);
}





void  * init_xfade (void *dat,cbitmap *s, cbitmap *d,int duration)
{
  return (void *)duration;
}


void  doit_xfade (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
  int x,y;

  float ut=(double)time/(double)duration;



  char ipol[128];



  if (s1->x!=s2->x || s1->x!=d->x || s1->y!=s2->y || s1->y!=d->y)
      m_fatalerror ("xfade all pic must have the same size");

  if (s1->bpp!=s2->bpp)
      m_fatalerror ("xfade source pics must have the same bpp");

  if (d->bpp!=18)
      m_fatalerror ("xfade dest pic must habe 18Bit");




  if (s1->bpp==8)
  {
    int pal1[256];
    int pal2[256];
    long *buf=(long *)d->data;

    for (x=0;x<64;x++)
      ipol[x]=(char) (x*ut);

    for (x=0;x<1024;x++)
    {
      ((char *)pal1)[x]=((char *)s1->pal)[x]-ipol[ ((char *)s1->pal)[x] ];
      ((char *)pal2)[x]=ipol[ ((char *)s2->pal)[x] ];
    }

    for (y=0;y<(d->y*d->x);y++)
    {
      *buf=pal1[(unsigned char) s1->data[y]];
      *buf+=pal2[(unsigned char) s2->data[y]];
      buf++;
    }
  }
  else
  if (s1->bpp==18)
  {
    char *buf=(char *)d->data;
    char *p1=(char *)s1->data;
    char *p2=(char *)s2->data;

    for (x=0;x<128;x++)
      ipol[x]=(char) ((x-63)*ut);

    for (y=0;y<(d->y*d->x);y++)
    {
      p1++;
      p2++;
      buf++;


      *buf++=(unsigned char)*p1+(unsigned char)ipol[(*p2++-*p1)+63];
      p1++;
      *buf++=(unsigned char)*p1+(unsigned char)ipol[(*p2++-*p1)+63];
      p1++;
      *buf++=(unsigned char)*p1+(unsigned char)ipol[(*p2++-*p1)+63];
      p1++;

    }
  }
  else
      m_fatalerror ("xfade check bitmaps");

}

void  exit_xfade (void *dat)
{
}



void  * init_shadem (void *dat,cbitmap *s, cbitmap *d,int duration)
{



  return (void *)dat;
}


void  doit_shadem (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
  int x,y;
  float ut=(double)time/(double)duration;

  ShadeIn *dat=(ShadeIn *)data;

  float py1;
  float dy1;

  float py2;
  float dy2;

  char *buf=d->data;

  float st1,st2;
  st2=(float)sin(ut*3.14)*127;
  st1=127-st2;//(float)sin((1-ut)*3.14)*127;

  py1=(int)  ((float)sin (ut*dat->winkel1)*st2+st1+127);
  dy1=( ((int) ((float)sin (ut*dat->winkel2)*st2+st1+127)) -py1)/(d->x-1);

  py2=(int)  ((float)sin (ut*dat->winkel3)*st2+st1+127);
  dy2=( ((int) ((float)sin (ut*dat->winkel4)*st2+st1+127)) -py2)/(d->x-1);

  if (d->bpp!=8)
    m_fatalerror ("shadem dest pic1 must be 8bit!!");


  for (y=0;y<d->y;y++)
  {
    int dx=(int)((py2-py1)/(d->x+1)*256);
    int px=(int)(py1*256);
    for (x=0;x<d->x;x++)
    {
      *buf++=px>>8;
      px+=dx;
    }
    py1+=dy1;
    py2+=dy2;
  }

}

void  exit_shadem (void *dat)
{
}


char *itab=0;



void  * init_fadem (void *dat,cbitmap *s, cbitmap *d,int duration)
{

  return (void *)dat;
}


void  doit_fadem (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
    int x,y;
//    float ut=(double)time/(double)duration;


    char *p1=(char *)s1->data;
    char *p2=(char *)s2->data;
    char *d1=(char *)d->data;

      int t;
      char *p=(char *)&t;



  float ut=(double)time/(double)duration;

  ShadeIn *dat=(ShadeIn *)data;

  float py1;
  float dy1;

  float py2;
  float dy2;


  float st1,st2;
  st2=(float)sin(ut*3.14)*127;
  st1=127-st2;//(float)sin((1-ut)*3.14)*127;

  py1=(int)  ((float)sin (ut*dat->winkel1)*st2+st1+127);
  dy1=( ((int) ((float)sin (ut*dat->winkel2)*st2+st1+127)) -py1)/(d->x-1);

  py2=(int)  ((float)sin (ut*dat->winkel3)*st2+st1+127);
  dy2=( ((int) ((float)sin (ut*dat->winkel4)*st2+st1+127)) -py2)/(d->x-1);


    if (s2->bpp!=18 || d->bpp!=18)
      m_fatalerror ("fadem all sourcepic1 and destpic must be 18bit");

    if (s1->x!=s2->x || s2->x!=d->x || s1->y!=s2->y || s2->y!=d->y )
      m_fatalerror ("fadem all pics must have the same size");


    if (s1->bpp==18)
    {
      for (y=0;y<d->y;y++)
      {
        int dx=(int)((py2-py1)/(d->x+1)*256);
        int px=(int)(py1*256);
        for (x=0;x<d->x;x++)
        {
          int f=(int)(px)+128;

        d1++;
        p1++;
        p2++;

        *d1++=*p1+++ itab[f+(int)(*p2++-*p1)];
        *d1++=*p1+++ itab[f+(int)(*p2++-*p1)];
        *d1++=*p1+++ itab[f+(int)(*p2++-*p1)];

          px+=dx;
        }
        py1+=dy1;
        py2+=dy2;
      }
    }
    else
    {

      for (y=0;y<d->y;y++)
      {
        int dx=(int)((py2-py1)/(d->x+1)*256);
        int px=(int)(py1*256);


        for (x=0;x<d->x;x++)
        {
          int f=(int)(px&0xff00)+128;
          t=s1->pal[(unsigned char)(*p1++)];


          d1++;
          p2++;

          *d1++=p[1]+itab[f+(int)( *p2++-p[1])];
          *d1++=p[2]+itab[f+(int)( *p2++-p[2])];
          *d1++=p[3]+itab[f+(int)( *p2++-p[3])];

          px+=dx;
        }



        py1+=dy1;
        py2+=dy2;
      }

    }


}

void  exit_fadem (void *dat)
{
}





int getrnd2 (int seed)
{
   return ( (seed<<1)|(((seed^(seed<<2)^(seed<<3)^(seed<<5))>>15)&1))&0xffff;

}


int getrnd ()
{
    static int seed=47;
    return (seed = ( (seed<<1)|(((seed^(seed<<2)^(seed<<3)^(seed<<5))>>15)&1))&0xffff);
}


void blur (char *so1, char *des, int x, int y)
{
  int i,k;
  int ta,tb,tc,off;
  so1+=x;

 off=x+1;

  for (i=0; i<x;i++) *des++=0;
    for (i=0; i<y-2; i++)
    {
      ta=0;
      for (k=0; k<x; k++)
      {
        tb=*so1;
        tc=*(so1+off);
        so1++;
        *des++=((ta+tb+tc)>>2);//&0x3f3f3f3f;
        ta=tb+tc;
     }
  }

  for (i=0; i<x;i++) *des++=0;

}


void blur2 (int *so1, int *des, int x, int y)
{
  int i,k;
  int ta,tb,tc,off;
  so1+=x;

 off=x;

  for (i=0; i<x;i++) *des++=0;
    for (i=0; i<y-2; i++)
    {
      ta=0;
      for (k=0; k<x; k++)
      {
        tb=*so1;
        tc=*(so1+off);
        so1++;
        *des++=((ta+tb+tc)>>2)&0x3f3f3f3f;
        ta=tb+tc;
     }
  }

  for (i=0; i<x;i++) *des++=0;

}




typedef
struct tron
{
  int timer;
  int px;
  int py;
  int ax;
  int ay;

}Tron;


Tron beams[8];


tObject *TestO;

tVector Pos;
tVector oPos;

tVector Pos0;

long wx,wy,wz;
long owx,owy,owz;

tWindow Win;

void  * init_water (void *dat,cbitmap *s, cbitmap *d,int duration)
{
  int i=0;

  Pos0.x = 0;
  Pos0.y = 0;
  Pos0.z = 0;

  tInitSinus ();

  s->pal[0]=s->pal[1];

  TestO = GetObject (2, 4, 0, 0, 0);



  if (s->x!=256 || s->y!=256)
      m_fatalerror ("water check bitmaps");



  TestO->opoints[0].x = -3000;
  TestO->opoints[0].y = -3000;
  TestO->opoints[0].z = 0;

  TestO->opoints[1].x = 3000;
  TestO->opoints[1].y = -3000;
  TestO->opoints[1].z = 0;

  TestO->opoints[2].x = 3000;
  TestO->opoints[2].y = 3000;
  TestO->opoints[2].z = 0;

  TestO->opoints[3].x = -3000;
  TestO->opoints[3].y = 3000;
  TestO->opoints[3].z = 0;

  TestO->faces[0].p1 = 0;
  TestO->faces[0].p2 = 1;
  TestO->faces[0].p3 = 2;

  TestO->faces[0].u1 = 0;
  TestO->faces[0].v1 = 0;

  TestO->faces[0].u2 = 255;
  TestO->faces[0].v2 = 0;

  TestO->faces[0].u3 = 255;
  TestO->faces[0].v3 = 255;

  TestO->faces[0].text = (unsigned char *) s->data;
  TestO->faces[0].pal = (unsigned char *)s->pal;


  TestO->faces[1].p1 = 0;
  TestO->faces[1].p2 = 2;
  TestO->faces[1].p3 = 3;

  TestO->faces[1].u1 = 0;
  TestO->faces[1].v1 = 0;

  TestO->faces[1].u2 = 255;
  TestO->faces[1].v2 = 255;

  TestO->faces[1].u3 = 0;
  TestO->faces[1].v3 = 255;

  TestO->faces[1].text = (unsigned char *) s->data;
  TestO->faces[1].pal = (unsigned char *) s->pal;



  for ( i=0;i<8;i++)
  {
    beams[i].timer=getrnd()&127+64;
    beams[i].px=getrnd()&255;
    beams[i].py=getrnd()&255*256;
    beams[i].ax=(getrnd()&15)-8;
    beams[i].ay=((getrnd()&15)-8)*256;
  }


  Filter=0;
  return (void *)dat;
}



void  doit_water (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
  float ut=(double)time/(double)duration;
  WaterIn *dat = (WaterIn *)data;

  static long seed=7;
  static long seed2=76;

  int i;
  int x;//,y;

  char *src=s1->data;

  x=(seed&255)+200;

    for (i=0;i<x;i++)
    {
      seed = getrnd2 (seed);
      seed2 = getrnd2 (seed2);

      src[seed&0xffff]=seed2&0xff;
   }


     for (i=0;i<8;i++)
     {
       int post=(beams[i].px+beams[i].py)&0xffff;

       if (!(--beams[i].timer))
       {
         beams[i].timer=(getrnd()&31)+7;
         beams[i].ax=(getrnd()&15)-8;
         beams[i].ay=((getrnd()&15)-8)*256;
       }

       src[post]=0xff;
       src[(post+1)&0xffff]=0xff;
       src[(post+2)&0xffff]=0xff;
       src[(post+256)&0xffff]=0xff;
       src[(post+1+256)&0xffff]=0xff;
       src[(post+2+256)&0xffff]=0xff;
       src[(post-256)&0xffff]=0xff;
       src[(post-1-256)&0xffff]=0xff;
       src[(post-2-256)&0xffff]=0xff;

       beams[i].px+=beams[i].ax;
       beams[i].py+=beams[i].ay;
     }



    blur ( (char *)src, (char *)src, 256 ,256);
    x=0;



    Win.Screen=(char *)d->data;

    Win.x=d->x+1;
    Win.y=d->y;
    Win.kx=d->x/2;
    Win.ky=d->y/2;


  if (d->bpp==18)
   {
      tBpp=24;
      for (i=0;i<d->x*d->y;i++)
        ((long *)d->data)[i]=0;
      Win.bpr=d->x*4;


    }
    else
   {
      tBpp=8;
      for (i=0;i<256;i++) d->pal[i]=s1->pal[i];
      for (i=0;i<d->x*d->y/4;i++)
        ((long *)d->data)[i]=0;
      Win.bpr=d->x;

   }




  Pos.x = oPos.x+ut*(dat->posx-oPos.x);
  Pos.y = oPos.y+ut*(dat->posy-oPos.y);
  Pos.z = oPos.z+ut*(dat->posz-oPos.z);

  wx = (int)(owx +ut*(dat->winkelx-owx));
  wy = (int)(owy +ut*(dat->winkely-owy));
  wz = (int)(owz +ut*(dat->winkelz-owz));

    tInitMatrix (wx,wy,wz,&TestO->rotmatrix);
    tCalcObject (TestO, 0, &Pos);


    for (i=0;i<(TestO->nbFaces);i++)
      tDrawFace (&TestO->faces[i],TestO->bpoints,&Win);


}

void  exit_water (void *data)
{
  WaterIn *dat = (WaterIn *)data;

  FreeObject (TestO);

  owx=(long)dat->winkelx;
  owy=(long)dat->winkely;
  owz=(long)dat->winkelz;

  oPos.x=dat->posx;
  oPos.y=dat->posy;
  oPos.z=dat->posz;

}


void  * init_rain (void *dat,cbitmap *s, cbitmap *d,int duration)
{

 int i;
 for (i=0;i<256;i++)
    s->pal[i]=(s->pal[i]>>1)&0x3f3f3f3f;


  for ( i=0;i<8;i++)
  {
    beams[i].timer=getrnd()&127+64;
    beams[i].px=getrnd()&255;
    beams[i].py=(getrnd()&127)*s->x;
    beams[i].ax=(getrnd()&15)-8;
    beams[i].ay=((getrnd()&15)-8)*s->x;
  }


  return (void *)-1;
}


void  doit_rain (void *data, cbitmap *s1, cbitmap *s2, cbitmap *d,int time,int duration)
{
  int x,i,s;
  static long seed=6;
  static long seed2=47;
  int t;
  int ta,tb,tc;


  int *dst=(int *)d->data;

  s=s1->x*(s1->y-4);

  if (d->x!=s1->x || d->y!=s1->y)
    m_fatalerror ("rain all pics must have same size!!");


  if (d->bpp!=18)
    m_fatalerror ("rain dest pic1 must be 18bit!!");

  if (s1->bpp!=8)
    m_fatalerror ("rain source1 must be 8bit!!");



    for (i=0;i<100;i++)
    {
      seed = getrnd2 (seed);
      seed2 = getrnd2 (seed2);
      t=seed;
      if (t<s) s1->data[seed]=seed2&0xff;

    }


     for (i=0;i<8;i++)
     {
       int post=(beams[i].px+beams[i].py)&0xffff;

       if (!(--beams[i].timer))
       {
         beams[i].timer=(getrnd()&31)+7;
         beams[i].ax=(getrnd()&15)-8;
         beams[i].ay=((getrnd()&15)-8)*s1->x;
       }


       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       post+=s1->x-4;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       post+=s1->x-4;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       post+=s1->x-4;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;
       if (post<s) s1->data[post++]=0xff;


       beams[i].px+=beams[i].ax;
       beams[i].py+=beams[i].ay;
     }




    blur ((char *)s1->data,(char *)s1->data,s1->x,s1->y);
    s1->pal[0]=s1->pal[1];



    for (x=0;x<(d->x*d->y);x++)
    {
        ta=*dst + s1->pal[(unsigned char)s1->data[x]];
        tc=tb=ta&0x40404040;
        tc>>=6;
        tb-=tc;
        *dst++=(ta|tb)&0x3f3f3f3f;
    }

}

void  exit_rain (void *dat)
{
}



void Init_Tabs (void)
{
  int x,y;
  if (!itab)
  {
    itab=m_alloc(65536);
    for (y=0;y<256;y++)
    {
      float m=(float)y/256;
      int i=0;
      for (x=-128;x<128;x++)
      {
        itab[y*256+i++]=(char) (x*m);
      }

    }
  }

}

void Exit_Tabs (void)
{
  if (itab) m_free (itab);
}

