#include<stdlib.h>
#include"vbe2.h"
#include<time.h>
/* =(define)============================================================================ */

#define slimcharwith 13
#define fatcharwith 35

#define m320x200x16
//#define m640x400x16
//#define m800x600x16
//#define m1024x768x16

#ifdef m1024x768x16
 #define X_RES 640
 #define Y_RES 400
 #define BPP   16
#endif

#ifdef m800x600x16
 #define X_RES 640
 #define Y_RES 400
 #define BPP   16
#endif

#ifdef m640x400x16
 #define X_RES 640
 #define Y_RES 400
 #define BPP   16
#endif

#ifdef m320x200x16
 #define X_RES    320
 #define Y_RES    200
 #define BPP      16
#endif


/* =(variables)========================================================================= */
#define COUNTERSTEP 30*2

extern unsigned char blur_buffer[320*21];
extern void writechar(long,long);		//thats the external proc.
extern void writechar2(long,long);		//thats the external proc.
extern void maggeonscreen(char*,char*);
extern void initasmcode();
extern unsigned char credits[320*200*3];
unsigned char credits32b[320*200*4];
//unsigned char tex[256*256*4];

extern unsigned short *vid_point;
unsigned char *screen;

//plsm
unsigned char cosine[256];
unsigned char p1,p2,p3,p4;


/* ==(procedures)======================================================================= */
/* ===================================================================================== */


void memory_error()
{
  printf("\nNot enough memory!\n");
  exit(1);
}

/* ===================================================================================== */
/* ===================================================================================== */

void init_demo_system(short x,short y,short bpp)
{
  int mode;
  if ((screen = (unsigned char*)malloc(X_RES*Y_RES*4)) == NULL) memory_error();
  mode = testmode(x,y,bpp);
  initmode(mode);
}

/* ===================================================================================== */
/* ===================================================================================== */

void exit_demo_system()
{
  free(screen);
  settextmode();
}

/* ===================================================================================== */
/* ===================================================================================== */


void __write13h(int yposition,char *str, int anzahl, int bufferpos){
	int x,lol;
        int w,w2;

	if (yposition==0) {yposition=( ((X_RES- (strlen(str)*slimcharwith)) >> 1)+(anzahl>>1) )<<2;}
	                  else yposition=(yposition+anzahl>>2)<<2;

        memset(blur_buffer,0,21*320*4);

/* =(print the string)================================================================= */
        for (x=0;x<str[x]!='\0';x++)
		writechar((x*slimcharwith<<2)+yposition, 12*(str[x]-65));


/* =(blur it!)========================================================================== */
        if (anzahl!=0)
        for (w=0;w<320*20*4;w+=4){
          lol=0;

          for (w2=0;w2<anzahl<<2;w2+=4)
            lol+=blur_buffer[w+w2] + blur_buffer[w-w2];
            /* achtung! da b/w font ist, wird hier nur der ROTE kanal gebraucht
               und berechnet, und als b/w ausgegeben! */

//00/1L/1L/4mal = goldig
//00/1R/1L/4mal = rtlich
//1R/00/1L/3mal = orange/goldif
//if (lol>80)          lol-=80;
          lol=lol / (anzahl);//<<1);
          blur_buffer[w  ]=lol>>2;
          blur_buffer[w+1]=lol>>2;
          blur_buffer[w+2]=lol>>3;
        }

        maggeonscreen(blur_buffer,screen+bufferpos*320);
}



void __write13h2(int yposition,char *str, int anzahl, int bufferpos){
	int x,lol;
        int w,w2;


	if (yposition==0) yposition=( ((X_RES- (strlen(str)*fatcharwith)) >> 1)+(anzahl>>1) )<<2;
	                  else yposition=(yposition+anzahl>>2)<<2;

        memset(blur_buffer,0,21*320*4);

/* =(print the string)================================================================= */
        for (x=0;x<str[x]!='\0';x++)
            writechar2((x*fatcharwith<<2)+yposition, 12*(str[x]-65));

/* =(blur it!)========================================================================== */
        if (anzahl!=0)
        for (w=0;w<320*20*4;w+=4){
          lol=0;
          for (w2=0;w2<(anzahl<<2);w2+=4)
            lol+=blur_buffer[w+w2] + blur_buffer[w-w2];
            // achtung! da b/w font ist, wird hier nur der ROTE kanal gebraucht
            // und berechnet, und als b/w ausgegeben!

           lol=lol / (anzahl);//<<1);
           blur_buffer[w  ]=lol>>3;// 3  2  1
           blur_buffer[w+1]=lol>>2;
           blur_buffer[w+2]=lol>>2;
        }

        maggeonscreen(blur_buffer,screen+bufferpos*320);
}



void convert2432(unsigned char *src, unsigned char *dest, long size)
{
int n,pos,pos1;
pos=pos1=0;
for (n=0;n<size;n++)
{
           dest[pos+2]=src[pos1];
           dest[pos+1]=src[pos1+1];
           dest[pos+0]=src[pos1+2];
           pos1+=3;
           pos+=4;
           }
}





void do_plasma_precalc(){
int x;
float v,vadd;
	v=0.0;
	vadd=(2.0*PI/256.0);
        for (x=0;x<256;x++){
                cosine[x]=cos(v)*32;
                v+=vadd;
        }
}

void do_plasma(){
  int x,y;
  char tmp;
  long l,l1;
  unsigned int sc1,sc2;

          sc1=0;
          sc2=(64000<<2)-4;

          for (y=0;y<Y_RES;y++)
          {
          for (x=0;x<X_RES;x++)
              {

                 l=(long)screen[(x+y*X_RES) <<2];
                 l1=(long)screen[((319-x)+(199-y)*X_RES) <<2];

                 if (l!=0||l1!=0){
                   tmp+=cosine[p4]+cosine[p1]+cosine[p3]+cosine[p2]+((x*y)>>6);
                   tmp>>=2;
                   if (tmp<1) tmp=0-tmp;
                 }

                 if (l!=0){
//                   screen[sc1]+=tmp;//0 2
//                   screen[sc1+2]+=tmp;
                   screen[sc1]+=tmp;//0 2
                   screen[sc1+2]+=tmp;
                 }
                 sc1+=4;

                 if (l1!=0){   //1 2
//                   screen[sc2+1]+=tmp;
//                   screen[sc2+2]+=tmp;
                   screen[sc2+1]+=tmp;
                   screen[sc2+2]+=tmp;
                 }
                 sc2-=4;

              }
              p2+=4;
              p1+=4;
          }
          p4+=5;
          p1-=1;
          p3-=3;
}
/**/



int main(int argc,char *argv[])
{
        int x,y,counter=0;
        int a;
        long frames;
        double fps;
        time_t tim2;

        time_t tim = time (NULL);

        __djgpp_nearptr_enable();
        init_demo_system(X_RES,Y_RES,BPP);
        initasmcode();                    //buffers auf 0 setzen
        memset(screen,0,X_RES*Y_RES*4);
	srand(0x46c);

        do_plasma_precalc();
        convert2432(credits,credits32b,64000);

        x=y=p1=p2=p3=p4=frames=0;

        while(!kbhit()){

            if ((x=random()%10)>3) y=random()%8;
            if (x<3) x+=15; else x+=4;



if (counter<COUNTERSTEP*1){
            __write13h2(0,"`D[[\0",x,(35+y)<<2);
            __write13h2(0,"\\CODE\\[[\0",x,(60+y)<<2);
            __write13h(0,"IQUITO[[[[[[\0",x,(85+y)<<2);
}

else

if (counter<COUNTERSTEP*2){
            __write13h2(0,"_D[[[\0",x,(105+y)<<2);
            __write13h2(0,"\\CODE\\[[[\0",x,(130+y)<<2);
            __write13h(0,"GENOZ[TASH[[[[[[[[\0",x,(155+y)<<2);
}

else

if (counter<COUNTERSTEP*3){
            __write13h2(0,"[[VESA\0",x,(35+y)<<2);
            __write13h2(0,"[[ENGINE\0",x,(60+y)<<2);
            __write13h(0,"[[[[[[FAIRWAY\0",x,(85+y)<<2);
} else

if (counter<COUNTERSTEP*4){
            __write13h2(0,"MUSIC[[\0",x,(125+y)<<2);
            __write13h(0,"PICARD[[[[[[\0",x,(150+y)<<2);
}

else

if (counter<COUNTERSTEP*5){

            __write13h2(0,"[[\\GFX\\\0",x,(35+y)<<2);
            __write13h(0,"[[[[[[SID[SWEEPER\0",x,(60+y)<<2);
} else counter=0;


counter++;
/**/
            do_plasma();
//__write13h2(0,"\\CREDS\\[[\0",x,(160+y)<<2);
            blitscreen3216(screen,vid_point,X_RES*Y_RES);
            memset(screen,0,X_RES*Y_RES*4);
//memcpy(screen,credits32b,320*200*4);

            frames++;
        }

  tim2 = time(NULL);

  exit_demo_system();

  fps=frames/difftime(tim2,tim);

  printf("fps: %f",fps);
  return 0;
}
/* ===================================================================================== */
