
#include "dots.h"
#include <math.h>

#ifdef PSP

#define XS 480
#define YS 272

#else

#define XS 320 /* Must be multiple of SIZE */
#define YS 200

#endif

#define SIZE 32
#define PHASES 256

static signed char circle[PHASES][SIZE][2];

void dots_init(void)
{
    int n,i,r,maxr,tmp;
    double dr;

    maxr=sqrt((SIZE/2)*(SIZE/2)+(SIZE/2)*(SIZE/2))+1;

    for(r=0;r<PHASES;r++)
    {
        dr=(double)r/(double)PHASES*maxr;
        for(n=0;n<SIZE;n++)
        {
            i=n-SIZE/2;
            if(dr*dr-i*i<0)
                circle[r][n][0]=0;
            else
            {
                tmp=sqrt(dr*dr-i*i);
                if(tmp>=SIZE/2)
                    tmp=SIZE/2;
                circle[r][n][0]=tmp*2;
                circle[r][n][1]=SIZE/2-tmp;
            }
        }
    }
}

void dots(unsigned char *buf,int type,unsigned char col,int phase)
{
    int x,y,n,local,t,tmp;

    for(x=0;x<XS;x+=SIZE)
    {
        for(y=0;y<YS;y++)
        {
            if(y%SIZE==0)
            {
                t=sqrt((x-XS/2+SIZE/2)*(x-XS/2+SIZE/2)
                       +(y-YS/2+SIZE/2)*(y-YS/2+SIZE/2));
                tmp=(sin(x/40.0)+cos(y/40.0))*50-100;
            }
        
            switch(type%FADEIN)
            {
                case  0: local=(x/SIZE+y/SIZE)*10-200+phase*2; break;
                case  1: local=(x/SIZE)*13-200+phase*2; break;
                case  2: local=t-200+phase*2; break;
                case  3: local=phase*2-tmp; break;
                case  4: local=tmp+phase*2; break;
                default: local=phase;
            }
            if(local<0) local=0;
            if(local>=PHASES) local=PHASES-1;

            n=circle[local][y%SIZE][0];
            if(type&FADEIN)
            {
                t=SIZE/2-n/2;

                memset(&buf[x+y*XS],col,t);
                memset(&buf[x+y*XS+SIZE-t],col,t);
            }
            else
            {
                if(n)
                    memset(&buf[x+y*XS+circle[local][y%SIZE][1]],col,n);
            }
        }
    }
}
