/* * TITLE: Palette.c --- Adjusts colors of front screen or custom test screen * * Palette.c C. Scheppner CBM 10/86 * * Inspired by Charlie Heath's Palette.c * * Opens a palette tool in the front or only screen. * Optional args open a test screen for the palette: * USAGE: palette [bitplanes] [screentype] * screentype 1=320x200 2=320x400 3=640x200 4=640x400 */ #include #include #include #include #define WIDE 320 #define HIGH 200 #define DEEP 5 /* Screen for custom screen palette */ struct TextAttr topaz80 = {"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT }; struct NewScreen newtScreen = { 0,0,WIDE,HIGH,DEEP, /* Corner, Size */ 1,2,0, /* Detail, Block, Modes */ CUSTOMSCREEN,&topaz80, /* ScreenType, Font */ "Custom Screen", 0,0 }; /* Gadgets, Bitmap */ /* Other globals of caller */ struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Screen *pscreen, *tscreen; BOOL FromCLI = TRUE; /* Sample calling program */ main(argc,argv) int argc; char **argv; { USHORT testpl, testsz; if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",30))) cleanexit("Can't open intuition\n"); if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",30))) cleanexit("Can't open graphics\n"); if (argc==0) FromCLI = FALSE; tscreen = NULL; /* Null so we won't close if we didn't need to open */ if (argc==3) /* Arguments passed, open a test screen */ { testpl = ((USHORT)*argv[1])&0x0F; testsz = ((USHORT)*argv[2])&0x0F; if ((testpl<1)||(testpl>5)) testpl = 5; if (((testsz==2)||(testsz==4))&&(testpl==5)) testpl = 4; newtScreen.Depth = testpl; if (testsz==2) newtScreen.Width=640, newtScreen.ViewModes = HIRES; if (testsz==3) newtScreen.Height=400, newtScreen.ViewModes = LACE; if (testsz==4) newtScreen.Width=640, newtScreen.Height = 400, newtScreen.ViewModes = HIRES|LACE; if (!(tscreen= (struct Screen *)OpenScreen(&newtScreen))) cleanexit("Can't open test screen\n"); pscreen = tscreen; } else /* Open palette on the front screen */ { pscreen = IntuitionBase->FirstScreen; } if (!(doPalette(pscreen))) cleanexit ("Can't open palette\n"); cleanexit(""); } cleanexit(s) char *s; { int error = 0; if ((*s)&&(FromCLI)) printf(s); if (*s) error = 1; if (tscreen) CloseScreen(tscreen); /* if test screen opened */ if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); exit(error); } /* ================================================================ */ /* Globals for doPalette() */ #define MAXCOLORS 32 #define RGB_BODY 0xFFF #define PWIDE 192 /* Palette Window Width */ #define PBASEHIGH 72 /* Height before adjust for color rows */ /* Gadget ID's */ #define colID 1 #define okID MAXCOLORS + 1 #define resID MAXCOLORS + 2 #define canID MAXCOLORS + 3 #define rID MAXCOLORS + 4 #define bID MAXCOLORS + 5 #define gID MAXCOLORS + 6 /* Proportional RGB Gadgets */ #define PRPX 52 #define PRPY -62 /* Top prop, relative to bottom */ #define PRPW 90 #define PRPH 11 struct IntuiText rTxt = {1,0,JAM1,-11,2,0,"R",0}, gTxt = {1,0,JAM1,-11,2,0,"G",0}, bTxt = {1,0,JAM1,-11,2,0,"B",0}; struct Image rImg, gImg, bImg; struct PropInfo rInf = {AUTOKNOB|FREEHORIZ,0,0,RGB_BODY,0,0,0,0,0,0,0}, gInf = {AUTOKNOB|FREEHORIZ,0,0,RGB_BODY,0,0,0,0,0,0,0}, bInf = {AUTOKNOB|FREEHORIZ,0,0,RGB_BODY,0,0,0,0,0,0,0}; struct Gadget bGad = { NULL, PRPX,PRPY+30, PRPW,PRPH, GADGHNONE|GADGIMAGE|GRELBOTTOM, GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE, PROPGADGET,(APTR)&bImg, 0, &bTxt, 0,(APTR)&bInf, bID, 0 }, /* Last Gadget */ gGad = { &bGad, PRPX,PRPY+15, PRPW,PRPH, GADGHNONE|GADGIMAGE|GRELBOTTOM, GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE, PROPGADGET,(APTR)&gImg, 0, &gTxt, 0,(APTR)&gInf, gID, 0 }, rGad = { &gGad, PRPX,PRPY, PRPW,PRPH, GADGHNONE|GADGIMAGE|GRELBOTTOM, GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE, PROPGADGET,(APTR)&rImg, 0, &rTxt, 0,(APTR)&rInf, rID, 0 }; /* Text Selection Gadgets */ #define TXTX 8 #define TXTY -17 /* Relative to bottom */ #define TXTW 54 #define TXTH 13 SHORT txtBorXY[10] = {0,0, TXTW-1,0, TXTW-1,TXTH-1, 0,TXTH-1, 0,0}; struct Border txtBor = { 0,0,3,0,JAM1,5,&txtBorXY[0],NULL }; struct IntuiText canTxt = {1,0,JAM1,4,3,0,"CANCEL",0}; struct Gadget canGad = { &rGad, TXTX+122,TXTY,TXTW,TXTH, GADGHCOMP|GRELBOTTOM, RELVERIFY, BOOLGADGET, (APTR)&txtBor, 0, &canTxt, 0,0, canID, 0 }; /* Linked to red Prop Gadget */ struct IntuiText resTxt = {1,0,JAM1,8,3,0,"RESET",0}; struct Gadget resGad = { &canGad, TXTX+61,TXTY,TXTW,TXTH, GADGHCOMP|GRELBOTTOM, RELVERIFY, BOOLGADGET, (APTR)&txtBor, 0, &resTxt, 0,0, resID, 0 }; struct IntuiText okTxt = {1,0,JAM1,19,3,0,"OK",0}; struct Gadget okGad = { &resGad, TXTX,TXTY,TXTW,TXTH, GADGHCOMP|GRELBOTTOM, RELVERIFY, BOOLGADGET, (APTR)&txtBor, 0, &okTxt, 0,0, okID, 0 }; /* Color gads will be linked to this one */ /* Palette Color Gadgets */ #define COLX 10 /* Offsets of first color gadget */ #define COLY 14 #define COLSW 4 /* Spacing between color gadgets */ #define COLSH 4 #define COLW8 18 /* Image width if 8 or more colors */ #define COLW4 (COLW8+COLW8+COLSW) /* 4 colors */ #define COLW2 (COLW4+COLW4+COLSW) /* 2 colors */ #define COLH 10 /* Image height */ #define COLDY (COLH+COLSH) SHORT colW, colDX; /* Drawn with DrawBorder() when color is selected */ /* Note - the border coords will be filled in by initColGads() */ SHORT colBorXY[10] = {-2,-2, NULL,-2, NULL,COLH+1, -2,COLH+1, -2,-2}; struct Border colBor = { 0,0,1,0,JAM1,5,&colBorXY[0],NULL }; SHORT colGadX[MAXCOLORS], colGadY[MAXCOLORS]; struct Image *colImgs; struct Gadget *colGads; /* Palette Window */ struct NewWindow newpWin = { 36,24, PWIDE,NULL, /* Height set before opening */ 2,1, MOUSEMOVE | GADGETUP | GADGETDOWN, /* IDCMP Flags */ ACTIVATE | SMART_REFRESH | WINDOWDRAG | WINDOWDEPTH, /* Flags */ NULL, /* First Gadget - set before OpenWindow */ NULL, /* CheckMark */ "Palette Tool", /* Title */ NULL, /* Set up screen pointer before opening */ NULL, /* No superbitmap */ 0,0,0,0, /* Max and Min (no sizing) */ NULL /* Screen type - set before opening */ }; struct Window *pWin; /* Palette window pointer */ struct ViewPort *pVp; struct RastPort *pRp; struct IntuiMessage *pMsg; struct Gadget *pMGad; int pDepth, pColors, pReg, pTopSize; ULONG pMClass, colGadMem, colGadMemSize; UWORD curColor[MAXCOLORS], resColor[MAXCOLORS]; USHORT pMGadID; BOOL Done; /* * doPalette(screen) */ doPalette(pScr) struct Screen *pScr; { int k; /* For safe pcleanup */ pWin = NULL; colGadMem = NULL; /* From the screen - needed by Allocations */ pVp = &pScr->ViewPort; pDepth = pScr->RastPort.BitMap->Depth; pColors = 1 << pDepth; /* Allocations - Note: Requires initialized pDepth, pColors ! */ colGadMemSize = (sizeof(struct Gadget)<Flags & 0x000f; /* Color rows * color gad Y spacing + 10 for top border */ pTopSize = ((((pColors-1) >> 3)+1) * COLDY)+ 10; newpWin.Height = PBASEHIGH + pTopSize; if (!(pWin = (struct Window *)OpenWindow(&newpWin))) { pcleanup("Can't open palette window\n"); return(0); } pRp = pWin->RPort; /* Get current colors and save for RESET */ for (k=0; k < pColors; k++) curColor[k] = resColor[k] = GetRGB4(pVp->ColorMap,k); pReg = 0; /* initially select color 0 */ selectColor(0, pReg); Done = FALSE; while(! Done) { Wait(1<UserPort->mp_SigBit); while (pMsg=(struct IntuiMessage *)GetMsg(pWin->UserPort)) { /* Note that rbg values are modified in 3 cases: * GADGETDOWN of the props * GADGETUP of the props * MOUSEMOVE (reporting turned on by the props) */ pMClass = pMsg->Class; pMGad = (struct Gadget *)pMsg->IAddress; pMGadID = pMGad->GadgetID; ReplyMsg(pMsg); switch(pMClass) { case MOUSEMOVE: modColor(pReg); break; case GADGETDOWN: switch(pMGadID) { case rID: case gID: case bID: modColor(pReg); break; default: if ((pMGadID >= colID)&&(pMGadID<(colID+pColors))) { k = pReg; pReg = pMGadID - colID; selectColor(k,pReg); } break; } case GADGETUP: switch (pMGadID) { case okID: /* OK */ Done = TRUE; break; case resID: /* RESET */ resetColors(); selectColor(pReg,pReg); break; case canID: /* CANCEL */ resetColors(); Done = TRUE; break; case rID: case gID: case bID: modColor(pReg); break; default: break; } default: break; } } } pcleanup(""); return(1); } pcleanup(s) char *s; { if (*s) printf(s); if (pWin) { while (pMsg=(struct IntuiMessage *)GetMsg(pWin->UserPort)) { ReplyMsg(pMsg); } CloseWindow(pWin); if (colGadMem) FreeMem(colGadMem,colGadMemSize); } } initColGads(gad,img,colors,lastLink) struct Gadget *gad; struct Image *img; int colors; struct Gadget *lastLink; { struct Gadget *nextgad; int k, lastk, row, col, rows; colW = COLW8; if (colors == 4) colW = COLW4; if (colors == 2) colW = COLW2; colDX = colW + COLSW; /* color width + space between colors */ colBorXY[2] = colW+1; colBorXY[4] = colW+1; /* Make array of colGad xy positions */ rows = ((colors-1) >> 3) + 1; /* 8 colors per row */ for (row=0, k=0; rowNextGadget = nextgad; else gad->NextGadget = lastLink; gad->LeftEdge = colGadX[k]; gad->TopEdge = colGadY[k]; gad->Width = colW; gad->Height = COLH; gad->Flags = GADGHBOX|GADGIMAGE; gad->Activation = GADGIMMEDIATE; gad->GadgetType = BOOLGADGET; gad->GadgetRender = (APTR)img; gad->GadgetID = colID + k; img->Width = colW; img->Height = COLH; img->Depth = 1; img->PlaneOnOff = k; } } resetColors() { int k; for(k=0; kHeight - 63; chx2 = 34; chy2 = pWin->Height - 23; SetDrMd(pRp,JAM1); SetAPen(pRp,1); Move(pRp,chx1,chy1); Draw(pRp,chx2,chy1); Draw(pRp,chx2,chy2); Draw(pRp,chx1,chy2); Draw(pRp,chx1,chy1); SetAPen(pRp,newreg); RectFill(pRp,chx1+2,chy1+2,chx2-2,chy2-2); rgb = curColor[newreg]; modColorProps(rgb); printRGB((rgb>>8)&0xF, (rgb>>4)&0xF, rgb&0xF); } modColor(reg) int reg; { USHORT r,g,b; r = (rInf.HorizPot >> 12) & 0x0F; g = (gInf.HorizPot >> 12) & 0x0F; b = (bInf.HorizPot >> 12) & 0x0F; curColor[reg] = (r << 8)|(g << 4)|b; LoadRGB4(pVp,&curColor[0],pColors); printRGB(r,g,b); } modColorProps(rgb) USHORT rgb; { USHORT r,g,b; r = (rgb >> 8) & 0xF; g = (rgb >> 4) & 0xF; b = rgb & 0xF; ModifyProp(&rGad,pWin,0,rInf.Flags,(r*0x11111111), rInf.VertPot,rInf.HorizBody,rInf.VertBody); ModifyProp(&gGad,pWin,0,gInf.Flags,(g*0x11111111), gInf.VertPot,gInf.HorizBody,gInf.VertBody); ModifyProp(&bGad,pWin,0,bInf.Flags,(b*0x11111111), bInf.VertPot,bInf.HorizBody,bInf.VertBody); } printRGB(r,g,b) USHORT r,g,b; { char str[4]; char *xstr; xstr = "0123456789ABCDEF"; str[0] = xstr[r]; str[1] = xstr[g]; str[2] = xstr[b]; SetAPen(pRp,1); SetBPen(pRp,0); SetDrMd(pRp,JAM2); Move(pRp,PWIDE-40,pWin->Height - 40); Text(pRp,&str[0],3); }