/* * MandelVroom 2.0 * * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA * * All rights reserved. * * Permission is hereby granted to distribute this program's source * executable, and documentation for non-comercial purposes, so long as the * copyright notices are not removed from the sources, executable or * documentation. This program may not be distributed for a profit without * the express written consent of the author Kevin L. Clague. * * This program is not in the public domain. * * Fred Fish is expressly granted permission to distribute this program's * source and executable as part of the "Fred Fish freely redistributable * Amiga software library." * * Permission is expressly granted for this program and it's source to be * distributed as part of the Amicus Amiga software disks, and the * First Amiga User Group's Hot Mix disks. * * contents: this file contains main(), Workbench support code, and * miscellaneous funtions. */ #define COLORCYCLE #include "mandp.h" extern struct NewScreen NewScreen; extern struct Picture *ZoomedPict; extern UBYTE ContOpen, PaletteOpen, CycleOpen, HistOpen; struct Window *CurWind; struct Picture *CurPict; struct Window *ClosedWind; UBYTE QuitScreen; SHORT MouseX,MouseY; LONG mSigBit, mSigMask; /* Finished Signal */ struct Task *mTask; extern int Num_vp_Colors; extern LONG MainPri, TaskPri; extern struct WBStartup *WBenchMsg; struct IntuiMessage *ParseMsg; BYTE FromWB; /* * Do it all */ main (argc, argv) int argc; char *argv[]; { struct WBArg *arg; char *LoadFile; char *NameFromLock(); struct Process *Process; int i, rc; AllocArrows(); ToggleEnableds(); Menu[CALCULATEMENU].Flags ^= MENUENABLED; MainPri = FindTask(0)->tc_Node.ln_Pri; TaskPri = MainPri - 1; FromWB = argc == 0; Process = (struct Process *) FindTask(0); /* Set up Mandelbrot Pict */ if (OpenLibs() == 0 && OpenTasks() == 0 && OpenDisp() == 0) { DefaultColors(); if (FromWB) { argc = WBenchMsg->sm_NumArgs; arg = WBenchMsg->sm_ArgList; } if (argc == 1) { if (SetPreset( 0 ) == UNSUCCESSFUL) AndDie( "Can't open preset 0. No RAM\n" ); } else { rc = SUCCESSFUL; /* get all the projects indicated */ for (i = 1; i < argc && rc == SUCCESSFUL; i++) { if (FromWB) { arg++; rc = LoadPicture( NameFromLock( (struct Lock *) arg->wa_Lock, arg->wa_Name ) ); } else { rc = LoadPicture( NameFromLock( (struct Lock *) Process->pr_CurrentDir), argv[i]); } if (rc == UNSUCCESSFUL) { DispErrMsg("Failure opening project",0); } else { if (CurPict->Flags & NO_RAM_GENERATE) rc = UNSUCCESSFUL; } } } DoBrot(); } #ifdef CHECK_TASK_STACK PrintStack(); #endif ThrowPicts(); CloseTasks(); CloseDisp(); CloseLibs(); FreeArrows(); #ifdef MEM_DEBUG TERMINATE(); #endif } char * NameFromLock(Lock,WBName) struct Lock *Lock; char *WBName; { struct FileInfoBlock *fib; struct Lock *lock,*newlock; static char cwd[255]; int i,len; char *name; i = 255; cwd[255] = '\0'; len = strlen( WBName ); i -= len; movmem(WBName, cwd + i, (unsigned) len); fib = (struct FileInfoBlock *) safeAllocMem( (long) sizeof(struct FileInfoBlock), MEMF_CLEAR ); if (fib == NULL) { DispErrMsg("Can't Allocate FileInfoBlock",0); return(NULL); } lock = Lock; while (lock) { /* while the lock is good */ newlock = (struct Lock *) ParentDir(lock); (void) Examine(lock, fib); name = fib->fib_FileName; if (*name == '\0') name = "ram"; len = strlen(name); if (newlock) { i -= len + 1; movmem(name, cwd + i, (unsigned) len); cwd[i+len] = '/'; } else { i -= len + 1; movmem(name, cwd + i, (unsigned) len); cwd[i + len] = ':'; } if (lock != Lock) UnLock(lock); lock = newlock; } movmem(cwd + i, cwd, (unsigned) 256 - i); FreeMem( (char *) fib, (long) sizeof(struct FileInfoBlock) ); return( cwd ); } /* * Wait and process a message */ DoBrot() { LONG bSigMask = 1 << BackWind->UserPort->mp_SigBit; LONG rc; while (QuitScreen == FALSE) { rc = Wait( bSigMask | mSigMask ); if (rc & bSigMask) DoMsg(); if (rc & mSigMask) ServiceTasks(); } if (CurPict == NULL) { GetCurPict(); } } /* * if there is a message, process it */ DoMsg() { register SHORT MouseMoved, Activate; register struct IntuiMessage *message; register struct IntuiMessage *CopyMsg; struct IntuiMessage LocalMsg; struct IntuiMessage MouseMsg; struct IntuiMessage ActiveMsg; MouseMoved = FALSE; Activate = FALSE; while (message = (struct IntuiMessage *) GetMsg( BackWind->UserPort)) { if (message->Class == MOUSEMOVE) { CopyMsg = &MouseMsg; MouseMoved = TRUE; } else if (message->Class == ACTIVEWINDOW) { CopyMsg = &ActiveMsg; Activate = TRUE; } else { CopyMsg = &LocalMsg; } CopyMsg->Class = message->Class; CopyMsg->Code = message->Code; CopyMsg->IAddress = message->IAddress; CopyMsg->MouseX = message->MouseX; CopyMsg->MouseY = message->MouseY; MouseX = message->MouseX; MouseY = message->MouseY; CopyMsg->IDCMPWindow = message->IDCMPWindow; /* got a message */ ReplyMsg(message); if (CopyMsg->Class != MOUSEMOVE && CopyMsg->Class != ACTIVEWINDOW) { if (CopyMsg->Class == MOUSEBUTTONS && MouseMoved) { ProcessCmd( &MouseMsg ); MouseMoved = FALSE; } ProcessCmd( CopyMsg ); } } /* If the Mouse moved during the loop, respond to it now */ if ( MouseMoved ) { ProcessCmd( &MouseMsg ); } /* If there was one or more WindowActive then service the last one */ if ( Activate ) { ProcessCmd( &ActiveMsg ); } } /* DoMsg */ UBYTE ScreenSizeChanged; MaybeNewScreen() { int rc; extern USHORT NewViewModes; extern UBYTE NewDepth; #define VIEW_MODE_MASK (HIRES|INTERLACE|EXTRA_HALFBRITE) if (screen->BitMap.Depth != NewDepth || (screen->ViewPort.Modes & VIEW_MODE_MASK) != NewViewModes || ScreenSizeChanged ) { if (CheckNewScreen( NewViewModes ) == SUCCESSFUL) { NewScreen.ViewModes = NewViewModes; NewScreen.Depth = NewDepth; CloseDisp(); (void) OpenDisp(); rc = 1; } else { DispErrMsg("Can't change screen. Projects too big",0); rc = 0; } ScreenSizeChanged = 0; } else { rc = 0; } NewViewModes = NewScreen.ViewModes; NewDepth = NewScreen.Depth; return( rc ); } ActivatePict( Window ) register struct Window *Window; { SetMouse( Window ); CurWind = Window; DisplayMsg(); } CloseWinds( Window ) register struct Window *Window; { register struct Picture *NewPict; extern UBYTE ContOpen, OrbitOpen, StatsOpen; ForceNormPointer(); if ( Window == ContWind) { CloseContWind(); ContOpen = 0; } else if ( Window == HistWind) { CloseHistWind(); HistOpen = 0; } else if ( Window == PalWind) { ClosePalWind(); PaletteOpen = 0; } else if ( Window == CycWind) { CloseCycWind(); CycleOpen = 0; } else if ( Window == HelpWind) { CloseHelpWind(0,NULL); } else if ( Window == StatsWind) { CloseStatsWind(); StatsOpen = 0; } else if ( Window == OrbitWind) { CloseOrbitWind(); OrbitOpen = 0; } else { if ( NewPict = (struct Picture *) Window->UserData ) { /* Erase the Zoom box if it is open */ if (NewPict->DrawPict) ZoomOnOff( NewPict ); /* Undo any pictures that have zoom boxes open in this window */ CloseZoomedPicts( NewPict ); ThrowPict( NewPict ); /* Figure out who is next */ GetCurPict(); if (CurPict == NULL) { /* Close the contour window */ CloseContWind(); ContOpen = 0; ClosePalWind(); PaletteOpen = 0; CloseCycWind(); CycleOpen = 0; CloseOrbitWind(); OrbitOpen = 0; CloseHistWind(); HistOpen = 0; CloseStatsWind(); StatsOpen = 0; } else { LoadRGB4(vp, CurPict->RGBs, (long) Num_vp_Colors); RefreshContours(); } } } } ToggleEnableds( ) { extern struct MenuItem ProjectItems[]; extern struct MenuItem DisplayItems[]; extern struct MenuItem SpecialItems[]; extern struct Menu Menu[]; ProjectItems[CURITEM].Flags ^= ITEMENABLED; ProjectItems[SAVEPROJ].Flags ^= ITEMENABLED; ProjectItems[CLOSEPROJ].Flags ^= ITEMENABLED; ProjectItems[SAVEILBM].Flags ^= ITEMENABLED; DisplayItems[COLORITEM].Flags ^= ITEMENABLED; DisplayItems[CYCLEITEM].Flags ^= ITEMENABLED; DisplayItems[CONTOURITEM].Flags ^= ITEMENABLED; DisplayItems[AUTOCNTRITEM].Flags ^= ITEMENABLED; DisplayItems[HISTOGRAMITEM].Flags ^= ITEMENABLED; DisplayItems[BORDERITEM].Flags ^= ITEMENABLED; Menu[CALCULATEMENU].Flags ^= MENUENABLED; SpecialItems[ORBITITEM].Flags ^= ITEMENABLED; SpecialItems[ORBITMATHITEM].Flags ^= ITEMENABLED; SpecialItems[MAXORBITEM].Flags ^= ITEMENABLED; } BorderWindow( Window ) register struct Window *Window; { register struct RastPort *Rp; register LONG Bottom, Right; register struct Picture *Pict; register LONG Max; struct Gadget *Sizing; int Top; extern struct Gadget *OrbitResize; Pict = (struct Picture *) Window->UserData; if (Pict && (Pict->Flags & BORDERLESS_PROJ)) return; Bottom = Window->Height - 1; Right = Window->Width - 1; Rp = Window->RPort; if (Pict || Window == OrbitWind) { if (Pict) { ObtainSemaphore( &Pict->WindowSemi ); Sizing = Pict->SizingGadget; } else { Sizing = OrbitResize; } SetAPen( Rp, NORMALPEN ); Move( Rp, LEFTMARG, Bottom - 1); Draw( Rp, Right - RIGHTMARG/2 - 1, Bottom - 1); if (Pict) { if (Pict->pNode.ln_Type == MANDPICT) { Max = 10+4*14; } else { Max = 10+5*14; } } else { Max = 10+1*14; } if ( Bottom > Max ) { RectFill( Rp, Right - RIGHTMARG + 1, Max, Right - 1, Bottom - 1); RefreshGadgets( Window->FirstGadget, Window, NULL); } /* Bevel the resize gadget edges */ Max = Right + Sizing->LeftEdge; Top = Bottom+ Sizing->TopEdge-1+YScale; SetAPen( Rp, HIGHLIGHTPEN ); Move(Rp, Max, Bottom-2+YScale); Draw(Rp, Max, Top); Draw(Rp, Right-2+XScale, Top); SetAPen( Rp, SHADOWPEN ); Move(Rp, Right-2+XScale, Top+1); Draw(Rp, Right-2+XScale, Bottom-2+YScale); Draw(Rp, Max, Bottom-2+YScale); } SetAPen( Rp, SHADOWPEN ); WritePixel( Rp, (long) 0, TOPMARG ); Move( Rp, (long) 0, Bottom ); Draw( Rp, Right, Bottom ); Draw( Rp, Right, TOPMARG); SetAPen( Rp, HIGHLIGHTPEN ); Move( Rp, (long) 0, TOPMARG + 1); Draw( Rp, (long) 0, Bottom - 1 ); if (Pict) ReleaseSemaphore( &Pict->WindowSemi ); } MakeCurProj( NewPict ) register struct Picture *NewPict; { extern USHORT NewViewModes; extern UBYTE NewDepth; if ( NewPict ) { if ( NewPict != CurPict ) { SetWindowActive( NewPict->Window , '*' ); if (CurPict) { SetWindowActive( CurPict->Window, ' ' ); } SetOnString( NewPict->CycleOn ); KillCycle(); CurPict = NewPict; NewViewModes = NewPict->ViewModes; NewDepth = NewPict->Depth; InitGenSubs(); InitBorderSubs(); InitOrbitSubs(); if (MaybeNewScreen() == 0) { LoadRGB4(vp, NewPict->RGBs, (long) Num_vp_Colors); SetColorProps(CurPen); ReDoHist(CurPict); ShowStats(CurPict); RefreshContours(); } ModifySpeedPot(); SetDirGadget(CurPict); if (CurPict->CycleOn) { CreateCycle(); } } } }