/*
**
**      Project     : 16BitFillDemo - this is the main file
**      Version     : 1.0
**      File        : 16BitFillDemo - Demonstration of using the 16 Bit mode.
**                                    Fills some rectangles into the screen.
**                               Can be aborted with keystroke or mouseclick.
**
**      Authors     : David Göhler, Uwe Röhm
**      Date   Init : 21. November 1992
**             Last : 28. April 1993
**      Company     : Village Tronic Marketing GmbH, Hannover, Germany
**
**      To compile with
**         DICE          type "make"
**         SAS/C V6.x    type "sc LINK OPT PARMS=REGS NOSTKCHK 8BitFillDemo.c vilintuisup.c"
**      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 <stdlib.h>

BOOL Demo16Bit(struct Screen *s, struct Dimensions *dm, ULONG sigs);

static char Version[] = "$VER: 16BitFillDemo 1.0 (24.9.93) (c) 1993 by Village Tronic Marketing GmbH";

extern struct Library *SysBase;
extern struct Library *DOSBase;
struct Library *VilIntuiBase;
struct Library *IntuitionBase;
struct Library *GfxBase;

main()
{
   struct Dimensions     dm;  /* structure with dimensions for the new screen */
   struct NewWindow      nw;  /* to open a window on that screen    */
   struct Screen        *s = NULL; /* pointer to the new screen */
   struct Window        *w = NULL; /* pointer to the new window */

   /*
    *    some libraries are always necessary.
    *    if the vilintuisup.library can't be opened, there might be
    *    no Picasso-II builtin.
    */
   if (VilIntuiBase = OpenLibrary("vilintuisup.library",0))
   {
     if (IntuitionBase = OpenLibrary("intuition.library",0))
     {
       if (GfxBase = OpenLibrary("graphics.library",0))
       {
	 /*
	  *    the easy way to open a village screen is to
	  *    specify the desired dimensions in a "struct Dimensions"
	  *    structure.
	  */
	 dm.width  = 800;    /* Breite in Pixeln  */
	 dm.height = 600;    /* Höhe   in Pixeln  */
	 dm.depth  = 16;     /* Tiefe in Bit      */

	 /*
	  *    this will open a screen, if nothing goes wrong
	  */
	 if ( s = OpenVillageScreen(&dm) )
	 {
	   /*
	    *    Now we have to fill out the "struct NewWindow" structure for
	    *    a window the will fill the entire screen. To hear about mouse
	    *    clicks and key strokes we specify IDCMP_VANILLAKEY and
	    *    IDCMP_MOUSEBUTTONS
	    */
	   nw.LeftEdge  = 0;         /* window start is at position 0,0 */
	   nw.TopEdge   = 0;
	   nw.Width     = s->Width;  /* window as width and height as the screen */
	   nw.Height    = s->Height;
	   nw.FirstGadget = NULL;    /* no gadgets */
	   nw.Title     = NULL;
	   nw.IDCMPFlags= IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS;
	   nw.Flags     = WFLG_BORDERLESS | WFLG_RMBTRAP | WFLG_ACTIVATE;
	   nw.Type      = CUSTOMSCREEN;
	   nw.Screen    = s;

	   if ( w = OpenWindow(&nw) )
	   {
	     struct Message *msg;

	     /*
	      * we are waiting for key strokes, mouse buttons and CTRL_C
	      */
	     ULONG           sigs = SIGBREAKF_CTRL_C | (1 << w->UserPort->mp_SigBit);

	     /*
	      *   Die Rechtecke zeichnen, bis abgebrochen wurde
	      */
	     Demo16Bit(s, &dm, sigs);

	     /*
	      *   it's better to read all messages before closing the window
	      */
	     while ( msg = GetMsg(w->UserPort) )
	       ReplyMsg( msg );
	     CloseWindow(w);               /* close the window */

	   }
	   CloseVillageScreen(s);          /* close the screen */

	 }
	 else
	 {  PutStr("can't open VILLAGE-Screen in 16 bit\n");
	 }
	 CloseLibrary(GfxBase);

       }
       CloseLibrary(IntuitionBase);

     }
     CloseLibrary(VilIntuiBase);

   }
   else
   {  PutStr("can't open \"vilintuisup.library\"\n");
   }

   return 0;
}

/*
 * the following code will work for 15 and 24 bit screen without
 * any modification, too.
 */

BOOL Demo16Bit(struct Screen *s, struct Dimensions *dm, ULONG sigs)
{
   register WORD xpos = 0, ypos = 0;
   UBYTE *memstart;
   int   bpp = (dm->depth+1) / 8;
   struct VilFillRecord vilfill = { 0,0,0,0,0 };

   /*
   /* This is important for the blitter use !
    */
   Forbid();
   ScreenToFront(s);        /* screen must be in displaymem !!! */
   memstart = LockVillageScreen(s);
   Permit();

   while (CheckSignal(sigs) == 0)
   {
     xpos   = rand() % s->Width;
     ypos   = rand() % s->Height;

     /*
      *     You have to supply the start address, not position,
      *     where the fill should start.
      */
     vilfill.DestAdr   = (APTR)(memstart +(xpos*bpp + (ypos * s->Width*bpp)));
     vilfill.DestPitch = s->Width;
     vilfill.Width     = rand() % (s->Width-xpos);
     vilfill.Height    = rand() % (s->Height-ypos);
     vilfill.Color     = rand() % 16777216;

     VillageRectFill(s,&vilfill); /* does it's own WaitVillageBlit() inside */

   } /* while !CheckSignal() */

   UnLockVillageScreen(s);

   return TRUE;
}


