/*************************************************************************** * * MandelVroom Contour Editing Window * * Kevin L. Clague * * Copyright (C) 1987 * **************************************************************************/ #include "mand.h" extern struct Screen *screen; extern struct RastPort *rp; extern struct Window *MandWind; extern SHORT MouseX,MouseY; extern SHORT MaxCount; extern struct Menu Menu[]; extern USHORT CmdMode; extern SHORT Zoom; USHORT CurContour; struct Window *ContWind; BYTE ContTitle[80]; struct NewWindow NewCont = { 0,200-80, /* start position */ 320,200, /* width, height */ (UBYTE) 0, (UBYTE) 1, /* detail pen, block pen */ /* IDCMP flags */ MENUPICK | GADGETDOWN | GADGETUP | REQCLEAR | CLOSEWINDOW, /* MandWind flags */ WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH | NOCAREREFRESH, (struct Gadget *) NULL, /* first gadget */ (struct Image *) NULL, /* user checkmark */ (UBYTE *) NULL, /* window title */ (struct Screen *) NULL, /* pointer to screen */ (struct BitMap *) NULL, /* pointer to superbitmap */ 80,80,320,200, /* sizing */ CUSTOMSCREEN /* type of screen */ }; SHORT Ceiling = 1023; extern SHORT *CountBase; extern SHORT CountX, CountY; SHORT Contours[NUMCONTS] = { 1023,128,64, 32, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; SHORT *ContourBase = Contours; SHORT NumContours = NUMCONTS; UBYTE Colors[NUMCONTS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; UBYTE *ColorBase = Colors; struct Gadget *ContGadget[NUMCONTS]; struct Gadget *SelGadget[NUMCONTS]; /* * Figure out what to do for this contour gadget */ DoContourDown(gadget) struct Gadget *gadget; { USHORT ContNum; USHORT Type; extern LONG NavTop, NavBot, NavLeft, NavRight; ContNum = gadget->GadgetID & NUMMASK; switch (Type = gadget->GadgetID >> TYPEBITS & TYPEMASK) { case CONTCNTLS: switch (gadget->GadgetID) { case CONTRECOL: ReColor(); DisplayBeep(screen); if (Zoom) { DrawBox(NavLeft, NavTop, NavRight, NavBot ); DrawExtras(NavLeft, NavTop, NavRight, NavBot ); } SetNormPointer(); break; case CONTSMTH: SetToPointer(); CmdMode = SMOOTH; break; } break; case CONTSELS: if (CmdMode == SMOOTH) { SetNormPointer(); SmoothContours(CurContour, ContNum); } else { SetNormPointer(); CmdMode = IMPLIEDSET; } break; case CONTDOWNS: if (*(ContourBase + ContNum) > 0) { *(ContourBase + ContNum) -= 1; } ReString(ContNum); SetNormPointer(); break; case CONTUPS: if (*(ContourBase + ContNum) < MaxCount) { *(ContourBase + ContNum) += 1; } ReString(ContNum); SetNormPointer(); break; } if ( Type != CONTCNTLS ) { DrawContBox(CurContour, 0); DrawContBox(ContNum, 1); CurContour = ContNum; SetContTitle(ContNum); } } /* * Figure out what to do for this contour gadget */ DoContourUp(gadget) struct Gadget *gadget; { USHORT ContNum; struct PropInfo *PropInfo; ULONG VertPot; char msg[80]; ContNum = gadget->GadgetID & NUMMASK; SetNormPointer(); PropInfo = (struct PropInfo *) gadget->SpecialInfo; VertPot = PropInfo->VertPot + 1; switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) { case CONTCNTLS: Ceiling = ((LONG) MaxCount - ( VertPot * MaxCount >> 16)); ModAll(); break; case CONTPOTS: if (ContourBase[ContNum] < Ceiling) { ContourBase[ContNum] = ( (LONG) Ceiling ) - (VertPot * Ceiling >> 16); } else { PropInfo->VertPot = 0; RefreshGList(gadget,ContWind,NULL,1); } DrawContBox(CurContour, 0); DrawContBox(ContNum, 1); CurContour = ContNum; SetContTitle(ContNum); break; } } /* * Set the contour window's new title */ SetContTitle(ContNum) int ContNum; { SHORT Low, High; char *fmt1 = "Contour: %d Alt: %d-%d Pen: %d"; char *fmt2 = "Contour: %d Alt: %d Pen: %d"; High = ContourBase[ContNum]; if (ContNum != 0) { Low = ContourBase[ContNum-1]; if (Low == High || Low - High == 1) { sprintf(ContTitle, fmt2, ContNum, High, ColorBase[ContNum]); } else { sprintf(ContTitle, fmt1, ContNum, Low - 1, High, ColorBase[ContNum]); } } else { sprintf(ContTitle, fmt2, ContNum, MaxCount, High, ColorBase[ContNum]); } SetWindowTitles(ContWind, ContTitle, NULL); } /* * Set Potentiometer knob's pen */ DrawContBox(Contour, pen) ULONG Contour; int pen; { LONG Left, Right, Top, Bottom; LONG Scaled4; struct RastPort *rp = ContWind->RPort; extern USHORT XScale, YScale; Scaled4 = 4 << XScale; Left = (6 << XScale) * Contour + Scaled4 - 1; Right = Left + Scaled4 + 1; Top = (12 << YScale) - 1; Bottom = Top + (4 << YScale) + 1; SetDrMd(rp, (LONG) JAM1); SetAPen(rp, (LONG) pen); /* * Draw the new box */ Move(rp, Left, Top ); Draw(rp, Right, Top ); Draw(rp, Right, Bottom); Draw(rp, Left, Bottom); Draw(rp, Left, Top+1 ); } /* DrawContBox */ /* * There was a window pick. Do what we need to do to service it */ DoWindowPick(MouseX,MouseY) SHORT MouseX,MouseY; { USHORT Height; if (MouseX >= LEFTMARG && MouseX <= MandWind->Width-RIGHTMARG && MouseY >= TOPMARG && MouseY <= MandWind->Height-BOTMARG) { if (CmdMode == IMPLIEDSET) { Height = *(CountBase + (MouseY-TOPMARG)*CountX + MouseX - LEFTMARG); *(ContourBase + CurContour) = Height; ReString(CurContour); } } } /* * Smooth the heights over a subrange of contours */ SmoothContours(First,Second) USHORT First, Second; { USHORT Temp; float Diff,Start; if (Second-First != 0) { if (Second < First) { Temp = First; First = Second; Second = Temp; } Start = (float) ContourBase[First]; Diff = (((float) ContourBase[Second]) - Start)/((float)(Second-First)); if (Diff > -1.0) { Diff = -1.0; } for ( ; First < Second && Start > 0; First++) ContourBase[First + 1] = (SHORT) (Start += Diff); if (Start == 0) { for ( ; First < NumContours; First++) { ContourBase[First] = 0; } } ModAll(); } } /* SmoothContours */ /* * ReColor the Mandelbrot image */ ReColor() { SHORT *CountPtr = CountBase; SHORT Mask,Width; LONG Mod,CMod; SHORT LF,LP,RF,RP,D[6]; SHORT i,j,k,l, Depth; LONG Sx,TL; SHORT *Planes[6]; UBYTE *ColorPtr; UBYTE *ColorSave,t; UBYTE T[1030]; Depth = screen->BitMap.Depth; if (CountPtr == NULL) { DispErrMsg("No counts to recolor",0); return(0); } if (screen->Width < CountX+LEFTMARG+RIGHTMARG || screen->Height < CountY+TOPMARG+BOTMARG) { DispErrMsg("Picture too big for screen.",0); return(0); } if (MandWind->Width != CountX+LEFTMARG+RIGHTMARG || MandWind->Height != CountY+TOPMARG+BOTMARG) SizeWindow(MandWind,CountX+LEFTMARG+RIGHTMARG-MandWind->Width, CountY+TOPMARG+BOTMARG-MandWind->Height); WindowToFront(MandWind); SetAPen( rp, 0L ); RectFill( rp, LEFTMARG, TOPMARG, LEFTMARG + CountX, TOPMARG + CountY ); if ( Depth < 4 || Depth == 6) { ReColorSlow(); return(0); } /* try to get enough memory to recolor the picture fast. */ ColorPtr = ColorSave = (UBYTE *) AllocMem((LONG) CountX * CountY, 0L); if (ColorPtr == (UBYTE *) NULL) { ReColorSlow(); return(0); } /* So recolor it now that you have the memory */ for (i = 0,j = 1029; i < NUMCONTS; i++) for (; j >= ContourBase[i] && j; ) T[j--] = ColorBase[i]; while (j >= 0) T[j--] = 0; ; #ifdef SLOW1 for (Sx = CountX*CountY; Sx-- >= 0; ) *(ColorPtr++) = T[*(CountPtr++)]; #else #asm CountPtr equ -4 ColorBase equ -82 T equ -1117 move.w _CountX,d1 muls.w _CountY,d1 sub.l #1,d1 move.l CountPtr(a5),a0 lea T(a5),a1 move.l ColorBase(a5),a6 ColorLoop move.w (a0)+,d0 move.b (a1,d0.w),(a6)+ sub.l #1,d1 bge ColorLoop #endasm #endif ClearMenuStrip(MandWind); if (Depth == 4) { ReColor4(ColorSave); } else if (Depth == 5) { ReColor5(ColorSave); } SetMenuStrip(MandWind, Menu); FreeMem(ColorSave,CountX*CountY); } /* ReColor */ /* * Assembly code to recolor 4 bit planes */ ReColor4(ColorSave) UBYTE *ColorSave; { SHORT Mask,Width; LONG Mod,CMod; SHORT LF,LP,RF,RP; SHORT i,j,k,l; LONG Sx,TL; UBYTE *ColorPtr; struct BitMap *BitMap = MandWind->RPort->BitMap; #asm SaveReg reg a0-a6/d0-d7 Plane0 equ 8 Plane1 equ Plane0+4 Plane2 equ Plane0+8 Plane3 equ Plane0+12 Plane4 equ Plane0+16 Plane5 equ Plane0+20 BitMap equ -44 ColorPtr equ -40 TL equ -36 Sx equ -32 l equ -28 k equ -26 j equ -24 i equ -22 RP equ -20 RF equ -18 LP equ -16 LF equ -14 CMod equ -12 Mod equ -8 Width equ -4 Mask equ -2 ColorSave equ 8 #endasm ColorPtr = ColorSave; Sx = screen->Width >> 4; LF = MandWind->LeftEdge + 17 & 0xfff0; LP = MandWind->LeftEdge + LEFTMARG; CMod = CountX - (LF-LP); Mod = Sx - 1; TL = Sx * (MandWind->TopEdge + TOPMARG) + (LP >> 4); Width = LF-LP; Mask = 0xffff << Width; #asm movem.l SaveReg,-(sp) ;Save all the gprs to the stack move.l a5,a1 ;We need a5, so put MANX stack in a1 move.w _CountY,i(a1) move.l BitMap(a1),a0 move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen asl.l #1,d0 ; and make it a 'word' offset move.l Plane0(a0),a2 ;Get address of screens first bit plane adda.l d0,a2 ; add in window top-left offset. move.l Plane1(a0),a3 ;Same for second bit plane. adda.l d0,a3 move.l Plane2(a0),a4 ;Same for third bit plane. adda.l d0,a4 move.l Plane3(a0),a5 ;Same for fourth bit plane. adda.l d0,a5 move.l ColorPtr(a1),a0 ;Load up pointer to recolored data. move.l #1,d1 ;/* for each row */ ; for (i = CountY; i; i--) { Y0Loop4 ; /* for each pixel in column */ move.w Width(a1),d7 ; for (k = Width; k; k--) { eor.w d2,d2 ; Clear all bits in the bit plane data regs. eor.w d3,d3 eor.w d4,d4 eor.w d5,d5 B0Loop4 move.b (a0)+,d0 ; d0 = *(ColorPtr++); asr.b d1,d0 ; get low order bit from d0 addx.w d2,d2 ; put it in bit plane 0 data asr.b d1,d0 ; same for bit plane 1 addx.w d3,d3 asr.b d1,d0 ; same for bit plane 2 addx.w d4,d4 asr.b d1,d0 ; same for bit plane 3 addx.w d5,d5 sub.w d1,d7 ; same for bit plane 5 bgt B0Loop4 ; } /* did each bit in bit plane word */ move.w Mask(a1),d0 ; Turn off all the new bits in planes and.w d0,(a2) and.w d0,(a3) and.w d0,(a4) and.w d0,(a5) or.w d2,(a2)+ ; Set the new bits in the bit planes or.w d3,(a3)+ or.w d4,(a4)+ or.w d5,(a5)+ move.l Mod(a1),d0 ; Adjust plane pointers to start of next line add.l d0,d0 add.l d0,a2 add.l d0,a3 add.l d0,a4 add.l d0,a5 adda.l CMod(a1),a0 ; Adjust color pointer to start of next line sub.w d1,i(a1) ;} /* did each row */ tst.w i(a1) bgt Y0Loop4 movem.l (sp)+,SaveReg ;better restore the registers #endasm RP = LP + CountX & 0xfff0; RF = RP - 16; CMod = CountX - (RP-LF); Mod = Sx - ((RP-LF) >> 4); TL++; Width = (RP-LF) >> 4; ColorPtr = ColorSave + LF - LP; #asm movem.l SaveReg,-(sp) ;Save all the gprs to the stack move.l a5,a1 ;We need a5, so put MANX stack in a1 move.w _CountY,i(a1) ;i = CountY; move.l BitMap(a1),a0 move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen asl.l #1,d0 ; and make it a 'word' offset move.l Plane0(a0),a2 ;Get address of screens first bit plane adda.l d0,a2 ; add in window top-left offset. move.l Plane1(a0),a3 ;Same for second bit plane. adda.l d0,a3 move.l Plane2(a0),a4 ;Same for third bit plane. adda.l d0,a4 move.l Plane3(a0),a5 ;Same for fourth bit plane. adda.l d0,a5 move.l ColorPtr(a1),a0 ;Load up pointer to recolored data. move.l #1,d1 ;/* for each row */ ; for (i = CountY; i; i--) { YLoop4 ; /* for each column */ move.w Width(a1),j(a1) ; for (j = Width; j; j--) { XLoop4 ; /* pack a word for each bit plane */ move.w #16,d7 ; for (k = 16; k; k--) { BLoop4 move.b (a0)+,d0 ; d0 = *(ColorPtr++); asr.b d1,d0 ; get low order bit from d0 addx.w d2,d2 ; put it in bit plane 0 data asr.b d1,d0 ; same for bit plane 1 addx.w d3,d3 asr.b d1,d0 ; same for bit plane 2 addx.w d4,d4 asr.b d1,d0 ; same for bit plane 3 addx.w d5,d5 sub.w d1,d7 ; same for bit plane 5 bgt BLoop4 ; } /* did each bit in bit plane word */ move.w d2,(a2)+ ; Save the packed data in bit planes move.w d3,(a3)+ move.w d4,(a4)+ move.w d5,(a5)+ sub.w d1,j(a1) ; } /* did each word in a row */ tst.w j(a1) bgt XLoop4 move.l Mod(a1),d0 ; Adjust plane pointers to start of next line add.l d0,d0 add.l d0,a2 add.l d0,a3 add.l d0,a4 add.l d0,a5 adda.l CMod(a1),a0 ; Adjust color pointer to start of next line sub.w d1,i(a1) ;} /* did each row */ tst.w i(a1) bgt YLoop4 movem.l (sp)+,SaveReg ;better restore the registers #endasm TL += Width; Width = LP + CountX - RP; CMod = CountX - Width; Mod = Sx - 1; Mask = 0xffff >> Width; ColorPtr = ColorSave + RP - LP; #asm movem.l SaveReg,-(sp) ;Save all the gprs to the stack move.l a5,a1 ;We need a5, so put MANX stack in a1 move.w _CountY,i(a1) move.l BitMap(a1),a0 move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen asl.l #1,d0 ; and make it a 'word' offset move.l Plane0(a0),a2 ;Get address of screens first bit plane adda.l d0,a2 ; add in window top-left offset. move.l Plane1(a0),a3 ;Same for second bit plane. adda.l d0,a3 move.l Plane2(a0),a4 ;Same for third bit plane. adda.l d0,a4 move.l Plane3(a0),a5 ;Same for fourth bit plane. adda.l d0,a5 move.l ColorPtr(a1),a0 ;Load up pointer to recolored data. move.l #1,d1 ;/* for each row */ ; ;for (i = CountY; i; i--) { Y2Loop4 ; /* for each pixel in column */ move.w Width(a1),d7 ; for (k = Width; k; k--) { eor.w d2,d2 ; Clear all bits in the bit plane data regs. eor.w d3,d3 eor.w d4,d4 eor.w d5,d5 B2Loop4 move.b (a0)+,d0 ; d0 = *(ColorPtr++); asr.b d1,d0 ; get low order bit from d0 addx.w d2,d2 ; put it in bit plane 0 data asr.b d1,d0 ; same for bit plane 1 addx.w d3,d3 asr.b d1,d0 ; same for bit plane 2 addx.w d4,d4 asr.b d1,d0 ; same for bit plane 3 addx.w d5,d5 sub.w d1,d7 ; same for bit plane 5 bgt B2Loop4 ; } /* did each bit in bit plane word */ move.w Mask(a1),d0 ; Turn off all the new bits in planes and.w d0,(a2) and.w d0,(a3) and.w d0,(a4) and.w d0,(a5) move.w #16,d0 sub.w Width(a1),d0 asl.w d0,d2 asl.w d0,d3 asl.w d0,d4 asl.w d0,d5 or.w d2,(a2)+ ; Set the new bits in the bit planes or.w d3,(a3)+ or.w d4,(a4)+ or.w d5,(a5)+ move.l Mod(a1),d0 ; Adjust plane pointers to start of next line add.l d0,d0 add.l d0,a2 add.l d0,a3 add.l d0,a4 add.l d0,a5 adda.l CMod(a1),a0 ; Adjust color pointer to start of next line sub.w d1,i(a1) ;} /* did each row */ tst.w i(a1) bgt Y2Loop4 movem.l (sp)+,SaveReg ;better restore the registers #endasm } /* ReColor 4 bit planes */ /* * Assembly code to recolor 5 bit planes */ ReColor5(ColorSave) UBYTE *ColorSave; { SHORT Mask,Width; LONG Mod,CMod; SHORT LF,LP,RF,RP; SHORT i,j,k,l; LONG Sx,TL; UBYTE *ColorPtr; struct BitMap *BitMap = MandWind->RPort->BitMap; ColorPtr = ColorSave; Sx = screen->Width >> 4; LF = MandWind->LeftEdge + 17 & 0xfff0; LP = MandWind->LeftEdge + LEFTMARG; CMod = CountX - (LF-LP); Mod = Sx - 1; TL = Sx * (MandWind->TopEdge + TOPMARG) + (LP >> 4); Width = LF-LP; Mask = 0xffff << Width; #asm movem.l SaveReg,-(sp) ;Save all the gprs to the stack move.l a5,a1 ;We need a5, so put MANX stack in a1 move.w _CountY,i(a1) move.l BitMap(a1),a0 move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen asl.l #1,d0 ; and make it a 'word' offset move.l Plane0(a0),a2 ;Get address of screens first bit plane adda.l d0,a2 ; add in window top-left offset. move.l Plane1(a0),a3 ;Same for second bit plane. adda.l d0,a3 move.l Plane2(a0),a4 ;Same for third bit plane. adda.l d0,a4 move.l Plane3(a0),a5 ;Same for fourth bit plane. adda.l d0,a5 move.l Plane4(a0),a6 ;Same for fifth bit plane. adda.l d0,a6 move.l ColorPtr(a1),a0 ;Load up pointer to recolored data. move.l #1,d1 ;/* for each row */ ; ;for (i = CountY; i; i--) { Y0Loop5 ; /* for each pixel in column */ move.w Width(a1),d7 ; for (k = Width; k; k--) { eor.w d2,d2 ; Clear all bits in the bit plane data regs. eor.w d3,d3 eor.w d4,d4 eor.w d5,d5 eor.w d6,d6 B0Loop5 move.b (a0)+,d0 ; d0 = *(ColorPtr++); asr.b d1,d0 ; get low order bit from d0 addx.w d2,d2 ; put it in bit plane 0 data asr.b d1,d0 ; same for bit plane 1 addx.w d3,d3 asr.b d1,d0 ; same for bit plane 2 addx.w d4,d4 asr.b d1,d0 ; same for bit plane 3 addx.w d5,d5 asr.b d1,d0 ; same for bit plane 4 addx.w d6,d6 sub.w d1,d7 ; same for bit plane 5 bgt B0Loop5 ; } /* did each bit in bit plane word */ move.w Mask(a1),d0 ; Turn off all the new bits in planes and.w d0,(a2) and.w d0,(a3) and.w d0,(a4) and.w d0,(a5) and.w d0,(a6) or.w d2,(a2)+ ; Set the new bits in the bit planes or.w d3,(a3)+ or.w d4,(a4)+ or.w d5,(a5)+ or.w d6,(a6)+ move.l Mod(a1),d0 ; Adjust plane pointers to start of next line add.l d0,d0 add.l d0,a2 add.l d0,a3 add.l d0,a4 add.l d0,a5 add.l d0,a6 adda.l CMod(a1),a0 ; Adjust color pointer to start of next line sub.w d1,i(a1) ;} /* did each row */ tst.w i(a1) bgt Y0Loop5 movem.l (sp)+,SaveReg ;better restore the registers #endasm RP = LP + CountX & 0xfff0; RF = RP - 16; CMod = CountX - (RP-LF); Mod = Sx - ((RP-LF) >> 4); TL++; Width = (RP-LF) >> 4; ColorPtr = ColorSave + LF - LP; #asm movem.l SaveReg,-(sp) ;Save all the gprs to the stack move.l a5,a1 ;We need a5, so put MANX stack in a1 move.w _CountY,i(a1) ;i = CountY; move.l BitMap(a1),a0 move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen asl.l #1,d0 ; and make it a 'word' offset move.l Plane0(a0),a2 ;Get address of screens first bit plane adda.l d0,a2 ; add in window top-left offset. move.l Plane1(a0),a3 ;Same for second bit plane. adda.l d0,a3 move.l Plane2(a0),a4 ;Same for third bit plane. adda.l d0,a4 move.l Plane3(a0),a5 ;Same for fourth bit plane. adda.l d0,a5 move.l Plane4(a0),a6 ;Same for fifth bit plane. adda.l d0,a6 move.l ColorPtr(a1),a0 ;Load up pointer to recolored data. move.l #1,d1 ;/* for each row */ ; ;for (i = CountY; i; i--) { YLoop5 ; /* for each column */ move.w Width(a1),j(a1) ; for (j = Width; j; j--) { XLoop5 ; /* pack a word for each bit plane */ move.w #16,d7 ; for (k = 16; k; k--) { BLoop5 move.b (a0)+,d0 ; d0 = *(ColorPtr++); asr.b d1,d0 ; get low order bit from d0 addx.w d2,d2 ; put it in bit plane 0 data asr.b d1,d0 ; same for bit plane 1 addx.w d3,d3 asr.b d1,d0 ; same for bit plane 2 addx.w d4,d4 asr.b d1,d0 ; same for bit plane 3 addx.w d5,d5 asr.b d1,d0 ; same for bit plane 4 addx.w d6,d6 sub.w d1,d7 ; same for bit plane 5 bgt BLoop5 ; } /* did each bit in bit plane word */ move.w d2,(a2)+ ; Save the packed data in bit planes move.w d3,(a3)+ move.w d4,(a4)+ move.w d5,(a5)+ move.w d6,(a6)+ sub.w d1,j(a1) ; } /* did each word in a row */ tst.w j(a1) bgt XLoop5 move.l Mod(a1),d0 ; Adjust plane pointers to start of next line add.l d0,d0 add.l d0,a2 add.l d0,a3 add.l d0,a4 add.l d0,a5 add.l d0,a6 adda.l CMod(a1),a0 ; Adjust color pointer to start of next line sub.w d1,i(a1) ;} /* did each row */ tst.w i(a1) bgt YLoop5 movem.l (sp)+,SaveReg ;better restore the registers #endasm TL += Width; Width = LP + CountX - RP; CMod = CountX - Width; Mod = Sx - 1; Mask = 0xffff >> Width; ColorPtr = ColorSave + RP - LP; #asm movem.l SaveReg,-(sp) ;Save all the gprs to the stack move.l a5,a1 ;We need a5, so put MANX stack in a1 move.w _CountY,i(a1) move.l BitMap(a1),a0 move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen asl.l #1,d0 ; and make it a 'word' offset move.l Plane0(a0),a2 ;Get address of screens first bit plane adda.l d0,a2 ; add in window top-left offset. move.l Plane1(a0),a3 ;Same for second bit plane. adda.l d0,a3 move.l Plane2(a0),a4 ;Same for third bit plane. adda.l d0,a4 move.l Plane3(a0),a5 ;Same for fourth bit plane. adda.l d0,a5 move.l Plane4(a0),a6 ;Same for fifth bit plane. adda.l d0,a6 move.l ColorPtr(a1),a0 ;Load up pointer to recolored data. move.l #1,d1 ;/* for each row */ ; ;for (i = CountY; i; i--) { Y2Loop5 ; ; /* for each pixel in column */ move.w Width(a1),d7 ; for (k = Width; k; k--) { eor.w d2,d2 ; Clear all bits in the bit plane data regs. eor.w d3,d3 eor.w d4,d4 eor.w d5,d5 eor.w d6,d6 B2Loop5 move.b (a0)+,d0 ; d0 = *(ColorPtr++); asr.b d1,d0 ; get low order bit from d0 addx.w d2,d2 ; put it in bit plane 0 data asr.b d1,d0 ; same for bit plane 1 addx.w d3,d3 asr.b d1,d0 ; same for bit plane 2 addx.w d4,d4 asr.b d1,d0 ; same for bit plane 3 addx.w d5,d5 asr.b d1,d0 ; same for bit plane 4 addx.w d6,d6 sub.w d1,d7 ; same for bit plane 5 bgt B2Loop5 ; } /* did each bit in bit plane word */ move.w Mask(a1),d0 ; Turn off all the new bits in planes and.w d0,(a2) and.w d0,(a3) and.w d0,(a4) and.w d0,(a5) and.w d0,(a6) move.w #16,d0 sub.w Width(a1),d0 asl.w d0,d2 asl.w d0,d3 asl.w d0,d4 asl.w d0,d5 asl.w d0,d6 or.w d2,(a2)+ ; Set the new bits in the bit planes or.w d3,(a3)+ or.w d4,(a4)+ or.w d5,(a5)+ or.w d6,(a6)+ move.l Mod(a1),d0 ; Adjust plane pointers to start of next line add.l d0,d0 add.l d0,a2 add.l d0,a3 add.l d0,a4 add.l d0,a5 add.l d0,a6 adda.l CMod(a1),a0 ; Adjust color pointer to start of next line sub.w d1,i(a1) ;} /* did each row */ tst.w i(a1) bgt Y2Loop5 movem.l (sp)+,SaveReg ;better restore the registers #endasm } /* ReColor 5 bit planes */ ReColorSlow() { LONG i, j, x, y, xl, yl; SHORT *CountPtr = CountBase; UBYTE T[1030]; UBYTE OldColor; UBYTE NewColor; j = MaxCount; for (i = 0; i < NUMCONTS && j >= 0; i++) for (; j >= ContourBase[i] && j >=0 ; ) T[j--] = ColorBase[i]; while (j >= 0) T[j--] = 0; OldColor = 0xff; xl = CountX + LEFTMARG; yl = CountY + TOPMARG; for (y = TOPMARG; y < yl; y++) { for (x = LEFTMARG; x < xl; x++) { NewColor = T[ *CountPtr++ ]; if ( NewColor != OldColor) { SetAPen( rp, NewColor ); OldColor = NewColor; } if (NewColor) WritePixel(rp, x, y); } } } /* ReColorSlow */ /* * Allocate all the gadgets and things for the contour window */ struct Gadget *MakeContours() { struct Gadget *FirstGadget, *NextGadget, *OldGadget; extern struct Gadget *MakeBool(), *MakePot(); extern struct IntuiText *MakeIntui(); USHORT i,x,y; UBYTE c = 0; struct PropInfo *PropInfo; FirstGadget = OldGadget = MakePot(228, 26, 4, 32, CONTCEIL, 0); if (OldGadget == (struct Gadget *) NULL) goto error; for (x = y = 0; x < 2; y += 10, x++) { NextGadget = MakeBool(234,y+14,6,6,1,CONTCNTL+x); if (NextGadget == (struct Gadget *) NULL) goto error; switch (x) { case 0: NextGadget->GadgetText = MakeIntui("ReColor",10,-1,3,3,JAM1); break; case 1: NextGadget->GadgetText = MakeIntui("Smooth",10,-1,3,3,JAM1); break; } OldGadget->NextGadget = NextGadget; OldGadget = NextGadget; } for (x = y = 0; y < NumContours; x += 6, y++) { NextGadget = MakeBool(4+x, 12,4,4,Colors[y],CONTSEL+y); if (NextGadget == (struct Gadget *) NULL) goto error; OldGadget->NextGadget = NextGadget; OldGadget = SelGadget[y] = NextGadget; } NextGadget->GadgetText = MakeIntui("Set",6,-2,3,3,JAM1); for (x = y = 0; y < NumContours; x += 6, y++) { NextGadget = MakeBool(4+x, 18, 4, 4, 3, CONTUP + y); if (NextGadget == (struct Gadget *) NULL) goto error; OldGadget->NextGadget = NextGadget; OldGadget = NextGadget; } NextGadget->GadgetText = MakeIntui("+",6,-2,3,3,JAM1); /* * Allocate the potentiometer gadgets for contour window */ for (x = y = 0; y < NumContours; x += 6, y++) { NextGadget = MakePot(4+x, 24, 4, 32, CONTPOT+y, y); if (NextGadget == (struct Gadget *) NULL) goto error; PropInfo = (struct PropInfo *) NextGadget->SpecialInfo; if (ContourBase[y] < Ceiling) { PropInfo->VertPot = (USHORT) ((((Ceiling - (ContourBase[y] + 1))<<16)/(Ceiling)) & 0xffff); } else PropInfo->VertPot = 0; OldGadget->NextGadget = NextGadget; ContGadget[y] = NextGadget; OldGadget = NextGadget; } NextGadget->GadgetText = MakeIntui("Alt.",6,12,3,3,JAM1); /* * Allocate the push button gadgets for decrementing contours */ for (x = y = 0; y < NumContours; x += 6, y++) { NextGadget = MakeBool(4+x, 58, 4, 4, 3, CONTDOWN + y); if (NextGadget == (struct Gadget *) NULL) goto error; if (y == NUMCONTS - 1) { NextGadget->GadgetText = MakeIntui("-",6,-2,3,3,JAM1); } OldGadget->NextGadget = NextGadget; OldGadget = NextGadget; } return( FirstGadget ); error: FreeGadgets(FirstGadget); return((struct Gadget *) NULL); } /* MakeContours */ /* * Open the Contour window */ OpenContWind() { struct Window *OpenMyWind(); struct Gadget *gadgets; extern USHORT YScale; if (ContWind == (struct Window *) NULL) { gadgets = MakeContours(); if (gadgets == (struct Gadget *) NULL) { DispErrMsg("Can't allocate contour gadget chain",0); return(0); } NewCont.TopEdge = 119 << YScale; ContWind = OpenMyWind(&NewCont, screen, gadgets, 320, 80, 320, 80); if (ContWind == (struct Window *) NULL) { DispErrMsg("Can't open Contour window",0); FreeGadgets(gadgets); return(0); } SetContTitle(0); DrawContBox(CurContour); ForceNormPointer(); } else { WindowToFront( ContWind ); } return(1); } /* OpenContWind */ /* * Close the Mand window */ CloseContWind() { if (ContWind != (struct Window *) NULL) { CloseMyWind(ContWind,NewCont.FirstGadget); ContWind = (struct Window *) NULL; } } /* ClosePalWind */ /* * ReDisplay a given contour potentiometer gadget */ ReString(PotNum) SHORT PotNum; { SHORT i; USHORT VertPot; if (ContourBase[PotNum] < Ceiling) VertPot = (USHORT) ((((Ceiling - (ContourBase[PotNum]+1))<<16)/(Ceiling)) & 0xffff); else VertPot = (USHORT) 0; NewModifyProp(ContGadget[PotNum], ContWind, NULL, FREEVERT | PROPBORDERLESS, 0L, VertPot, 0L, 0L, 1L); } /* ReString */ /* * ReDisplay all the contour potentiometer gadgets */ ModAll() { SHORT i; USHORT VertPot; struct Gadget *PropGad = (struct Gadget *) ContGadget[0]; for (i = 0; i < NUMCONTS; i++) { if (ContourBase[i] < Ceiling) { VertPot = (USHORT) ((((Ceiling - (ContourBase[i] + 1))<<16)/(Ceiling)) & 0xffff); } else VertPot = (USHORT) 0; NewModifyProp(PropGad,ContWind,NULL,FREEVERT|PROPBORDERLESS,0L,VertPot,0L,0L,1L); PropGad = PropGad->NextGadget; } } /* ModAll */