#include <time.h>
#include <math.h>
#include "e:\t\code\h\graph.h"
#include "e:\t\code\h\loadpcx.h"

#define DEG_256PERIOD_TORAD 0.02454369260616

int s1,s2,s3,s4;

void fwaitvretrace();
#pragma aux fwaitvretrace = \
"mov    dx,03DAh" \
"vr:" \
"in     al,dx" \
"test   al,8" \
"jz short vr" \
modify exact [eax edx];

void thing()
{
   outp(0x3d4,9);
   outp(0x3d5,3);
}

void roto(byte *scr,byte *pic,int sx,int sy,int rot,double scale)
{
   int dx,dy,sxi,syi,ox,oy;
   int wid,hei,owid;
   int i=0;
   static int cx=10,cy=150,xv,yv;
   int tx,ty;
   float off;

   owid=wid=*(short *)pic;
   hei=*(short *)(pic+2);
   pic+=4;
   wid<<=16,hei<<=16;

   sx<<=16,sy<<=16;

   sxi=(long)(cos(rot*DEG_256PERIOD_TORAD)*scale*65536);
   syi=(long)(sin(rot*DEG_256PERIOD_TORAD)*scale*65536);

   for(dy=0;dy<200;dy++)
   {
      ox=sx;
      oy=sy;
      for(dx=0;dx<320;dx++)
      {
         scr[i++]=pic[(sy>>16)*owid+(sx>>16)];
//         off=sqrt((cx-dx*2)*(cx-dx*2)+(cy-dy*2)*(cy-dy*2))/80;
//         off=((cx-dx*2)*(cx-dx*2)+(cy-dy*2)*(cy-dy*2))/30000.0;

//         sx+=sxi*off;
//         sy+=syi*off;
         sx+=sxi;
         sy+=syi;

xchk:
         if (sx>=wid) { sx-=wid; goto xchk; }
         else if (sx<0) { sx+=wid; goto xchk; }
ychk:
         if (sy>=hei) { sy-=hei; goto ychk; }
         else if (sy<0) { sy+=hei; goto ychk; }
      }
      sx=ox-syi;
      sy=oy+sxi;
      if (sx>=wid) sx-=wid;
      else if (sx<0) sx+=wid;
      if (sy>=hei) sy-=hei;
      else if (sy<0) sy+=hei;
   }

   if (!s4)
   {
      cx+=xv,cy+=yv;
      if (cx >= 160) xv--;
      else xv++;
      if (cy >= 100) yv--;
      else yv++;
   }
}

main()
{
   byte pal[768],*pic=loadpcx("thing.pcx",pal);
   byte *virt=malloc(64000);
   byte ang=rand();
   int wid,hei,x=0,y=0,f=0,i;
   double dist=0,di=0.01;
   char live=1;

   wid=*(short *)pic;
   hei=*(short *)(pic+2);

   setvideomode(19);
//   thing();
   setpal(pal);

   while(live)
   {
      if (kbhit())
      {
         switch(getch())
         {
            case '1':
               s1=!s1;
               break;
            case '-':
               s2++;
               break;
            case '+':
               if (s2) s2--;
               break;
            case '3':
               s3=!s3;
               break;
            case '4':
               s4=!s4;
               break;
            default:
               live=0;
               break;
         }
      }
      roto(virt,pic,x,y,s2?ang:ang++,dist);
      x++,y++;

      if (!s3)
      {
         dist+=di;
         if (x>wid) x=1;
         if (y>hei) y=1;
         if (dist>3.1) di=-0.01;
         else if (dist<0.02) di=0.01;
      }

for(i=0;i<s2;i++) fwaitvretrace();
      copyscreen((byte *)0xa0000,virt);
//memcpy(0xa0000,virt,32000);
      f++;
   }
   
   setvideomode(3);
   printf("%f frames/sec\n",(double)f/(clock()/CLOCKS_PER_SEC));
}
