/*
      Programma: FIGURES , versie 1.0 .
      Auteur: Only Once , Zeishof 58
                          6681 EN  Bemmel .
      Taal: C , te vertalen met Lattice en Aztec .

      Dit is een op zich zelf staand demonstratie-programma van de taal C,
      vooral met het gebruik van menu's, screen's en window's .
      Het programma is direct te compileren en te linken. Verder kan dit
      programma geheel met de muis bestuurt worden.
      Men heeft de beschikking over 4 lijnen, 4 vlakken en 4 cirkels, die men
      elk kan aan of uitzetten. Verder kan men elk soort schermresolutie aan-
      roepen, wel of geen interlace, wel of geen high resolution.
      Bovendien zijn nog een aantal simpel te gebruiken commando's opgenomen
      in de menu's, zoals het voordurend wissen van het scherm (na elke teke-
      ning) voor een animatie-effect, zoals een pauze-commando, zoals het kiezen
      van het aantal kleuren: minimum (2 kleuren) of maximum (16 of 32).
      Hierbij heeft het minimum bij het voordurend wissen meer voordeel, daar
      dan het animatie-effect beter is door de hogere tekensnelheid.
      We merken overigens nog op, dat de getrokken cirkels, geen echte cirkels
      zijn, maar vrij groffe benaderingen, dit wegens snelheidsoverwegingen.
      Dit verschil is echter niet storend (het lijken wel cirkels).
*/


#include "exec/types.h"
#include "exec/devices.h"
#include "intuition/intuition.h"
#include "graphics/gels.h"
#include "graphics/copper.h"
#include "graphics/regions.h"
#include "graphics/gfxbase.h"
#include "devices/keymap.h"

struct bltnode { int a; };

struct IntuitionBase *IntuitionBase ;
struct GfxBase       *GfxBase       ;

struct Window *window ;
struct Screen *screen ;
struct RastPort *rp ;
struct ViewPort *vp ;
struct IntuiMessage *message ;

#define N NULL

struct NewScreen newscreen = {  0,0,320,250,5,0,1,N,CUSTOMSCREEN,N,"",N,N  } ;
struct NewWindow newwindow = {  0,0,320,250,-1,-1,CLOSEWINDOW|MOUSEBUTTONS|MENUPICK,SIMPLE_REFRESH|ACTIVATE|WINDOWCLOSE,N,N,
                                (UBYTE *)"FIGURES",N,N,0,0,0,0,CUSTOMSCREEN  } ;

char *tekst_uit_aan [ 24 ] =
{ "1e Lijn Uit"  ,"1e Lijn Aan"  ,"2e Lijn Uit"  ,"2e Lijn Aan"  ,"3e Lijn Uit"  ,"3e Lijn Aan"  ,"4e Lijn Uit"  ,"4e Lijn Aan"  ,
  "1e Cirkel Uit","1e Cirkel Aan","2e Cirkel Uit","2e Cirkel Aan","3e Cirkel Uit","3e Cirkel Aan","4e Cirkel Uit","4e Cirkel Aan",
  "1e Vlak Uit"  ,"1e Vlak Aan"  ,"2e Vlak Uit"  ,"2e Vlak Aan"  ,"3e Vlak Uit"  ,"3e Vlak Aan"  ,"4e Vlak Uit"  ,"4e Vlak Aan"} ;

char *voortdurend = "Voortdurend" ;  char *vast           = "Vast"      ;  char *minimum   = "Minimum"  ;
char *maximum     = "Maximum"     ;  char *high_tekst     = "HIGH res"  ;  char *low_tekst = "LOW  res" ;
char *lace_tekst  = "Interlace"   ;  char *geenlace_tekst = "Geen Lace" ;  char *pauze     = "Pauze"    ;
char *geen_pauze  = "Stop Pauze"  ;

struct IntuiText voorpauze = {  0,1,JAM2,10,1,N,(UBYTE *)"Pauze"      ,N  } ;
struct IntuiText vegen =     {  0,1,JAM2,10,1,N,(UBYTE *)"Vegen"      ,N  } ;
struct IntuiText veeg =      {  0,1,JAM2,10,1,N,(UBYTE *)"Voortdurend",N  } ;
struct IntuiText kleur =     {  0,1,JAM2,10,1,N,(UBYTE *)"Vast"       ,N  } ;
struct IntuiText aantal =    {  0,1,JAM2,10,1,N,(UBYTE *)"Minimum"    ,N  } ;
struct IntuiText res =       {  0,1,JAM2,10,1,N,(UBYTE *)"HIGH res"   ,N  } ;
struct IntuiText interlace = {  0,1,JAM2,10,1,N,(UBYTE *)"Interlace"  ,N  } ;

struct IntuiText figuur[ 12 ] = 
{  {  0,1,JAM2,10,1,N,(UBYTE *)"1e Lijn Uit",N  }   ,  {  0,1,JAM2,10,1,N,(UBYTE *)"2e Lijn Uit",N  }   ,
   {  0,1,JAM2,10,1,N,(UBYTE *)"3e Lijn Uit",N  }   ,  {  0,1,JAM2,10,1,N,(UBYTE *)"4e Lijn Uit",N  }   ,
   {  0,1,JAM2,10,1,N,(UBYTE *)"1e Cirkel Aan",N  } ,  {  0,1,JAM2,10,1,N,(UBYTE *)"2e Cirkel Aan",N  } ,
   {  0,1,JAM2,10,1,N,(UBYTE *)"3e Cirkel Aan",N  } ,  {  0,1,JAM2,10,1,N,(UBYTE *)"4e Cirkel Aan",N  } ,
   {  0,1,JAM2,10,1,N,(UBYTE *)"1e Vlak Aan",N  }   ,  {  0,1,JAM2,10,1,N,(UBYTE *)"2e Vlak Aan",N  }   ,
   {  0,1,JAM2,10,1,N,(UBYTE *)"3e Vlak Aan",N  }   ,  {  0,1,JAM2,10,1,N,(UBYTE *)"4e Vlak Aan",N  }   } ;

#define menutype HIGHCOMP|ITEMENABLED|ITEMTEXT

struct MenuItem scherm_item3 =  {  N,             0, 22,100,10,menutype,N,(APTR)&voorpauze, N,N,N  } ;
struct MenuItem scherm_item2 =  {  &scherm_item3, 0, 11,100,10,menutype,N,(APTR)&veeg,      N,N,N  } ;
struct MenuItem scherm_item1 =  {  &scherm_item2, 0,  0,100,10,menutype,N,(APTR)&vegen,     N,N,N  } ;

struct MenuItem kleur_item2 =   {  N,             0, 11,100,10,menutype,N,(APTR)&kleur,     N,N,N  } ;
struct MenuItem kleur_item1 =   {  &kleur_item2,  0,  0,100,10,menutype,N,(APTR)&aantal,    N,N,N  } ;

struct MenuItem grafiek_item2 = {  N,             0, 11,130,10,menutype,N,(APTR)&interlace, N,N,N  } ;
struct MenuItem grafiek_item1 = {  &grafiek_item2,0,  0,130,10,menutype,N,(APTR)&res,       N,N,N  } ;

struct MenuItem vlakken_item4 = {  N,             0,121,165,10,menutype,N,(APTR)&figuur[11],N,N,N  } ;
struct MenuItem vlakken_item3 = {  &vlakken_item4,0,110,140,10,menutype,N,(APTR)&figuur[10],N,N,N  } ;
struct MenuItem vlakken_item2 = {  &vlakken_item3,0, 99,140,10,menutype,N,(APTR)&figuur[ 9],N,N,N  } ;
struct MenuItem vlakken_item1 = {  &vlakken_item2,0, 88,140,10,menutype,N,(APTR)&figuur[ 8],N,N,N  } ;
struct MenuItem cirkels_item4 = {  &vlakken_item1,0, 77,140,10,menutype,N,(APTR)&figuur[ 7],N,N,N  } ;
struct MenuItem cirkels_item3 = {  &cirkels_item4,0, 66,140,10,menutype,N,(APTR)&figuur[ 6],N,N,N  } ;
struct MenuItem cirkels_item2 = {  &cirkels_item3,0, 55,140,10,menutype,N,(APTR)&figuur[ 5],N,N,N  } ;
struct MenuItem cirkels_item1 = {  &cirkels_item2,0, 44,140,10,menutype,N,(APTR)&figuur[ 4],N,N,N  } ;
struct MenuItem lijnen_item4 =  {  &cirkels_item1,0, 33,140,10,menutype,N,(APTR)&figuur[ 3],N,N,N  } ;
struct MenuItem lijnen_item3 =  {  &lijnen_item4, 0, 22,140,10,menutype,N,(APTR)&figuur[ 2],N,N,N  } ;
struct MenuItem lijnen_item2 =  {  &lijnen_item3, 0, 11,140,10,menutype,N,(APTR)&figuur[ 1],N,N,N  } ;
struct MenuItem lijnen_item1 =  {  &lijnen_item2, 0,  0,140,10,menutype,N,(APTR)&figuur[ 0],N,N,N  } ;

struct Menu scherm_menu  = {  N,           200,0,50,10,MENUENABLED,"Scherm" ,&scherm_item1   } ;
struct Menu kleur_menu   = {  &scherm_menu,143,0,45,10,MENUENABLED,"Kleur"  ,&kleur_item1    } ;
struct Menu grafiek_menu = {  &kleur_menu,  73,0,60,10,MENUENABLED,"Grafiek",&grafiek_item1  } ;
struct Menu figuren_menu = {  &grafiek_menu, 5,0,58,10,MENUENABLED,"Figuren",&lijnen_item1   } ;

#define  false    0
#define  true     1
#define  uit      0
#define  aan      1
#define  low      0
#define  high     1
#define  geenlace 0
#define  lace     1
#define  steeds   0
#define  eenmaal  1

int figures[12] = { aan,aan,aan,aan,uit,uit,uit,uit,uit,uit,uit,uit };
int resolutie = low,  inter = geenlace,  max_kleuren = true,  kleur_modus = steeds,  veeg_modus = eenmaal,  pauze_modus = false ;
int *lijn1,*lijn2,*lijn3,*lijn4 ;
int *vlak1,*vlak2,*vlak3,*vlak4 ;
int *cirk1,*cirk2,*cirk3,*cirk4 ;

int x_grens,y_grens,aantal_kleuren ,  class=0 , code=0 , item , mode ;

int ak = 0 ;
int aa=0,a=0,b=0,x=0,y=0,ad=0,bd=0,xd=0,yd=0,kl=1 ;
int aac=0,xm=0,ym=0,xmd=0,ymd=0,r=0,rd=0,kc=1 ;
int aav=0,xl=0,yt=0,yv=10,xv=10,xld=0,ytd=0,xvd=0,yvd=0,kv=1 ;

int xq,yq,vxp,vyp,vap,vbp,r2,vxm,vym,vam,vbm,g,s ;
int txp,typ,txm,tym,tap,tbp,tam,tbm ;
int vxpg,vypg,vxmg,vymg,vapg,vbpg,vamg,vbmg;
int txpg,typg,txmg,tymg,tapg,tbpg,tamg,tbmg;

int root[4000];

void _main()
{
   register no=0,rr=0,k=1;
   root[0]=0;
   while( ++no < 4000 ) { if( no==k ) { rr++ ; k = (rr+1)*(rr+1) ; }
      root[no] = rr ; }

   initialisatie_screen_en_window();
   while( !message || class != CLOSEWINDOW )
   {  if( pauze_modus == false )
      {  verander_kleur();
         eventueel_nieuwe_coordinaten();
         schuif_coordinaten_op();
         teken_alles_in();
      }
      message = (struct IntuiMessage *)GetMsg( window->UserPort );
      bekijk_menu();
   }
   afsluiten_screen_en_window();
}

initialisatie_screen_en_window()
{
   if( !( IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library")) ||
       !( GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)) ) exit(20);
   open_screen_en_window();
   lijn1 = &figures[0] ; lijn2 = &figures[1] ; lijn3 = &figures[ 2] ; lijn4 = &figures[ 3] ;
   cirk1 = &figures[4] ; cirk2 = &figures[5] ; cirk3 = &figures[ 6] ; cirk4 = &figures[ 7] ;
   vlak1 = &figures[8] ; vlak2 = &figures[9] ; vlak3 = &figures[10] ; vlak4 = &figures[11] ;
}

verander_kleur()
{
   if( ak-- < 0 && kleur_modus == steeds && veeg_modus == eenmaal )
   {  SetRGB4( vp,RangeRand(16),RangeRand(16),RangeRand(16),RangeRand(16) );
      ak = RangeRand(100)+50 ;
   }
}

eventueel_nieuwe_coordinaten()
{
   if( veeg_modus == eenmaal )
   {  if( aa--  <= 0 ) nieuwe_lijnen();
      if( aav-- <= 0 ) nieuwe_vlakken();
      if( aac-- <= 0 ) nieuwe_cirkels();
   }
}

nieuwe_lijnen()
{
   aa = RangeRand(100)+50 ; kl = RangeRand(aantal_kleuren) ;
   a = RangeRand(x_grens) ; ad = RangeRand(20)-10 ; b = RangeRand(y_grens) ; bd = RangeRand(20)-10 ;
   x = RangeRand(x_grens) ; xd = RangeRand(20)-10 ; y = RangeRand(y_grens) ; yd = RangeRand(20)-10 ;
}

nieuwe_vlakken()
{
   aav = RangeRand(30)+10 ; kv = RangeRand(aantal_kleuren) ;
   xv = RangeRand(x_grens/6)+5 ; yv = RangeRand(y_grens/6)+5 ; xvd = RangeRand(10)-5  ; yvd = RangeRand(10)-5  ;
   xl = RangeRand( x_grens-xv ); yt = RangeRand( y_grens-yv ); xld = RangeRand(30)-15 ; ytd = RangeRand(30)-15 ;
 }

nieuwe_cirkels()
{
   aac = RangeRand(100)+50 ; kc = RangeRand(aantal_kleuren) ;
   r  = RangeRand( x_grens/8 )+5 ; rd  = RangeRand(10)-5  ;
   xm = RangeRand(x_grens-r*2)+r ; xmd = RangeRand(30)-15 ;
   ym = RangeRand(y_grens-r*2)+r ; ymd = RangeRand(30)-15 ;
}

schuif_coordinaten_op()
{
   if( *lijn1 || *lijn2 || *lijn3 || *lijn4 ) schuif_lijnen() ;
   if( *vlak1 || *vlak2 || *vlak3 || *vlak4 ) schuif_vlakken();
   if( *cirk1 || *cirk2 || *cirk3 || *cirk4 ) schuif_cirkels();
}

schuif_lijnen()
{
   a += ( a+ad > x_grens || a+ad < 0 )? (ad=-ad) : ad ;
   b += ( b+bd > y_grens || b+bd < 0 )? (bd=-bd) : bd ;
   x += ( x+xd > x_grens || x+xd < 0 )? (xd=-xd) : xd ;
   y += ( y+yd > y_grens || y+yd < 0 )? (yd=-yd) : yd ;
}

schuif_vlakken()
{
   xv += ( xv+xvd > x_grens/6+5 || xv+xvd < 5 )? (xvd=-xvd) : xvd ;
   yv += ( yv+yvd > y_grens/6+5 || yv+yvd < 5 )? (yvd=-yvd) : yvd ;
   xl += ( xl+xld > x_grens-xv  || xl+xld < 0 )? (xld=-xld) : xld ;
   yt += ( yt+ytd > y_grens-yv  || yt+ytd < 0 )? (ytd=-ytd) : ytd ;
}

schuif_cirkels()
{
   r  += ( r+rd > x_grens/8+5 || r+rd   < 5 )? ( rd= -rd) :  rd ;
   xm += ( xm+xmd > x_grens-r || xm+xmd < r )? (xmd=-xmd) : xmd ;
   ym += ( ym+ymd > y_grens-r || ym+ymd < r )? (ymd=-ymd) : ymd ;
   xq = -r  ; vxp = xm-r ; vyp = ym ; vap = xm ; vbp = ym-r ;
   r2 = r*r ; vxm = xm+r ; vym = ym ; vam = xm ; vbm = ym+r ;
   vxpg = x_grens-vxp ; vypg = y_grens-vyp ; vxmg = x_grens-vxm ; vymg = vypg ;
   vapg = x_grens-vap ; vamg = vapg        ; vbpg = y_grens-vbp ; vbmg = y_grens-vbm ;
   g = (10*r)/14 ; s = (r-g)/4+1 ; g = -g+s ;
}

#define d(a,b,x,y) { (rp)->cp_x = a ; (rp)->cp_y = b ; Draw(rp,x,y) ; }

teken_alles_in()
{
   if( veeg_modus == steeds )
   {  SetAPen( rp,0 );
      RectFill( rp,0,0,x_grens,y_grens ) ;
   }
   
   SetAPen( rp,kl );
   if( *lijn1 ) d(         a,        b,        x,        y );
   if( *lijn2 ) d( x_grens-a,        b,x_grens-x,        y );
   if( *lijn3 ) d(         a,y_grens-b,        x,y_grens-y );
   if( *lijn4 ) d( x_grens-a,y_grens-b,x_grens-x,y_grens-y );

   SetAPen( rp,kv );
   if( *vlak1 ) RectFill( rp,           xl,           yt,     xl+xv,     yt+yv );
   if( *vlak2 ) RectFill( rp,x_grens-xl-xv,           yt,x_grens-xl,     yt+yv );
   if( *vlak3 ) RectFill( rp,           xl,y_grens-yt-yv,     xl+xv,y_grens-yt );
   if( *vlak4 ) RectFill( rp,x_grens-xl-xv,y_grens-yt-yv,x_grens-xl,y_grens-yt );

   SetAPen( rp,kc );
   while( (xq+=s) < g )
   {  yq = root[ r2 - xq*xq ];
      txp = xm+xq ; txm = xm-xq ; tap = xm+yq ; tam = xm-yq ;
      typ = ym+yq ; tym = ym-yq ; tbp = ym+xq ; tbm = ym-xq ;
      txpg = x_grens-txp ; typg = y_grens-typ ; txmg = x_grens-txm ; tymg = y_grens-tym ;
      tapg = x_grens-tap ; tbpg = y_grens-tbp ; tamg = x_grens-tam ; tbmg = y_grens-tbm ;
      if( *cirk1 ) { d(  vxp, vyp, txp, typ ); d(  vxm, vyp, txm, typ ); d(  vxm, vym, txm, tym ); d(  vxp, vym, txp, tym );
                     d(  vap, vbp, tap, tbp ); d(  vam, vbp, tam, tbp ); d(  vam, vbm, tam, tbm ); d(  vap, vbm, tap, tbm ); }
      if( *cirk2 ) { d( vxpg, vyp,txpg, typ ); d( vxmg, vyp,txmg, typ ); d( vxmg, vym,txmg, tym ); d( vxpg, vym,txpg, tym );
                     d( vapg, vbp,tapg, tbp ); d( vamg, vbp,tamg, tbp ); d( vamg, vbm,tamg, tbm ); d( vapg, vbm,tapg, tbm ); }
      if( *cirk3 ) { d(  vxp,vypg, txp,typg ); d(  vxm,vypg, txm,typg ); d(  vxm,vymg, txm,tymg ); d(  vxp,vymg, txp,tymg );
                     d(  vap,vbpg, tap,tbpg ); d(  vam,vbpg, tam,tbpg ); d(  vam,vbmg, tam,tbmg ); d(  vap,vbmg, tap,tbmg ); }
      if( *cirk4 ) { d( vxpg,vypg,txpg,typg ); d( vxmg,vypg,txmg,typg ); d( vxmg,vymg,txmg,tymg ); d( vxpg,vymg,txpg,tymg );
                     d( vapg,vbpg,tapg,tbpg ); d( vamg,vbpg,tamg,tbpg ); d( vamg,vbmg,tamg,tbmg ); d( vapg,vbmg,tapg,tbmg ); }
      vxm = txm ; vxp = txp ; vym = tym ; vyp = typ ; vam = tam ; vap = tap ; vbm = tbm ; vbp = tbp ;
      vxmg=txmg ; vxpg=txpg ; vymg=tymg ; vypg=typg ; vamg=tamg ; vapg=tapg ; vbmg=tbmg ; vbpg=tbpg ;
   }
}

bekijk_menu()
{
   class = message->Class ; code = message->Code ;
   switch( class )
   {  case CLOSEWINDOW: break ;
      case MENUPICK: 
         item = ITEMNUM( code ) ;
         switch( MENUNUM( code ) )
         {  case 0: bekijk_figuren(); break;          case 1: bekijk_grafiek(); break;
            case 2: bekijk_kleuren(); break;          case 3: bekijk_scherm();  break;
         }
   }
}

bekijk_figuren()
{
   (figuur[ item ]).IText = tekst_uit_aan[ item*2 + (mode = figures[item]) ] ;
   figures[ item ] = 1-mode ;
}

bekijk_grafiek()
{
   switch( item )
   {  case 0: res.IText = ( (resolutie = 1-resolutie) != high )?  high_tekst : low_tekst ;
              break ;
      case 1: interlace.IText = ( (inter = 1-inter) != lace )?  lace_tekst : geenlace_tekst ;
              break ;
   }
   vorm_nieuw_screen_en_window();
}

bekijk_kleuren()
{
   switch( item )
   {  case 0: aantal.IText = ( (max_kleuren = 1-max_kleuren) != true )? maximum : minimum ;
              vorm_nieuw_screen_en_window();
              break;
      case 1: kleur.IText = ( (kleur_modus = 1-kleur_modus) != steeds )? voortdurend : vast ;
              break;
   }
}

bekijk_scherm()
{
   switch( item )
   {  case 0: SetAPen( rp,0 ) ; RectFill( rp,0,0,x_grens,y_grens ) ;
              break;
      case 1: if( (veeg_modus = 1-veeg_modus) != steeds )   veeg.IText = voortdurend ;
              else {  veeg.IText = vast ;
                      kl = RangeRand(aantal_kleuren-1)+1 ;
                      kc = RangeRand(aantal_kleuren-1)+1 ;
                      kv = RangeRand(aantal_kleuren-1)+1 ;
                   }
              break;
      case 2: voorpauze.IText = ( (pauze_modus = 1-pauze_modus) != false )? geen_pauze : pauze ;
              break;
   }
}

vorm_nieuw_screen_en_window()
{
   aa=0 ; aac=0 ; aav=0 ; veeg_modus=eenmaal ; veeg.IText=voortdurend ; 
   afsluiten_screen_en_window();
   open_screen_en_window();
}

afsluiten_screen_en_window()
{
   ClearMenuStrip( window ); CloseWindow( window ); CloseScreen( screen );
}

open_screen_en_window()
{
   x_grens = ( newscreen.Width  = ( newwindow.Width  = 320 * (1+resolutie) ) ) ;
   y_grens = ( newscreen.Height = ( newwindow.Height = 250 * ( 1 + inter ) ) ) ;
   newscreen.ViewModes = ( newscreen.ViewModes = (( inter == lace )? LACE : N ) ) | (( resolutie == high )? HIRES : N ) ;
   newscreen.Depth = 1 + max_kleuren * ( 4-   resolutie);
   aantal_kleuren  = 2 + max_kleuren * (32-16*resolutie);

   if( (screen = (struct Screen *)OpenScreen( &newscreen ) ) == N ) exit(1);
   ShowTitle( screen,FALSE );
   newwindow.Screen = screen ;
   if( (window = (struct Window *)OpenWindow( &newwindow ) ) == N ) { CloseScreen( screen ); exit(1); }

   vp = &screen->ViewPort ; rp = window->RPort ;
   SetMenuStrip( window,&figuren_menu ) ;
}

                      