/************************************************************************ * Version 3.00 MANDELBROT - Self-Squared Dragon Generator 29-May-86 * * Commodore Amiga Color Window MAND5.C * ************************************************************************* * Copyright (c) 1986, Robert S. French and R. J. Mical * * --------------------------------------------------------------------- * * This program has been placed in the public domain. A limited * * license is hereby granted for the unlimited use and distribution of * * this program, provided it is not used for commercial or profit- * * making purposes. Thank you. * ************************************************************************* * Author information: | Name: R. J. Mical * * | USnail: Commodore-Amiga, Inc. * * Name: Robert S. French | 983 University Avenue * * USnail: 2740 Frankfort Avenue | Los Gatos, CA 95030 * * Louisville, KY 40206 \-------------------------------------* * Phone: (502) 897-5096 UUCP: ihnp4!ptsfa!well!french * * ARPA: French#Robert%d@LLL-MFE or RFrench@MIT-MULTICS * ************************************************************************* * Please send any comments, suggestions, or bugs to one of the above * * addresses. * ************************************************************************/ #include "mand.h" #include "globals.h" #define COPYCOLOR 1 #define RANGE_FIRST 2 #define RANGE_SECOND 3 #define COLOR_IDCMP_FLAGS (GADGETDOWN | GADGETUP | MOUSEBUTTONS | MENUPICK | MOUSEMOVE | ACTIVEWINDOW | INACTIVEWINDOW) USHORT ColorMode; USHORT SavePalette[32]; USHORT RangeFirst; /* the first selection of the range-color pair */ /***************************************************************************** * * Color initialization and routines * ****************************************************************************/ BOOL OpenColorWindow() { SHORT i; if (ColorWindow) return(TRUE); disable_some(~0,~0,~0); ColorNewWindow.Screen = screen; ColorNewWindow.IDCMPFlags = NULL; ColorNewWindow.FirstGadget = &ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1]; SetColorProps(); InitSuperColors(); ColorMode = NULL; if ((ColorWindow = (struct Window *)OpenWindow(&ColorNewWindow)) == 0) { printf("no memory!\n"); return(FALSE); } ColorWindow->UserPort = w->UserPort; ModifyIDCMP(ColorWindow, COLOR_IDCMP_FLAGS); reset_menus(); for (i = 0; i < 32; i++) SavePalette[i] = GetRGB4(vp->ColorMap, i); DrawColorWindow(); return(TRUE); } VOID CloseColorWindow(accept) BOOL accept; { SHORT i; if (ColorWindow == NULL) return; ClearMenuStrip(ColorWindow); ColorWindow->UserPort = NULL; CloseWindow(ColorWindow); ColorWindow = NULL; if (NOT accept) LoadRGB4(vp, &SavePalette[0], 32); else { color_set = 2; UserPalette[0] = GetRGB4(vp->ColorMap, 0); UserPalette[1] = GetRGB4(vp->ColorMap, 1); UserPalette[2] = GetRGB4(vp->ColorMap, 2); for (i = 3; i <= 31; i++) *(color_table + color_offset + (i - 2) * color_inc) = GetRGB4(vp->ColorMap, i); } } VOID 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); } } BOOL ColorGadgetGotten(gadget) struct Gadget *gadget; { USHORT rgb, pen; struct RastPort *RPort; SHORT greenpos, redpos, bluepos; RPort = ColorWindow->RPort; /* Have we got a color specifier? */ if (gadget->GadgetID < 32) { /* Yes, it's a color gadget. Set this pen number */ pen = gadget->GadgetID; /* first, were we in COPY COLOR mode? */ if (ColorMode == COPYCOLOR) { /* ok, copy old color here first! */ rgb = GetRGB4(vp->ColorMap, rp->FgPen); SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb); ColorMode = NULL; } if (ColorMode == RANGE_FIRST) { ColorMode = RANGE_SECOND; RangeFirst = pen; } else if (ColorMode == RANGE_SECOND) { ColorMode = NULL; ColorRange(RangeFirst, pen); } SetAPen(rp, pen); rgb = GetRGB4(vp->ColorMap, pen); ColorRectFill(RPort, pen); redpos = RemoveGadget(ColorWindow, &ColorTemplateGadgets[COLOR_RED]); greenpos = RemoveGadget(ColorWindow, &ColorTemplateGadgets[COLOR_GREEN]); bluepos = RemoveGadget(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE]); SetColorProps(); AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], bluepos); AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_GREEN], greenpos); AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_RED], redpos); RefreshGadgets(&ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1], ColorWindow); } else switch (gadget->GadgetID) { case COLOR_OK: CloseColorWindow(TRUE); return(FALSE); break; case COLOR_CANCEL: CloseColorWindow(FALSE); return(FALSE); break; case COLOR_COPY: ColorMode = COPYCOLOR; break; case COLOR_RANGE: ColorMode = RANGE_FIRST; break; } return(TRUE); } ModifyColors() { USHORT pen, newred, newgreen, newblue; pen = w->RPort->FgPen; newred = ((struct PropInfo *) ColorTemplateGadgets[COLOR_RED].SpecialInfo)->HorizPot >> 12; newgreen = ((struct PropInfo *) ColorTemplateGadgets[COLOR_GREEN].SpecialInfo)->HorizPot >> 12; newblue = ((struct PropInfo *) ColorTemplateGadgets[COLOR_BLUE].SpecialInfo)->HorizPot >> 12; SetRGB4(vp, pen, newred, newgreen, newblue); } DrawColorWindow() { struct RastPort *RPort; RPort = ColorWindow->RPort; ColorRectFill(RPort, rp->FgPen); SetAPen(RPort, 1); DrawBox(RPort, 1, 1, COLORWINDOW_WIDTH - 2, COLORWINDOW_HEIGHT - 2); DrawBox(RPort, COLOR_BOX_LEFT - 2, COLOR_BOX_TOP - 2, COLOR_BOX_RIGHT + 2, COLOR_BOX_BOTTOM + 2); DrawBox(RPort, COLOR_BOX_LEFT - 2, COLOR_COLOR_TOP - 2, COLOR_BOX_LEFT + (8 * 15) + 1, COLOR_COLOR_TOP + (4 * 10) + 1); } SetColorProps() { USHORT rgb, red, green, blue; rgb = GetRGB4(vp->ColorMap, rp->FgPen); red = (rgb >> 8) & 0xF; green = (rgb >> 4) & 0xF; blue = (rgb >> 0) & 0xF; ((struct PropInfo *)ColorTemplateGadgets[COLOR_RED] .SpecialInfo)->HorizPot = (red << 12) | (red << 8) | (red << 4) | red; ((struct PropInfo *)ColorTemplateGadgets[COLOR_GREEN] .SpecialInfo)->HorizPot = (green << 12) | (green << 8) | (green << 4) | green; ((struct PropInfo *)ColorTemplateGadgets[COLOR_BLUE] .SpecialInfo)->HorizPot = (blue << 12) | (blue << 8) | (blue << 4) | blue; } ColorRectFill(RPort, pen) struct RastPort *RPort; SHORT pen; { SetAPen(RPort, pen); SetDrMd(RPort, JAM2); WaitBOVP(vp); RectFill(RPort, COLOR_BOX_LEFT, COLOR_BOX_TOP, COLOR_BOX_RIGHT, COLOR_BOX_BOTTOM); } VOID DoColorWindow() { struct IntuiMessage *message; ULONG class; struct Gadget *gadget; if (NOT OpenColorWindow()) return; for (EVER) { Wait((1 << ColorWindow->UserPort->mp_SigBit)); while (message = (struct IntuiMessage *)GetMsg(ColorWindow->UserPort)) { class = message->Class; gadget = (struct Gadget *)(message->IAddress); ReplyMsg(message); switch (class) { case GADGETDOWN: case GADGETUP: if (ColorGadgetGotten(gadget) == FALSE) return; break; case MOUSEMOVE: ModifyColors(); break; } } } } InitSuperColors() { SHORT i; /* OK, initialize those Super Color Gadgets! */ for (i = 0; i < 32; i++) { SuperColorImages[i].LeftEdge = 0; SuperColorImages[i].TopEdge = 0; SuperColorImages[i].Width = 15; SuperColorImages[i].Height = 10; SuperColorImages[i].Depth = 0; SuperColorImages[i].ImageData = NULL; SuperColorImages[i].PlanePick = 0; SuperColorImages[i].PlaneOnOff = i; SuperColorImages[i].NextImage = NULL; } }