/*
**
**      Project     : Styx - a nice line demo, well known, new implemented
**      Version     : 1.1
**      File        : Styx - Demonstration of using the 8 Bit mode
**                           Fills the entire screen with coloured lines.
**                           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 Styx.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"

BOOL StyxDemo(struct Screen *s, struct Dimensions *dm, ULONG sigs);
void SetPalette256(struct Screen *s);

static char Version[] = "$VER: StyxDemo 1.1 (28.04.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;  /* Struktur mit den Dimensionen des Screens */
   struct NewWindow      nw;  /* Struktur für das IDCMP Fenster           */
   struct Screen        *s = NULL;
   struct Window        *w = NULL;

   /*
    *    Wir benötigen eine Reihe von Libraries.
    *    Wenn keine Picasso im System vorhanden ist, kann die vilintuisup
    *    Library nicht geöffnet werden!
    */
   if (VilIntuiBase = OpenLibrary("vilintuisup.library",0))
   {
     if (IntuitionBase = OpenLibrary("intuition.library",0))
     {
       if (GfxBase = OpenLibrary("graphics.library",0))
       {
         /*
          *    Initialisieren der Dimensionen für den Bildschirm
          */
         dm.width  = 800;    /* Breite in Pixeln                                */
         dm.height = 600;    /* Höhe   in Pixeln                                */
         dm.depth  = 8;      /* Tiefe in Bit - 8 steht für 2^8(=256) Farben     */

         /*
          *    Den 256 Farben Screen öffnen
          */
         if ( s = OpenVillageScreen(&dm) )
         {
           /*
            *    Die NewScreen-Struktur vorbereiten. Auf dem Bildschirm wird ein
            *    Backdrop Fenster geöffnet, um von der Intuition IDCMP Messages
            *    bekommen zu können (Hier im Beispiel: Tasten und Mausklicks).
            */
           nw.LeftEdge  = 0; /*Das Fenster soll den ganzen Screen abdecken*/
           nw.TopEdge   = 0;
           nw.Width     = s->Width;
           nw.Height    = s->Height;
           nw.FirstGadget = NULL; /* keine Gadgets im Fenster */
           nw.Title     = NULL;
           nw.IDCMPFlags= IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS;
           nw.Flags     = WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_RMBTRAP | WFLG_ACTIVATE;
           nw.Type      = CUSTOMSCREEN;
           nw.Screen    = s;

           if ( w = OpenWindow(&nw) )
           {
             struct Message *msg;
             ULONG           sigs = SIGBREAKF_CTRL_C | (1 << w->UserPort->mp_SigBit);

             /*
              *   Die Linien zeichnen und danach warten (falls nicht abgebrochen)
              */
             StyxDemo(s, &dm, sigs);

             /*
              *   Als vorsichtige Menschen den UserPort leeren und dann
              *   erst das Fenster schließen.
              */
             while ( msg = GetMsg(w->UserPort) )
               ReplyMsg( msg );
             CloseWindow(w);               /* Fenster wieder schließen    */

           }
           CloseVillageScreen(s);          /* und Screen wieder schließen */

         }
         else
         {  PutStr("Konnte VILLAGE-Screen 8 Bit nicht öffnen\n");
         }
         CloseLibrary(GfxBase);

       }
       CloseLibrary(IntuitionBase);

     }
     CloseLibrary(VilIntuiBase);

   }
   else
   {  PutStr("Konnte \"vilintuisup.library\" nicht öffnen\n");
   }

   return 0;
}

struct OneLine {
   UWORD xs,ys,xe,ye,color;
} lines[100];

/*
 * StyxDemo zeichnet buntige schräge Linien über den ganzen Screen.
 */
BOOL StyxDemo(struct Screen *s, struct Dimensions *dm, ULONG sigs)
{
   register struct OneLine *lp = &lines[0];
   int   firstline= 0,    /* gerade gezeichnete Linie */
   maxline        =  80;  /* Anzahl linien auf dem Schirm */
   UBYTE color    =   4;  /* damit geht es los */
   WORD xsoff     =   4,  /* additive für x und y */
        ysoff     =  -4,
        xeoff     =   5,
        yeoff     =  -7;
   WORD xs        = 200,  /* Startpositionen */
        ys        = 200,
        xe        = 300,
        ye        = 237;
   UWORD width    = dm->width,
         height   = dm->height;
   UWORD loesch   = maxline - 1;

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

   /*
    *  Der Screen wird hier kurz gelocked und die
    *  256 Farben gesetzt.
    */
   LockVillageScreen(s);
   SetPalette256(s);
   UnLockVillageScreen(s);

   /*
    *  Bis zu einer Benutzereingabe...
    */
   while ( !CheckSignal( sigs) )
   {
      /* zuerst Linie zeichnen */
      LinePacked(s,xs,ys,xe,ye,color);

      /* dann Linie merken */
      lp->xs    = xs;
      lp->xe    = xe;
      lp->ys    = ys;
      lp->ye    = ye;
      lp->color = color;

      /* Farbzirkel weiterschalten, aber ohne die Farben 0-3 */
      color = (color - 3) % 252 + 4;

      /* eine Zeile löschen wenn nötig */
      if (loesch == 0)
      {  register struct OneLine *lp2;

         lp2 = &lines[(firstline+1) % maxline];
         LinePacked(s,lp2->xs,lp2->ys,lp2->xe,lp2->ye,0);
      }
      else
      {  loesch--; }

      /* ein wenig Zeigerarithmetik, Zeiger auf Zeilenspeicher ++ */
      lp++; firstline++;
      if (firstline == maxline)
      {  firstline = 0;
         lp = &lines[0];
      }

      /* an den Rändern wieder umdrehen */
      if (xs + xsoff >= width)  xsoff = -xsoff; else
      if (xs + xsoff <= 0)      xsoff = -xsoff;

      if (ys + ysoff >= height) ysoff = -ysoff; else
      if (ys + ysoff <= 0)      ysoff = -ysoff;

      if (xe + xeoff >= width)  xeoff = -xeoff; else
      if (xe + xeoff <= 0)      xeoff = -xeoff;

      if (ye + yeoff >= height) yeoff = -yeoff; else
      if (ye + yeoff <= 0)      yeoff = -yeoff;

      /* neue Position berechnen */
      xs += xsoff; xe += xeoff;
      ys += ysoff; ye += yeoff;

   } /* while !CheckSignal */

   return FALSE;
}

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 */
   }
}
