/*
**
**      Project     : FastFillDemo - this is the main file
**      Version     : 1.0
**      File        : FastFillDemo - how fast is the blitter?
**
**      Author      : David Göhler, Hannover, Germany
**      Date   Init : 21. November 1992
**             Last : 24. September 1993
**      Company     : VillageTronic, Hannover, Germany
**
**      Type "make" to compile it with DICE.
**      For other compilers you may have to do minor changes.
**
**      This programm will only run, if the monitor file supplied
**      with your graphics card is installed and running.
**
**      THIS IS NOT PD. THIS IS COMMERCIAL SOFTWARE.
**
*/
#include "SysInclude.h"
#include "vilintuisup.h"
#include <clib/timer_protos.h>

double GetAmiTime(void);
int    Demo8Bit(struct Screen *s, struct Dimensions *dm);
void   SetPalette256(struct Screen *s);

struct Library *VilIntuiBase;
struct Library *IntuitionBase;
struct Library *GfxBase;

main()
{
   struct Dimensions     dm;
   struct Screen         *s = 0;

   if (VilIntuiBase = OpenLibrary ("vilintuisup.library",0))
   { if (IntuitionBase = OpenLibrary("intuition.library",0))
     { if (GfxBase = OpenLibrary("graphics.library",0))
       {
	 dm.width  = 640;
	 dm.height = 480;
	 dm.depth  = 8;     /* depth of the new screen */

	 if (s = OpenVillageScreen(&dm)) /* open it */
	 {
	    Demo8Bit(s,&dm);       /* do the demo */
	    CloseVillageScreen(s); /* and close the screen */
	 }
	 else
	 {  PutStr("Can't open VILLAGE-Screen in 8 bit\n");
	 }
	 CloseLibrary(GfxBase);
       }
       CloseLibrary(IntuitionBase);
     }
     CloseLibrary(VilIntuiBase);
   }
   else
   {  PutStr("Can't open \"vilintuisup.library\"\n");
   }

   return 0;
}

/*
 * Demo8Bit fills up the display
 */

int Demo8Bit(struct Screen *s, struct Dimensions *dm)
{
   register WORD x = 0;
   UBYTE *memstart;
   double start;

   if (dm->depth != 8)
   {  PutStr("Not a 8 Bit Videomode\n");
      return 0;
   }

   LockVillageScreen(s);
   SetPalette256(s);
   UnLockVillageScreen(s);

   {  struct VilCopyRecord vilcopy =
      {  0, /* Source offset from beginning of displaymem */
	 0,
	 640,              /* Width of source display */
	 640,              /* Width of destination display */
	 640,              /* Width of rectangle box */
	 480,              /* Height of rectangle box */
	 VIL_ZERO
      };


      /* This is new for the blitter demo */

      Forbid();            /* screen must be in displaymem !!! */
      ScreenToFront(s);
      memstart = LockVillageScreen(s);
      Permit();
      WaitVillageBlit();

      vilcopy.SrcAdr           = memstart;
      vilcopy.DestAdr          = memstart;
      vilcopy.Width            = s->Width;
      vilcopy.Height           = s->Height;

      /*
       * that's it: fill the area with 0x00s. This is twice as fast
       * as using copying.
       */

      vilcopy.ROP              = VIL_ZERO;

      x = 500;

      start = GetAmiTime();
      while (x--)
      {
	    VillageBlitCopy(s,&vilcopy);
	    WaitVillageBlit();
	    /*
	     * use 0xFF for filling
	     */
	    vilcopy.ROP              = VIL_ONE;
	    VillageBlitCopy(s,&vilcopy);
	    WaitVillageBlit();
	    /*
	     * use 0x00 for filling
	     */
	    vilcopy.ROP              = VIL_ZERO;
      }
      start = GetAmiTime() - start;

      UnLockVillageScreen(s);
      Printf("Duration in seconds: %5ld\n",(ULONG)start);
      Printf("Transfer rate  %5ld KByte/s\n",
	      (ULONG)((s->Width * s->Height) / (start)) * 1000 / 1024);
   }
   return 0;
}


#include <devices/timer.h>

struct Library *TimerBase;
/*
 * GetAmiTime returns a float value. It's the system time in
 * seconds. If the value returned is -1.0, something went wrong.
 */

double GetAmiTime(void)
{
   struct timeval time = {0,0};      /* tv_secs & tv_micro */
   struct timerequest timereq = {0};
   double retcode = -1.0;

   if (!OpenDevice(TIMERNAME,UNIT_ECLOCK,(struct IORequest *)&timereq,0L))
   {  TimerBase = (struct Library *)timereq.tr_node.io_Device;

      GetSysTime(&time);

      retcode = (double)(time.tv_secs) + (double)(time.tv_micro)/1000000.0;
      CloseDevice((struct IORequest *)&timereq);
   }

   return retcode;
}


void SetPalette256(struct Screen *s)    /* Palette for 256 Color Demo */
{
   UBYTE entry;

   SETRGB(s,0x00, 0x00<<2, 0x00<<2, 0x00<<2);        /* black */
   SETRGB(s,0x01, 0x15<<2, 0x15<<2, 0x15<<2);        /* dark grey */
   SETRGB(s,0x02, 0x2a<<2, 0x2a<<2, 0x2a<<2);        /* light grey */
   SETRGB(s,0x03, 0x3f<<2, 0x3f<<2, 0x3f<<2);        /* white */

   for(entry = 0x00; entry < 0x2a; entry++)
   {
      SETRGB(s,entry + 0x04, 0x3f<<2, (entry * 3 / 2)<<2, 0x00<<2);           /* red -> yellow */
      SETRGB(s,entry + 0x2e, ((0x29 - entry) * 3 / 2)<<2, 0x3f<<2, 0x00<<2);  /* yellow -> green */
      SETRGB(s,entry + 0x58, 0x00<<2, 0x3f<<2, (entry * 3 / 2)<<2);           /* green -> cyan */
      SETRGB(s,entry + 0x82, 0x00<<2, ((0x29 - entry) * 3 / 2)<<2, 0x3f<<2);  /* cyan -> blue */
      SETRGB(s,entry + 0xac, (entry * 3 / 2)<<2, 0x00<<2, 0x3f<<2);           /* blue -> magenta */
      SETRGB(s,entry + 0xd6, 0x3f<<2, 0x00<<2, ((0x29 - entry) * 3 / 2)<<2);  /* magenta -> red */
   }
}


