rj@amiga.UUCP (Robert J. Mical) (01/11/86)
/***************************************************************************** * MAND5.C - Color Window * Mandelbrot Self-Squared Dragon Generator * For the Commodore Amiga * Version 2.01 * * Copyright (C) 1986, =Robert J. Mical= * Placed in the Public Domain * * This program may be distributed free of charge as long as the above * notice is retained. You may extract any or all information contained * in this file for use in your own programs * ****************************************************************************/ #include "mand.h" extern struct Menu MainMenu[MENU_COUNT]; extern struct MenuItem OptionsItems[OPTIONS_COUNT]; extern int MathBase, MathTransBase; extern SHORT Color0, Color1, Color2; extern SHORT UserPalette[29]; /*----------------------*/ /* Graphics definitions */ extern struct GfxBase *GfxBase; extern struct IntuitionBase *IntuitionBase; extern struct RastPort *rp,*rp2; extern struct ViewPort *vp; extern struct Window *w,*w2, *ColorWindow; extern struct Screen *screen; extern struct IntuiMessage *message; extern long last_color; extern BOOL SettingCenter, SettingBoxSize; /*----------------------------------*/ /* Miscellaneous Global Definitions */ extern union kludge { float f; int i; } start_r,end_r,start_i,end_i; /* Block bounds for set */ extern int max_x,max_y,max_mem_y; /* Graphics window size */ extern int max_count,color_inc,color_offset,color_set,color_mode,color_div; extern int color_inset,func_num; extern int v_starty,max_mem; extern long v_offset; extern UWORD *color_table,*v_mand_store; extern int modified,want_read; extern FILE *console,*v_fp,*redir_fp; extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY; extern SHORT ZoomBoxStartX, ZoomBoxStartY; /***************************************************************************** * * Color initialization and routines * ****************************************************************************/ #define COPYCOLOR 1 #define RANGE_FIRST 2 #define RANGE_SECOND 3 USHORT ColorMode; extern struct Gadget ColorTemplateGadgets[COLOR_GADGETS_COUNT]; extern struct Image ColorPropsImages[3]; extern struct PropInfo ColorPropsInfos[3]; extern struct IntuiText ColorClusterText[4]; USHORT SavePalette[32]; extern struct Image SuperColorImages[32]; #define COLOR_IDCMP_FLAGS (GADGETDOWN | GADGETUP | MOUSEBUTTONS \ | MENUPICK | MOUSEMOVE | ACTIVEWINDOW | INACTIVEWINDOW) struct NewWindow ColorNewWindow = { /* SHORT LeftEdge, TopEdge; /* screen dimensions of window */ /* SHORT Width, Height; /* screen dimensions of window */ DEFAULT_WINDOW_LEFT, DEFAULT_WINDOW_TOP, COLORWINDOW_WIDTH, COLORWINDOW_HEIGHT, /* UBYTE DetailPen, BlockPen; /* for bar/border/gadget rendering */ -1, -1, /* ULONG IDCMPFlags; /* User-selected IDCMP flags */ NULL, /* ULONG Flags; /* see Window struct for defines */ BORDERLESS | SMART_REFRESH | NOCAREREFRESH, /* struct Gadget *FirstGadget;*/ NULL, /* struct Image *CheckMark;*/ NULL, /* UBYTE *Title; /* the title text for this window */ NULL, /* struct Screen *Screen;*/ NULL, /* struct BitMap *BitMap;*/ NULL, /* SHORT MinWidth, MinHeight; /* minimums */ 0, 0, /* SHORT MaxWidth, MaxHeight; /* maximums */ 0, 0, /* USHORT Type;*/ CUSTOMSCREEN, }; USHORT RangeFirst; /* the first selection of the range-color pair */ /* ======================================================================== */ /* ======================================================================== */ /* ======================================================================== */ BOOL OpenColorWindow() { SHORT i; if (ColorWindow) return(TRUE); ClearMenuStrip(w); ColorNewWindow.Screen = screen; ColorNewWindow.IDCMPFlags = NULL; ColorNewWindow.FirstGadget = &ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1]; SetColorProps(); InitSuperColors(); ColorMode = NULL; if ((ColorWindow = (struct Window *)OpenWindow(&ColorNewWindow)) == 0) { fputs("no memory!\n", console); return(FALSE); } ColorWindow->UserPort = w->UserPort; ModifyIDCMP(ColorWindow, COLOR_IDCMP_FLAGS); SetMenuStrip(w, &MainMenu[0]); 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; Color0 = GetRGB4(vp->ColorMap, 0); Color1 = GetRGB4(vp->ColorMap, 1); Color2 = GetRGB4(vp->ColorMap, 2); for (i = 2; i <= 31; i++) { if (i == 2) *(color_table) = GetRGB4(vp->ColorMap, 2); else *(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; FOREVER { 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; } }