[comp.sources.amiga] v89i143: mandel - mandelobrot generator v180, Part02/04

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