/*--------------------------------------------------------------------------
                           Rainer Stork
                          Krefelder Str.5
                           4044 Kaarst 2
                         Tel. 02101/511027

                             04.12.87
----------------------------------------------------------------------------
                  Programm zur Einstellung der Screen-Farben
                          mit einem Gadgetfenster

   Funktionsaufruf : Change_Color(Screen);

   Screen          : hier muß der Zeiger auf den Screen übergeben werden
                     ( oder NULL bei WorkbenchScreen )

----------------------------------------------------------------------------
>>>  Achtung !! --> im aufrufenden Programm muß die GFX- und Intuition-  <<<
>>>             --> Library geöffnet werden  !!                          <<<
---------------------------------------------------------------------------*/

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>

/* definieren der Gadget-ID's */
#define OKAY    3123
#define CANCEL  4892
#define RESET   5037
#define COPY    9692
#define SPREAD  9167

#define VONOBEN 8      /* Abstand der Gadgets von Fensteroberkante */

long *OpenWindow();     /* vermeidet Warnings vom Aztec */
VOID CloseWindow();
long *GetMsg();
char *Str();

extern struct IntuitionBase *IntuitionBase;


/*-------------------------------------------------------
         Proportional-Gadgets definieren
-------------------------------------------------------*/

struct IntuiText FarbNr1 = {1,0,JAM2,5,-15,NULL,"Farbe",NULL};
struct IntuiText FarbNr2 = {1,0,JAM2,55,-15,NULL,"0 ",&FarbNr1};
struct IntuiText ROT_Text   = {1,0,JAM1,-11,2,NULL,"R",&FarbNr2};
struct IntuiText GRUEN_Text = {1,0,JAM1,-11,2,NULL,"G",NULL};
struct IntuiText BLAU_Text  = {1,0,JAM1,-11,2,NULL,"B",NULL};

USHORT Schieber_BorderVec[] = {0,0,152,0,152,13,0,13,0,0};
struct Border Schieber_Border1 = {-1,-1,3,0,JAM1,5,Schieber_BorderVec,NULL};
struct Border Schieber_Border2 = {-1,-1,3,0,JAM1,5,Schieber_BorderVec,NULL};
struct Border Schieber_Border3 = {-1,-1,3,0,JAM1,5,Schieber_BorderVec,NULL};

struct PropInfo RotInfo   = {FREEHORIZ + AUTOKNOB,0x0000,0,4096,0,0,0,0,0,0,0};
struct Gadget ROT_Schieber   = {NULL,20,-51,150,12,GADGHCOMP + GRELBOTTOM,
   RELVERIFY,PROPGADGET,&Schieber_Border1,NULL,&ROT_Text,0,&RotInfo,2,NULL};

struct PropInfo GruenInfo = {FREEHORIZ + AUTOKNOB,0x0000,0,4096,0,0,0,0,0,0,0};
struct Gadget GRUEN_Schieber = {&ROT_Schieber,20,-33,150,12,GADGHCOMP + GRELBOTTOM,
   RELVERIFY,PROPGADGET,&Schieber_Border2,NULL,&GRUEN_Text,0,&GruenInfo,1,NULL};

struct PropInfo BlauInfo  = {FREEHORIZ + AUTOKNOB,0x0000,0,4096,0,0,0,0,0,0,0};
struct Gadget BLAU_Schieber  = {&GRUEN_Schieber,20,-15,150,12,GADGHCOMP + GRELBOTTOM,
   RELVERIFY,PROPGADGET,&Schieber_Border3,NULL,&BLAU_Text,0,&BlauInfo,0,NULL};


/*-------------------------------------------------------
            Boolean-Gadgets definieren
-------------------------------------------------------*/
struct IntuiText Verlauf_Text = {1,0,JAM2,2,1,NULL,"Verlauf",NULL};
struct IntuiText Kopie_Text = {1,0,JAM2,10,1,NULL,"Kopie",NULL};
struct IntuiText Reset_Text = {1,0,JAM2,10,1,NULL,"Reset",NULL};
struct IntuiText CANCEL_Text = {1,0,JAM2,6,1,NULL,"CANCEL",NULL};
struct IntuiText OK_Text = {1,0,JAM2,14,1,NULL,"OKAY",NULL};

USHORT FarbBorderVec2[] = {2,11,61,11,61,1,62,2,62,11};
USHORT FarbBorderVec1[] = {0,0,60,0,60,10,0,10,0,0};
struct Border Farb_Border2 = {-1,-1,3,0,JAM1,5,FarbBorderVec2,NULL};
struct Border Farb_Border1 = {-1,-1,1,0,JAM1,5,FarbBorderVec1,&Farb_Border2};


struct Gadget Verlauf_Gadget =
   {  &BLAU_Schieber,220,-66,59,9,GADGHCOMP + GRELBOTTOM,RELVERIFY+GADGIMMEDIATE+TOGGLESELECT,
       BOOLGADGET,&Farb_Border1,NULL,&Verlauf_Text,0,NULL,SPREAD,NULL };

struct Gadget Kopie_Gadget =
   {  &Verlauf_Gadget,220,-53,59,9,GADGHCOMP + GRELBOTTOM,RELVERIFY+GADGIMMEDIATE+TOGGLESELECT,
       BOOLGADGET,&Farb_Border1,NULL,&Kopie_Text,0,NULL,COPY,NULL };


struct Gadget RESET_Gadget =
   {  &Kopie_Gadget,220,-40,59,9,GADGHCOMP + GRELBOTTOM,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,
      &Farb_Border1,NULL,&Reset_Text,0,NULL,RESET,NULL };

struct Gadget CANCEL_Gadget =
   {  &RESET_Gadget,220,-27,59,9,GADGHCOMP + GRELBOTTOM,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,
      &Farb_Border1,NULL,&CANCEL_Text,0,NULL,CANCEL,NULL };

struct Gadget OK_Gadget =
   {  &CANCEL_Gadget,220,-14,59,9,GADGHCOMP + GRELBOTTOM,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,
      &Farb_Border1,NULL,&OK_Text,0,NULL,OKAY,NULL };

/*------------------------------------------------------------------
                Rahmen für Farbfläche
------------------------------------------------------------------*/
USHORT FlaechenVec[] = {0,0,53,0,53,13,0,13,0,0};
struct Border FlaechenBord = {0,0,1,0,JAM1,5,FlaechenVec,NULL};




BOOL VerlaufFlag,KopierFlag;

VOID Change_Color(Schirm)
struct Screen *Schirm;
{

   char windowname[40];
   ULONG class;
   USHORT code,RotWert,GruenWert,BlauWert;
   USHORT MerkeRot[32],MerkeGruen[32],MerkeBlau[32];
   USHORT Rand[26];
   SHORT AnzahlFarben;
   SHORT gadid,CurrentColor,farbe,Tiefe;
   SHORT i,j,reihe;
   SHORT Start,Breite,Hoehe,Abstand;
   BOOL go_on = TRUE;

   struct ViewPort *MyVPort;
   struct RastPort *rp;
   struct Window *FarbFenster;
   struct Gadget *gad;
   struct NewWindow NewFarbFenster;
   struct IntuiMessage *FarbMessage;
   struct Gadget FarbGadget[32];
   struct Border Farb_Rand;


   VerlaufFlag = FALSE;
   KopierFlag  = FALSE;

   if (Schirm != NULL)
      Tiefe = (SHORT)(Schirm->RastPort.BitMap->Depth);
   else
      Tiefe = 2;   /* WBScreen hat 2 Bitplanes */


/*-------------------------------------------------------------------
      Größe der Farbgadgets und Anzahl der Farben festlegen
-------------------------------------------------------------------*/
   switch (Tiefe)
   {
      case 1:
         AnzahlFarben = 2;
         Breite       = 120;
         Hoehe        = 23;
         Abstand      = 10;
         Start        = 23;
      break;
      case 2:
         AnzahlFarben = 4;
         Breite       = 60;
         Hoehe        = 23;
         Abstand      = 8;
         Start        = 14;
      break;
      case 3:
         AnzahlFarben = 8;
         Breite       = 30;
         Hoehe        = 23;
         Abstand      = 4;
         Start        = 11;
      break;
      case 4:
         AnzahlFarben = 16;
         Breite       = 15;
         Hoehe        = 16;
         Abstand      = 2;
         Start        = 12;
      break;
      case 5:
         AnzahlFarben = 32;
         Breite       = 15;
         Hoehe        = 16;
         Abstand      = 2;
         Start        = 12;
      break;
      default:
         return();
      break;
   }


/*-------------------------------------------------------------------
                 NewWindow-Struktur initialisieren
-------------------------------------------------------------------*/

   strcpy(windowname,"            Farbeinsteller            ");
   NewFarbFenster.LeftEdge    =10;
   NewFarbFenster.TopEdge     =50;
   NewFarbFenster.Width       =300;
   NewFarbFenster.Height      =120;

   if (AnzahlFarben == 32)
      NewFarbFenster.Height      =138;

   NewFarbFenster.DetailPen   = 0;
   NewFarbFenster.BlockPen    = 1;
   NewFarbFenster.Flags       = ACTIVATE | GIMMEZEROZERO | WINDOWDRAG;
   NewFarbFenster.IDCMPFlags  = GADGETUP | GADGETDOWN;
   NewFarbFenster.FirstGadget = &FarbGadget[0];
   NewFarbFenster.CheckMark   = NULL;
   NewFarbFenster.BitMap      = NULL;
   NewFarbFenster.MinWidth    = 0;
   NewFarbFenster.MinHeight   = 0;
   NewFarbFenster.MaxWidth    = 0;
   NewFarbFenster.MaxHeight   = 0;
   NewFarbFenster.Screen      = Schirm;
   NewFarbFenster.Title       = windowname;

/*--------- Workbench- oder Customscreen ?? ----------*/
   if (Schirm == NULL)
   {
      NewFarbFenster.Type     =WBENCHSCREEN;
   }
   else
   {
      NewFarbFenster.Type     =CUSTOMSCREEN;
   }


/*-------------------------------------------------------------------
                   Rand für Farbfläche definieren
-------------------------------------------------------------------*/

   Rand[0] = 3;
   Rand[1] = 2;
   Rand[2] = Breite;
   Rand[3] = 2;
   Rand[4] = Breite;
   Rand[5] = Hoehe;
   Rand[6] = 2;
   Rand[7] = Hoehe;
   Rand[8] = 2;
   Rand[9] = 1;           /* erste Runde fertig */
   Rand[10] = Breite+1;
   Rand[11] = 1;
   Rand[12] = Breite+1;
   Rand[13] = Hoehe+1;
   Rand[14] = 1;
   Rand[15] = Hoehe+1;
   Rand[16] = 1;
   Rand[17] = 0;         /* zweite Runde fertig */
   Rand[18] = Breite+2;
   Rand[19] = 0;
   Rand[20] = Breite+2;
   Rand[21] = Hoehe+2;
   Rand[22] = 0;
   Rand[23] = Hoehe+2;
   Rand[24] = 0;
   Rand[25] = 0;         /* dritte Runde fertig */


   Farb_Rand.LeftEdge  = 0;
   Farb_Rand.TopEdge   = 0;
   Farb_Rand.FrontPen  = 1;
   Farb_Rand.BackPen   = 0;
   Farb_Rand.DrawMode  = COMPLEMENT;
   Farb_Rand.Count     = 13;
   Farb_Rand.XY        = (SHORT *)&Rand[0];
   Farb_Rand.NextBorder= NULL;


/*-------------------------------------------------------------------
                 Farbgadget-Strukturen initialisieren
-------------------------------------------------------------------*/
   j = 0;
   reihe = 0;
   for (i=0 ; i<AnzahlFarben ; i++,j++)
   {
      if (j == 16)
      {
         j = 0;
         reihe = 1;
      }
      FarbGadget[i].NextGadget    = &FarbGadget[i+1];
      FarbGadget[i].LeftEdge      = (Start+j*(Breite+Abstand));
      FarbGadget[i].TopEdge       = VONOBEN + (reihe * Hoehe);
      FarbGadget[i].Width         = Breite + 1;
      FarbGadget[i].Height        = Hoehe + 1;
      FarbGadget[i].Flags         = GADGHCOMP;
      FarbGadget[i].Activation    = RELVERIFY | GADGIMMEDIATE;
      FarbGadget[i].GadgetType    = BOOLGADGET;
      FarbGadget[i].GadgetRender  = NULL;
      FarbGadget[i].SelectRender  = NULL;
      FarbGadget[i].GadgetText    = NULL;
      FarbGadget[i].MutualExclude = 0;
      FarbGadget[i].SpecialInfo   = NULL;
      FarbGadget[i].GadgetID      = i+6;
      FarbGadget[i].UserData      = NULL;
   }

/*---------- Bool- und PropGadgets in Liste einhängen -----------*/
   FarbGadget[AnzahlFarben-1].NextGadget=&OK_Gadget;


/*-----------------  GadgetFenster aufmachen --------------------*/
/*------- wenn nicht möglich dann zurück zum Hauptprogramm ------*/

   if ((FarbFenster=(struct Window *)OpenWindow(&NewFarbFenster)) == 0)
      return;

/*-------------- Rastport und ViewPort auf Fenster ----------------*/
   rp=FarbFenster->RPort;
   MyVPort = ViewPortAddress(FarbFenster);


/*------------------- Farbfläche zeichnen -----------------------*/
   CurrentColor=0;
   SetAPen(rp,CurrentColor);
   RectFill(rp,118,FarbFenster->Height - 82,167,FarbFenster->Height - 73);
   DrawBorder(rp,&FlaechenBord,116,FarbFenster->Height -84);

/*------------- erste Farbnummer in Textstruktur --------------*/
   Str((LONG)CurrentColor,FarbNr2.IText);
   strcat(FarbNr2.IText," ");

/*----------------------------------------------------------------
      Farbe 0 auslesen und PropGadgets entsprechend setzen
----------------------------------------------------------------*/

   farbe    =GetRGB4 (MyVPort->ColorMap,CurrentColor);
   RotWert  =(farbe >> 8) & 0x000f;
   GruenWert=(farbe >> 4) & 0x000f;
   BlauWert = farbe       & 0x000f;

   ModifyProp(&ROT_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,RotWert*4369,0,4096,0);
   ModifyProp(&GRUEN_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,GruenWert*4369,0,4096,0);
   ModifyProp(&BLAU_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,BlauWert*4369,0,4096,0);
   RefreshGadgets(&BLAU_Schieber,FarbFenster,NULL);

/*---------------- Gadgets mit Farbe füllen ---------------------*/
   j = 0;
   reihe = 0;
   for (i=0 ; i<AnzahlFarben ; i++ , j++)
   {
      if (i == 16)
      {
         j = 0;
         reihe = 1;
      }

      SetAPen(rp,i);
      RectFill(rp,Start+j*(Breite+Abstand),VONOBEN+(reihe*(Hoehe+Abstand)),
                  Breite+Start+j*(Breite+Abstand),Hoehe+VONOBEN+(reihe*Hoehe));
   }

/*-------------------- Umrahmung zeichnen -------------------------*/
   if (AnzahlFarben == 32)
   {
      reihe = 1;
      j     = 16;
   }
   else
   {
      reihe = 0;
      j     = 0;
   }

   Move(rp,Start-3,VONOBEN-2);
   Draw(rp,Start+3-Abstand+(AnzahlFarben-j)*(Breite+Abstand),VONOBEN-2);
   Draw(rp,Start+3-Abstand+(AnzahlFarben-j)*(Breite+Abstand),VONOBEN+2+(Hoehe*(reihe+1)));
   Draw(rp,Start-3,VONOBEN+2+(Hoehe*(reihe+1)));
   Draw(rp,Start-3,VONOBEN-2);

   DoFarbRand(Start,Breite,Abstand,Hoehe,0,&Farb_Rand,rp);


/*---------------------------------------------------------------------
                  alle Farbwerte zwischenspeichern
---------------------------------------------------------------------*/
   for (i=0 ; i<AnzahlFarben ; i++)
   {
      farbe    =GetRGB4 (MyVPort->ColorMap,i);
      MerkeRot[i]  =(farbe >> 8) & 0x000f;;
      MerkeGruen[i]=(farbe >> 4) & 0x000f;
      MerkeBlau[i] =(farbe       & 0x000f);
   }



/*---------------------------------------------------------------------
                          Warteschleife
---------------------------------------------------------------------*/
   for (;;)
   {

/*---------------- kleine Pause (für andere Tasks)-------------------*/
      Delay(5);

/*---------------------------------------------------------------------
    Farbänderungen kontrollieren und Farben setzen wenn geändert
---------------------------------------------------------------------*/
      if (RotWert != RotInfo.HorizPot/4369)
      {
         RotWert   = RotInfo.HorizPot/4369;
         GruenWert = GruenInfo.HorizPot/4369;
         BlauWert  = BlauInfo.HorizPot/4369;
         SetRGB4(MyVPort,CurrentColor,RotWert,GruenWert,BlauWert);
      }
      if (GruenWert != GruenInfo.HorizPot/4369)
      {
         RotWert   = RotInfo.HorizPot/4369;
         GruenWert = GruenInfo.HorizPot/4369;
         BlauWert  = BlauInfo.HorizPot/4369;
         SetRGB4(MyVPort,CurrentColor,RotWert,GruenWert,BlauWert);
      }
      if (BlauWert != BlauInfo.HorizPot/4369)
      {
         RotWert   = RotInfo.HorizPot/4369;
         GruenWert = GruenInfo.HorizPot/4369;
         BlauWert  = BlauInfo.HorizPot/4369;
         SetRGB4(MyVPort,CurrentColor,RotWert,GruenWert,BlauWert);
      }


/*--------------- Message von Gadgets abfragen ------------------*/

      if ((FarbMessage=(struct IntuiMessage *)GetMsg(FarbFenster->UserPort)) != 0)
      {
      ReplyMsg(FarbMessage);
      class=FarbMessage->Class;
      code =FarbMessage->Code;
      gad=(struct Gadget *)FarbMessage->IAddress;
      gadid=gad->GadgetID;

      switch(class)
      {
         case GADGETDOWN:
            if ((gadid >= 6) && (gadid < (AnzahlFarben+6)) && ((gadid-6) != CurrentColor))
            {
               if (VerlaufFlag == TRUE)
                  DoSpread(MyVPort,CurrentColor,gadid-6);

               if (KopierFlag == TRUE)
                  DoCopy(MyVPort,CurrentColor,gadid-6);

/*------------ Rand um aktueller Farbe löschen -------------------*/
               DoFarbRand(Start,Breite,Abstand,Hoehe,CurrentColor,&Farb_Rand,rp);

/*---------- Rand um neu gewählte Farbe zeichnen -----------------*/
               CurrentColor=gadid-6;
               DoFarbRand(Start,Breite,Abstand,Hoehe,CurrentColor,&Farb_Rand,rp);
               Str((LONG)CurrentColor,FarbNr2.IText);
               strcat(FarbNr2.IText," ");

               SetAPen(rp,CurrentColor);
               RectFill(rp,118,FarbFenster->Height - 82,167,FarbFenster->Height - 73);
               SetAPen(rp,1);
/*---- neue Farbe auslesen und PropGadgets entsprechend setzen ----*/
               farbe    =GetRGB4 (MyVPort->ColorMap,CurrentColor);
               RotWert  =(farbe >> 8) & 0x000f;
               GruenWert=(farbe >> 4) & 0x000f;
               BlauWert = farbe       & 0x000f;
               ModifyProp(&ROT_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,RotWert*4369,0,4096,0);
               ModifyProp(&GRUEN_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,GruenWert*4369,0,4096,0);
               ModifyProp(&BLAU_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,BlauWert*4369,0,4096,0);
               RefreshGadgets(&BLAU_Schieber,FarbFenster,NULL);

            }
         break;
         case GADGETUP:
            EntSelect(FarbFenster);
            switch(gadid)
            {
               case COPY:
                  if (Kopie_Gadget.Flags == (GADGHCOMP+GRELBOTTOM+SELECTED))
                     KopierFlag = TRUE;
                  else
                     KopierFlag = FALSE;
               break;

               case SPREAD:
                  if (Verlauf_Gadget.Flags == (GADGHCOMP+GRELBOTTOM+SELECTED))
                     VerlaufFlag = TRUE;
                  else
                     VerlaufFlag = FALSE;
               break;

               case OKAY:
                  CloseWindow(FarbFenster);
                  return;
               break;

               case CANCEL:
/*--- zwischengespeicherte Farben wieder in Farbregister schreiben ---*/
                  for (i=0 ; i<AnzahlFarben ; i++)
                  {
                     SetRGB4(MyVPort,i,MerkeRot[i],MerkeGruen[i],MerkeBlau[i]);
                  }

/*------ Fenster schließen und zurück zum Hauptprogramm ------*/
                  CloseWindow(FarbFenster);
                  return;
               break;

               case RESET:       /* Reset-Gadget angeklickt */
/*--- zwischengespeicherte Farben wieder in Farbregister schreiben ---*/
                  for (i=0 ; i<AnzahlFarben ; i++)
                  {
                     SetRGB4(MyVPort,i,MerkeRot[i],MerkeGruen[i],MerkeBlau[i]);
                  }

/*---------------- PropGadgets wieder richtig setzen ---------------*/
                  farbe    =GetRGB4 (MyVPort->ColorMap,CurrentColor);
                  RotWert  =(farbe >> 8) & 0x000f;
                  GruenWert=(farbe >> 4) & 0x000f;
                  BlauWert = farbe       & 0x000f;
                  ModifyProp(&ROT_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,RotWert*4369,0,4096,0);
                  ModifyProp(&GRUEN_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,GruenWert*4369,0,4096,0);
                  ModifyProp(&BLAU_Schieber,FarbFenster,NULL,AUTOKNOB | FREEHORIZ,BlauWert*4369,0,4096,0);
                  RefreshGadgets(&BLAU_Schieber,FarbFenster,NULL);
               break;
            }
         break;
         }    /*   Ende switch     */
      }      /*    Ende if        */
   }        /*    Ende for       */
}          /* Ende Change_Color */



/*-----------------------------------------------------------------
              zeichnet Rand um Farbgadgets
-----------------------------------------------------------------*/
DoFarbRand(Start,Breite,Abstand,Hoehe,Farbe,FRand,rp)
SHORT Start,Breite,Hoehe,Abstand,Farbe;
struct Border *FRand;
struct RastPort *rp;
{
   SHORT j,reihe;

   if (Farbe >= 16)
   {
      j = Farbe - 16;
      reihe = 1;
   }
   else
   {
      j = Farbe;
      reihe = 0;
   }
   DrawBorder(rp,FRand,Start-1+j*(Breite+Abstand),VONOBEN-1+(reihe*Hoehe));
}



/*-------------------------------------------------------------------
             selektierte Gadgets werden zurückgesetzt
-------------------------------------------------------------------*/
EntSelect(Fenster)
struct Window *Fenster;
{
   if (VerlaufFlag == TRUE)
   {
      VerlaufFlag = FALSE;
      Verlauf_Gadget.Flags = GADGHCOMP + GRELBOTTOM;
      SetAPen(Fenster->RPort,0);
      RectFill(Fenster->RPort,220,Fenster->Height - 80,278,Fenster->Height - 71);
      RefreshGList(&Verlauf_Gadget,Fenster,NULL,1);
   }

   if (KopierFlag == TRUE)
   {
      KopierFlag = FALSE;
      Kopie_Gadget.Flags = GADGHCOMP + GRELBOTTOM;
      SetAPen(Fenster->RPort,0);
      RectFill(Fenster->RPort,220,Fenster->Height - 67,278,Fenster->Height - 58);
      RefreshGList(&Kopie_Gadget,Fenster,NULL,1);
   }
}



/*-------------------------------------------------------------------
                       Farbverlauf machen
-------------------------------------------------------------------*/
DoSpread(vp,vonFarbe,bisFarbe)
struct ViewPort *vp;
SHORT vonFarbe,bisFarbe;
{
   FLOAT vonRot,bisRot,vonGruen,bisGruen,vonBlau,bisBlau;
   FLOAT RotStep,GruenStep,BlauStep;
   SHORT i,x,Step,farbe;


   x = bisFarbe - vonFarbe;
   if (x < 0)      /*  Absolutwert bilden */
      Step = -1;
   else
      Step = 1;

   farbe    = GetRGB4 (vp->ColorMap,vonFarbe);
   vonRot   = (FLOAT)((farbe >> 8) & 0x000f);
   vonGruen = (FLOAT)((farbe >> 4) & 0x000f);
   vonBlau  = (FLOAT)( farbe       & 0x000f);

   farbe    = GetRGB4 (vp->ColorMap,bisFarbe);
   bisRot   = (FLOAT)((farbe >> 8) & 0x000f);
   bisGruen = (FLOAT)((farbe >> 4) & 0x000f);
   bisBlau  = (FLOAT)( farbe       & 0x000f);

   RotStep   = (bisRot   - vonRot)   / (FLOAT)(Step * x);
   GruenStep = (bisGruen - vonGruen) / (FLOAT)(Step * x);
   BlauStep  = (bisBlau  - vonBlau)  / (FLOAT)(Step * x);

   for (i=(vonFarbe+Step) ; i!=bisFarbe ; i+=Step)
   {
      vonRot   = vonRot   + RotStep   ;
      vonGruen = vonGruen + GruenStep ;
      vonBlau  = vonBlau  + BlauStep  ;
      SetRGB4(vp,i,(USHORT)(vonRot+0.5),(USHORT)(vonGruen+0.5),(USHORT)(vonBlau+0.5));

   }
}



/*-------------------------------------------------------------------
                       Farbe kopieren
-------------------------------------------------------------------*/
DoCopy(vp,vonFarbe,bisFarbe)
struct ViewPort *vp;
SHORT vonFarbe,bisFarbe;
{
   SHORT farbe,RotWert,GruenWert,BlauWert;

   farbe    = GetRGB4 (vp->ColorMap,vonFarbe);
   RotWert  = (farbe >> 8) & 0x000f;
   GruenWert= (farbe >> 4) & 0x000f;
   BlauWert =  farbe       & 0x000f;
   SetRGB4(vp,bisFarbe,RotWert,GruenWert,BlauWert);
}



/*---------------------------------------------------------------------
    Funktion zur Umwandlung einer LONG-Variabelen in ASCII
---------------------------------------------------------------------*/

char *Str(w,s)
LONG w;       /* Integer-Wert */
char s[];     /* Zeiger auf Zeichenkette */
{
   int sign = 0;
   WORD i,t,c;
   LONG x;
   if (w < 0)
   {
      sign=1;
      s[0]='-';
      w=(-1)*w;
   }

   x=1;i=0;
   if (w==0)
   {
      s[0]=48;s[1]=0;return(s);
   }
   while (x<=w)
   {
      x*=10;i++;
   }
   x/=10;i--;
   for(c=sign;c<=(i+sign);c++)
   {
      t=w/x;
      s[c]=48+t;
      w-=t*x;x/=10;
   }
   s[c]=0;
   return(s);
}   /* Ende Str()  */

