home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff214.lzh / MandelVroom / src / palette.c < prev    next >
C/C++ Source or Header  |  1989-05-30  |  14KB  |  614 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains the functions that open, maintain, operate
  25.  * and close the color palette.
  26.  */
  27.  
  28. #include "mandp.h"
  29.  
  30. #include <ctype.h>
  31.  
  32. #define PENLEFT 8
  33. #define PENTOP  15
  34.  
  35. extern struct Gadget *ContGadget[], *SelGadget[];
  36.  
  37. UBYTE PaletteOpen;
  38.  
  39. /*
  40.  * Holder for Allocated color potentiometer gadgets.
  41.  */
  42. struct ColorGads {
  43.   struct Gadget *RedPot;
  44.   struct Gadget *GreenPot;
  45.   struct Gadget *BluePot;
  46. };
  47.  
  48. struct Window          *PalWind;
  49. struct ColorGads        PalGads;
  50.  
  51. LONG CurPen;
  52.  
  53. struct NewWindow NewPal = {
  54.    128,0,                    /* start position           */
  55.    70,80,                    /* width, height            */
  56.    (UBYTE) 0, (UBYTE) -1,   /* detail pen, block pen    */
  57.    NULL,                     /* IDCMP flags */
  58.                              /* MandWind flags */
  59.    WINDOWCLOSE   | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH,
  60.    (struct Gadget *) NULL,   /* first gadget             */
  61.    (struct Image *) NULL,    /* user checkmark           */
  62.    (UBYTE *) "Colors",       /* window title             */
  63.    (struct Screen *) NULL,   /* pointer to screen        */
  64.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  65.    80,80,80,80,              /* sizing                   */
  66.    CUSTOMSCREEN              /* type of screen           */
  67.    };
  68.  
  69. /*
  70.  * Color Palette Commands
  71.  */
  72.  
  73. CopyRGBCmd(Msg)
  74.   struct IntuiMessage *Msg;
  75. {
  76.   struct Gadget  *gadget;
  77.   register LONG rgb, pen;
  78.  
  79.   /* Need contour selection to complete */
  80.  
  81.   gadget = (struct Gadget *) Msg->IAddress;
  82.  
  83.   if (Msg->Class == GADGETDOWN) {
  84.  
  85.     if (gadget->GadgetID == PALCOPY) { /* Copy command gadget */
  86.  
  87.       SetToPointer();
  88.       State = COPYRGBSTATE;
  89.     } else {
  90.  
  91.       if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
  92.  
  93.         /* Copy the RGBs from CurPen to NewPen */
  94.  
  95.         pen = GADG_NUM(gadget->GadgetID);
  96.         rgb = GetRGB4(vp->ColorMap, CurPen);
  97.         SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb);
  98.         SaveRGBs(CurPict);
  99.  
  100.         State = IDLESTATE;
  101.       }
  102.     }
  103.   }
  104. }
  105.  
  106. SpreadRGBCmd(Msg)
  107.   struct IntuiMessage *Msg;
  108. {
  109.   struct Gadget *gadget;
  110.   register LONG  pen;
  111.  
  112.   /* Need contour selection to complete */
  113.  
  114.   gadget = (struct Gadget *) Msg->IAddress;
  115.  
  116.   if (Msg->Class == GADGETDOWN) {
  117.  
  118.     if (gadget->GadgetID == PALRANGE) { /* Spread command gadget */
  119.  
  120.       SetToPointer();
  121.       State = SPREADRGBSTATE;
  122.     } else {
  123.  
  124.       if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
  125.  
  126.         /* Spread the RGBs from CurPen to NewPen */
  127.  
  128.         pen = GADG_NUM(gadget->GadgetID);
  129.         ColorRange(CurPen, pen);
  130.         SaveRGBs(CurPict);
  131.  
  132.         State = IDLESTATE;
  133.       }
  134.     }
  135.   }
  136. }
  137.  
  138. ExchangeRGBCmd(Msg)
  139.   struct IntuiMessage *Msg;
  140. {
  141.   register LONG rgb, rgb2, pen;
  142.   struct Gadget *gadget;
  143.  
  144.   /* Need contour selection to complete */
  145.  
  146.   gadget = (struct Gadget *) Msg->IAddress;
  147.  
  148.   if (Msg->Class == GADGETDOWN) {
  149.  
  150.     if (gadget->GadgetID == PALEXCG) { /* Exchange command gadget */
  151.  
  152.       SetWithPointer();
  153.       State = XCHGRGBSTATE;
  154.     } else {
  155.  
  156.       if (GADG_TYPE(gadget->GadgetID) == PALPEN) {
  157.  
  158.         /* exchange the RGBs in CurPen and NewPen */
  159.  
  160.         pen = GADG_NUM(gadget->GadgetID);
  161.         rgb  = GetRGB4(vp->ColorMap, CurPen);
  162.         rgb2 = GetRGB4(vp->ColorMap, pen);
  163.         SetRGB4(vp, CurPen, rgb2 >> 8, rgb2 >> 4, rgb2 );
  164.         SetRGB4(vp, pen,    rgb  >> 8, rgb  >> 4, rgb  );
  165.         SaveRGBs(CurPict);
  166.  
  167.         State = IDLESTATE;
  168.       }
  169.     }
  170.   }
  171. }
  172.  
  173. SlideRGBCmd(Msg)
  174.   struct IntuiMessage *Msg;
  175. {
  176.   struct Gadget *gadget;
  177.  
  178.   gadget = (struct Gadget *) Msg->IAddress;
  179.  
  180.   switch( Msg->Class ) {
  181.  
  182.     case GADGETDOWN:                          /* Start RGB slide    */
  183.          StartBarDrag();
  184.          State = SLIDERGBSTATE;
  185.          break;
  186.  
  187.     case MOUSEMOVE:
  188.          ModifyColors();                      /* change RGB colors */
  189.          break;
  190.  
  191.     case GADGETUP:                            /* Stop the RGB slide */
  192.          ModifyColors();
  193.          SaveRGBs(CurPict);
  194.          State = IDLESTATE;
  195.          break;
  196.   }
  197. }
  198.  
  199. SetCurPen( pen )
  200.   int pen;
  201. {
  202.   BoxPen( CurPen, NORMALPEN );
  203.   CurPen = pen;
  204.   SetColorProps(pen);
  205.   BoxPen( CurPen, MEDIUMPEN );
  206.   SaveRGBs( CurPict );
  207. }
  208.  
  209. /*
  210.  * Blend a range of colors between two pens
  211.  */
  212. ColorRange(first, last)
  213.   LONG first, last;
  214. {
  215.     LONG i;
  216.     register LONG whole, redfraction, greenfraction, bluefraction;
  217.     register USHORT rgb;
  218.     LONG firstred, firstgreen, firstblue;
  219.     LONG lastred, lastgreen, lastblue;
  220.     LONG workred, workgreen, workblue;
  221.  
  222.     if (first > last) {
  223.         i = first;
  224.         first = last;
  225.         last = i;
  226.      }
  227.  
  228.     /* I need to see a spread of at least two, where there's at least one
  229.      * spot between the endpoints, else there's no work to do so I
  230.      * might as well just return now.
  231.      */
  232.     if (first >= last - 1) return;
  233.  
  234.     rgb = GetRGB4(vp->ColorMap, first);
  235.     firstred = (rgb >> 8) & 0xF;
  236.     firstgreen = (rgb >> 4) & 0xF;
  237.     firstblue = (rgb >> 0) & 0xF;
  238.  
  239.     rgb = GetRGB4(vp->ColorMap, last);
  240.     lastred = (rgb >> 8) & 0xF;
  241.     lastgreen = (rgb >> 4) & 0xF;
  242.     lastblue = (rgb >> 0) & 0xF;
  243.  
  244.     whole = (lastred - firstred) << 16;
  245.     redfraction = whole / (last - first);
  246.     whole = (lastgreen - firstgreen) << 16;
  247.     greenfraction = whole / (last - first);
  248.     whole = (lastblue - firstblue) << 16;
  249.     bluefraction = whole / (last - first);
  250.  
  251.     for (i = first + 1; i < last; i++)
  252.         {
  253.         lastred = (redfraction * (i - first) + 0x8000) >> 16;
  254.         workred = firstred + lastred;
  255.         lastgreen = (greenfraction * (i - first) + 0x8000) >> 16;
  256.         workgreen = firstgreen + lastgreen;
  257.         lastblue = (bluefraction * (i - first) + 0x8000) >> 16;
  258.         workblue = firstblue + lastblue;
  259.         SetRGB4(vp, i, workred, workgreen, workblue);
  260.         }
  261. } /* ColorRange */
  262.  
  263. /*
  264.  * Modify the colors in the current pen
  265.  */
  266. ModifyColors( )
  267. {
  268.   register LONG newred, newgreen, newblue;
  269.  
  270.   newred = ((struct PropInfo *)
  271.            PalGads.RedPot->SpecialInfo)->VertPot >> 12;
  272.   newgreen = ((struct PropInfo *)
  273.            PalGads.GreenPot->SpecialInfo)->VertPot >> 12;
  274.   newblue = ((struct PropInfo *)
  275.            PalGads.BluePot->SpecialInfo)->VertPot >> 12;
  276.  
  277.   newred   = 0xF ^ newred;
  278.   newgreen = 0xF ^ newgreen;
  279.   newblue  = 0xF ^ newblue;
  280.  
  281.   PrintRGB( newred, newgreen, newblue );
  282.  
  283.   SetRGB4(vp, CurPen, newred, newgreen, newblue);
  284. } /* ModifyColors */
  285.  
  286. PrintRGB( r, g, b )
  287.   LONG r,g,b;
  288. {
  289.   PrintGad( PalGads.RedPot,   r );
  290.   PrintGad( PalGads.GreenPot, g );
  291.   PrintGad( PalGads.BluePot,  b );
  292. }
  293.  
  294. PrintGad( gadget, Color )
  295.   register struct Gadget *gadget;
  296.   LONG   Color;
  297. {
  298.   register struct IntuiText *SaveIntui, *IntuiText = gadget->GadgetText;
  299.  
  300.   char d[4];
  301.  
  302.   SaveIntui = IntuiText;
  303.  
  304.   Color &= 0xf;
  305.   sprintf( d, "%x", Color );
  306.  
  307.   d[0] = toupper(d[0]);
  308.  
  309.   IntuiText = IntuiText->NextText;
  310.  
  311.   IntuiText->IText[0] = d[0];
  312.  
  313.   IntuiText = IntuiText->NextText;
  314.  
  315.   IntuiText->IText[0] = d[0];
  316.  
  317.   PrintIText( PalWind->RPort, SaveIntui, gadget->LeftEdge, gadget->TopEdge);
  318. }
  319.  
  320. /*
  321.  * Reflect a pen's new color in the proportional gadget
  322.  */
  323. SetColorProps(pen)
  324.   LONG pen;
  325. {
  326.   register LONG rgb, red, green, blue;
  327.  
  328.   if (PalWind == NULL)
  329.     return;
  330.  
  331.   pen &= Num_vp_Colors - 1;
  332.  
  333.   rgb = GetRGB4(vp->ColorMap, pen);
  334.  
  335.   red = 0xF - ((rgb >> 8) & 0xF);
  336.   green = 0xF - ((rgb >> 4) & 0xF);
  337.   blue = 0xF - (rgb & 0xF);
  338.  
  339.   red   |= (red << 4);
  340.   red   |= (red << 8);
  341.   green |= (green << 4);
  342.   green |= (green << 8);
  343.   blue  |= (blue <<  4);
  344.   blue  |= (blue <<  8);
  345.  
  346.   NewModifyProp(PalGads.RedPot,  PalWind,NULL,FREEVERT|PROPBORDERLESS,
  347.              0L,red,0L,0xfffL,1L);
  348.   NewModifyProp(PalGads.GreenPot,PalWind,NULL,FREEVERT|PROPBORDERLESS,
  349.              0L,green,0L,0xfffL,1L);
  350.   NewModifyProp(PalGads.BluePot, PalWind,NULL,FREEVERT|PROPBORDERLESS,
  351.              0L,blue,0L,0xfffL,1L);
  352. } /* SetColorProps */
  353.  
  354. BoxPen(BoxPen, DrawPen)
  355.   LONG BoxPen, DrawPen;
  356. {
  357.   register LONG  Top, Bot, Left, Right;
  358.   register ULONG row, column;
  359.  
  360. #define PALTOP    (PENTOP - 1)
  361. #define PALLEFT   (PENLEFT - 1)
  362. #define PENWIDTH  (4 << XScale)
  363. #define PENHEIGHT (4 << YScale)
  364. #define PENXPITCH (6 << XScale)
  365. #define PENYPITCH (6 << YScale)
  366.  
  367.   if (PalWind == NULL)
  368.     return;
  369.  
  370.   column = BoxPen/8;
  371.  
  372.   row = BoxPen - column*8;
  373.  
  374.   SetAPen(PalWind->RPort, DrawPen);
  375.  
  376.   Left  = PALLEFT + PENXPITCH * column;
  377.   Top   = PALTOP  + PENYPITCH * row;
  378.   Right = Left    + PENWIDTH  + 2 + XScale;
  379.   Bot   = Top     + PENHEIGHT + 2 + YScale;
  380.  
  381.   Move(PalWind->RPort, Left,  Top);
  382.   Draw(PalWind->RPort, Right, Top);
  383.  
  384.   if (DrawPen == HIGHLIGHTPEN) SetAPen(PalWind->RPort, SHADOWPEN);
  385.  
  386.   Draw(PalWind->RPort, Right, Bot);
  387.   Draw(PalWind->RPort, Left,  Bot);
  388.  
  389.   SetAPen(PalWind->RPort, DrawPen);
  390.  
  391.   Draw(PalWind->RPort, Left,  Top + 1);
  392.  
  393.   if (DrawPen) {
  394.     row = GetRGB4(vp->ColorMap, BoxPen & (Num_vp_Colors - 1));
  395.     PrintRGB( (long) row >> 8, (long) row >> 4, (long) row );
  396.   }
  397. }
  398.  
  399. static LONG WindowWidth;
  400. static LONG WindowHeight;
  401. static LONG BorderLeft;
  402.  
  403. static struct Border *PensBorder;
  404. /*
  405.  * Allocate all the gadgets for the color palette window
  406.  */
  407. struct Gadget *MakePalette()
  408. {
  409.            struct Gadget *FirstGadget;
  410.   register struct Gadget *NextGadget;
  411.   register LONG i,Left,x,y,c = 0;
  412.  
  413.   struct IntuiText *Text, *NextText;
  414.   struct PropInfo  *PropInfo;
  415.  
  416.   LONG fourx = 4 << XScale;
  417.   LONG foury = 4 << YScale;
  418.  
  419.   char *str;
  420.  
  421.   Left = PENLEFT;
  422.  
  423.   FirstGadget = NextGadget =
  424.     MakeBool( Left, PENTOP, fourx, foury, 0, PALPEN, GADGIMAGE );
  425.  
  426.   if ( FirstGadget == NULL ) goto error;
  427.  
  428.   i = 1 << (screen->BitMap.Depth);
  429.  
  430.   for (x = 0; x < 6*8 && i > 0; x += 6) {
  431.     for (y = 0; y < 6*8 && i > 0; y += 6) {
  432.       if (c != 0) {
  433.  
  434.         NextGadget->NextGadget =
  435.           MakeBool( Left, (y<<YScale)+PENTOP, fourx, foury, c, PALPEN+c,
  436.                     GADGIMAGE);
  437.  
  438.         if ((NextGadget = NextGadget->NextGadget) == NULL) goto error;
  439.       }
  440.       c++;
  441.       i--;
  442.     }
  443.     Left += 6 << XScale;
  444.   }
  445.   WindowHeight = ((6*8) << YScale) + PENTOP + 6;
  446.  
  447.   c = ((y + 1) << YScale) + 2;
  448.  
  449.   if ( c > WindowHeight ) {
  450.     WindowHeight = c + 4;
  451.   }
  452.  
  453.   PensBorder = ShadowBorder( BEVELEDUP, 4, 12, Left - 2, c+1);
  454.  
  455.   if (PensBorder == NULL) goto error;
  456.  
  457.   Left += 9;
  458.  
  459.   BorderLeft = Left - 1;
  460.  
  461.   i = -2 * ( XScale ^ 1 );
  462.  
  463.   for (x = y = 0; y < 3; x += 10, y++) {
  464.  
  465.     NextGadget->NextGadget = MakePot( Left + x, 22, fourx,
  466.                                       WindowHeight - 35, PALPOT, y);
  467.     NextGadget = NextGadget->NextGadget;
  468.  
  469.     if ( NextGadget == NULL ) goto error;
  470.  
  471.     NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
  472.     NextGadget->GadgetText = Text =
  473.                            ShadowIntui("0", i, WindowHeight - 32 );
  474.     if ( Text == NULL ) goto error;
  475.  
  476.     PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
  477.     PropInfo->VertBody  = 0xfff;
  478.  
  479.     switch (y) {
  480.       case 0:  PalGads.RedPot = NextGadget;
  481.                str = "R";
  482.                break;
  483.  
  484.       case 1:  PalGads.GreenPot = NextGadget;
  485.                str = "G";
  486.                break;
  487.  
  488.       case 2:  PalGads.BluePot = NextGadget;
  489.                str = "B";
  490.                break;
  491.     }
  492.     NextText = Text;
  493.  
  494.     while ( NextText->NextText ) {
  495.       NextText = NextText->NextText;
  496.     }
  497.  
  498.     NextText->NextText = ShadowIntui( str, i, -11 );
  499.  
  500.     if ( NextText->NextText == NULL ) goto error;
  501.   }
  502.   Left += 32;
  503.  
  504.   for (c = 0, x = 0; x < 17*3; x += 17) {
  505.  
  506.     NextGadget->NextGadget =
  507.       MakeBool( Left, x + 11, 54, 13, 1, PALCNTL+c, NULL);
  508.  
  509.     NextGadget = NextGadget->NextGadget;
  510.  
  511.     if ( NextGadget == NULL) goto error;
  512.  
  513.     switch (c) {
  514.       case 0:  NextGadget->GadgetText =
  515.                   ShadowIntui("Copy", 12,3);
  516.                break;
  517.  
  518.       case 1:  NextGadget->GadgetText =
  519.                   ShadowIntui("Spread",4,3);
  520.                break;
  521.  
  522.       case 2:  NextGadget->GadgetText =
  523.                   ShadowIntui("Exchg", 8,3);
  524.                break;
  525.     }
  526.     c++;
  527.   }
  528.   WindowWidth = Left + 59;
  529.  
  530.   return(FirstGadget);
  531.  
  532. error:
  533.   FreeBorder( PensBorder );
  534.   FreeGadgets( FirstGadget );
  535.   return( NULL );
  536. } /* MakePalette */
  537.  
  538. static struct Gadget *PalGadgets;
  539.  
  540. /*
  541.  * Open the Palette window
  542.  */
  543. OpenPalWind()
  544. {
  545.   struct Window *OpenMyWind();
  546.  
  547.   register struct Gadget *gadget;
  548.   register struct RastPort *Rp;
  549.   LONG fourx = 4 << XScale;
  550.  
  551.   if (CurPict == NULL)
  552.     return;
  553.  
  554.   if ( PalWind == NULL ) {
  555.  
  556.     gadget = MakePalette();
  557.  
  558.     if ( gadget == NULL ) {
  559.       DispErrMsg("Couldn't get palette gadgets", 0 );
  560.       return;
  561.     }
  562.  
  563.     PalWind = OpenMyWind( &NewPal, screen, NULL, WindowWidth, WindowHeight);
  564.  
  565.     if ( PalWind != NULL ) {
  566.  
  567.       ModifyIDCMP( PalWind,  (long)
  568.                    PalWind->IDCMPFlags | MOUSEBUTTONS | MOUSEMOVE );
  569.  
  570.       Rp = PalWind->RPort;
  571.  
  572.       SetAPen( Rp, NORMALPEN );
  573.       RectFill( Rp, LEFTMARG, TOPMARG,
  574.                 WindowWidth,WindowHeight);
  575.  
  576.       BorderWindow( PalWind );
  577.  
  578.       PalGadgets = gadget;
  579.  
  580.       AddGList( PalWind, gadget, -1, -1);
  581.  
  582.       RefreshGadgets( gadget, PalWind, NULL );
  583.  
  584.       DrawBorder( Rp, PensBorder, 0L, 0L );
  585.       FreeBorder( PensBorder );
  586.  
  587.       CurPen &= Num_vp_Colors - 1;
  588.  
  589.       BoxPen( CurPen, MEDIUMPEN );
  590.       SetColorProps( CurPen );
  591.     }
  592.   } else {
  593.     WindowToFront( PalWind );
  594.   }
  595.   PaletteOpen = 1;
  596. } /* OpenPalWind */
  597.  
  598. /*
  599.  * Close the Palette window
  600.  */
  601. ClosePalWind()
  602. {
  603.   if (PalWind != NULL) {
  604.  
  605.     NewPal.LeftEdge = PalWind->LeftEdge;
  606.     NewPal.TopEdge  = PalWind->TopEdge;
  607.  
  608.     CloseMyWind(PalWind,PalGadgets);
  609.     PalGadgets = NULL;
  610.   }
  611.   PalWind = NULL;
  612. } /* ClosePalWind */
  613.  
  614.