
   /***********************************************************************
   *                                                                      *
   *                            COPYRIGHTS                                *
   *                                                                      *
   *   Copyright (c) 1990  Commodore-Amiga, Inc.  All Rights Reserved.    *
   *                                                                      *
   ***********************************************************************/

#include "app.h"
#include <graphics/gfxmacros.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <intuition/gadgetclass.h>

#include <stdlib.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <utility/tagitem.h>

extern struct Custom custom;

ULONG timeout = 0L;
ULONG blanked = 0L;
ULONG seconds = 10L;
short rangex, rangey;
short hlfrngx, hlfrngy;

struct Gadget *secgad;
struct Screen *s = NULL;
struct Window *w = NULL;
struct RastPort *rp;

#define NSTARS 150

short x[NSTARS],y[NSTARS],z[NSTARS];
short xo[NSTARS],yo[NSTARS],jo[NSTARS];

USHORT chip SpriteData[] = {
               0,0,
               0,0,
               0,0 };

int  rand(void);
BOOL setupBlanker(void);
VOID BlankerAction(struct CxMsg *cxm,CxObj *co);
VOID mkpoint(short);
VOID DrawStar(short, long, long);
VOID mysetupCustomGadgets(struct Gadget **gad);
VOID myHandleGadget(ULONG gad,ULONG code);
VOID MyHandleCustomSignal(VOID);

BOOL setupBlanker(VOID)
{
   CxObj   *objectlist;

   seconds = ArgInt( ttypes, "SECONDS", 300 );

   objectlist=CxCustom( BlankerAction, 0L);

   if (CxObjError(objectlist))
   {
      D( printf("blanker: filter error %lx\n", CxObjError(objectlist) ) );
      DeleteCxObjAll(objectlist);
      return(0);
   }

   AttachCxObj(broker, objectlist);
   return(TRUE);
}

VOID BlankerAction(struct CxMsg *cxm,CxObj *co)
{
   register struct InputEvent *ie;

   /* D( kprintf("BlankerAction\n") ); */

   /* i KNOW that all messages getting this far are CXM_IEVENT   */
   ie = (struct InputEvent *) CxMsgData(cxm);


   if(ie->ie_Class==IECLASS_TIMER)
   {
      /* D( printf("IECLASS_TIMER\n"); ) */
      if(! blanked)
      {
         if ((IntuitionBase->FirstScreen->MouseX >= 
                IntuitionBase->FirstScreen->Width - 5) &&
             (IntuitionBase->FirstScreen->MouseY >=
                IntuitionBase->FirstScreen->Height - 5) &&
             (timeout >= 5)) 
         {
            D( printf("########Blank Screen\n"); )
            /* Blank(); */
            Signal(maintask,csigflag);
            blanked=TRUE;
         }
         if ((!((IntuitionBase->FirstScreen->MouseX >= 
                                   IntuitionBase->FirstScreen->Width - 5) &&
             (IntuitionBase->FirstScreen->MouseY < 5))) && (! blanked))
         {
            D( printf("blanked=0x%lx Bump timeout=%ld\n",blanked,timeout);)
            if(++timeout >= ((ULONG)(seconds*10L)))
            {
               D( printf("########Blank Screen\n"); )
               /* Blank(); */
               Signal(maintask,csigflag);
               blanked=TRUE;
            }
         }
     }
   } else {
      if(ie->ie_Class!=IECLASS_TIMER)
      {
         D( printf("########UnBlank\n"); )
         /* UnBlank(); */
         timeout=0L;
         blanked=FALSE;
      }
   }

}
VOID mkpoint (i)
register short i;
{
        x[i] = rand() % rangex - hlfrngx;
        y[i] = rand() % rangey - hlfrngy;
        z[i] = 255;
}
VOID mysetupCustomGadgets(struct Gadget **gad)
{
   struct NewGadget ng;

   ng.ng_VisualInfo=vi;

   ng.ng_TopEdge    = topborder+27;
   ng.ng_LeftEdge   = 10;
   ng.ng_Width      = 40;
   ng.ng_Height     = 12;
   ng.ng_GadgetText = "Hide";
   ng.ng_TextAttr   = &mydesiredfont;
   ng.ng_GadgetID   = GAD_HIDE;
   ng.ng_Flags      = NULL;
   ng.ng_VisualInfo = vi;
   *gad = CreateGadget(BUTTON_KIND,*gad, &ng,TAG_DONE);

   ng.ng_TopEdge    = topborder+27;
   ng.ng_LeftEdge   = 60;
   ng.ng_Width      = 40;
   ng.ng_Height     = 12;
   ng.ng_GadgetText = "Quit";
   ng.ng_TextAttr   = &mydesiredfont;
   ng.ng_GadgetID   = GAD_DIE;
   ng.ng_Flags      = NULL;
   ng.ng_VisualInfo = vi;
   *gad = CreateGadget(BUTTON_KIND,*gad, &ng,TAG_DONE);

   ng.ng_TopEdge    = topborder+5;
   ng.ng_LeftEdge   = 80;
   ng.ng_Width      = 60;
   ng.ng_Height     = 14;
   ng.ng_GadgetText = "Seconds";
   ng.ng_TextAttr   = &mydesiredfont;
   ng.ng_GadgetID   = GAD_SECS;
   ng.ng_Flags      = NULL;
   ng.ng_VisualInfo = vi;
   secgad = *gad = CreateGadget(INTEGER_KIND,*gad, &ng,GTIN_Number,seconds,GTIN_MaxChars,4,STRINGA_Justification,STRINGRIGHT,TAG_DONE);
}
VOID myHandleGadget(ULONG gad,ULONG code)
{
   D( kprintf("custom: HandleGadget(%lx)\n",gad); )
   switch(gad)
   {
      case GAD_HIDE:
            D( kprintf("custom: HandleGadget() GAD_HIDE\n"); )
            shutdownWindow();
            break;
      case GAD_DIE:
            D( kprintf("custom: HandleGadget() GAD_DIE\n"); )
            terminate();
      case GAD_SECS:
            D( kprintf("custom: HandleGadget() GAD_SECS\n"); )
            seconds=((struct StringInfo *)secgad->SpecialInfo)->LongInt;
   }
}
VOID MyHandleCustomSignal(VOID)
{
   struct NewWindow nw = {
      0,0,
      0,0,
      -1,-1,
      0,
      SIMPLE_REFRESH | RMBTRAP | BACKDROP | BORDERLESS | ACTIVATE,
      0,
      0,
      0,
      0,
      0,
      0,0,0,0,
      CUSTOMSCREEN
      };

long xs, ys;
short magic;
register short i, j, inc;	/* k = 0; */
short wide, high;

   magic = rand() % 100 + 170;
   inc = (rand() % 8) / 2;
   inc = inc ? inc : 2;

   if( ! s)
   {
      s=OpenScreenTags(NULL, SA_DisplayID, HIRESLACE_KEY, SA_Depth, 2,
                              SA_Overscan, OSCAN_STANDARD, TAG_END);
      rp = &(s -> RastPort);
      if( ! w)
      {
         nw.Width = wide = s->Width;
         nw.Height= high = s->Height;
         nw.Screen=s;
         
         w = OpenWindow(&nw);
      }
      if(w)
      {
         SetPointer(w,SpriteData,1,1,0,0);			/* Blank Pointer	*/
         SetRast (rp, 0L);							/* Clear Screen		*/
         SetRGB4 (&(s -> ViewPort), 0L, 0L, 0L, 0L);/* Set Color Palette*/
         SetRGB4 (&(s -> ViewPort), 1L, 3L, 3L, 3L);
         SetRGB4 (&(s -> ViewPort), 2L, 8L, 8L, 8L);
         SetRGB4 (&(s -> ViewPort), 3L, 15L, 15L, 15L);
      }

      rangex = (wide/5)*3;
      hlfrngx = rangex/2;
      rangey = (high/5)*3;
      hlfrngy = rangey/2;
      for (i=0; i<NSTARS; i++)						/* Plot initial			*/
                mkpoint (i);						/*  starfield			*/
      for (i=0; i<NSTARS; i++)						/* Randomize the stars	*/
                z[i] = rand() % 256;				/*  distance away		*/

      FOREVER {
         if (blanked==FALSE)						/* Flag set by UI		*/
         {
            if(w)
            {
               ClearPointer(w);						/* Restore old Pointer	*/
               CloseWindow(w);
               w=NULL;
            }
            if(s)
            {
               CloseScreen(s);
               s=NULL;
               }
            break;
         }
         for (i=0; i<NSTARS; i++) {
            if ((z[i] -= inc) <= 0)					/* Increment, kill old	*/
               mkpoint (i);							/*  and get a new one	*/
            xs = x[i] * magic / z[i] + wide / 2;	/* Calc new X pos		*/
            ys = y[i] * magic / z[i] + high / 2;	/* Calc new Y pos		*/
            j = 256-z[i] >> 5;						/* Get Dist as 0-7		*/
            SetAPen(rp, 0L);
            switch (jo[i])
            {
               case 0:
               case 1:
               case 2:
               case 3:
               case 4:
                 {
                    WritePixel (rp, xo[i], yo[i]);
                    break;
                 }
               case 5:
                 {
                    RectFill (rp, xo[i], yo[i], xo[i]+1, yo[i]+1);
                    break;
                 }
               case 6:
                 {
                    RectFill (rp, xo[i]-1, yo[i]-1, xo[i]+1, yo[i]+1);
                    break;
                 }
               case 7:
                 {
                    RectFill (rp, xo[i]-1, yo[i]-1, xo[i]+2, yo[i]+2);
                    break;
                 }
               default:
                 {
                    SetAPen(rp, 1L);
                    Move (rp, 0, 0);
                    Draw (rp, wide - 1, 0);
                    break;
                 }
            }
            if (xs < 2 || xs > wide - 4 || ys < 2 || ys > high - 3)
               mkpoint (i);							/* If offscreen, new	*/
            else
            {
               SetAPen(rp, 3L);
               switch (j)
               {
                  case 0:
                  case 1:
                  case 2:
                  case 3:
                    {
                       SetAPen(rp, (long) j);
                       WritePixel (rp, xs, ys);
                       break;
                    }
                  case 4:
                    {
                       WritePixel (rp, xs, ys);
                       break;
                    }
                  case 5:
                    {
                       RectFill (rp, xs, ys, xs+1, ys+1);
                       break;
                    }
                  case 6:
                    {
                       RectFill (rp, xs-1, ys-1, xs+1, ys+1);
                       break;
                    }
                  case 7:
                    {
                       RectFill (rp, xs-1, ys-1, xs+2, ys+2);
                       break;
                    }
                  default:
                    {
                       SetAPen(rp, 3L);
                       Move (rp, 0, 0);
                       Draw (rp, wide - 1, 0);
                       break;
                    }
               }
            xo[i] = xs;  yo[i] = ys;  jo[i] = j;
            }
         }
      }      
   }
}
