page%swap@Sun.COM (Bob Page) (05/17/89)
Submitted-by: u211344@hnykun11.bitnet (Olaf 'Rhialto' Seibert) Posting-number: Volume 89, Issue 143 Archive-name: graphics/mandel180.2 # This is a shell archive. # Remove anything above and including the cut line. # Then run the rest of the file through 'sh'. # Unpacked files will be owned by you and have default permissions. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: SHell ARchive # Run the following text through 'sh' to create: # GotMenu.c # Jiff.c # This is archive 2 of a 4-part kit. # This archive created: Wed May 17 20:45:12 1989 echo "extracting GotMenu.c" sed 's/^X//' << \SHAR_EOF > GotMenu.c X/* X * M A N D E L B R O T C O N S T R U C T I O N S E T X * X * (C) Copyright 1989 by Olaf Seibert. X * Mandel may be freely distributed. See file 'doc/Notice' for details. X * X * GotMenu and some (many) related things. X */ X X#include <exec/types.h> X#include <intuition/intuition.h> X#include "mandel.h" X#ifdef DEBUG X# include <stdio.h> X# undef STATIC X# define STATIC /* EMPTY */ X#endif X Xextern double ReMouse, ImMouse; Xextern UBYTE IPlotNr, EPlotNr; Xextern void UpdateDrwCm(); X XTEXT FileName[FNAME_SIZE+1] = "Mandel.pic"; XTEXT DirName[DNAME_SIZE+2] = ""; XUBYTE Buffer[5][20]; X Xint (*DepthFuncArray[])() = { X ZQuadMinC, ZC1MinZ, Z3PlusZCMin1MinC, UserProgFunc, I_ZQuadMinC X}; X Xvoid (*IPlotFuncArray[])() = { X None, PlotZ X}; X Xvoid (*EPlotFuncArray[])() = { X PlotIterationCount, PlotZ, X}; X X/* Forward declarations of static procedures */ XSTATIC void PrjNew(); X Xvoid GotMenu(Code) XUSHORT Code; X{ X static void (*MenuFunc[])()= { X CprMenu, PrjMenu, OptMenu, DrwMenu, BatchMenu X }; X while (Code != MENUNULL) { X (*MenuFunc[MENUNUM(Code)]) (Code); X Code = ItemAddress(MandelMenu, (long) Code)->NextSelect; X } X} X Xvoid CprMenu(Code) XUSHORT Code; X{ X extern long Revision; /* From IncRev */ X ULONG OldIDCMP = MainWindow->IDCMPFlags; X X#define DATE "16 April 1989 V1.3 (" X#define strlen_DATE 20 X X static UBYTE DateVersion[strlen_DATE+9] = DATE; X X static struct IntuiText Body[] = X { X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, X 10, 15, NULL, (UBYTE *)"Mandelbrot Construction Set", &Body[1] }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, X 10, 30, NULL, (UBYTE *)"By KosmoSoft Productions", &Body[2] }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, X 10, 40, NULL, DateVersion, &Body[3] }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, X 10, 55, NULL, (UBYTE *)"Ohh, please Copy-Me!", NULL } X }, X ExitText = X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, X AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (UBYTE *)" OK ", NULL }; X X sprintf(&DateVersion[strlen_DATE], "%ld)", Revision); X X ModifyIDCMP(MainWindow, OldIDCMP &~ (MENUVERIFY | SIZEVERIFY | REQVERIFY)); X AutoRequest(MainWindow, &Body[0], NULL, &ExitText, NULL, NULL, 258L, 100L); X ModifyIDCMP(MainWindow, OldIDCMP); X} X Xchar *CatFileComponents(dest, dirname, filename) Xchar *dest; Xchar *dirname; Xchar *filename; X{ X strcpy(dest, dirname); X if (dirname[0] && dirname[strlen(dirname) - 1] != ':') X strcat(dest, "/"); X strcat(dest, FileName); X X return dest; X} X X Xbool OpenAs(name) Xchar *name; X{ X struct Mand MandChunk; X struct ILBM_info *ilbminfo, *win_read_iff(); X X StopDrawing(); X MandChunk.MandID = 0; X if (ilbminfo = win_read_iff(name, (short)FALSE, X MainWindow, sizeof(MandChunk), &MandChunk)) { X put_ea_cmap(&ilbminfo->cmap, NumColors, MandelScreen); X InterpretMAND(&MandChunk, ilbminfo); X } X Saved = TRUE; X NameValid = FALSE; X X return ilbminfo != NULL; X} X Xbool SaveAs(name) Xchar *name; X{ X struct Mand MandChunk; X unsigned char ea_colormap[3*MAXCOL]; X X get_ea_cmap(ea_colormap, NumColors, MandelScreen); X MakeMAND(&MandChunk); X SuspendDrawing(); X NameValid = Saved = write_iff(name, ea_colormap, MainWindow, X (short) 0, (short) 0, (short) TRUE, sizeof(MandChunk), X &MandChunk); X ResumeDrawing(); X X return Saved; X} X XSTATIC void PrjMenu(Code) XUSHORT Code; X{ X int SubNum = SUBNUM(Code); X int ItemNum = ITEMNUM(Code); X X struct Mand MandChunk; X char Name[DNAME_SIZE + FNAME_SIZE + 3]; X X switch (ItemNum) { X case PRJNEW: X PrjNew(SubNum); X break; X case PRJOPN: X if ( get_fname(MainWindow, "Select a filename to OPEN", X FileName, DirName) == NULL ) X break; X CatFileComponents(Name, DirName, FileName); X OpenAs(Name); X break; X case PRJSVE: /* Save */ X if (NameValid) skipto prjsve; X /* Fall Through */ X case PRJSVA: /* Save As */ X if ( get_fname(MainWindow, "Select a filename to SAVE", X FileName, DirName) == NULL ) X break; Xprjsve: X CatFileComponents(Name, DirName, FileName); X SaveAs(Name); X break; X case PRJSTP: X StopDrawing(); X break; X case PRJQUI: X finished = TRUE; X } X} X XSTATIC void OptMenu(Code) XUSHORT Code; X{ X int SubNum = SUBNUM(Code); X int ItemNum = ITEMNUM(Code); X X switch (ItemNum) { X case OPTCOL: X switch (SubNum) { X case OCSEL: X PenTableMode = SELECT; X Select(); X break; X case OCMOD: X PenTableMode = MODULO; X break; X case OCRAN: X PenTableMode = RANGES; X break; X case OCPAL: X OpenColorWindow(MainWindow); X } /* End Switch SUBNUM */ X InitPenTable(); X break; X case OPTRES: X switch (SubNum) { X case ORNRM: X PixelStep = 1; X break; X case OR12: X PixelStep = 2; X break; X case OR13: X PixelStep = 3; X break; X case OR14: X PixelStep = 4; X break; X case ORFIL: /* Fill in */ X DrawPicture((bool)TRUE); X break; X case ORHI: X case ORILC: X case OREHB: X { X USHORT newmode = MandelNScreen.ViewModes & ~(HIRES | LACE | EXTRA_HALFBRITE); X X if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, ORHI)) X -> Flags & CHECKED) X newmode |= HIRES; X if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, ORILC)) X -> Flags & CHECKED) X newmode |= LACE; X if (ItemAddress(MandelMenu, MENU(OPTMENU, OPTRES, OREHB)) X -> Flags & CHECKED) X newmode |= EXTRA_HALFBRITE; X if (newmode != MandelNScreen.ViewModes) { X MandelNScreen.ViewModes = newmode; X if (Sure()) X ReInitDisplay(); X else X UpdateOptViewResCm(); X } X } X break; X case ORBCK: X if (ItemAddress(MandelMenu, MENU(OPTMENU,OPTRES,ORBCK))->Flags & CHECKED) X DoBorderless(MainWindow, &borderinfo); X else X UndoBorderless(MainWindow, &borderinfo); X } /* End Switch SUBNUM */ X break; X case OPTPAR: X Parameters(); X break; X case OPTPRI: X switch (SubNum) { X case OPNOR: X SetDrawPri(0); X break; X case OPLOW: X SetDrawPri(-5); X break; X } X break; X } /* End Switch ITEMNUM */ X} X X/* X * This function sets the drawing function, numbered from 0. X */ X Xvoid SetDrawingFunction(number) Xint number; X{ X if (number >= 0 && number <= DF5) { X FunctionNr = number; X DepthFunc = DepthFuncArray[FunctionNr]; X } X} X X/* X * This function sets the i plotting function, numbered from 0. X */ X Xvoid SetIPlotFunction(number) Xint number; X{ X if (number >= 0 && number <= DIZ) { X IPlotNr = number; X IPlotFunc = IPlotFuncArray[IPlotNr]; X } X} X X/* X * This function sets the e plotting function, numbered from 0. X */ X Xvoid SetEPlotFunction(number) Xint number; X{ X if (number >= 0 && number <= DEZ) { X EPlotNr = number; X EPlotFunc = EPlotFuncArray[EPlotNr]; X } X} X Xvoid DrwMenu(Code) XUSHORT Code; X{ X int ItemNum = ITEMNUM(Code); X int SubNum = SUBNUM(Code); X X switch (ItemNum) { X case DRWFUN: X SetDrawingFunction(SubNum + DF1); X break; X case DRWIPL: X SetIPlotFunction(SubNum + DINONE); X break; X case DRWEPL: X SetEPlotFunction(SubNum + DEDEPTH); X break; X } X} X Xvoid UnImpl() X{ X static char alert[] = "\ X\0\144\25Mandelbrot Construction Set -- By KosmoSoft Productions\0a\ X\0\170\40Sorry, this function has not been implemented yet!\0"; X DisplayAlert(RECOVERY_ALERT, alert, 50L); X} X XSTATIC USHORT OldMinWidth, OldMinHeight, OldMaxWidth, OldMaxHeight; X X/* Do not nest calls to DisableSizing: the original values will be lost. */ X Xvoid DisableSizing() X{ X OldMinWidth = MainWindow->MinWidth; X OldMaxWidth = MainWindow->MaxWidth; X OldMinHeight = MainWindow->MinHeight; X OldMaxHeight = MainWindow->MaxHeight; X WindowLimits(MainWindow, (long) MainWindow->Width, (long) MainWindow->Height, X (long) MainWindow->Width, (long) MainWindow->Height); X} X Xvoid EnableSizing() X{ X WindowLimits(MainWindow, (long) OldMinWidth, (long) OldMinHeight, X (long) OldMaxWidth, (long) OldMaxHeight); X} X XSTATIC void PrjNew(SubNum) XUSHORT SubNum; X{ X struct Window *window; X int ID; X static double HShift = 0.0, X VShift = 0.0; X static double Factor = 3.0; X double Width = RightEdge - LeftEdge, X Height = TopEdge - BottomEdge, X NewLeftEdge = LeftEdge, X NewTopEdge = TopEdge, X NewRightEdge = RightEdge, X NewBottomEdge = BottomEdge; X X /* Stuff for the ABSOLUTE requester */ X X static struct IntuiText RatioText = { X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 90, NULL, X (UBYTE *) "Ratio: ", NULL }; X static struct IntuiText AbsText = { X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL, X (UBYTE *) "Select an absolute position", &RatioText }; X static struct IntuiText LRTBText[] = { X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Left", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Right", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Top", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Bottom", NULL } X }; X static struct StringInfo LRTBinfo[] = { X { &Buffer[0][0], &Buffer[4][0], 0, 20, 0 }, X { &Buffer[1][0], &Buffer[4][0], 0, 20, 0 }, X { &Buffer[2][0], &Buffer[4][0], 0, 20, 0 }, X { &Buffer[3][0], &Buffer[4][0], 0, 20, 0 } X }; X static struct Gadget LRTBGadget[] = { X { &LRTBGadget[1], 66, 30, 160, 10, /* next, LTWH */ X GADGHCOMP, /* Flags */ X RELVERIFY, /* Activation */ X STRGADGET | REQGADGET, /* GadgetType */ X (APTR) NULL, NULL, /* rendering */ X &LRTBText[0], 0, (APTR) &LRTBinfo[0], /* "Left" */ X NEGGADGETID+1, NULL }, X { &LRTBGadget[2], 66, 45, 160, 10, /* next, LTWH */ X GADGHCOMP, X RELVERIFY, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &LRTBText[1], 0, (APTR) &LRTBinfo[1], /* Right */ X NEGGADGETID+1, NULL }, X { &LRTBGadget[3], 66, 60, 160, 10, /* next, LTWH */ X GADGHCOMP, X RELVERIFY, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &LRTBText[2], 0, (APTR) &LRTBinfo[2], /* Top */ X NEGGADGETID+1, NULL }, X { NULL, 66, 75, 160, 10, /* next, LTWH */ X GADGHCOMP, X RELVERIFY, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &LRTBText[3], 0, (APTR) &LRTBinfo[3], /* Bottom */ X NEGGADGETID+1, NULL } X }; X static struct Requester AbsRequest = { X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL, X &AbsText, 0, 1 }; X X /* Stuff for the SHIFT requester */ X X static struct IntuiText ShiftText = { X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL, X (UBYTE *) "Select a window shift amount", NULL }; X static struct IntuiText RDText[] = { X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Right", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Down", NULL } X }; X static struct Gadget RDGadget[] = { X { &RDGadget[1], 66, 45, 160, 10, /* next, LTWH */ X GADGHCOMP, X 0, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &RDText[0], 0, (APTR) &LRTBinfo[0], /* Right */ X 0, NULL }, X { NULL, 66, 60, 160, 10, /* next, LTWH */ X GADGHCOMP, X 0, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &RDText[1], 0, (APTR) &LRTBinfo[1], /* Down */ X 0, NULL } X }; X static struct Requester ShiftRequest = { X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL, X &ShiftText, 0, 1 }; X X /* Stuff for the ZOOM requester */ X X static struct IntuiText ZoomText = { X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL, X (UBYTE *) "Select a zoom center", NULL }; X static struct IntuiText RIFText[] = { X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "X:Real", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Y:Imag", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -56, 0, NULL, X (UBYTE *) "Factor", NULL } X }; X static struct Gadget RIFGadget[] = { X { &RIFGadget[1], 66, 30, 160, 10, /* next, LTWH */ X GADGHCOMP, X 0, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &RIFText[0], 0, (APTR) &LRTBinfo[0], /* Re */ X 0, NULL }, X { &RIFGadget[2], 66, 45, 160, 10, /* next, LTWH */ X GADGHCOMP, X 0, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &RIFText[1], 0, (APTR) &LRTBinfo[1], /* Im */ X 0, NULL }, X { NULL, 66, 60, 160, 10, /* next, LTWH */ X GADGHCOMP, X 0, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &RIFText[2], 0, (APTR) &LRTBinfo[2], /* Factor */ X 0, NULL } X }; X static struct Requester ZoomRequest = { X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL, X &ZoomText, 0, 1 }; X X switch (SubNum) { X case PNRED: X if (MouseStatus != FLASHING) return; X else { X register SHORT w = MainWindow -> GZZWidth, X h = MainWindow -> GZZHeight; X register SHORT X1, Y1, X2, Y2; X X /* If you cast less, Aztec seems to do it wrong... */ X X1 = (-(long)FrameX1 * w) / ((long)FrameX2 - (long)FrameX1); X Y1 = (-(long)FrameY1 * h) / ((long)FrameY2 - (long)FrameY1); X X2 = ((long)(w-1-FrameX1) * w) / ((long)FrameX2 - (long)FrameX1) X - 1; X Y2 = ((long)(h-1-FrameY1) * h) / ((long)FrameY2 - (long)FrameY1) X - 1; X X NewLeftEdge = LeftEdge + X1 * CXStep; X NewRightEdge = LeftEdge + X2 * CXStep; X NewTopEdge = TopEdge - Y1 * CYStep; X NewBottomEdge = TopEdge - Y2 * CYStep; X X skipto pnabs; X } X case PNENL: X if (MouseStatus != FLASHING) return; X X NewLeftEdge = LeftEdge + FrameX1 * CXStep; X NewRightEdge = LeftEdge + FrameX2 * CXStep; X NewTopEdge = TopEdge - FrameY1 * CYStep; X NewBottomEdge = TopEdge - FrameY2 * CYStep; X skipto pnabs; X case PNSHF: X NegativeGadget.NextGadget = &RDGadget[0]; X do { X sprintf(Buffer[0], "%1.6g",HShift); X sprintf(Buffer[1], "%1.6g",VShift); X X window = MyRequest(&ShiftRequest, MainWindow); X ID = WaitMyRequest(window); X EndMyRequest(&ShiftRequest, window, MainWindow); X if (ID == NEGGADGETID) return; X X } while (sscanf(Buffer[0], "%lf", &HShift)+ X sscanf(Buffer[1], "%lf", &VShift) != 2); X X NewLeftEdge = LeftEdge + HShift * Width; X NewRightEdge = RightEdge + HShift * Width; X NewTopEdge = TopEdge - VShift * Height; X NewBottomEdge = BottomEdge - VShift * Height; X X skipto pnabs; X case PNZI: X case PNZO: { X double ReMid, ImMid; X X if (MouseStatus == NOTFRAMING) { X ReMid = (RightEdge + LeftEdge) / 2.0; X ImMid = (TopEdge + BottomEdge) / 2.0; X } else { X ReMid = ReMouse; X ImMid = ImMouse; X } X X NegativeGadget.NextGadget = &RIFGadget[0]; X do { X sprintf(Buffer[0], "%1.6g",ReMid); X sprintf(Buffer[1], "%1.6g",ImMid); X sprintf(Buffer[2], "%1.6g",Factor); X X window = MyRequest(&ZoomRequest, MainWindow); X ID = WaitMyRequest(window); X EndMyRequest(&ZoomRequest, window, MainWindow); X if (ID == NEGGADGETID) return; X X } while (sscanf(Buffer[0], "%lf", &ReMid)+ X sscanf(Buffer[1], "%lf", &ImMid)+ X sscanf(Buffer[2], "%lf", &Factor) != 3); X if (SubNum == PNZI) { X if (Factor == 0.0) { X Factor = 1.0; X } X Width /= Factor; X Height /= Factor; X } else { X Width *= Factor; X Height *= Factor; X } X NewLeftEdge = ReMid - Width / 2.0; X NewTopEdge = ImMid + Height / 2.0; X NewRightEdge = NewLeftEdge + Width; X NewBottomEdge = NewTopEdge - Height; X skipto pnabs; X } X case PNABS: X NewLeftEdge = LeftEdge; X NewRightEdge = RightEdge; X NewTopEdge = TopEdge; X NewBottomEdge = BottomEdge; X Xpnabs: X NegativeGadget.NextGadget = &LRTBGadget[0]; X sprintf(Buffer[0], "%1.10g", NewLeftEdge); X sprintf(Buffer[1], "%1.10g", NewRightEdge); X sprintf(Buffer[2], "%1.10g", NewTopEdge); X sprintf(Buffer[3], "%1.10g", NewBottomEdge); X sprintf(RatioText.IText+7, "%1.4f ", Ratio(NewLeftEdge, X NewRightEdge, NewTopEdge, NewBottomEdge, MainWindow)); X X do { X window = MyRequest(&AbsRequest, MainWindow); X X while ( (ID = WaitMyRequest(window) ) > NEGGADGETID) { X sscanf(Buffer[0], "%lf", &NewLeftEdge); X sscanf(Buffer[1], "%lf", &NewRightEdge); X sscanf(Buffer[2], "%lf", &NewTopEdge); X sscanf(Buffer[3], "%lf", &NewBottomEdge); X sprintf(RatioText.IText+7, "%1.4f ", X Ratio(NewLeftEdge, NewRightEdge, NewTopEdge, X NewBottomEdge, MainWindow)); X X PrintIText(AbsRequest.ReqLayer->rp, &RatioText, 0L, 0L); X } X X EndMyRequest(&AbsRequest, window, MainWindow); X X } while (sscanf(Buffer[0], "%lf", &NewLeftEdge)+ X sscanf(Buffer[1], "%lf", &NewRightEdge)+ X sscanf(Buffer[2], "%lf", &NewTopEdge)+ X sscanf(Buffer[3], "%lf", &NewBottomEdge) < 4); X X if (ID != POSGADGETID) return; X X LeftEdge = NewLeftEdge; X RightEdge = NewRightEdge; X TopEdge = NewTopEdge; X BottomEdge = NewBottomEdge; X X StopFraming(); X StopDrawing(); X X break; X } X DrawPicture((bool)FALSE); /* Don't fill in */ X} X Xfloat Ratio(l, r, t, b, window) Xdouble l, r, t, b; Xstruct Window *window; X{ X float PixelRatio; X float ReImRatio; X X if (t == b) t = b+1; /* You never know... */ X X PixelRatio = (float) window->GZZWidth / window->GZZHeight; X X if (window->WScreen->ViewPort.Modes & HIRES) PixelRatio /= 2; X if (window->WScreen->ViewPort.Modes & LACE) PixelRatio *= 2; X ReImRatio = (r - l)/(t - b); X X return ReImRatio / PixelRatio; X} X Xvoid Parameters() X{ X struct Window *window; X int ID; X int NewMaxDepth, NewRangeWidth, NewWBwidth, NewWBheight; X X static struct IntuiText ParamText = { X MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, 10, 10, NULL, X (UBYTE *) "Select these parameters", NULL }; X static struct IntuiText ParmText[] = { X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL, X (UBYTE *) "Max depth", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL, X (UBYTE *) "Range width", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL, X (UBYTE *) "Screen width", NULL }, X { MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE, -120, 0, NULL, X (UBYTE *) "Screen height", NULL } X }; X static struct StringInfo Parminfo[] = { X { &Buffer[0][0], &Buffer[4][0], 0, 20, 0 }, X { &Buffer[1][0], &Buffer[4][0], 0, 20, 0 }, X { &Buffer[2][0], &Buffer[4][0], 0, 20, 0 }, X { &Buffer[3][0], &Buffer[4][0], 0, 20, 0 } X }; X static struct Gadget ParmGadget[] = { X { &ParmGadget[1], 130, 30, 96, 10, /* next, LTWH */ X GADGHCOMP, /* Flags */ X RELVERIFY | LONGINT, /* Activation */ X STRGADGET | REQGADGET, /* GadgetType */ X (APTR) NULL, NULL, /* rendering */ X &ParmText[0], 0, (APTR) &Parminfo[0], /* "MaxDepth" */ X 0, NULL }, X { &ParmGadget[2], 130, 45, 96, 10, /* next, LTWH */ X GADGHCOMP, X RELVERIFY | LONGINT, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &ParmText[1], 0, (APTR) &Parminfo[1], /* "RangeWidth" */ X 0, NULL }, X { &ParmGadget[3], 130, 60, 96, 10, /* next, LTWH */ X GADGHCOMP, X RELVERIFY | LONGINT, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &ParmText[2], 0, (APTR) &Parminfo[2], /* "Screen width" */ X 0, NULL }, X { NULL, 130, 75, 96, 10, /* next, LTWH */ X GADGHCOMP, X RELVERIFY | LONGINT, X STRGADGET | REQGADGET, X (APTR) NULL, NULL, X &ParmText[3], 0, (APTR) &Parminfo[3], /* "Screen height" */ X 0, NULL } X }; X static struct Requester ParmRequest = { X NULL, 25, 40, 260, 130, 0,0, &PositiveGadget, NULL, X &ParamText, 0, 1 }; X X /* Stuff for the PARAMETERS requester */ X NegativeGadget.NextGadget = &ParmGadget[0]; X Parminfo[0].LongInt = MaxDepth; X Parminfo[1].LongInt = RangeWidth; X Parminfo[2].LongInt = WBWidth; X Parminfo[3].LongInt = WBHeight; X do { X sprintf(Buffer[0], "%ld", Parminfo[0].LongInt); X sprintf(Buffer[1], "%ld", Parminfo[1].LongInt); X sprintf(Buffer[2], "%ld", Parminfo[2].LongInt); X sprintf(Buffer[3], "%ld", Parminfo[3].LongInt); X X window = MyRequest(&ParmRequest, MainWindow); X ID = WaitMyRequest(window); X EndMyRequest(&ParmRequest, window, MainWindow); X if (ID == NEGGADGETID) return; X X NewMaxDepth = Parminfo[0].LongInt; X NewRangeWidth = Parminfo[1].LongInt; X NewWBwidth = Parminfo[2].LongInt; X NewWBheight = Parminfo[3].LongInt; X } while ( NewMaxDepth < 0 || NewMaxDepth > MAXDEPTH || X NewRangeWidth < 0 || NewRangeWidth > MAXDEPTH ); X X if (NewRangeWidth != RangeWidth) InitPenTable(); X MaxDepth = NewMaxDepth; X RangeWidth = NewRangeWidth; X X if ((NewWBwidth != WBWidth || NewWBheight != WBHeight) && Sure()) { X WBWidth = NewWBwidth; X WBHeight = NewWBheight; X ReInitDisplay(); X } X} X Xvoid UpdateCheckmarks() X{ X UpdateOptColorCm(); X UpdateOptDrawResCm(); X UpdateOptViewResCm(); X UpdateOptPriCm(); X UpdateDrwCm(); X} X Xvoid UpdateOptColorCm() X{ X SelectMenu(MENU(OPTMENU, OPTCOL, OCSEL), (bool)(PenTableMode == SELECT)); X SelectMenu(MENU(OPTMENU, OPTCOL, OCMOD), (bool)(PenTableMode == MODULO)); X SelectMenu(MENU(OPTMENU, OPTCOL, OCRAN), (bool)(PenTableMode == RANGES)); X} X Xvoid UpdateOptDrawResCm() X{ X SelectMenu(MENU(OPTMENU, OPTRES, ORNRM), (bool)(PixelStep == 1)); X SelectMenu(MENU(OPTMENU, OPTRES, OR12 ), (bool)(PixelStep == 2)); X SelectMenu(MENU(OPTMENU, OPTRES, OR13 ), (bool)(PixelStep == 3)); X SelectMenu(MENU(OPTMENU, OPTRES, OR14 ), (bool)(PixelStep == 4)); X} X Xvoid UpdateOptViewResCm() X{ X SelectMenu(MENU(OPTMENU, OPTRES, ORHI ), X (bool)((MandelNScreen.ViewModes & HIRES) != 0)); X SelectMenu(MENU(OPTMENU, OPTRES, ORILC), X (bool)((MandelNScreen.ViewModes & LACE) != 0)); X SelectMenu(MENU(OPTMENU, OPTRES, OREHB), X (bool)((MandelNScreen.ViewModes & EXTRA_HALFBRITE) != 0)); X SelectMenu(MENU(OPTMENU, OPTRES, ORBCK), X (bool)((MainWindow->Flags & BORDERLESS) != 0)); X} X Xvoid UpdateOptPriCm() X{ X SelectMenu(MENU(OPTMENU, OPTPRI, OPNOR), (bool)(DrawPri == 0)); X SelectMenu(MENU(OPTMENU, OPTPRI, OPLOW), (bool)(DrawPri < 0)); X} X Xvoid UpdateFunCm() X{ X SelectMenu(MENU(DRWMENU, DRWFUN, DF1), (bool)(FunctionNr == DF1-DF1)); X SelectMenu(MENU(DRWMENU, DRWFUN, DF2), (bool)(FunctionNr == DF2-DF1)); X SelectMenu(MENU(DRWMENU, DRWFUN, DF3), (bool)(FunctionNr == DF3-DF1)); X SelectMenu(MENU(DRWMENU, DRWFUN, DFUPF), (bool)(FunctionNr == DFUPF-DF1)); X SelectMenu(MENU(DRWMENU, DRWFUN, DF5), (bool)(FunctionNr == DF5-DF1)); X} X Xvoid UpdateIPlotCm() X{ X SelectMenu(MENU(DRWMENU, DRWIPL, DINONE), (bool)(IPlotNr == DINONE-DINONE)); X SelectMenu(MENU(DRWMENU, DRWIPL, DIZ) , (bool)(IPlotNr == DIZ-DINONE)); X} X Xvoid UpdateEPlotCm() X{ X SelectMenu(MENU(DRWMENU, DRWEPL, DEDEPTH), (bool)(EPlotNr == DEDEPTH-DEDEPTH)); X SelectMenu(MENU(DRWMENU, DRWEPL, DEZ) , (bool)(EPlotNr == DEZ-DEDEPTH)); X} X Xvoid UpdateDrwCm() X{ X UpdateFunCm(); X UpdateIPlotCm(); X UpdateEPlotCm(); X} SHAR_EOF echo "extracting Jiff.c" sed 's/^X//' << \SHAR_EOF > Jiff.c X X/* X * JIFF.H X */ X X#define XMAX 640 X#define LOXMAX 320 X#define YMAX 200 X#define XASPECT 5 X#define YASPECT 11 X X/* X * EA handy make a long from 4 chars macros redone to work with Aztec X */ X#define MAKE_ID(a, b, c, d)\ X( ((long)(a)<<24) | ((long)(b)<<16) | ((long)(c)<<8) | (long)(d) ) X X/* X * These are the IFF types I deal with X */ X#define FORM MAKE_ID('F', 'O', 'R', 'M') X#define ILBM MAKE_ID('I', 'L', 'B', 'M') X#define BMHD MAKE_ID('B', 'M', 'H', 'D') X#define CMAP MAKE_ID('C', 'M', 'A', 'P') X#define BODY MAKE_ID('B', 'O', 'D', 'Y') X X/* X * And these are the IFF types I ignore but don't squawk about X */ X#define GRAB MAKE_ID('G', 'R', 'A', 'B') X#define DEST MAKE_ID('D', 'E', 'S', 'T') X#define SPRT MAKE_ID('S', 'P', 'R', 'T') X#define CAMG MAKE_ID('C', 'A', 'M', 'G') X#define CRNG MAKE_ID('C', 'R', 'N', 'G') X#define CCRT MAKE_ID('C', 'C', 'R', 'T') X X#define EVEN(x) (((x) + 1) & ~1) X#define MANDEL X X/* X * Some macros for raster memory allocation ... redefine if you're X * sensible and manage memory locally X */ X X#ifndef MANDEL X X/* X * ralloc - raster alloc X */ X# define ralloc(amount) (PLANEPTR)AllocMem((long)(amount), MEMF_CHIP) X/* X * rfree - raster free X */ X# define rfree(pt, amount) FreeMem( (pt), (long)(amount) ) X X#else /* MANDEL */ X X# include <mandel.h> X X/* X * We don't want to allocate a complete raster for the picture, since we X * already have a screen with a window where we want to have it. X * Therefore, we allocate some small buffers, which get blitted into our X * window as soon as they fill up. X */ X# define MAXPLANESIZE 1040L X/* X * ralloc - raster alloc X */ X# define ralloc(amount) (PLANEPTR)AllocMem(MAXPLANESIZE, MEMF_CHIP | MEMF_CLEAR) X/* X * rfree - raster free X */ X# define rfree(pt, amount) FreeMem( (pt), MAXPLANESIZE ) X X#endif /* !MANDEL */ X X/* X * line_bytes = the number of words * 2 (for bytes) a raster line takes up X */ X#define line_bytes(width) ((((width) + 15) >> 3) & ~0x0001) X X/* X * psize - plane size in bytes (an even number) of a raster given width X * and height X */ X#define psize(width, height) ( line_bytes(width)*height) X X/* X * The place to throw excess bits X */ X#define bit_bucket(file, length) fseek(file, (long)EVEN(length), 1) X X Xunion bytes4 { X char b4_name[4]; X LONG b4_type; X}; X Xstruct iff_chunk { X union bytes4 iff_type; X LONG iff_length; X}; X Xstruct form_chunk { X union bytes4 fc_type; /* == FORM */ X LONG fc_length; X union bytes4 fc_subtype; X}; X Xstruct CommodoreAmiga { X struct iff_chunk camg_iffc; /* == CAMG */ X LONG camg_data; X}; X X#ifndef MANDEL /* We have this already in Mandel.h */ Xstruct BitMapHeader { X UWORD w, X h; X UWORD x, X y; X UBYTE nPlanes; X UBYTE masking; X UBYTE compression; X UBYTE pad1; X UWORD transparentColor; X UBYTE xAspect, X yAspect; X WORD pageWidth, X pageHeight; X}; X X/* X * ILBM_info is the structure win_read_iff returns, and is hopefully all X * you need to deal with out of the iff reader routines below X */ Xstruct ILBM_info { X struct BitMapHeader header; X UBYTE cmap[MAXCOL * 3]; X struct BitMap bitmap; X#ifdef MANDEL X struct Mand *mand; X long mandsize; X#endif X}; X X#endif /* !MANDEL */ X X/*- X * I sure wish C function "prototypes" were real and not just ANSI X * X * extern struct ILBM_info *win_read_iff(); X * win_read_iff( char *filename, short just_colors, int MandSize, X * APTR MandPointer ); X * extern void free_planes(); free_planes( struct BitMap *bitmap); X * extern int write_iff(); X * write_iff(char *name, unsigned char *colors, struct Window *window, X * short xoff, short yoff, short compressed); X */ X X/* X * Anyone know where some useful minterms are defined? X */ X#define COPY_MINTERM 0x0C0L X X/*** X X A meditation for the guru from the Diamond Sutra - X X So shall you think of all this fleeting world: X A star at dawn, a bubble in a stream; X A flash of lightning in a summer cloud, X A flickering lamp, a phantom, and a dream. X X***/ X X X/* X * jiff.c Jim Kent's iff - ilbm reader X * X * This is the (sortof) short (sortof) simple no-frills IFF reader to get X * something out of DPaint, Images, or the Animator. It works well with X * the Aztec C compiler. It should work with Lattice but you never know X * until you try it. I haven't. X * X * I've included a simple main program. This is just to make it stand alone. X * Since amiga screen initializations are massive, all it does as is is X * read it into a BitMap, and then free up the BitMap. Should crash it if X * it's gonna crash though. X * X * The main interface to this is through the routine win_read_iff(filename). X * This returns a ILBM_info structure-pointer on success, and NULL on X * failure. It cleans up after itself on failure. X * X * I hope you will find this useful and easy to use. Please forgive my funky X * indentation style? Well at least I'm consistent! (* Run through the X * C-Beautifier by Olaf Seibert !! *) X * X * To demonstrate what a nice guy I am even though I'm far from wild about X * the IFF standard I'm placing this in the public domain. When you X * remove the DEBUG and PARANOID definitions the code is only 1536 bytes X * long. X * X * -Jim Kent April 22, 1986 X */ X X X#include <stdio.h> X#include <exec/types.h> X#include <exec/memory.h> X#include <graphics/gfx.h> X#include <libraries/dos.h> X#include <intuition/intuition.h> X/* #include "jiff.h" */ X X X/* X * This is an all too common state of software development. Get rid of X * this define as soon as it runs. X */ X#undef DEBUG X/* #define DEBUG/* */ X X/* X * This is the normal state of software development. Seriously undefine X * this to make it shut up about errors and reduce code size half way X * through beta testing... X */ X#undef PARANOID X X/* X * This is nice if you want to use a debugger on the STATIC data and X * routines in this file. Redefine only if you don't need a debugger. X */ X X#ifdef DEBUG X# undef STATIC X# define STATIC X#endif X XSTATIC struct ILBM_info *win_read_ilbm(); XSTATIC struct ILBM_info *win_read_body(); X X/* X * OK this code is almost re-entrant. Pass this guy from above to make it X * really re-entrant. (Why do you need a reentrant ILBM reader though?? X * Maybe for Dale ... ) Well, look in the IFF specs for instance... [Olaf X * Seibert, KosmoSoft] X */ XSTATIC struct ILBM_info root_info; /* static so get initialized to X * zero */ X X X#ifdef PARANOID X/* X * a little paranoid routine that say's where we got before EOF X */ XSTATIC void Xiff_truncated(where) Xint where; X{ X printf("ILBM truncated %d\n", where); X free_planes(&root_info.bitmap); X} X X#endif PARANOID X X Xstruct ILBM_info * Xwin_read_iff(name, just_colors, window, MandSize, MandPointer) Xchar *name; Xshort just_colors; Xstruct Window *window; Xint MandSize; XAPTR MandPointer; X{ X struct ILBM_info *info = &root_info; X FILE *file; X struct form_chunk chunk; X X if ((file = fopen(name, "r")) == 0) { X#ifdef PARANOID X printf("couldn't fopen %s to read\n", name); X#endif PARANOID X return NULL; X } X if (fread(&chunk, sizeof (struct form_chunk), 1, file) != 1) { X#ifdef PARANOID X iff_truncated(0); X#endif PARANOID X fclose(file); X return NULL; X } X if (chunk.fc_type.b4_type != FORM) { X#ifdef PARANOID X printf("not a FORM - %s\n", name); X#endif PARANOID X fclose(file); X return NULL; X } X if (chunk.fc_subtype.b4_type != ILBM) { X#ifdef PARANOID X printf("FORM not an ILBM - %s\n", name); X#endif PARANOID X fclose(file); X return NULL; X } X#ifdef DEBUG X printf("FORM %ld ILBM\n", chunk.fc_length); X#endif DEBUG X X#ifdef MANDEL X info->mand = (struct Mand *) MandPointer; X info->mandsize = MandSize; X info->mand->MandID = 0; /* we have not yet read it */ X#endif X X info = win_read_ilbm(file, info, chunk.fc_length - sizeof (chunk), X just_colors, window); X#ifdef DEBUG X printf("info = %lx\n", info); X#endif DEBUG X X#ifdef MANDEL X /* X * Backward compatibility with non-standard code: We may want to read X * the extra MAND if we have not read it by now. X */ X if (info && MandSize && info->mand->MandID != MAND) { X fread(MandPointer, 1, MandSize, file); X info->mand->Size -= 2 * sizeof (long); /* patch bug */ X } X#endif MANDEL X X fclose(file); X X return info; X} X XSTATIC struct ILBM_info * Xwin_read_ilbm(file, info, length, just_colors, window) XFILE *file; Xstruct ILBM_info *info; Xlong length; Xshort just_colors; Xstruct Window *window; X{ X struct iff_chunk chunk; X int i; X long read_in = 0; X int got_header = FALSE; /* To make sure gots the header X * first */ X int got_cmap = FALSE; /* Make sure get cmap before X * "BODY" */ X X /* X * Make sure the Planes are all NULL so can free up memory easily on X * error abort X */ X for (i = 0; i < 8; i++) X info->bitmap.Planes[i] = NULL; X X while (read_in < length) { X if (fread(&chunk, sizeof (chunk), 1, file) != 1) { X#ifdef PARANOID X iff_truncated(1); X#endif PARANOID X return NULL; X } X switch (chunk.iff_type.b4_type) { X case BMHD: X#ifdef DEBUG X printf("\tBMHD %ld\n", chunk.iff_length); X#endif DEBUG X if (fread(&info->header, sizeof (info->header), 1, file) != 1) { X#ifdef PARANOID X iff_truncated(2); X#endif PARANOID X return NULL; X } X got_header = TRUE; X break; X case CMAP: X#ifdef DEBUG X printf("\tCMAP %ld\n", chunk.iff_length); X#endif DEBUG X if (!got_header) { X#ifdef PARANOID X printf("CMAP before BMHD\n"); X#endif PARANOID X return NULL; X } X if (chunk.iff_length <= 3 * MAXCOL) { X if (fread(info->cmap, (int) chunk.iff_length, 1, file) != 1) { X#ifdef PARANOID X iff_truncated(3); X#endif PARANOID X return NULL; X } X } else { X#ifdef PARANOID X printf("warning, more than %d colors in ILBM CMAP\n", X MAXCOL); X#endif PARANOID X if (fread(info->cmap, (int) 3 * MAXCOL, 1, file) != 1) { X#ifdef PARANOID X iff_truncated(4); X#endif PARANOID X return NULL; X } X bit_bucket(file, chunk.iff_length - 3 * MAXCOL); X } X got_cmap = TRUE; X if (just_colors) X return info; X break; X case MAND: X#ifdef DEBUG X printf("\tMAND %ld\n", chunk.iff_length); X#endif DEBUG X if (chunk.iff_length + sizeof (chunk) <= info->mandsize) { X if (fread((char *) info->mand + sizeof (chunk), X (int) chunk.iff_length, 1, file) != 1) { X#ifdef DEBUG X printf("fread MAND fails; filepos %ld ferror %d\n", X (long) ftell(file), (int) ferror(file)); X#endif X return NULL; X } X *(struct iff_chunk *) info->mand = chunk; X X /* X * skip padding byte X */ X if (chunk.iff_length & 1) X getc(file); X } else { X#ifdef DEBUG X printf("skipping MAND; too large for buffer (%ld)\n", X (long) info->mandsize); X#endif X bit_bucket(file, chunk.iff_length); X } X break; X case BODY: X if (!got_cmap) { X#ifdef PARANOID X printf("BODY before CMAP\n"); X#endif PARANOID X return NULL; X } X#ifdef DEBUG X printf("\tBODY %ld\n", chunk.iff_length); X#endif DEBUG X return win_read_body(file, info, chunk.iff_length, window); X X default: /* Squawk about unknown types if PARANOID */ X#ifdef PARANOID X printf("\t unknown type %lx of b4_type\n", chunk.iff_type.b4_type); X case GRAB: /* Ignore documented but unwanted types */ X case DEST: X case SPRT: X case CAMG: X case CRNG: X case CCRT: X#endif PARANOID X bit_bucket(file, chunk.iff_length); X break; X } X read_in += EVEN(chunk.iff_length) + sizeof (chunk); X } X#ifdef PARANOID X printf("no BODY in ILBM\n"); X#endif PARANOID X return NULL; X} X X X XSTATIC struct ILBM_info * Xwin_read_body(file, info, length, window) XFILE *file; Xregister struct ILBM_info *info; Xlong length; Xstruct Window *window; X{ X struct ILBM_header *header; X struct BitMap *bm; X int i, X j; X int rlength; X int plane_offset; X ULONG YSize, X DestX, X DestY; X X#ifdef DEBUG X printf("win_read_body( %lx %lx %ld)\n", file, info, length); X#endif DEBUG X X#ifdef PARANOID X /* X * When paranoid do a little error checking first ... fail fast! X */ X if (info->header.nPlanes > 8) { X printf("Whoa, woe Dale only speaks 8 planes boy, not %d\n", X info->header.nPlanes); X return NULL; X } X#endif PARANOID X X /* X * Ok a little more error checking X */ X if (info->header.compression != 0 && info->header.compression != 1) { X#ifdef PARANOID X printf("unrecognized compression type %d\n", info->header.compression); X#endif PARANOID X return NULL; X } X /* X * Set up the bitmap part that doesn't involve memory allocation first X * - hey this part does get done, and let's be optimistic... X */ X info->bitmap.BytesPerRow = line_bytes(info->header.w); X info->bitmap.Rows = info->header.h; X info->bitmap.Depth = info->header.nPlanes; X info->bitmap.Flags = info->bitmap.pad = 0; X X rlength = info->bitmap.Rows * info->bitmap.BytesPerRow; X X for (i = 0; i < info->header.nPlanes; i++) { X if ((info->bitmap.Planes[i] = ralloc(rlength)) == NULL) { X#ifdef PARANOID X printf("couldn't alloc plane %d in win_read_body\n", i); X#endif PARANOID X free_planes(&info->bitmap); X return NULL; X } X } X X plane_offset = 0; X YSize = (MAXPLANESIZE / info->bitmap.BytesPerRow); X if (window->Flags & GIMMEZEROZERO) { X DestX = 0; X DestY = 0; X } else { X DestX = window->BorderLeft; X DestY = window->BorderTop; X } X X for (i = 0; i < info->bitmap.Rows; i++) { X /* X * This test should be in the inner loop for shortest code, in the X * outer loop for greatest speed, so sue me I compromised X */ X if (info->header.compression == 0) { X for (j = 0; j < info->bitmap.Depth; j++) { X if (fread(info->bitmap.Planes[j] + plane_offset, X info->bitmap.BytesPerRow, 1, file) != 1) { X#ifdef PARANOID X iff_truncated(6); X#endif PARANOID X free_planes(&info->bitmap); X return NULL; X } X } X } else { X register char *dest, X value; X register int so_far, X count; /* How much have unpacked so far */ X X for (j = 0; j < info->bitmap.Depth; j++) { X so_far = info->bitmap.BytesPerRow; X dest = (char *) info->bitmap.Planes[j] + plane_offset; X while (so_far > 0) { X if ((value = getc(file)) == 128) { X#ifdef DEBUG X printf("NOP\n"); X#endif DEBUG X } else if (value > 0) { X count = (int) value + 1; X so_far -= count; X if (fread(dest, count, 1, file) != 1) { X#ifdef PARANOID X iff_truncated(7); X#endif PARANOID X free_planes(&info->bitmap); X return NULL; X } X dest += count; X } else { X count = (int) -value + 1; X so_far -= count; X value = getc(file); X while (--count >= 0) /* This is fastest loop on X * the 68000 */ X *dest++ = value; X } X } X if (so_far != 0) { X#ifdef PARANOID X printf("compression quite screwed up, aborting %d\n", so_far); X#endif PARANOID X free_planes(&info->bitmap); X return NULL; X } X } X } X plane_offset += info->bitmap.BytesPerRow; X X if (plane_offset > MAXPLANESIZE - info->bitmap.BytesPerRow) { X BltBitMapRastPort(&info->bitmap, 0L, 0L, X window->RPort, DestX, DestY, X info->bitmap.BytesPerRow * 8L, YSize, X COPY_MINTERM); X plane_offset = 0; X DestY += YSize; X } X } X X if (plane_offset) { X BltBitMapRastPort(&info->bitmap, 0L, 0L, X window->RPort, DestX, DestY, X info->bitmap.BytesPerRow * 8L, X (long) plane_offset / info->bitmap.BytesPerRow, X COPY_MINTERM); X } X if (length & 1) { X /* X * Skip padding byte X */ X getc(file); X } X free_planes(&info->bitmap); X return info; X} X X Xvoid Xfree_planes(bmap) Xregister struct BitMap *bmap; X{ X PLANEPTR plane; X long length; X short i; X X length = bmap->BytesPerRow * bmap->Rows; X X for (i = bmap->Depth; --i >= 0;) { X if ((plane = bmap->Planes[i]) != NULL) { X rfree(plane, length); X bmap->Planes[i] = NULL; X } X } X} X X X X X X X#undef DEBUG X/* #define DEBUG/* */ X#undef PARANOID X X/*----------------------------------------------------------------------* X * jpacker.c Convert data to "cmpByteRun1" run compression. X * X * pack_row() is an adaptation of PackRow() X * by Jerry Morrison and Steve Shaw, Electronic Arts, X * modified and tweaked by Jim Kent, Dancing Flame 05/02/86 X * X * control bytes: X * [0..127] : followed by n+1 bytes of data. X * [-1..-127] : followed by byte to be repeated(-n)+1 times. X * -128 : NOOP. X * X * X * write_iff() is the only function you can access in this module. X *----------------------------------------------------------------------*/ X X/*- X#include <exec/types.h> X#include <graphics/gfx.h> X#include <stdio.h> X#include "jiff.h" X*/ X X#define DUMP 0 X#define RUN 1 X X#define MINRUN 3 X#define MAXRUN 128 X#define MAXDAT 128 X X/* X * pack_row - pass source line pointer, length of line, and file. Returns X * # of bytes after compression. Returns 0 on write error. Pass file = X * NULL to just find out length, otherwise will write compressed row to X * file. X */ X XSTATIC unsigned int Xpack_row(file, source, size) XFILE *file; Xchar *source; Xint size; X{ X char c, X lastc = '\0'; X short mode = DUMP; X short nbuf = 0; /* Number of chars in buffer */ X short rstart = 0; /* Buffer index current run starts */ X unsigned short putsize; X X#if OLD X char buf[MAXDAT * 3 / 2]; /* I think MAXDAT+1 would X * suffice */ X X#else X /* X * And I think that buf can be changed into a pointer to the source X * line, to the beginning of a dump. Saves stack space and copying. X */ X char *buf; X X#endif X X putsize = 0; X#if OLD X buf[0] = lastc = *source++; /* So have valid lastc */ X#else X buf = source; X lastc = *source++; /* So have valid lastc */ X#endif X nbuf = 1; X size--; /* Since one byte eaten */ X X X for (; size; --size) { X#if OLD X buf[nbuf++] = c = *source++; X#else X nbuf++; X c = *source++; X#endif X switch (mode) { X case DUMP: X /* X * If the buffer is full, write the length byte, then the data X */ X if (nbuf > MAXDAT) { X if (file != NULL) { X if (putc(nbuf - 2, file) == EOF) X return 0; X if (fwrite(buf, nbuf - 1, 1, file) != 1) X return 0; X } X putsize += nbuf; X#if OLD X buf[0] = c; X#else X buf = source - 1; /* Undo the previous source++ */ X#endif X nbuf = 1; X rstart = 0; X break; X } X if (c == lastc) { X if (nbuf - rstart >= MINRUN) { X if (rstart > 0) { X if (file != NULL) { X if (putc(rstart - 1, file) == EOF) X return 0; X if (fwrite(buf, rstart, 1, file) != 1) X return 0; X } X putsize += rstart + 1; X } X mode = RUN; X } else if (rstart == 0) X mode = RUN; X /* X * No dump in progress, so can't lose by making these 2 a X * run. X */ X } else X rstart = nbuf - 1; /* First of run */ X break; X X case RUN: X if ((c != lastc) || (nbuf - rstart > MAXRUN)) { X /* X * Output run X */ X if (file != NULL) { X if (putc(-(nbuf - rstart - 2), file) == EOF) X return 0; X if (putc(lastc, file) == EOF) X return 0; X } X putsize += 2; X#if OLD X buf[0] = c; X#else X buf = source - 1; /* Undo the previous source++ */ X#endif X nbuf = 1; X rstart = 0; X mode = DUMP; X } X break; X } X X lastc = c; X } X X switch (mode) { X case DUMP: X if (file != NULL) { X if (putc(nbuf - 1, file) == EOF) X return 0; X if (fwrite(buf, nbuf, 1, file) != 1) X return 0; X } X putsize += nbuf + 1; X break; X case RUN: X if (file != NULL) { X if (putc(-(nbuf - rstart - 1), file) == EOF) X return 0; X if (putc(lastc, file) == EOF) X return 0; X } X putsize += 2; X break; X } X return putsize; X} X X/* X * write_row - pass source line pointer, length of line, and file. Returns X * # of bytes after not compressing. Returns 0 on write error. Pass file X * = NULL to just find out length, otherwise will write non-compressed row X * to file. X */ X XSTATIC unsigned int Xwrite_row(file, source, size) XFILE *file; Xchar *source; Xint size; X{ X if (file) { X if (fwrite(source, size, 1, file) != 1) X return 0; X } X return size; X} X X XSTATIC unsigned long Xpack_window(file, window, writer) XFILE *file; Xregister struct Window *window; Xregister unsigned int (*writer) (); X X{ X unsigned short i, X j; X unsigned row_length; X unsigned long compressed_length; X unsigned plane_offset; X int BytesPerRow; X int YSize; X ULONG SrcX, X SrcY; X struct RastPort Rp; X struct BitMap Bitmap; X X#ifdef DEBUG X printf("pack_window( %lx %lx)\n", file, window); X#endif DEBUG X X compressed_length = 0; X plane_offset = 0; X X BytesPerRow = line_bytes(window->GZZWidth); X Bitmap.Depth = window->WScreen->BitMap.Depth; X if (window->Flags & GIMMEZEROZERO) { X SrcX = 0; X SrcY = 0; X } else { X SrcX = window->BorderLeft; X SrcY = window->BorderTop; X } X YSize = MAXPLANESIZE / BytesPerRow; X InitBitMap(&Bitmap, (ULONG) Bitmap.Depth, X (ULONG) (8 * BytesPerRow), (ULONG) YSize); X X /* X * Make sure the Planes are all NULL so can free up memory easily on X * error abort X */ X for (i = 0; i < 8; i++) X Bitmap.Planes[i] = NULL; X X for (i = 0; i < Bitmap.Depth; i++) { X if ((Bitmap.Planes[i] = ralloc(MAXPLANESIZE)) == NULL) { X#ifdef DEBUG X printf("couldn't alloc plane %d in pack_window\n", i); X printf("pack_window: aborting; free_planes\n"); X#endif X free_planes(&Bitmap); X return 0; X } X } X InitRastPort(&Rp); X Rp.BitMap = &Bitmap; X#ifdef DEBUG X printf("pack_window BytesPerRow=%ld Depth=%ld\n", (long) BytesPerRow, X (long) Bitmap.Depth); X#endif X X for (i = 0; i < window->GZZHeight; i++) { X if (plane_offset == 0) { X#ifdef DEBUG X printf("pack_window ClipBlit SrcX=%ld SrcY=%ld YSize=%ld\n", X SrcX, SrcY, (ULONG) YSize); X#endif X#define DestX 0L X#define DestY 0L X ClipBlit(window->RPort, SrcX, SrcY, X &Rp, DestX, DestY, X (ULONG) window->GZZWidth, (ULONG) YSize, X COPY_MINTERM); X#undef DestX X#undef DestY X SrcY += YSize; X } X for (j = 0; j < Bitmap.Depth; j++) { X if ((row_length = (*writer) (file, Bitmap.Planes[j] + plane_offset, X BytesPerRow)) == 0) { X#ifdef DEBUG X printf("error packing row %d plane %d\n", i, j); X printf("pack_window: aborting; free_planes\n"); X#endif X free_planes(&Bitmap); X return 0; X } X compressed_length += row_length; X } X X plane_offset += BytesPerRow; X if (plane_offset > MAXPLANESIZE - BytesPerRow) X plane_offset = 0; X } X X#ifdef DEBUG X printf("pack_window: free_planes\n"); X#endif X free_planes(&Bitmap); X X if (compressed_length & 1) {/* Check to see odd length */ X if (file != NULL) { X if (putc(0, file) == EOF) { X return 0; X } X } X /* X * compressed_length++; Deleted!!! Padding should NOT be included X * in the chunk size !!! X */ X } X return compressed_length; X} X Xint Xwrite_iff(name, colors, window, xoff, yoff, compressed, MandSize, MandPointer) Xchar *name; Xunsigned char *colors; Xregister struct Window *window; Xshort xoff, X yoff; Xshort compressed; Xint MandSize; XAPTR MandPointer; X{ X FILE *file; X struct form_chunk chunk; X struct iff_chunk ichunk; X struct BitMapHeader header; X long bits_size; X short i; X int width = 0; X int Depth; X int BytesPerRow; X X#ifdef DEBUG X printf("write_iff\n"); X#endif X X if ((file = fopen(name, "w")) == 0) { X#ifdef PARANOID X printf("couldn't fopen %s to write\n", name); X#endif PARANOID X goto abort; X } X /* X * Say its a FORM ILBM X */ X chunk.fc_type.b4_type = FORM; X chunk.fc_subtype.b4_type = ILBM; X#ifdef MANDEL X chunk.fc_length = 4 + 3 * sizeof (struct iff_chunk) + MAXCOL * 3 + X sizeof (struct BitMapHeader) + sizeof (struct CommodoreAmiga) + MandSize; X#else X chunk.fc_length = 4 + 3 * sizeof (struct iff_chunk) + MAXCOL * 3 + X sizeof (struct BitMapHeader) + sizeof (struct CommodoreAmiga); X#endif MANDEL X if (window) { X width = window->GZZWidth; X BytesPerRow = line_bytes(width); X Depth = window->WScreen->BitMap.Depth; X if (compressed) { X#ifdef DEBUG X printf("write_iff: call pack_window for sizing\n"); X#endif X if ((bits_size = pack_window(NULL, window, pack_row)) == 0) X goto abort; X } else { X bits_size = BytesPerRow * window->GZZHeight * Depth; X } X chunk.fc_length += bits_size; X if (bits_size & 1) X chunk.fc_length++; X } X if (fwrite(&chunk, sizeof (chunk), 1, file) != 1) X goto abort; X X /* X * Here comes a BitMapHeader X */ X { X struct iff_chunk ichunk; X X ichunk.iff_type.b4_type = BMHD; X ichunk.iff_length = sizeof (header); X if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1) X goto abort; X } X X /* X * Initialize the BitMapHeader to normal values X */ X header.masking = 0; X header.pad1 = 0; X header.transparentColor = 0; X if (compressed) X header.compression = 1; X else X header.compression = 0; X header.pageWidth = width; X header.pageHeight = window ? window->GZZHeight : YMAX; X header.xAspect = width > LOXMAX ? XASPECT : XASPECT * 2; X header.yAspect = YASPECT; X /* X * If it's not just a color map give the dimensions of rasters X */ X if (window) { X header.w = width; X header.h = window->GZZHeight; X header.nPlanes = Depth; X header.x = xoff; X header.y = yoff; X } X if (fwrite(&header, sizeof (header), 1, file) != 1) X goto abort; X X /* X * Squirt out the color map X */ X { X struct iff_chunk ichunk; X X ichunk.iff_type.b4_type = CMAP; X ichunk.iff_length = MAXCOL * 3; X if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1) X goto abort; X if (fwrite(colors, (int) 3 * MAXCOL, 1, file) != 1) X goto abort; X } X X /* X * Write a CAMG chunk with ViewPort modes X */ X { X struct CommodoreAmiga camg; X X camg.camg_iffc.iff_type.b4_type = CAMG; X camg.camg_iffc.iff_length = sizeof (camg) - sizeof (camg.camg_iffc); X camg.camg_data = window->WScreen->ViewPort.Modes; X if (fwrite(&camg, sizeof (camg), 1, file) != 1) X goto abort; X } X X#ifdef MANDEL X /* X * We want to write our own private MAND chunk X */ X if (MandSize) { X if (fwrite(MandPointer, MandSize, 1, file) != 1) X goto abort; X } X#endif MANDEL X X /* X * If they be bits then squirt out the bits X */ X if (window) { X struct iff_chunk ichunk; X X ichunk.iff_type.b4_type = BODY; X ichunk.iff_length = bits_size; X if (fwrite(&ichunk, sizeof (ichunk), 1, file) != 1) X goto abort; X#ifdef DEBUG X printf("write_iff: call pack_window for real\n"); X#endif X if (compressed) { X if (pack_window(file, window, pack_row) == 0) X goto abort; X } else { X if (pack_window(file, window, write_row) == 0) X goto abort; X } X } X fclose(file); X X return 1; Xabort: X#ifdef DEBUG X printf("write_iff: aborting !!!\n"); X#endif X fclose(file); X return 0; X} X X X/* X * put_ea_cmap given an ea-type color map: X * X * an array of unsigned chars of form ea_cmap[] = {r, g, b, r, g, b...} X * X * turn it into an amiga-type color map: X * X * an array of unsigned short of form amiga_cmap = {0xrgb, 0xrgb, ...} X * X * and then tell Dale this is the colors we want for our viewport X */ X Xvoid Xput_ea_cmap(ea_cmap, colors, Screen) Xunsigned char *ea_cmap; Xint colors; Xstruct Screen *Screen; X{ X unsigned short amy_cmap[MAXCOL]; X register int i; X register short color; X X if (colors > MAXCOL) /* Color clipping */ X colors = MAXCOL; X for (i = 0; i < colors; i++) { X color = (*ea_cmap++ & 0xF0) << 4; X color |= *ea_cmap++ & 0xF0; X color |= (*ea_cmap++ & 0xF0) >> 4; X amy_cmap[i] = color; X } X LoadRGB4(&Screen->ViewPort, amy_cmap, (long) colors); X} X Xvoid Xget_ea_cmap(ea_cmap, colors, Screen) Xunsigned char *ea_cmap; Xint colors; Xstruct Screen *Screen; X{ X register long i; X register unsigned short rgb; X X if (colors > MAXCOL) /* Color clipping */ X colors = MAXCOL; X for (i = 0; i < colors; i++) { X rgb = GetRGB4(Screen->ViewPort.ColorMap, i); X *ea_cmap++ = (rgb & 0xF00) >> 4; X *ea_cmap++ = (rgb & 0x0F0); X *ea_cmap++ = (rgb & 0x00F) << 4; X } X} SHAR_EOF echo "End of archive 2 (of 4)" # if you want to concatenate archives, remove anything after this line exit