/******************************* * TURBOMANDEL 1.0 * * by Philip Marivoet * * Nico Francois * *******************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern struct Custom __far custom; #define ISCHECKED(x) (x.Flags & CHECKED) #define CHECK(x) (x.Flags |=CHECKED) #define UNCHECK(x) (x.Flags &=~CHECKED) #define TITLECHECK ShowTitle(ManScr,(ISCHECKED(TitleItem) ? TRUE : FALSE)) /* assembler function call structure */ extern LONG __asm Int32Mand_asm(register __a0 LONG,register __a1 LONG,register __d0 LONG); extern LONG __asm FloatMand_asm(register __a0 float,register __a1 float,register __d0 LONG); extern void __asm DoCycle_asm(); extern void __asm PaletteLeft(); extern void __asm PaletteRight(); extern void __asm F2I(register __a0 ULONG *,register __d0 float); extern float __asm I2F(register __a0 ULONG *); /********** * Palette * **********/ #define OK 10 #define CANCEL 11 #define RED 12 #define GREEN 13 #define BLUE 14 #define INTPLUS 15 #define INTMIN 16 #define SLOPEPLUS 17 #define SLOPEMIN 18 #define TOPRIGHT 19 #define TOPLEFT 20 SHORT BorderVectors1[] = { 0,0,26,0,26,11,0,11,0,0 }; SHORT BorderVectors2[] = { 0,0,52,0,52,12,0,12,0,0 }; struct Border Border26x11 = { -2,-1,3,0,JAM1,5,BorderVectors1,NULL }; struct Border Border52x12 = { -2,-1,3,0,JAM1,5,BorderVectors2,NULL }; #define MakeGText(n,x,y,t) struct IntuiText n =\ { 1,0,JAM1,x,y,NULL,(UBYTE *)t,NULL } MakeGText (DecrText,8,1,"-"); MakeGText (IncrText,8,1,"+"); MakeGText (RightText,8,1,">"); MakeGText (LeftText,8,1,"<"); MakeGText (GreenText,8,1,"G"); MakeGText (RedText,8,1,"R"); MakeGText (BlueText,8,1,"B"); MakeGText (CancelText,1,2,"CANCEL"); MakeGText (OkText,17,2,"OK"); #define MakeRText(n,x,y,t) struct IntuiText n =\ { 2,0,JAM1,x,y,NULL,(UBYTE *)t,NULL} MakeRText (BodyText,5,5,""); MakeRText (YesText,5,3,""); MakeRText (NoText,5,3,""); struct IntuiText PText = { 1,0,JAM1,35,58,NULL,(UBYTE *)"P",NULL }; struct IntuiText SText = { 1,0,JAM1,75,63,NULL,(UBYTE *)"S",&PText }; struct IntuiText IText = { 1,0,JAM1,151,63,NULL,(UBYTE *)"I",&SText }; #define MakeGBox(n,p,x,y,t,id) struct Gadget n = {p,x,y,23,10,NULL\ ,RELVERIFY,BOOLGADGET,(APTR)&Border26x11,NULL,&t,NULL,NULL,id,NULL} MakeGBox (DecrIntG,NULL,123,69,DecrText,INTMIN); MakeGBox (IncrIntG,&DecrIntG,123,54,IncrText,INTPLUS); MakeGBox (DecrSlopeG,&IncrIntG,88,69,DecrText,SLOPEMIN); MakeGBox (IncrSlopeG,&DecrSlopeG,88,54,IncrText,SLOPEPLUS); MakeGBox (RightTopG,&IncrSlopeG,43,69,RightText,TOPRIGHT); MakeGBox (LeftTopG,&RightTopG,11,69,LeftText,TOPLEFT); MakeGBox (GreenG,&LeftTopG,219,54,GreenText,GREEN); MakeGBox (BlueG,&GreenG,261,54,BlueText,BLUE); MakeGBox (RedG,&BlueG,178,54,RedText,RED); struct Gadget CancelGb = { &RedG,235,69,49,11,NULL,RELVERIFY,BOOLGADGET, (APTR)&Border52x12,NULL,&CancelText,NULL,NULL,CANCEL,NULL }; struct Gadget OkGb = { &CancelGb,178,69,49,11,NULL,RELVERIFY,BOOLGADGET, (APTR)&Border52x12,NULL,&OkText,NULL,NULL,OK,NULL }; struct NewWindow NewPalWin = { 14,88,292,85,0,1,RAWKEY+GADGETDOWN+GADGETUP, WINDOWDRAG+ACTIVATE+RMBTRAP+NOCAREREFRESH,&OkGb,NULL,(UBYTE *)"Palette", NULL,NULL,5,5,640,200,CUSTOMSCREEN }; /********* * Coords * *********/ SHORT Vectors1[] = { 0,0,187,0,187,9,0,9,0,0 }; struct Border Border187x9 = { -1,-1,1,0,JAM1,5,Vectors1,NULL}; /* GADGETS */ struct Gadget CancelG = { NULL,125,86,49,11,NULL,RELVERIFY,BOOLGADGET, (APTR)&Border52x12,NULL,&CancelText,NULL,NULL,CANCEL,NULL }; struct Gadget OkG = { &CancelG,23,86,49,11,NULL,RELVERIFY,BOOLGADGET, (APTR)&Border52x12,NULL,&OkText,NULL,NULL,OK,NULL }; UBYTE bottomrighty[22], bottomrightx[22], toplefty[22], topleftx[22]; struct StringInfo BRyGInfo = { bottomrighty,NULL,0,22,0,0,0,0,0,0,0,0,NULL }; struct StringInfo BRxGInfo = { bottomrightx,NULL,0,22,0,0,0,0,0,0,0,0,NULL }; struct StringInfo TLyGInfo = { toplefty,NULL,0,22,0,0,0,0,0,0,0,0,NULL }; struct StringInfo TLxGInfo = { topleftx,NULL,0,22,0,0,0,0,0,0,0,0,NULL }; #define MakeCoordBox(n,p,x,y,info) struct Gadget n = {p,x,y,184,8,NULL,\ RELVERIFY+STRINGCENTER,STRGADGET,(APTR)&Border187x9,NULL,NULL,NULL,\ (APTR)&info,NULL,NULL } MakeCoordBox(BRyG,&OkG, 8,72,BRyGInfo); MakeCoordBox(BRxG,&BRyG,8,60,BRxGInfo); MakeCoordBox(TLyG,&BRxG,8,36,TLyGInfo); MakeCoordBox(TLxG,&TLyG,8,24,TLxGInfo); struct IntuiText BRText = { 1,0,JAM1,10,49,NULL,(UBYTE *)"Bottom right:",NULL }; struct IntuiText TLText = { 1,0,JAM1,10,13,NULL,(UBYTE *)"Top left:",&BRText }; struct NewWindow newcoowin = { 60,79,200,100,0,1,GADGETDOWN+GADGETUP, WINDOWDRAG+ACTIVATE+RMBTRAP+NOCAREREFRESH,&TLxG,NULL, (UBYTE *)"Enter Coordinates",NULL,NULL,5,5,640,200,CUSTOMSCREEN }; /*************** * filenamereq * ***************/ #define STRING 180 SHORT BorderVectors3[] = { 0,0,165,0,165,12,0,12,0,1 }; struct Border Border12x165 = { -3,-2,3,0,COMPLEMENT,5,BorderVectors3,NULL }; struct StringInfo StringGInfo = { NULL,NULL,0,64,0,0,0,0,0,0,0,0,NULL }; struct Gadget StringG = { NULL,20,20,160,9,NULL,RELVERIFY+STRINGCENTER, STRGADGET,(APTR)&Border12x165,NULL,NULL,NULL,(APTR)&StringGInfo,STRING,NULL }; struct NewWindow NewStringWin = { 0,0,200,40,0,1,GADGETUP, WINDOWDRAG+ACTIVATE+NOCAREREFRESH,&StringG,NULL, (UBYTE *)"Enter Filename",NULL,NULL,5,5,640,200,CUSTOMSCREEN }; /******** * Menus * ********/ #define makeMenuText(x,s,off) struct IntuiText x = {\ 3,1,COMPLEMENT,0,off,NULL,(UBYTE *)s,NULL } #define makeMenuTextCheck(x,s,o) struct IntuiText x = {\ 3,1,COMPLEMENT,19,o,NULL,(UBYTE *)s,NULL } #define makeITEM(x,y,h,w,t) struct MenuItem x = { y,0,h,w,9,ITEMTEXT\ +ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL } #define makeITEMCheckME(x,y,h,w,t,me) struct MenuItem x = { y,0,h,w,9,CHECKIT\ +ITEMTEXT+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL } #define makeITEMc(x,y,h,w,t,c) struct MenuItem x = { y,0,h,w,9,ITEMTEXT+\ ITEMENABLED+HIGHCOMP+COMMSEQ,0,(APTR)&t,NULL,c,NULL,MENUNULL } #define makeITEMcCheckT(x,y,h,w,t,c) struct MenuItem x = {\ y,0,h,w,9,CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP+COMMSEQ,\ NULL,(APTR)&t,NULL,c,NULL,MENUNULL } #define makeSUBCheckME(x,y,h,w,l,t,me) struct MenuItem x = { y,l,h,w,9,\ CHECKIT+ITEMTEXT+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL } #define makeITEMCheckT(x,y,h,w,t) struct MenuItem x = { y,0,h,w,9,CHECKIT+\ ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL } #define makeITEMCheckTME(x,y,h,w,t,me) struct MenuItem x = { y,0,h,w,9,CHECKIT+\ ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,me,(APTR)&t,NULL,NULL,NULL,MENUNULL} #define makeITEMSub(x,y,h,w,t,s) struct MenuItem x = {\ y,0,h,w,9,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,&s,MENUNULL } #define makeSUBItem(x,y,h,w,l,t) struct MenuItem x = {\ y,l,h,w,9,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&t,NULL,NULL,NULL,MENUNULL } #define makeMENU(m,n,x,w,s,i) struct Menu m = { n,x,0,w,0,MENUENABLED,s,i } /************* * Screenmenu * *************/ makeMenuTextCheck (HiresText,"Hires",1); makeMenuTextCheck (InterText,"Interlace",1); makeMenuTextCheck (EHBText,"EHB",1); makeMenuTextCheck (TurboText,"Turbo",1); makeMenuTextCheck (ThreeDText,"3-D",1); makeMenuText (NewScrText,"New Screen",1); makeMenuText (PaletteText,"Palette",1); makeITEMc (PalItem,NULL,54,95,PaletteText,'P'); makeITEM (NewScrItem,&PalItem,45,95,NewScrText); makeITEMCheckT (ThreeDItem,&NewScrItem,36,95,ThreeDText); makeITEMCheckTME (EHBItem,&ThreeDItem,27,95,EHBText,0x0002); makeITEMcCheckT (TurboItem,&EHBItem,18,95,TurboText,'T'); makeITEMCheckTME (HiresItem,&TurboItem,9,95,HiresText,0x0008); makeITEMCheckT (InterItem,&HiresItem,0,95,InterText); makeMENU (ScreenMenu,NULL,164,66,"Screen",&InterItem); /*************** * fractalmenu * ***************/ makeMenuTextCheck (SuperText,"Super",1); makeMenuTextCheck (BestText,"Best",1); makeMenuTextCheck (GoodText,"Good",1); makeMenuTextCheck (NormalText,"Normal",1); makeMenuTextCheck (LowText,"Low",1); makeSUBCheckME (SuperItem, NULL,24,67,73,SuperText,0x000F); makeSUBCheckME (BestItem,&SuperItem,16,67,73,BestText,0x0017); makeSUBCheckME (GoodItem,&BestItem,8,67,73,GoodText,0x001B); makeSUBCheckME (NormItem,&GoodItem,0,67,73,NormalText,0x001D); makeSUBCheckME (LowItem,&NormItem,-8,67,73,LowText,0x001E); makeMenuTextCheck (D32Text,"32",1); makeMenuTextCheck (D64Text,"64",1); makeMenuTextCheck (D128Text,"128",1); makeMenuTextCheck (D256Text,"256",1); makeMenuTextCheck (D512Text,"512",1); makeMenuTextCheck (D1024Text,"1024",1); makeMenuTextCheck (DCustText,"Custom",1); makeSUBCheckME (DCustItem,NULL,40,68,73,DCustText,0x3F); makeSUBCheckME (D1024Item,&DCustItem,32,68,73,D1024Text,0x5F); makeSUBCheckME (D512Item,&D1024Item,24,68,73,D512Text,0x6F); makeSUBCheckME (D256Item,&D512Item,16,68,73,D256Text,0x77); makeSUBCheckME (D128Item,&D256Item, 8,68,73,D128Text,0x7B); makeSUBCheckME (D64Item,&D128Item, 0,68,73,D64Text,0x7D); makeSUBCheckME (D32Item,&D64Item,-8,68,73,D32Text,0x7E); makeMenuTextCheck (IntText,"Integer",1); makeMenuTextCheck (FloatText,"Float",1); makeSUBCheckME (FloatItem,NULL,0,75,73,FloatText,0x0001); makeSUBCheckME (IntItem,&FloatItem,-8,75,73,IntText,0x0002); makeMenuText (AccText,"Accuracy",1); makeMenuText (DepthText,"Depth",1); makeMenuText (CalcText,"Calculation",1); makeMenuText (CoordText,"Coords",1); makeMenuText (ResetText,"Reset",1); makeMenuText (RestText,"Restart",1); makeITEM (RestItem,NULL,45,88,RestText); makeITEM (ResetItem,&RestItem,36,88,ResetText); makeITEMc (CoordItem,&ResetItem,27,88,CoordText,'C'); makeITEMSub (CalcItem,&CoordItem,18,88,CalcText,IntItem); makeITEMSub (DepthItem,&CalcItem,9,88,DepthText,D32Item); makeITEMSub (AccItem,&DepthItem,0,88,AccText,LowItem); makeMENU (MandelMenu,&ScreenMenu,82,75,"Mandel",&AccItem); /*************** * ProjectMenu * ***************/ makeMenuText (AboutText,"About",1); makeMenuText (LoadText,"Load",1); makeMenuText (SaveText,"Save",1); makeMenuTextCheck (TitleText,"Title",1); makeMenuText (QuitText,"Quit",1); makeITEMc (QuitItem,NULL,36,80,QuitText,'Q'); makeITEMCheckT (TitleItem,&QuitItem,27,80,TitleText); makeITEMc (AboutItem,&TitleItem,18,80,AboutText,'A'); makeITEMc (SaveItem,&AboutItem,9,80,SaveText,'S'); makeITEMc (LoadItem,&SaveItem,0,80,LoadText,'L'); makeMENU (ProjectMenu,&MandelMenu,0,75,"Project",&LoadItem); #define PROJECT 0 #define LOAD 0 #define SAVE 1 #define ABOUT 2 #define TITLE 3 #define QUIT 4 #define MANDEL 1 #define ACCURACY 0 #define SUPER 4 #define DEPTH 1 #define CUSTOMD 6 #define CALCULATION 2 #define INTCALC 0 #define FLOATCALC 1 #define COORD 3 #define RESET 4 #define RESTART 5 #define SCREEN 2 #define TURBO 2 #define NEWSCR 5 #define PALETTE 6 struct TextAttr TOPAZ80 = { (STRPTR)"topaz.font",TOPAZ_EIGHTY,0,0 }; struct NewScreen ScrStruct = { 0,0,320,256,5,0,1,NULL,CUSTOMSCREEN,&TOPAZ80, (UBYTE *)"TurboMandel V1.0",NULL,NULL}; struct NewWindow WinStruct = { 0,0,320,256,0,1,RAWKEY+MENUPICK+MOUSEBUTTONS +MOUSEMOVE,BORDERLESS+NOCAREREFRESH+ACTIVATE+BACKDROP,NULL,NULL,NULL, NULL,NULL,640,512,640,512,CUSTOMSCREEN}; USHORT Palette[32] = { 0x3a,0xfff,0x2,0xf00 }; /* for IFF read/write */ struct BitMapHeader { UWORD w, h, x, y; UBYTE nPlanes, masking, compression, pad1; UWORD transparentColor; UBYTE xAspect, yAspect; WORD pageWidth, pageHeight; }; struct ILBM_info { struct BitMapHeader header; struct BitMap bitmap; UBYTE cmap[32*3]; }; extern BOOL iff_read(), iff_write(); struct ILBM_info myILBMinfo; #define CALC_FFP 0 #define CALC_INT32 1 #define MAND_3D 1 struct MandelChunk { ULONG XCoo[2], YCoo[2], XSide[2], YSide[2]; UWORD Iteration; UBYTE Calculation, Flags; SHORT TopPos[3], DecrStep[3], ColInt[3]; /* for Palette */ } MandChunk; struct FileRequester *req = NULL; extern struct Library *MathTransBase; extern struct Library *MathBase; extern struct ExecBase *SysBase; struct ArpBase *ArpBase; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Screen *ManScr = NULL; struct Window *ManWin = NULL,*PalWin,*CoordWin,*StringWin; struct ViewPort *Manvp; struct RastPort *Manrp,*Palrp,*Coordrp; void (*Dot)(), Dot2D(), Dot3D(), (*Box)(), Box2D(), Box3D(); LONG (*Mand)(), FloatMand(), Int32Mand(); LONG (*CalcMandel)(), CalcMandel2D(), CalcMandel3D(); void AdjustArpReq (ULONG, struct NewWindow *); UBYTE *GetName (); double cos(); LONG MaxIter, Depth, TurboDepth, DotsH, DotsV, ColorMax; LONG XOffset, YOffset, NumCol, XRes, YRes, Factor; SHORT StopCalc, Stopped, Restart = TRUE, CalcAllPoints, DivDegree, DivNumber; SHORT i, BoxOn = FALSE, CycleOn = FALSE, CycleTemp, CycleLeft = TRUE; SHORT PaletteOn = FALSE, CycleSpeed = 4, CurrSpeed = 4, NoZoom = FALSE; UBYTE fname[64], ItBuffer[64]; float xmin, xmax, ymin, ymax, dx, dy; LONG ScrH; #define PI2 1.570796327 #define R 0 #define G 1 #define B 2 SHORT toppos[3] = { 7,14,21 }, decrstep[3] = { 17,17,17 }; SHORT colint[3] = { 15,15,15 }; main() { if (ArpBase = (struct ArpBase *)OpenLibrary ("arp.library",0L)) { if (req = ArpAllocFreq()) { req->fr_Function = AdjustArpReq; req->fr_FuncFlags = FRF_NewWindFunc; req->fr_Window = 0; } } if (!(MathTransBase=(struct Library *)OpenLibrary("mathtrans.library",0L))) { puts ("No mathtrans.library !"); exit (20); } if (!(MathBase=(struct Library *)OpenLibrary("mathffp.library",0L))) { CloseLibrary (MathTransBase); puts ("No math.library !"); exit (20); } IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L); GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L); /* PAL or NTSC ? */ ScrH = (SysBase->VBlankFrequency == 60) ? 200 : 256; PalSinus (R); PalSinus (G); PalSinus (B); xmax = 1.25; xmin = -2.25; ymax = 1.5; ymin = -1.5; MaxIter = 64 ; CHECK (D64Item); DivNumber = 2 ; CHECK (NormItem); Mand = Int32Mand; CHECK (IntItem); while (Restart) { if (!OpenDisplay()) { UNCHECK(HiresItem); UNCHECK(InterItem); if (! OpenDisplay()) CloseStuff(); Message("Not enough memory for screen ",NULL,"Proceed"); } StopCalc = Stopped = Restart = FALSE; dx = (xmax-xmin) / DotsH; dy = (ymax-ymin) / DotsV; NoZoom = ISCHECKED(ThreeDItem) != NULL; SubDivide (0L,0L,(LONG)(DotsH-1),(LONG)(DotsV-1)); UNCHECK(TurboItem); SetDepth(); while (!Stopped && !Restart) { WaitPort(ManWin->UserPort); TestInput(); } } CloseStuff(); } /* General routines */ CloseStuff() { DisableCycle(); if (ManWin) { ClearMenuStrip (ManWin); CloseWindow (ManWin); } if (ManScr) CloseScreen (ManScr); if (MathTransBase) CloseLibrary ((struct Library *)MathTransBase); if (MathBase) CloseLibrary ((struct Library *)MathBase); CloseLibrary ((struct Library *)GfxBase); CloseLibrary ((struct Library *)IntuitionBase); if (ArpBase) CloseLibrary ((struct Library *)ArpBase); } OpenDisplay() { CycleTemp = CycleOn; DisableCycle(); if (ManWin != NULL) { ClearMenuStrip(ManWin); CloseWindow(ManWin); ManWin = NULL; } if (ManScr != NULL) { CloseScreen(ManScr); ManScr = NULL; } ScrStruct.ViewModes = (ISCHECKED(InterItem) ? LACE : NULL) + (ISCHECKED(HiresItem) ? HIRES : NULL) + (ISCHECKED(EHBItem) ? EXTRA_HALFBRITE : NULL); YRes = WinStruct.Height = ScrStruct.Height = (ISCHECKED(InterItem) ? (ScrH * 2) : ScrH); XRes = WinStruct.Width = ScrStruct.Width = (ISCHECKED(HiresItem) ? 640 : 320); Factor = (YRes == (ScrH * 2) ? 1 : 2) * (XRes == 640 ? 2 : 1); Depth = ScrStruct.Depth = ((ISCHECKED(HiresItem) ? 4:5) + (ISCHECKED(EHBItem) ? 1 : 0)); TurboDepth = (ISCHECKED(HiresItem) ? 2 : 4); /* screen and window */ if (!(ManScr = OpenScreen(&ScrStruct))) return(FALSE); WinStruct.Screen = ManScr; if (!(ManWin = OpenWindow(&WinStruct))) return(FALSE); Manrp = ManWin->RPort; Manvp = &(ManScr->ViewPort); LoadRGB4(Manvp,Palette,(NumCol = ISCHECKED(HiresItem) ? 16L: 32L)); ColorMax = NumCol * (ISCHECKED(EHBItem) ? 2:1); SetDepth(); UNCHECK(TitleItem); TITLECHECK; SetMenuStrip (ManWin,&ProjectMenu); if (CycleTemp) EnableCycle(); if (ISCHECKED(ThreeDItem)) { XOffset = (DotsH = XRes/2)/2; YOffset = (DotsV = YRes/2)/2; Dot = Dot3D; Box = Box3D; CalcMandel = CalcMandel3D; } else { DotsH = XRes; DotsV = YRes; Dot = Dot2D; Box = Box2D; CalcMandel = CalcMandel2D; } return(TRUE); } SetDepth() /* Turbo */ { struct UCopList *cl; long dispconreg; CycleTemp = CycleOn; DisableCycle(); FreeVPortCopLists(Manvp); dispconreg = (Manvp->Modes & ~EXTRA_HALFBRITE) & 0x8fff; dispconreg |= (ISCHECKED(TurboItem)? TurboDepth : Depth) << 12; cl = (struct UCopList *)AllocMem ((LONG)sizeof(struct UCopList) ,MEMF_PUBLIC|MEMF_CLEAR); CWAIT (cl, 0L, 1L); CMOVE (cl, custom.bplcon0, dispconreg); CEND (cl); Manvp->UCopIns = cl; MakeScreen(ManScr); RethinkDisplay(); if (CycleTemp) EnableCycle(); } CalcNewPar(x1,y1,x2,y2) LONG x1,y1,x2,y2; { LONG res; if (x2RPort; PrintIText(Coordrp,&TLText,0L,0L); sprintf (topleftx, "%f", xmin); sprintf (toplefty, "%f", ymax); sprintf (bottomrightx, "%f", xmax); sprintf (bottomrighty, "%f", ymin); RefreshGList (&TLxG, CoordWin, NULL, 4L); ActivateGadget (&TLxG, CoordWin, NULL); ActG = &TLxG; while (!Exit) { WaitPort (CoordWin->UserPort); msg = (struct IntuiMessage *)GetMsg(CoordWin->UserPort); im = *msg; ReplyMsg (msg); id = ((struct Gadget *)im.IAddress)->GadgetID; switch (im.Class) { case GADGETUP: switch (id) { case OK: sscanf (topleftx, "%f", &xmin); sscanf (toplefty, "%f", &ymax); sscanf (bottomrightx, "%f", &xmax); sscanf (bottomrighty, "%f", &ymin); Exit = RCode = TRUE; break; case CANCEL: Exit = TRUE; RCode = FALSE; break; default: ActG = (ActG == &BRyG ? &TLxG : ActG->NextGadget); ActivateGadget (ActG, CoordWin, NULL); break; } } } if (xmax < xmin) { res=xmax; xmax=xmin; xmin=res; } if (ymax < ymin) { res=ymax; ymax=ymin; ymin=res; } CloseWindow (CoordWin); return ((int)RCode); } /* Palette */ SetPalette() { struct IntuiMessage *msg, im; UBYTE exit = FALSE,TurboOn; int i, id, oldpos[3], oldstep[3], oldint[3]; ULONG colw, lcol; static int color = R; CycleTemp = CycleOn; DisableCycle(); PaletteOn = TRUE; TurboOn = ISCHECKED(TurboItem); UNCHECK(TurboItem); SetDepth(); NewPalWin.LeftEdge = (XRes - 292) / 2; NewPalWin.TopEdge = (YRes - 85) / 2; NewPalWin.Screen = ManScr; if (!(PalWin = OpenWindow(&NewPalWin))) { Message ("Can't open window !",NULL,"Proceed"); return; } Palrp = PalWin->RPort; PrintIText (Palrp,&IText,0L,0L); colw = (NumCol == 16) ? 23 : 10; lcol = (NumCol == 16) ? 8 : 6; for (i = 0; i < NumCol - 4; i++ ) { SetAPen (Palrp,(LONG)i + 4L); RectFill (Palrp, lcol + i * colw, 15L, lcol - 1 + (i + 1) * colw, 47L); } SelectRGB (color); for (i = 0; i < 3; i++) { oldint[i] = colint[i]; oldstep[i] = decrstep[i]; oldpos[i] = toppos[i]; } while (!exit) { WaitPort (PalWin->UserPort); msg = (struct IntuiMessage *)(GetMsg (PalWin->UserPort)); im = *msg; ReplyMsg (msg); switch (im.Class) { case RAWKEY: HandleRawkey (&im); break; case GADGETUP: id = ((struct Gadget *)im.IAddress)->GadgetID; switch (id) { case CANCEL: for (i = 0; i < 3; i++) { colint[i] = oldint[i]; decrstep[i] = oldstep[i]; toppos[i] = oldpos[i]; } PalSinus (R); PalSinus (G); PalSinus (B); case OK: exit = TRUE; break; case RED: color = R; SelectRGB (color); break; case GREEN: color = G; SelectRGB (color); break; case BLUE: color = B; SelectRGB (color); break; case TOPLEFT: toppos[color] = (--toppos[color] < 4) ? 31 : toppos[color]; break; case TOPRIGHT: toppos[color] = (++toppos[color] > 31) ? 4 : toppos[color]; break; case SLOPEMIN: if (--decrstep[color] < 15) { decrstep[color] = 15; DisplayBeep (ManScr); } break; case SLOPEPLUS: if (++decrstep[color] > 40) { decrstep[color] = 40; DisplayBeep (ManScr); } break; case INTPLUS: if (++colint[color] > 0xf) { colint[color] = 0xf; DisplayBeep (ManScr); } break; case INTMIN: if (--colint[color] < 0) { colint[color] = 0; DisplayBeep (ManScr); } break; } PalSinus (color); LoadRGB4 (&ManScr->ViewPort, &Palette[0], 32L); break; } } if (TurboOn) { CHECK(TurboItem); SetDepth(); } PaletteOn = FALSE; if (CycleTemp) EnableCycle(); CloseWindow (PalWin); } UWORD colmask[3] = { 0x0ff, 0x0f0f, 0xff0 }; PalSinus (color) int color; { double x, xstep; int pos1, pos2, i; UWORD col, mask; x = 0; xstep = PI2 / decrstep[color]; pos1 = pos2 = toppos[color]; for (i = 0; i < 16; i++) { col = cos (x) * colint[color]; mask = colmask[color]; if (color == R) col <<= 8; else if (color == G) col <<= 4; Palette[pos1] = (Palette[pos1] & mask) | col; Palette[pos2] = (Palette[pos2] & mask) | col; x += xstep; pos1 = (++pos1 > 31) ? 4 : pos1; pos2 = (--pos2 < 4) ? 31 : pos2; } } SelectRGB (color) int color; { RedG.Flags &= ~SELECTED; BlueG.Flags &= ~SELECTED; GreenG.Flags &= ~SELECTED; switch (color) { case R: RedG.Flags |= SELECTED;break; case G: GreenG.Flags |= SELECTED;break; case B: BlueG.Flags |= SELECTED;break; } SetAPen (Palrp, 0L); RectFill (Palrp, 174L, 52L, 286L, 66L); RefreshGList (&RedG, PalWin, NULL, 3L); } /* intuition event handling */ #define TAB 0x42 #define UP 0x4c #define DOWN 0x4d #define LEFT 0x4f #define RIGHT 0x4e HandleRawkey (msg) struct IntuiMessage *msg; { switch (msg->Code) { case TAB: if (!PaletteOn) { if (msg->Qualifier & (IEQUALIFIER_LSHIFT+IEQUALIFIER_RSHIFT)) CycleLeft = !CycleLeft; else if (CycleOn) DisableCycle(); else EnableCycle(); } break; case UP: if (CycleOn) if (CycleSpeed > 1) CurrSpeed = --CycleSpeed; else DisplayBeep (ManScr); break; case DOWN: if (CycleOn) CurrSpeed = ++CycleSpeed; break; case LEFT: if (!CycleOn) { PaletteLeft(); LoadRGB4 (Manvp, Palette, 32L); } break; case RIGHT: if (!CycleOn) { PaletteRight(); LoadRGB4 (Manvp, Palette, 32L); } break; } } TestInput() { struct IntuiMessage *msg,im; short DoLoop= TRUE, Zooming = FALSE; LONG XCoord,YCoord,Distx,Disty; while (DoLoop){ if (msg=(struct IntuiMessage *)(GetMsg(ManWin->UserPort))) { im = *msg; ReplyMsg(msg); switch (im.Class) { case RAWKEY: HandleRawkey (&im); break; case MENUPICK: switch (MENUNUM(im.Code)) { case PROJECT: switch (ITEMNUM(im.Code)) { case LOAD: GetIff(); break; case SAVE: SaveIff(); break; case TITLE: TITLECHECK; break; case ABOUT: Message ("Programmed by Ph.Marivoet, N.Francois", NULL, "Proceed"); break; case QUIT: if (Message("Do you want to quit","Yes","No")) Stopped = StopCalc = TRUE; break; } break; case MANDEL: switch (ITEMNUM(im.Code)) { case COORD: if (SetCoords()) Restart = StopCalc = TRUE; break; case RESET: if (Message("Reset Mandel","Yes","No")) { xmax = 1.25; xmin = -2.25; ymax = 1.5; ymin = -1.5; StopCalc = Restart = TRUE; } break; case RESTART: if (Message("Restart Calculation","Yes","No")) StopCalc = Restart = TRUE; break; case ACCURACY: CalcAllPoints=((DivDegree=SUBNUM(im.Code))==SUPER); DivNumber = 1<Screen = ManScr; win->Type = CUSTOMSCREEN; win->LeftEdge = (XRes-win->Width)/2; win->TopEdge = (YRes-win->Height)/2; } UBYTE *GetName (title, str, FileReq) UBYTE *title, *str; BOOL FileReq; { static UBYTE Path[108]; UBYTE File[256]; if (req && FileReq) { req->fr_Hail = title; req->fr_Dir = Path; strcpy (str,FileRequest (req)); if (*str) { strcpy (File,Path); TackOn (File,str); strcpy (str,File); return (str); } else return (NULL); } StringGInfo.Buffer = str; NewStringWin.LeftEdge = (XRes-200)/2; NewStringWin.TopEdge = (YRes-40)/2; NewStringWin.Screen = ManScr; NewStringWin.Title = title; if (!(StringWin = OpenWindow (&NewStringWin))) { Message ("Can't open window !",NULL,"Proceed"); return (NULL); } ActivateGadget (&StringG, StringWin, NULL); WaitPort (StringWin->UserPort); CloseWindow (StringWin); if (*str) return (str); else return (NULL); } /* IFF load/save */ GetIff() { LONG d, i; struct IntuiMessage *msg; if (!GetName("Load file", fname, TRUE)) return; MandChunk.XSide[0] = NULL; if (read_iff (&myILBMinfo,fname,1)) { if (!MandChunk.XSide[0]) if (!Message ("MANDEL chunk not found, load anyway ?","Yes","No")) return; if ((myILBMinfo.header.h > (ScrH * 2)) || (myILBMinfo.header.w > 640)) { Message ("Picture too large, can't load",NULL,"Ok"); return; } if ((myILBMinfo.header.w > 320) && (myILBMinfo.header.nPlanes > 5)) { Message ("Picture too large, can't load",NULL,"Ok"); return; } NoZoom = StopCalc = TRUE; UNCHECK(TurboItem); if ((d = myILBMinfo.header.nPlanes) > 5) { d = 5; CHECK(EHBItem); } for (i = 0; i < 1<> 4); if (myILBMinfo.header.h > ScrH) CHECK (InterItem); else UNCHECK (InterItem); if (myILBMinfo.header.w > 320) CHECK (HiresItem); else UNCHECK (HiresItem); if (!OpenDisplay()) { UNCHECK (HiresItem); UNCHECK (InterItem); if (!OpenDisplay()) Stopped = TRUE; else Message ("No memory for screen !",NULL,"Proceed"); } else { ModifyIDCMP (ManWin, MENUVERIFY); if (MandChunk.XSide[0]) { xmax = (xmin = I2F(MandChunk.XCoo)) + I2F(MandChunk.XSide); ymax = (ymin = I2F(MandChunk.YCoo)) + I2F(MandChunk.YSide); dx = (xmax-xmin) / DotsH; dy = (ymax-ymin) / DotsV; UNCHECK (D32Item); UNCHECK (D64Item); UNCHECK (D128Item); UNCHECK (D256Item); UNCHECK (D512Item); UNCHECK (D1024Item); UNCHECK (DCustItem); switch (MaxIter = MandChunk.Iteration) { case 32: CHECK (D32Item); break; case 64: CHECK (D64Item); break; case 128: CHECK (D128Item); break; case 256: CHECK (D256Item); break; case 512: CHECK (D512Item); break; case 1024: CHECK (D1024Item); break; default: CHECK (DCustItem); sprintf (ItBuffer, "%ld", MaxIter); break; } UNCHECK (FloatItem); UNCHECK (IntItem); if (MandChunk.Calculation == CALC_INT32) { CHECK (IntItem); Mand = Int32Mand; } else { CHECK (FloatItem); Mand = FloatMand; } if (MandChunk.Flags & MAND_3D) CHECK (ThreeDItem); else { UNCHECK (ThreeDItem); NoZoom = FALSE; } for (i = 0; i < 3; i++) { toppos[i] = MandChunk.TopPos[i]; decrstep[i] = MandChunk.DecrStep[i]; colint[i] = MandChunk.ColInt[i]; } } myILBMinfo.bitmap = ManScr->BitMap; myILBMinfo.bitmap.BytesPerRow = ((myILBMinfo.header.w+15)>>4)<<1; myILBMinfo.bitmap.Rows = myILBMinfo.header.h; myILBMinfo.bitmap.Depth = myILBMinfo.header.nPlanes; if (!read_iff (&myILBMinfo,fname, 0)) Message ("Error loading file !",NULL,"Proceed"); } } else Message ("Can't load IFF file !",NULL,"Proceed"); while (msg = (struct IntuiMessage *)GetMsg (ManWin->UserPort)) ReplyMsg (msg); ModifyIDCMP (ManWin, RAWKEY+MOUSEMOVE+MENUPICK+MOUSEBUTTONS); } SaveIff() { struct IntuiMessage *msg; if (!GetName("Save file", fname, TRUE)) return; ModifyIDCMP (ManWin, MENUVERIFY); UNCHECK (TitleItem); TITLECHECK; F2I(MandChunk.XCoo, xmin); F2I(MandChunk.XSide, xmax - xmin); F2I(MandChunk.YCoo, ymin); F2I(MandChunk.YSide, ymax - ymin); MandChunk.Iteration = MaxIter; if (ISCHECKED(IntItem)) MandChunk.Calculation = CALC_INT32; else MandChunk.Calculation = CALC_FFP; MandChunk.Flags = 0; if (CalcMandel == CalcMandel3D) MandChunk.Flags |= MAND_3D; for (i = 0; i < 3; i++) { MandChunk.TopPos[i] = toppos[i]; MandChunk.DecrStep[i] = decrstep[i]; MandChunk.ColInt[i] = colint[i]; } if (!write_iff (fname,&Palette[0], ManScr, 1)) Message ("Couldn't save IFF file !",NULL,"Proceed"); while (msg = (struct IntuiMessage *)GetMsg (ManWin->UserPort)) ReplyMsg (msg); ModifyIDCMP (ManWin, RAWKEY+MOUSEMOVE+MENUPICK+MOUSEBUTTONS); DisplayBeep (ManScr); } /* 2D-3D subroutines */ LONG CalcMandel2D(ix,iy) LONG ix,iy; { LONG color; float x,y; if (!(color = ReadPixel(Manrp,ix,iy))) { x = xmin+ix*dx; y = ymax-iy*dy; color = Mand(x,y,MaxIter); SetAPen(Manrp,color); WritePixel(Manrp,ix,iy); } return(color); } LONG CalcMandel3D(ix,iy) LONG ix,iy; { return (Mand ((float)xmin+ix*dx, (float)ymax-iy*dy, MaxIter)); } void Dot2D(x,y,col) LONG x,y,col; { SetAPen(Manrp,col); WritePixel(Manrp,x,y); } void Dot3D(x,y,col) LONG x,y,col; { SetAPen (Manrp, col == 2L ? 2L : (col == 4L ? 31L : col-1L)); Move (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset-col); Draw (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset); SetAPen (Manrp,col); WritePixel (Manrp, x+XOffset+(YOffset-y)*Factor/2, y+YOffset-col); } void Box2D(x1,y1,x2,y2,col) LONG x1,y1,x2,y2,col; { SetAPen(Manrp,col); RectFill(Manrp,x1,y1,x2,y2); } void Box3D(x1,y1,x2,y2,col) LONG x1,y1,x2,y2,col; { LONG i, bcol; bcol = (col == 2L ? 2L : (col == 4L ? 31L : col-1L)); SetAPen (Manrp, bcol); RectFill (Manrp, x1+XOffset+(YOffset-y2)*Factor/2, y2+YOffset-col, x2+XOffset+(YOffset-y2)*Factor/2, y2+YOffset); for (i=y1; i<=y2; i++) { SetAPen (Manrp, bcol); Move (Manrp, x2+XOffset+(YOffset-i)*Factor/2, i+YOffset); Draw (Manrp, x2+XOffset+(YOffset-i)*Factor/2, i+YOffset-col); SetAPen(Manrp,col); Draw (Manrp, x1+XOffset+(YOffset-i)*Factor/2, i+YOffset-col); } } /* Recursive calculation of mandelbrot */ SubDivide(x1,y1,x2,y2) LONG x1,x2,y1,y2; { static LONG i,TestColor; LONG mx1,my1,mx2,my2,SameColor = TRUE,Step; if (StopCalc) return; if ((x1==x2) && (y1==y2)) { Dot(x1,y1,CalcMandel(x1,y1)); return; } mx1 = mx2 = (x1+x2)/2; my1 = my2 = (y1+y2)/2; TestColor = CalcMandel (mx1,my1); if (CalcAllPoints || !(Step=(x2-x1)/DivNumber)) Step = 1; for (i = 0; (i <= x2-x1) && !StopCalc; i += Step) { SameColor &= TestColor == CalcMandel (x1+i,y1); SameColor &= TestColor == CalcMandel (x2-i,y2); TestInput(); } if (CalcAllPoints || !(Step=(y2-y1)/DivNumber)) Step = 1; for (i = 0 ;(i <= y2-y1) && !StopCalc; i += Step) { SameColor &= TestColor == CalcMandel (x1,y2-i); SameColor &= TestColor == CalcMandel (x2,y1+i); TestInput(); } if (SameColor && !StopCalc) Box(x1,y1,x2,y2,TestColor); else { if ((x2-x1) == 1) mx2 = mx1 +1; if ((y2-y1) == 1) my2 = my1 +1; SubDivide (x1 ,y1 ,mx1,my1); SubDivide (x1 ,my2,mx1,y2 ); SubDivide (mx2,y1 ,x2 ,my1); SubDivide (mx2,my2,x2 ,y2 ); } } float fixedfactor = (float)(1L << 27); LONG Int32Mand (px, py, max_iter) float px, py; LONG max_iter; { register LONG color = 2; LONG itcountint; itcountint = Int32Mand_asm((long)(px * fixedfactor),(long)(py * fixedfactor),max_iter); if (itcountint) color = (max_iter - itcountint) % (ColorMax-4) + 4; return (color); } LONG FloatMand (px,py,max_iter) float px,py; LONG max_iter; { LONG color = 2,itcount; itcount = FloatMand_asm(px,py,max_iter); if (itcount) color = (max_iter - itcount) % (ColorMax-4) + 4; return(color); } /* Cycle subtask */ void __saveds DoCycle() { DoCycle_asm(); } EnableCycle() { struct Task *CycleTask; if (!CycleOn) CycleTask = (struct Task *)CreateTask ("TM VBlank", 2L, DoCycle, 1000L); CycleOn = TRUE; } DisableCycle() { CycleOn = FALSE; WaitTOF(); WaitTOF(); }