/* * 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 the routines that open and close * MandelVrooms custom screen as well as the required Amiga libraries. * */ #include "mandp.h" char *ExecLib = "exec.library"; char *IntuiLib = "intuition.library"; char *GfxLib = "graphics.library"; char *LayersLib = "layers.library"; char *FFPLib = "mathffp.library"; char *TransLib = "mathtrans.library"; char *IEEELib = "mathieeedoubbas.library"; char *IconLib = "icon.library"; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct MathBase *MathBase; struct MathTransBase *MathTransBase; struct LayersBase *LayersBase; struct ExecBase *ExecBase; struct MathIeeeDoubBasBase *MathIeeeDoubBasBase; extern struct IconBase *IconBase; struct Screen *screen; struct ViewPort *vp; int Num_vp_Colors; UBYTE StandardSize; extern BYTE FromWB; /* * The following window's message port is used to communicate with * all the other windows in the system. It is a small backdrop, * borderless window that is always open and in custom screen used * by MandelVroom. */ struct Window *BackWind; struct NewWindow NewBack = { 0,10, /* start position */ 0,0, /* width, height */ (UBYTE) 0, (UBYTE) 1, /* detail pen, block pen */ /* IDCMP flags */ MENUPICK | GADGETDOWN | GADGETUP | REQCLEAR | CLOSEWINDOW | MOUSEBUTTONS | ACTIVEWINDOW | NEWSIZE, /* backWind flags */ ACTIVATE|BACKDROP|BORDERLESS|REPORTMOUSE|NOCAREREFRESH|SIMPLE_REFRESH, (struct Gadget *) NULL, /* first gadget */ (struct Image *) NULL, /* user checkmark */ (UBYTE *) NULL, /* Title */ (struct Screen *) NULL, /* pointer to screen */ (struct BitMap *) NULL, /* pointer to superbitmap */ 8,8,-1,-1, /* sizing */ CUSTOMSCREEN /* type of screen */ }; extern struct Window *CurWind; SHORT YScale, XScale; static struct TextAttr myfont = { (STRPTR) "topaz.font", TOPAZ_EIGHTY, 0, 0 }; struct NewScreen NewScreen = { 0,0, /* start position */ 320, 200, 5, /* width, height, depth */ (UBYTE) 0, (UBYTE) 1, /* detail pen, block pen */ (USHORT) NULL, /* HIRES, INTERLACE, SPRITES, DUAL, HAM */ CUSTOMSCREEN, /* screen type */ &myfont, /* font to use */ (UBYTE *) NULL, (struct Gadget *) NULL /* pointer to extra gadgets */ }; /*************************************************************************** * * Open the Libraries and custom screen * **************************************************************************/ /* * Open the libraries */ int OpenLibs() { ExecBase = (struct ExecBase *) OpenLibrary( ExecLib, (long) 0); if (ExecBase == NULL) { LibErr( ExecLib ); return( 100); } #define LIB_FOR_1_2 33L IntuitionBase = (struct IntuitionBase *) OpenLibrary( IntuiLib, LIB_FOR_1_2); if (IntuitionBase == NULL) { LibErr( IntuiLib ); return(100); } GfxBase = (struct GfxBase *) OpenLibrary( GfxLib, (long) 0); if (GfxBase == NULL) { LibErr( GfxLib ); return(100); } LayersBase = (struct LayersBase *) OpenLibrary( LayersLib, (long) 0); if (LayersBase == NULL) { LibErr( LayersLib ); return(100); } MathIeeeDoubBasBase = (struct MathIeeeDoubBasBase *) OpenLibrary( IEEELib, (long) 0); if (MathIeeeDoubBasBase == NULL) { LibErr( IEEELib ); return(100); } /* if started from the workbench, then open the icon library */ if (FromWB) { IconBase = (struct IconBase *) OpenLibrary( IconLib, (long) 0); if (IconBase == NULL) { LibErr( IconLib ); return(100); } } return(0); } /* OpenLibs */ OpenFFPLibs() { if ( MathBase == NULL ) { MathBase = (struct MathBase *) OpenLibrary( FFPLib, (long) 0); if (MathBase == NULL) { DispErrMsg( "Can't open FFP library", 0); return(100); } } if ( MathTransBase == NULL ) { MathTransBase = (struct MathTransBase *) OpenLibrary( TransLib, (long) 0); if (MathTransBase == NULL) { DispErrMsg( "Can't open FFP transcendental library", 0); return(100); } } return(0); } LibErr( Name ) char *Name; { printf("Can't open %s\nPlease check to see if it is present on your disk\n",Name); } /* * Close the libraries used */ CloseLibs() { if ( MathBase ) CloseLibrary( MathBase ); MathBase = NULL; if ( MathTransBase ) CloseLibrary( MathTransBase ); MathTransBase = NULL; if ( MathIeeeDoubBasBase ) CloseLibrary( MathIeeeDoubBasBase ); MathIeeeDoubBasBase = NULL; if ( IconBase ) CloseLibrary( IconBase ); IconBase = NULL; if ( IntuitionBase ) CloseLibrary( IntuitionBase ); IntuitionBase = NULL; if ( LayersBase ) CloseLibrary( LayersBase ); LayersBase = NULL; if ( GfxBase ) CloseLibrary( GfxBase ); GfxBase = NULL; if ( ExecBase ) CloseLibrary( ExecBase ); ExecBase = NULL; } /* CloseLibs */ struct Window *Save_PR_Wind; /* * Open the display */ int OpenDisp() { extern UBYTE ContOpen, PaletteOpen, CycleOpen, HistOpen; extern struct MenuItem GenerateSubs[]; NewScreenSize( &NewScreen ); if (NewScreen.ViewModes & HIRES) { XScale = 1; } else { XScale = 0; } if (NewScreen.ViewModes & INTERLACE) { YScale = 1; } else { YScale = 0; } RightMarg = 16; screen = OpenScreen( (struct NewScreen *) &NewScreen); if (screen == NULL) { AndDie("Can't open new screen!\n"); } vp = &screen->ViewPort; Num_vp_Colors = 1 << NewScreen.Depth; if (Num_vp_Colors > 32) Num_vp_Colors = 32; if (CurPict) LoadRGB4(vp, CurPict->RGBs, Num_vp_Colors ); else DefaultColors(); if ( ExecBase->AttnFlags & AFF_68020 ) { GenerateSubs[ INTIIGENERATOR ].Flags |= ITEMENABLED; } if ( ExecBase->AttnFlags & AFF_68881 ) { GenerateSubs[ _81GENERATOR ].Flags |= ITEMENABLED; } InitViewModesSubs(); InitDepthSubs(); InitGenSubs(); AllocateMice(); OpenBackWind(); /* Open this before any other window */ Save_PR_Wind = (struct Window *) ((struct Process *) FindTask(0L))->pr_WindowPtr; ((struct Process *) FindTask(0L))->pr_WindowPtr = (APTR) BackWind; ReOpenPicts(); if (ContOpen) OpenContWind(); if (HistOpen) OpenHistWind(); if (PaletteOpen) OpenPalWind(); if (CycleOpen) OpenCycWind(); return(0); } /* opendisp */ /* * Close the screen */ CloseDisp() { if ( screen ) { CloseCycWind(); ClosePalWind(); CloseContWind(); CloseHistWind(); CloseStatsWind(); CloseOrbitWind(); CloseHelpWind(0,NULL); ClosePicts(); CloseBackWind(); /* Close this window last */ ((struct Process *) FindTask(0L))->pr_WindowPtr = (APTR) Save_PR_Wind; NewScreen.TopEdge = screen->TopEdge >> YScale; CloseScreen( screen ); screen = NULL; FreeMice(); } } /* CloseDisp */ /* * Check New Screen Size */ int NewScreenSize( NewScreen ) struct NewScreen *NewScreen; { extern struct MenuItem ScreenSizeSubs[]; struct Screen WBenchScreen; (void) GetScreenData( &WBenchScreen, sizeof(struct Screen), WBENCHSCREEN, NULL); if (!(WBenchScreen.ViewPort.Modes & LACE)) { WBenchScreen.Height <<= 1; } if ( StandardSize ) { WBenchScreen.Width = 640; if (GfxBase->DisplayFlags & PAL) WBenchScreen.Height = 512; else WBenchScreen.Height = 400; } if (NewScreen->ViewModes & HIRES) { if ( NewScreen->Depth > 4 ) NewScreen->Depth = 4; if ( NewScreen->ViewModes & EXTRA_HALFBRITE ) NewScreen->ViewModes &= ~EXTRA_HALFBRITE; NewScreen->Width = WBenchScreen.Width; } else { NewScreen->Width = WBenchScreen.Width >> 1; } if (NewScreen->ViewModes & INTERLACE) { NewScreen->Height = WBenchScreen.Height; } else { NewScreen->Height = WBenchScreen.Height >> 1; } if (NewScreen->ViewModes & EXTRA_HALFBRITE) { NewScreen->Depth = 6; } else { if (NewScreen->Depth == 6) NewScreen->Depth = 5; } NewScreen->TopEdge <<= YScale; } /* NewScreenSize */ SaveRGBs( Pict ) struct Picture *Pict; { register int i; register SHORT *RGBs; if (Pict) { RGBs = Pict->RGBs; for (i = 0; i < Num_vp_Colors; i++) *RGBs++ = GetRGB4(vp->ColorMap, i); } } AndDie( ErrMsg ) char *ErrMsg; { printf("%s\n", ErrMsg); ThrowPicts(); CloseTasks(); CloseDisp(); CloseLibs(); exit(0); } OpenBackWind() { NewBack.Screen = screen; NewBack.Width = screen->Width; NewBack.Height = screen->Height - NewBack.TopEdge - 1; BackWind = OpenWindow( &NewBack ); if ( BackWind == NULL ) { AndDie("Can't open common window\n"); } (void) SetMenuStrip( BackWind, Menu ); CurWind = BackWind; ForceNormPointer(); } CloseBackWind() { ClearPointer( BackWind ); ClearMenuStrip( BackWind ); CloseWindow( BackWind ); BackWind = NULL; } /*************************************************************************** * * Open and Close Window tools * **************************************************************************/ int NumWindows; /* * Open a window and put it in the window list */ struct Window *OpenMyWind(NewWind, Screen, Gadgets, Width, Height) struct NewWindow *NewWind; struct Screen *Screen; struct Gadget *Gadgets; SHORT Width, Height; { register struct Window *Window; register LONG t; NewWind->Screen = Screen; NewWind->FirstGadget = Gadgets; NewWind->Width = Width; NewWind->Height = Height; /* Window too wide ? */ t = Width - Screen->Width; if (t > 0) { Width -= t; } /* Too far to the right ? */ t = NewWind->LeftEdge + Width - Screen->Width; if ( t > 0 ) { NewWind->LeftEdge -= t; } /* Window too tall ? */ t = Height - Screen->Height; if (t > 0) { Height -= t; } /* Too close to the bottom ? */ t = NewWind->TopEdge + Height - Screen->Height; if ( t > 0 ) { NewWind->TopEdge -= t; } Window = OpenWindow( NewWind ); if (Window == (struct Window *) NULL) { DispErrMsg("Can't open new window",0); return( (struct Window *) NULL); } Window->UserPort = BackWind->UserPort; ModifyIDCMP( Window, (long) BackWind->IDCMPFlags ); Window->UserData = NULL; (void) SetMenuStrip(Window, Menu); CurWind = Window; ForceNormPointer(); return(Window); } /* OpenMyWind */ /* * Deallocate all the gadgets associated with this window * Close the window */ CloseMyWind(Window,Gadgets) struct Window *Window; struct Gadget *Gadgets; { if (Window) { /* get rid of the menu */ if (Window->MenuStrip) ClearMenuStrip(Window); /* get rid of the pointer */ if (Window->Pointer) ClearPointer( Window ); if ( Window == CurWind ) { CurWind = BackWind; } CloseWindowSafely( Window ); if (Gadgets) FreeGadgets(Gadgets); } } /* CloseMyWind */ /*************************************************************************** * * This section handles the Mouse pointer for the custom screen * **************************************************************************/ USHORT *BabyBrotPointer; USHORT *BabyToPointer; USHORT *BabyWithPointer; USHORT *SleepyPointer; /***************************************************************/ /* This is the image for baby Mandelbrot pointer */ /***************************************************************/ USHORT BabyBrotSprite[]= { 0x0000, 0x0000, 0x8000, 0x0000, 0x5000, 0x5000, 0x2202, 0x2202, 0x4D82, 0x5F82, 0x0013, 0x1913, 0x006C, 0x11FE, 0x2000, 0x300A, 0x0C00, 0x1C06, 0x1004, 0x1407, 0x0004, 0x0404, 0x0028, 0x042C, 0x0800, 0x0C1C, 0x0220, 0x0630, 0x01C0, 0x05F0, 0x3800, 0x3F80, 0x0000, 0x0880, 0x0000, 0x0000, }; /***************************************************************/ /* This is a baby brot pointer with 'TO' in it. */ /***************************************************************/ USHORT BabyToSprite[]= { 0x0000, 0x0000, 0x8000, 0x0000, 0x5000, 0x5000, 0x2202, 0x2202, 0x4D82, 0x5F82, 0x0013, 0x1913, 0x006C, 0x11FE, 0x2000, 0x300A, 0x0C00, 0x1C06, 0x1004, 0x1407, 0x0004, 0x0404, 0x0028, 0x042C, 0x0800, 0x0C1C, 0x0220, 0x0630, 0x01C0, 0x05F0, 0x3800, 0x3F80, 0x0000, 0x0880, 0x0000, 0x0000, 0x3F00, 0x3F00, 0x2D00, 0x3F80, 0x0C78, 0x1EF8, 0x0CCC, 0x0EFC, 0x0CCC, 0x0EEE, 0x0CCC, 0x0EEE, 0x1E78, 0x1E7E, 0x0000, 0x0F3C, 0x0000, 0x0000, }; /***************************************************************/ /* This is a baby brot pointer with 'WITH' in it. */ /***************************************************************/ USHORT BabyWithSprite[]= { 0x0000, 0x0000, 0x8000, 0x0000, 0x5000, 0x5000, 0x2202, 0x2202, 0x4D82, 0x5F82, 0x0013, 0x1913, 0x006C, 0x11FE, 0x2000, 0x300A, 0x0C00, 0x1C06, 0x1004, 0x1407, 0x0004, 0x0404, 0x0028, 0x042C, 0x0800, 0x0C1C, 0x0220, 0x0630, 0x01C0, 0x05F0, 0x3800, 0x3F80, 0x0000, 0x0880, 0x0000, 0x0000, 0x0630, 0x0630, 0x0630, 0x0738, 0x0630, 0x0738, 0x06B0, 0x07B8, 0x07F0, 0x07F8, 0x0770, 0x07F8, 0x0630, 0x07B8, 0x0000, 0x0318, 0x00C0, 0x00C0, 0x0000, 0x0060, 0x01C0, 0x01C0, 0x00C0, 0x00E0, 0x00C0, 0x00E0, 0x00C0, 0x00E0, 0x01E0, 0x01E0, 0x0000, 0x00F0, 0x0000, 0x0000, 0x0040, 0x0040, 0x00C0, 0x00E0, 0x01F0, 0x01F0, 0x00C0, 0x00F8, 0x00C0, 0x00E0, 0x00D0, 0x00F0, 0x0060, 0x0068, 0x0700, 0x0730, 0x0300, 0x0380, 0x0360, 0x03E0, 0x03B0, 0x03B0, 0x0330, 0x03F8, 0x0330, 0x03B8, 0x0730, 0x07B8, 0x0000, 0x0398, 0x0000, 0x0000, }; /***************************************************************/ /* This is a sleepy cloud pointer */ /***************************************************************/ USHORT SleepySprite[] = { 0x0000, 0x0000, 0x0fe0, 0x0000, 0x1830, 0x07c0, 0x7018, 0x0fe0, 0xc008, 0x3ff0, 0x9e0c, 0x7ff0, 0x8406, 0x7ff8, 0x8802, 0x7ffc, 0x1e03, 0xfffc, 0x80f1, 0x7ffe, 0x8021, 0x7ffe, 0x4040, 0x3fff, 0x80f1, 0x7ffe, 0xc001, 0x3ffe, 0x6003, 0x1ffc, 0x3006, 0x0ff8, 0x180c, 0x07f0, 0x0718, 0x00e0, 0x0070, 0x0f80, 0x1810, 0x07e0, 0x0820, 0x0740, 0x0ff0, 0x0000, 0x0020, 0x03c0, 0x0410, 0x03e0, 0x0310, 0x00e0, 0x00e0, 0x0000, 0x0000, 0x0000, }; /* pointer types */ #define UNINITIALIZED 0 #define NORMPOINTER 1 #define TOPOINTER 2 #define WITHPOINTER 3 #define SLEEPYPOINTER 4 UBYTE PointerType = UNINITIALIZED; /* defines for the cute pointer sprite */ #define MYSPRITE_WIDTH ((long) 16) #define MYSPRITE_HEIGHT ((long) 16) #define TOSPRITE_WIDTH ((long) 16) #define TOSPRITE_HEIGHT ((long) 25) #define WITHSPRITE_WIDTH ((long) 16) #define WITHSPRITE_HEIGHT ((long) 50) #define SLEEPY_WIDTH ((long) 16) #define SLEEPY_HEIGHT ((long) 25) #define MYSPRITE_HOTX ((long) -1) #define MYSPRITE_HOTY ((long) 0) #define BABYSIZE ((int) ((MYSPRITE_HEIGHT + 2) * 8)) #define TOSIZE ((int) ((TOSPRITE_HEIGHT + 2) * 8)) #define WITHSIZE ((int) ((WITHSPRITE_HEIGHT + 2) * 8)) #define SLEEPYSIZE ((int) ((SLEEPY_HEIGHT + 2) * 8)) /* * Copy an Image into a chip ram image */ USHORT * MakeChipSprite( FastRamSprite, Size ) register USHORT *FastRamSprite; register int Size; { register USHORT *ChipSprite, *SaveSprite; register int i; ChipSprite = (USHORT *) safeAllocMem( (ULONG) (Size * sizeof(SHORT)), MEMF_CHIP ); if ( ChipSprite == NULL ) return ( ChipSprite ); SaveSprite = ChipSprite; for ( i = 0; i < Size; i++) *(ChipSprite++) = *(FastRamSprite++); return( SaveSprite ); } /* * Allocate all the mouse pointer sprites used by this program */ AllocateMice() { BabyBrotPointer = MakeChipSprite( BabyBrotSprite, BABYSIZE ); BabyToPointer = MakeChipSprite( BabyToSprite, TOSIZE ); BabyWithPointer = MakeChipSprite( BabyWithSprite, WITHSIZE ); SleepyPointer = MakeChipSprite( SleepySprite, SLEEPYSIZE ); } /* * Free all the mouse pointer sprites used by this program */ FreeMice() { if ( BabyBrotPointer ) FreeMem( (char *) BabyBrotPointer, (long) BABYSIZE * sizeof(SHORT) ); BabyBrotPointer = NULL; if ( BabyToPointer ) FreeMem( (char *) BabyToPointer, (long) TOSIZE * sizeof(SHORT) ); BabyToPointer = NULL; if ( BabyWithPointer ) FreeMem( (char *) BabyWithPointer, (long) WITHSIZE * sizeof(SHORT) ); BabyWithPointer = NULL; if ( SleepyPointer ) FreeMem( (char *) SleepyPointer, (long) SLEEPYSIZE * sizeof(SHORT) ); SleepyPointer = NULL; } /* * Set all window pointers NewPointer */ SetPointers() { SetMouse( CurWind ); } /* * Force normal pointers */ ForceNormPointer() { PointerType = UNINITIALIZED; SetNormPointer(); } /* * Set Normal Mouse Pointer */ SetNormPointer() { if (PointerType != NORMPOINTER ) { PointerType = NORMPOINTER; SetPointers(); } } /* * Set 'To' Mouse Pointer */ SetToPointer() { if (PointerType != TOPOINTER ) { PointerType = TOPOINTER; SetPointers(); } } /* * Set 'With' Mouse Pointer */ SetWithPointer() { if (PointerType != TOPOINTER ) { PointerType = WITHPOINTER; SetPointers(); } } /* * Set Sleepy Mouse Pointer */ SetSleepyPointer() { if (PointerType != SLEEPYPOINTER ) { PointerType = SLEEPYPOINTER; SetPointers(); } } SetMouse( window ) struct Window *window; { if (window == NULL) return; switch ( PointerType ) { case NORMPOINTER: SetPointer( window, BabyBrotPointer, MYSPRITE_HEIGHT, MYSPRITE_WIDTH, MYSPRITE_HOTX, MYSPRITE_HOTY); break; case TOPOINTER: SetPointer( window, BabyToPointer, TOSPRITE_HEIGHT, TOSPRITE_WIDTH, MYSPRITE_HOTX, MYSPRITE_HOTY); break; case WITHPOINTER: SetPointer( window, BabyWithPointer, WITHSPRITE_HEIGHT, WITHSPRITE_WIDTH, MYSPRITE_HOTX, MYSPRITE_HOTY); break; case SLEEPYPOINTER: SetPointer( window, SleepyPointer, SLEEPY_HEIGHT, SLEEPY_WIDTH, MYSPRITE_HOTX, MYSPRITE_HOTY); break; } } /************************************************************************** * * This code is used to display error messages on the cusom screen * **************************************************************************/ struct IntuiText msg_txt = { 0, 1, JAM2, 5, 20, NULL, NULL, NULL }; struct IntuiText OK_txt = { 0, 1, JAM2, 5, 3, NULL, (UBYTE *) "YES", NULL }; struct IntuiText NO_txt = { 0, 1, JAM2, 5, 3, NULL, (UBYTE *) "NO", NULL }; struct IntuiText Cont_txt = { 0, 1, JAM2, 5, 3, NULL, (UBYTE *) "Continue", NULL }; DispErrMsg(ErrMsg, Flag) char *ErrMsg; SHORT Flag; { msg_txt.IText = (UBYTE *) ErrMsg; SetNormPointer(); if (BackWind) { if (Flag) { return( AutoRequest(BackWind, &msg_txt, &OK_txt, &NO_txt, 0L, 0L, (long) (IntuiTextLength(&msg_txt) + 50L), 70L)); } else { (void) AutoRequest(BackWind, &msg_txt, 0L, &Cont_txt, 0L, 0L, (long) (IntuiTextLength(&msg_txt) + 50L), 70L); } } else { if (FromWB) printf("%s\n", ErrMsg); } return(0); } #define _K (1024L) #define LOW_MEM_MARK (30*_K) #ifdef MEM_DEBUG APTR SafeAllocMem( size, flags ) #else APTR safeAllocMem( size, flags ) #endif ULONG size; ULONG flags; { register APTR p; if ( p = (APTR) AllocMem( (long) size, (long) flags) ) if ( AvailMem( (long) flags ) < LOW_MEM_MARK ) { FreeMem((char *) p, (long) size); return( NULL ); } return( p ); }