/*************************************************************************** * * MandleVroom Color Palette * * Kevin L. Clague * * Copyright (C) 1987 * **************************************************************************/ #include "mand.h" extern USHORT CurContour; extern struct Gadget *ContGadget[], *SelGadget[]; extern struct Window *ContWind, *MandWind; /* * Holder for Allocated color potentiometer gadgets. */ struct ColorGads { struct Gadget *RedPot; struct Gadget *GreenPot; struct Gadget *BluePot; }; extern struct Screen *screen; extern struct ViewPort *vp; extern struct IntuitionBase *IntuitionBase; extern char *ColorBase; extern struct IntuiText *MakeIntui(); struct Window *PalWind; extern SHORT XScale, YScale; extern struct Window *ContWind; struct ColorGads PalGads; USHORT CmdMode; USHORT CurPen; struct NewWindow NewPal = { 122,0, /* start position */ 90,120, /* width, height */ (UBYTE) 0, (UBYTE) 1, /* detail pen, block pen */ /* IDCMP flags */ MENUPICK | GADGETDOWN | GADGETUP | MOUSEMOVE | REQCLEAR| CLOSEWINDOW, /* MandWind flags */ WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH | NOCAREREFRESH, (struct Gadget *) NULL, /* first gadget */ (struct Image *) NULL, /* user checkmark */ (UBYTE *) "Colors", /* window title */ (struct Screen *) NULL, /* pointer to screen */ (struct BitMap *) NULL, /* pointer to superbitmap */ 80,80,80,80, /* sizing */ CUSTOMSCREEN /* type of screen */ }; extern struct Windows *WindowList; /* * Interpret the gadgets and do the right thing */ DoPalette(gadget) struct Gadget *gadget; { switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) { case PALPENS: ColorPenGotten(gadget); SetNormPointer(); break; case PALCNTLS: ColorCntlGotten(gadget); break; case PALPOTS: SetNormPointer(); CmdMode = COLORSLIDE; break; } } /* DoPalette */ /* * We got a color palette command gadget */ int ColorCntlGotten(gadget) struct Gadget *gadget; { switch (gadget->GadgetID) { case PALCOPY: SetToPointer(); CmdMode = COPY; break; case PALRANGE: SetToPointer(); CmdMode = RANGE; break; case PALEXCG: SetToPointer(); CmdMode = EXCG; break; } } /* ColorCntlGotten */ /* * We got a color pen. Now what was the command we were supposed to perform? */ int ColorPenGotten(gadget) struct Gadget *gadget; { USHORT rgb, rgb2, pen; struct Image *Image; BoxPen((USHORT) CurPen, 0); pen = gadget->GadgetID & 0x003f; switch (CmdMode) { case COPY: rgb = GetRGB4(vp->ColorMap, CurPen); SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb); break; case RANGE: ColorRange(CurPen, pen); break; case EXCG: rgb = GetRGB4(vp->ColorMap, CurPen); rgb2 = GetRGB4(vp->ColorMap, pen); SetRGB4(vp, CurPen, rgb2 >> 8, rgb2 >> 4, rgb2 ); SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb ); break; case IMPLIEDSET: Image = (struct Image *) SelGadget[ CurContour ]->GadgetRender; Image->PlaneOnOff = pen; RefreshGList( SelGadget[ CurContour ], ContWind, NULL, 1); *(ColorBase + CurContour) = pen; break; } CurPen = pen; SetColorProps( pen ); BoxPen( pen, 1); } /* ColorPenGotten */ /* * Blend a range of colors between two pens */ int ColorRange(first, last) SHORT first, last; { SHORT i; LONG whole, redfraction, greenfraction, bluefraction; USHORT rgb; SHORT firstred, firstgreen, firstblue; SHORT lastred, lastgreen, lastblue; SHORT workred, workgreen, workblue; if (first > last) { i = first; first = last; last = i; } /* I need to see a spread of at least two, where there's at least one * spot between the endpoints, else there's no work to do so I * might as well just return now. */ if (first >= last - 1) return; rgb = GetRGB4(vp->ColorMap, first); firstred = (rgb >> 8) & 0xF; firstgreen = (rgb >> 4) & 0xF; firstblue = (rgb >> 0) & 0xF; rgb = GetRGB4(vp->ColorMap, last); lastred = (rgb >> 8) & 0xF; lastgreen = (rgb >> 4) & 0xF; lastblue = (rgb >> 0) & 0xF; whole = (lastred - firstred) << 16; redfraction = whole / (last - first); whole = (lastgreen - firstgreen) << 16; greenfraction = whole / (last - first); whole = (lastblue - firstblue) << 16; bluefraction = whole / (last - first); for (i = first + 1; i < last; i++) { lastred = (redfraction * (i - first) + 0x8000) >> 16; workred = firstred + lastred; lastgreen = (greenfraction * (i - first) + 0x8000) >> 16; workgreen = firstgreen + lastgreen; lastblue = (bluefraction * (i - first) + 0x8000) >> 16; workblue = firstblue + lastblue; SetRGB4(vp, i, workred, workgreen, workblue); } } /* ColorRange */ /* * Modify the colors in the current pen */ ModifyColors() { USHORT newred, newgreen, newblue; newred = ((struct PropInfo *) PalGads.RedPot->SpecialInfo)->VertPot >> 12; newgreen = ((struct PropInfo *) PalGads.GreenPot->SpecialInfo)->VertPot >> 12; newblue = ((struct PropInfo *) PalGads.BluePot->SpecialInfo)->VertPot >> 12; SetRGB4(vp, CurPen, newred, newgreen, newblue); } /* ModifyColors */ /* * Reflect a pen's new color in the proportional gadget */ SetColorProps(pen) USHORT pen; { USHORT rgb, red, green, blue; rgb = GetRGB4(vp->ColorMap, pen); red = (rgb >> 8) & 0xF; green = (rgb >> 4) & 0xF; blue = (rgb >> 0) & 0xF; red = (red << 12); green = (green << 12); blue = (blue << 12); ModifyProp(PalGads.RedPot, PalWind,NULL,FREEVERT|PROPBORDERLESS, 0L,red,0L,0L); ModifyProp(PalGads.GreenPot,PalWind,NULL,FREEVERT|PROPBORDERLESS, 0L,green,0L,0L); ModifyProp(PalGads.BluePot, PalWind,NULL,FREEVERT|PROPBORDERLESS, 0L,blue,0L,0L); } /* SetColorProps */ BoxPen(BoxPen, DrawPen) USHORT BoxPen, DrawPen; { ULONG row, column; SHORT Top, Bot, Left, Right; #define PALTOP (12 << YScale) #define PALLEFT (4 << XScale) #define PENWIDTH (4 << XScale) #define PENHEIGHT (4 << YScale) #define PENXPITCH (6 << XScale) #define PENYPITCH (6 << YScale) column = BoxPen/8; row = BoxPen - column*8; SetAPen(PalWind->RPort, DrawPen); Left = PALLEFT + PENXPITCH * column - 1; Top = PALTOP + PENYPITCH * row - 1; Right = Left + PENWIDTH + 1; Bot = Top + PENHEIGHT + 1; Move(PalWind->RPort, Left, Top); Draw(PalWind->RPort, Right, Top); Draw(PalWind->RPort, Right, Bot); Draw(PalWind->RPort, Left, Bot); Draw(PalWind->RPort, Left, Top + 1); } /* * Allocate all the gadgets for the color palette window */ struct Gadget *MakePalette() { struct Gadget *FirstGadget, *NextGadget; extern struct Gadget *MakeBool(), *MakePot(); SHORT i,Left,x,y,c = 0; FirstGadget = NextGadget = MakeBool(4,12,5,5,0,PALPEN); i = 1 << (screen->BitMap.Depth); Left = 8; for (x = 0; x < 6*8 && i > 0; x += 6) { for (y = 0; y < 6*8 && i > 0; y += 6) { if (c != 0) { NextGadget->NextGadget = MakeBool(x+4, y+12, 4, 4, c, PALPEN+c); if ((NextGadget = NextGadget->NextGadget) == (struct Gadget *) NULL) return(FirstGadget); } c++; i--; } Left += 8; } for (c = 0, x = 0; x < 10*3; x += 10) { NextGadget->NextGadget = MakeBool(Left+36, x+12, 10, 6, 1, PALCNTL+c); if (NextGadget->NextGadget == (struct Gadget *) NULL) return(FirstGadget); switch (c) { case 0: NextGadget->NextGadget->GadgetText = MakeIntui("Copy",14,-1,3,3,JAM1); break; case 1: NextGadget->NextGadget->GadgetText = MakeIntui("Spread",14,-1,3,3,JAM1); break; case 2: NextGadget->NextGadget->GadgetText = MakeIntui("Exchg",14,-1,3,3,JAM1); break; } NextGadget = NextGadget->NextGadget; c++; } for (x = y = 0; y < 3; x += 10, y++) { NextGadget->NextGadget = MakePot(Left+x, 22, 5, 42, PALPOT + y, y); if (NextGadget->NextGadget == (struct Gadget *) NULL) return(FirstGadget); switch (y) { case 0: PalGads.RedPot = NextGadget->NextGadget; NextGadget->NextGadget->GadgetText = MakeIntui("R",-2,-10,3,3,JAM1); break; case 1: PalGads.GreenPot = NextGadget->NextGadget; NextGadget->NextGadget->GadgetText = MakeIntui("G",-2,-10,3,3,JAM1); break; case 2: PalGads.BluePot = NextGadget->NextGadget; NextGadget->NextGadget->GadgetText = MakeIntui("B",-2,-10,3,3,JAM1); break; } NextGadget = NextGadget->NextGadget; NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY; } return(FirstGadget); } /* MakePalette */ /* * Open the Palette window */ OpenPalWind() { struct Window *OpenMyWind(); if (PalWind == (struct Window *) NULL) { PalWind = OpenMyWind(&NewPal,screen,MakePalette(),140,70,140,70); if (PalWind) { CurPen = 0; BoxPen(CurPen, 1); SetColorProps( CurPen ); ForceNormPointer(); } } else { WindowToFront( PalWind ); } } /* OpenPalWind */ /* * Close the Palette window */ ClosePalWind() { if (PalWind != (struct Window *) NULL) { CloseMyWind(PalWind,NewPal.FirstGadget); PalWind = (struct Window *) NULL; } } /* ClosePalWind */