/* * 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 * * (C) Copyright 1989 by Olaf Seibert. * Mandel may be freely distributed. See file 'doc/Notice' for details. * * The Display routines; initialisation and de-initialisation of * screen and window. */ #include #include #ifdef DEBUG # include # undef STATIC # define STATIC /* EMPTY */ #endif #include "mandel.h" #define BUGHEIGHT 213 /* See later comment */ #define BUGWIDTH 640 USHORT ColorMap[MAXDEPTH]; bool ColorMapValid = FALSE; /* * Initialize the screen and the windows and the menus * Return value indicates FAILURE. */ bool InitDisplay(borderless) bool borderless; { USHORT ViewModes = MandelNScreen.ViewModes; struct Screen WBScreen; int i; StopFraming(); Saved = TRUE; /* We can easily reconstruct this `picture' */ if (WBWidth == 0) { /* Get Left, Top, Width, Height */ GetScreenData(&WBScreen, (long)sizeof(WBScreen), (long)WBENCHSCREEN, NULL); WBWidth = WBScreen.Width; WBHeight = WBScreen.Height; /* Maybe we have an interlaced WorkBench screen */ if (WBScreen.ViewPort.Modes & LACE) WBHeight >>= 1; /* And maybe, if we use MWB, it isn't hires... */ if (!(WBScreen.ViewPort.Modes & HIRES)) WBWidth <<= 1; } MandelNScreen.Width = WBWidth; MandelNScreen.Height = WBHeight; if (ViewModes & LACE) MandelNScreen.Height <<= 1; if (MandelNScreen.Height < MINSCREENHEIGHT) MandelNScreen.Height = MINSCREENHEIGHT; if (ViewModes & HIRES) { MandelNScreen.Depth = 4; /* Avoid a bug in MrgCop()?? if you have a PAL machine with */ /* a screen wider than 640 taller than 213 and with 4 bitplanes */ if (MandelNScreen.Width > BUGWIDTH && MandelNScreen.Height > BUGHEIGHT) MandelNScreen.Width = BUGWIDTH; } else { MandelNScreen.Width >>= 1; if (ViewModes & EXTRA_HALFBRITE) { MandelNScreen.Depth = 6; } else { MandelNScreen.Depth = 5; } } if (MandelNScreen.Width < MINSCREENWIDTH) MandelNScreen.Width = MINSCREENWIDTH; NumColors = 1 << MandelNScreen.Depth; if ( !MandelScreen && !(MandelScreen = OpenScreen(&MandelNScreen)) ) { skipto abort; } if (ColorMapValid) LoadRGB4(&MandelScreen->ViewPort, ColorMap, (long) NumColors); MainNWindow.Screen = MandelScreen; if (MainNWindow.Height < MainNWindow.MinHeight) { /* First time we open the window */ MainNWindow.LeftEdge = 0; MainNWindow.TopEdge = MandelScreen->BarHeight; MainNWindow.Width = MandelScreen->Width; MainNWindow.Height = MandelScreen->Height - MainNWindow.TopEdge; } else { if (ViewModes & HIRES) { MainNWindow.LeftEdge <<= 1; MainNWindow.Width <<= 1; } if (ViewModes & LACE) { MainNWindow.TopEdge <<= 1; MainNWindow.Height <<= 1; } } /* Check for windows that can't be opened */ if (MainNWindow.LeftEdge + MainNWindow.Width > MandelScreen->Width) MainNWindow.Width = MandelScreen->Width - MainNWindow.LeftEdge; if (MainNWindow.TopEdge + MainNWindow.Height > MandelScreen->Height) MainNWindow.Height = MandelScreen->Height - MainNWindow.TopEdge; if ( !MainWindow && !(MainWindow = OpenWindow(&MainNWindow)) ) { skipto abort; } SetMenuStrip(MainWindow, MandelMenu); if (borderless) { DoBorderless(MainWindow, &borderinfo); } InitPenTable(); return FALSE; abort: CleanupDisplay((bool) TRUE); return TRUE; } bool CleanupDisplay(everything) bool everything; { bool wasborderless; int i; StopDrawing(); StopFraming(); CloseColorWindow((BOOL) FALSE); wasborderless = (MainWindow != NULL) && ((MainWindow->Flags & BORDERLESS) != 0); if (MainWindow) { /* Save window appearance for later, in low-res non-lace pixels */ MainNWindow.LeftEdge = MainWindow->LeftEdge; MainNWindow.TopEdge = MainWindow->TopEdge; MainNWindow.Width = MainWindow->Width; MainNWindow.Height = MainWindow->Height; ClearMenuStrip(MainWindow); /* Remove menu strip */ CloseWindow(MainWindow); /* Finally close it */ MainWindow = NULL; } /* Save the colors we may have established with great care */ if (MandelScreen) { for (i=0; i < NumColors; i++) { ColorMap[i] = GetRGB4(MandelScreen->ViewPort.ColorMap, i); } ColorMapValid = TRUE; if (MandelScreen->ViewPort.Modes & HIRES) { MainNWindow.LeftEdge >>= 1; MainNWindow.Width >>= 1; } if (MandelScreen->ViewPort.Modes & LACE) { MainNWindow.TopEdge >>= 1; MainNWindow.Height >>= 1; } /* Close the screen only if `everything' must be cleaned up */ if (everything) { CloseScreen(MandelScreen); MandelScreen = NULL; } } return wasborderless; } bool ReInitDisplay() { bool WasBorderless; WasBorderless = CleanupDisplay((bool) TRUE); if (InitDisplay(WasBorderless)) { /* Trouble */ MandelNScreen.ViewModes &= ~(HIRES | LACE | EXTRA_HALFBRITE); WBWidth = 0; /* Re-use Workbench screen size */ if (InitDisplay((bool) FALSE)) MyExit("Can't re-init display - Maybe low on memory"); SelectMenu(MENU(OPTMENU, OPTRES, ORHI), (bool)FALSE); SelectMenu(MENU(OPTMENU, OPTRES, ORILC), (bool)FALSE); SelectMenu(MENU(OPTMENU, OPTRES, ORBCK), (bool)FALSE); SelectMenu(MENU(OPTMENU, OPTRES, OREHB), (bool)FALSE); return TRUE; } return FALSE; } bool DoBorderless(window, borderinfo) struct Window *window; struct BorderInfo *borderinfo; { /* Make window borderless */ /* register struct Layer_Info *LayerInfo = &window->WScreen->LayerInfo; */ #define LayerInfo NULL /* Since V1.2 */ register struct Layer *Layer = window->RPort->Layer; register long movex; register long movey; register long sizex; register long sizey; bool Success = FALSE; if (window->Flags & BORDERLESS) return TRUE; LockLayer(LayerInfo, Layer); window->Flags |= BORDERLESS; movex = -window->BorderLeft; movey = -window->BorderTop; sizex = window->BorderRight - movex; sizey = window->BorderBottom - movey; window->BorderLeft = window->BorderTop = window->BorderRight = window->BorderBottom = 0; window->GZZWidth += sizex; window->GZZHeight += sizey; if ( MoveLayer(LayerInfo, Layer, movex, movey) ) { Success = SizeLayer(LayerInfo, Layer, sizex, sizey); if (!Success) { sizex = sizey = 0; } } else { movex = movey = sizex = sizey = 0; } UnlockLayer(Layer); borderinfo->MoveX = movex; borderinfo->MoveY = movey; borderinfo->SizeX = sizex; borderinfo->SizeY = sizey; /* Done making borderless */ if (Success) { return Success; } else { /* Try to clean up the mess */ UndoBorderless(window, borderinfo); return FALSE; } #undef LayerInfo } void UndoBorderless(window, borderinfo) struct Window *window; struct BorderInfo *borderinfo; { /* ``Another fine mess you got me into!'' (Oliver Hardy) */ /* register struct Layer_Info *LayerInfo = &window->WScreen->LayerInfo; */ #define LayerInfo NULL /* Since V1.2 */ register struct Layer *Layer = window->RPort->Layer; register long movex = borderinfo->MoveX; register long movey = borderinfo->MoveY; register long sizex = borderinfo->SizeX; register long sizey = borderinfo->SizeY; bool Success = FALSE; if (!(window->Flags & BORDERLESS)) return; LockLayer(LayerInfo, Layer); SizeLayer(LayerInfo, Layer, -sizex, -sizey); MoveLayer(LayerInfo, Layer, -movex, -movey); window->GZZWidth -= sizex; window->GZZHeight -= sizey; window->BorderLeft = -movex; window->BorderTop = -movey; window->BorderRight = sizex + movex; window->BorderBottom = sizey + movey; window->Flags &= ~BORDERLESS; RefreshWindowFrame(window); UnlockLayer(Layer); /* Done Undoing Borderless */ #undef LayerInfo }