/*


    tilefx.c

*/


#include    "g_main.h"
#include    "tilefx.h"
#include    "m_main.h"

#include    <math.h>

static textile tiles[357];
static int sindone=0;
static float sinfloat[1024+256];
static int sin88[1024+256];

static void dosine(void) {
int i;

    for (i=0;i<(1024+256);i++) {
        sinfloat[i]=sin(2*3.14159265/1024*((float)i));
        sin88[i]=(int)(sinfloat[i]*256);
        }

    sindone=1;
    }

static void rendertiles(cbitmap *so,cbitmap *ta) {

int i,k,l,m;
int ak,line;

int tx,ty;
int dhx,dhy;
int dvx,dvy;
int ddhx,ddhy;

int dhex,dhey;

int lx,ly;

//int  *tso=(int*)(so->data);
//char *cso=(char*)(so->data);

int  *tta=(int*)(ta->data);
int  *tta2,*tta3;
char *cta=(char*)(ta->data);
char *cta2,*cta3;

int  *pal=(int*)so->pal;

    if  (!((so->x==256)&&(so->y==256))) m_fatalerror("tilefx - sourcemap must be 256x256");


    line=1+(ta->x>>3);
    ak=0;
    if ((so->bpp==8)&&(ta->bpp==18)) {

        for (i=0; i<(ta->y>>3);i++) {
            tta2=tta;
            tta+=ta->x<<3;
            for (k=0; k<(ta->x>>3);k++) {
                tta3=tta2;
                tta2+=8;

                tx=tiles[ak].x;
                ty=tiles[ak].y;

                dvx=(tiles[ak+line].x-tx)>>3;
                dvy=(tiles[ak+line].y-ty)>>3;

                dhx=(tiles[ak+1].x-tx)>>3;
                dhy=(tiles[ak+1].y-ty)>>3;

                dhex=(tiles[ak+line+1].x-tiles[ak+line].x)>>3;
                dhey=(tiles[ak+line+1].y-tiles[ak+line].y)>>3;

                ddhx=(dhex-dhx)>>3;
                ddhy=(dhey-dhy)>>3;

                ak++;
                for (l=0;l<8;l++) {
                    lx=tx;
                    ly=ty;

                    for (m=0; m<8;m++) {

                        *tta3++=pal[(unsigned char)so->data[((lx>>8)&0xff)+(ly&0xff00)]];

                        lx+=dhx;
                        ly+=dhy;
                        }
                    dhx+=ddhx;
                    dhy+=ddhy;
                    tx+=dvx;
                    ty+=dvy;
                    tta3+=(ta->x-8);

                    }
                }
            ak++;
            }
        }
    if ((so->bpp==8)&&(ta->bpp==8)) {

        for (i=0; i<(ta->y>>3);i++) {
            cta2=cta;
            cta+=ta->x<<3;
            for (k=0; k<(ta->x>>3);k++) {
                cta3=cta2;
                cta2+=8;

                tx=tiles[ak].x;
                ty=tiles[ak].y;

                dvx=(tiles[ak+line].x-tx)>>3;
                dvy=(tiles[ak+line].y-ty)>>3;

                dhx=(tiles[ak+1].x-tx)>>3;
                dhy=(tiles[ak+1].y-ty)>>3;

                dhex=(tiles[ak+line+1].x-tiles[ak+line].x)>>3;
                dhey=(tiles[ak+line+1].y-tiles[ak+line].y)>>3;

                ddhx=(dhex-dhx)>>3;
                ddhy=(dhey-dhy)>>3;

                ak++;
                for (l=0;l<8;l++) {
                    lx=tx;
                    ly=ty;

                    for (m=0; m<8;m++) {

                        *cta3++=so->data[((lx>>8)&0xff)+(ly&0xff00)];

                        lx+=dhx;
                        ly+=dhy;
                        }
                    dhx+=ddhx;
                    dhy+=ddhy;
                    tx+=dvx;
                    ty+=dvy;
                    cta3+=(ta->x-8);

                    }
                }
            ak++;
            }
        }


    }


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

    if  (!sindone) dosine();

    return (void*)1;
    }

void  doit_twobb (void *in,cbitmap *s1,cbitmap *s2,cbitmap *d,int time, int duration) {

int oxx[21];
int oxy[21];

int i,k;
int xs,ys,d2;
int vx,vy;

int sx,sy;
float ti;

int oyx,oyy;

int    va,vb,vc,vd;
float   vaa,vab,vac,vad;

int    sa,sb,sc,sd;

    ti=((float)time)/1000000;

    xs=(d->x>>3);
    ys=(d->y>>3);

    va=(int)((1024.0/((float)ys))*2);
    vb=(int)((1024.0/((float)ys))*1);

    vc=(int)((1024.0/((float)xs))*1);
    vd=(int)((1024.0/((float)xs))*1);

    sa=(int)(1000*ti);
    sb=(int)(500*ti);

    sc=(int)(500*ti);
    sd=(int)(300*ti);

    vaa=8*256;
    vab=8*256;

    vac=16*256;
    vad=32*256;

    sx=(int)((32+16*sin(2*3.1415/3*ti))*256);
    sy=(int)((48+32*cos(2*3.1415/3*ti))*256);

    for (i=0; i<(xs+1) ;i++) {
        oxx[i]=((int)(vac*sinfloat[sc&0x3ff]))+sx;
        oxy[i]=((int)(vad*sinfloat[sd&0x3ff]))+sy;

        sc+=vc;
        sd+=vd;

        }

    d2=0;
    for (i=0; i<(ys+1); i++) {

        oyx=((int)(vaa*sinfloat[sa&0x3ff]))+sx;
        oyy=((int)(vab*sinfloat[sb&0x3ff]))+sy;

        sa+=va;
        sb+=vb;

        for (k=0; k<(xs+1); k++) {

         vx=(((k<<3))<<8)+oyx+oxx[k];
         vy=(((i<<3))<<8)+oyy+oxy[k];


         tiles[d2].x=vx;
         tiles[d2].y=vy;
         d2++;
            }
        }
    rendertiles(s1,d);
    }

void  exit_twobb (void *dat) {


    }

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

    if  (!sindone) dosine();

    return (void*)1;
    }


void  doit_twirl (void *in,cbitmap *s1,cbitmap *s2,cbitmap *d,int time, int duration) {


int i,k;
int xs,ys,d2;

int vx,vy;
float tx,ty;
float ti;
int rad,r2;
int angsin,angcos;
int toff;
int rom;

float zx,zy,zom;

    ti=((float)time)/1000000;

    zom=1+0.25*sin(2*3.14159265*ti*0.3);
        
    zx=256*8*zom;
    zy=256*4*zom;    

    xs=d->x>>3;
    ys=d->y>>3;

    toff=(int)(ti*300);

    d2=0;
    for (i=-(ys>>1); i<((ys>>1)+1); i++) {

        r2=i*i;

        for (k=-(xs>>1); k<((xs>>1)+1); k++) {

         rad=k<<1;
         rad*=rad;
         rad+=r2;

         rom=sin88[((rad)+toff)&0x3ff];

         angsin=((rom)&0x3ff);
         angcos=(angsin+256);

         tx=((float)k)*zx;//<<(3+8)));
         ty=((float)i)*zy;//<<(2+8)));

         vx=(int)(tx*sinfloat[angsin]-ty*sinfloat[angcos]);
         vy=(int)(tx*sinfloat[angcos]+ty*sinfloat[angsin]);

         tiles[d2].x=vx+(128<<8);
         tiles[d2].y=vy+(128<<8);
         d2++;
            }
        }

    rendertiles(s1,d);
    }

void  exit_twirl (void *dat) {


    }

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

    if  (!sindone) dosine();

    return (void*)1;
    }


void  doit_twabb (void *in,cbitmap *s1,cbitmap *s2,cbitmap *d,int time, int duration) {

int oxx[21];
int oxy[21];

int i,k;
int xs,ys,d2;

int vx,vy;
float tx,ty;
float ti;
int rad,r2;
int toff;

float zx,zy,zom,ztr;
int oyx,oyy;

int    va,vb,vc,vd;
float   vaa,vab,vac,vad;

int    sa,sb,sc,sd;

    ti=((float)time)/1000000;

    xs=(d->x>>3);
    ys=(d->y>>3);

    va=(int)((1024.0/((float)ys))*2);
    vb=(int)((1024.0/((float)ys))*1);

    vc=(int)((1024.0/((float)xs))*1);
    vd=(int)((1024.0/((float)xs))*1);

    sa=(int)(1000*ti);
    sb=(int)(500*ti);

    sc=(int)(500*ti);
    sd=(int)(300*ti);

    vaa=4*256;
    vab=4*256;

    vac=4*256;
    vad=8*256;

    zom=1+0.25*sin(2*3.14159265*ti);
        
    zx=8*zom*256;
    zy=4*zom*256;

    xs=d->x>>3;
    ys=d->y>>3;

    toff=(int)(ti*300);

    for (i=0; i<(xs+1) ;i++) {
        oxx[i]=((int)(vac*sinfloat[sc&0x3ff]));
        oxy[i]=((int)(vad*sinfloat[sd&0x3ff]));

        sc+=vc;
        sd+=vd;

        }

    d2=0;
    for (i=-(ys>>1); i<((ys>>1)+1); i++) {

        r2=i*i;

        oyx=((int)(vaa*sinfloat[sa&0x3ff]));
        oyy=((int)(vab*sinfloat[sb&0x3ff]));

        sa+=va;
        sb+=vb;

        for (k=-(xs>>1); k<((xs>>1)+1); k++) {

         rad=k<<1;
         rad*=rad;
         rad+=r2;

         vx=oyx+oxx[k+xs>>1];
         vy=oyy+oxy[k+xs>>1];

         ztr=0.8+0.2*sinfloat[((rad)+toff)&0x3ff];

         tx=((float)k)*zx;//<<(3+8)));
         ty=((float)i)*zy;//<<(2+8)));

         vx+=(int)(tx*ztr);
         vy+=(int)(ty*ztr);

         tiles[d2].x=vx+(128<<8);
         tiles[d2].y=vy+(128<<8);
         d2++;
            }
        }

    rendertiles(s1,d);
    }

void  exit_twabb (void *dat) {


    }


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

    return 0;
    }

void  doit_null (void *in,cbitmap *s1,cbitmap *s2,cbitmap *d,int time,int duration) {

    }

void  exit_null (void *) {

    }
  */
