home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / windows / winsrc.zip / WINFRACT.C < prev    next >
C/C++ Source or Header  |  1990-12-20  |  52KB  |  1,410 lines

  1. /****************************************************************************
  2.  
  3.  
  4.     PROGRAM: winfract.c
  5.  
  6.     PURPOSE: Windows-specific main-driver code for Fractint for Windows
  7.              (look in MAINFRAC.C for the non-windows-specific code)
  8.  
  9.     Copyright (C) 1990 The Stone Soup Group.  Fractint for Windows 
  10.     may be freely copied and distributed, but may not be sold.
  11.     
  12.     We are, of course, copyrighting the code we wrote to implement
  13.     Fractint-for-Windows, and not the routines we lifted directly
  14.     or indirectly from Microsoft's Windows 3.0 Software Development Kit.
  15.  
  16. ****************************************************************************/
  17.  
  18. #include "windows.h"
  19. #include "winfract.h"
  20. #include "mathtool.h"
  21. #include "fractype.h"
  22. #include "fractint.h"
  23. #include "select.h"
  24. #include <math.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <search.h>
  28. #include <string.h>
  29. #include <time.h>
  30.  
  31. LPSTR win_lpCmdLine;
  32.  
  33. HANDLE hInst;
  34.  
  35. HWND hwnd;                               /* handle to main window */
  36. HWND hWndCopy;                 /* Copy of hWnd */
  37.  
  38. #define PALETTESIZE 256               /* dull-normal VGA                    */
  39. HANDLE hpal;                          /* palette handle                     */
  40. PAINTSTRUCT ps;                       /* paint structure                    */
  41. HDC hDC;                              /* handle to device context           */
  42. HDC hMemoryDC;                        /* handle to memory device context    */
  43. BITMAP Bitmap;                        /* bitmap structure                   */
  44.  
  45. HANDLE  hPal;          /* Handle to the application's logical palette  */
  46. HANDLE  hLogPal;       /* Temporary Handle */
  47. LPLOGPALETTE pLogPal;  /* pointer to tha application's logical palette */
  48. int     iNumColors;    /* Number of colors supported by device           */
  49. int     iRasterCaps;   /* Raster capabilities                           */
  50. int     iPalSize;      /* Size of Physical palette                       */
  51.  
  52. BOOL    win_systempaletteused = FALSE;    /* flag system palette set */
  53. extern int win_syscolorindex[21];
  54. extern DWORD win_syscolorold[21];
  55. extern DWORD win_syscolornew[21];
  56.  
  57. extern int CoordBoxOpen;
  58. extern HWND hCoordBox;
  59.  
  60. #define EXE_NAME_MAX_SIZE  128
  61.  
  62. BOOL       bHelp = FALSE;      /* Help mode flag; TRUE = "ON"*/
  63. HCURSOR    hHelpCursor;        /* Cursor displayed when in help mode*/
  64. char       szHelpFileName[EXE_NAME_MAX_SIZE+1];    /* Help file name*/
  65.  
  66. void MakeHelpPathName(char*);  /* Function deriving help file path */
  67.  
  68. unsigned char far win_dacbox[256][3];
  69. extern unsigned char dacbox[256][3];
  70.  
  71. BOOL bTrack = FALSE;                  /* TRUE if user is selecting a region */
  72. BOOL zoomflag = FALSE;                /* TRUE is a zoom-box selected */
  73. RECT Rect;
  74.  
  75. int Shape = SL_BLOCK;            /* shape to use for the selection rectangle */
  76.  
  77. /* pointers to various dialog-box routines */
  78. FARPROC lpProcAbout;
  79. FARPROC lpOpenDlg;
  80. FARPROC lpSelectFractal;
  81. FARPROC lpSelectFracParams;
  82. FARPROC lpSelectImage;
  83. FARPROC lpSelectDoodads;
  84. FARPROC lpSelectCycle;
  85. FARPROC lpSaveAsDlg;
  86. FARPROC lpProcStatus;
  87. FARPROC lpSelect3D;
  88. FARPROC lpSelect3DPlanar;
  89. FARPROC lpSelect3DSpherical;
  90.  
  91. extern unsigned char readname[], FileName[], FormFileName[];
  92. extern unsigned char LFileName[], LName[];
  93. extern unsigned char DialogTitle[], DefSpec[], DefExt[];
  94.  
  95. HBITMAP hBitmap, oldBitmap, oldoldbitmap;              /* working bitmaps */
  96.  
  97. HANDLE hDibInfo;        /* handle to the Device-independent bitmap */
  98. LPBITMAPINFO pDibInfo;        /* pointer to the DIB info */
  99. HANDLE hpixels;            /* handle to the DIB pixels */
  100. unsigned char huge *pixels;    /* the device-independent bitmap  pixels */
  101. extern int bytes_per_pixelline;    /* pixels/line / pixels/byte */
  102. extern long win_bitmapsize;     /* size of the DIB in bytes */
  103.  
  104. HANDLE hClipboard1, hClipboard2, hClipboard3; /* handles to clipboard info */
  105. LPSTR lpClipboard1, lpClipboard2;            /* pointers to clipboard info */
  106.  
  107. int last_written_y = -2;        /* last line written */
  108. int screen_to_be_cleared = 1;    /* flag that the screen is to be cleared */
  109. int time_to_act = 0;        /* time to take some sort of action? */
  110. int time_to_restart = 0;        /* time to restart?  */
  111. int time_to_reinit = 0;         /* time to reinitialize?  */
  112. int time_to_quit = 0;           /* time to quit? */
  113. int time_to_save = 0;        /* time to save the file? */
  114. int time_to_print = 0;        /* time to print the file? */
  115. int time_to_load = 0;        /* time to load a new file? */
  116. int time_to_cycle = 0;          /* time to begin color-cycling? */
  117.  
  118. int win_3dspherical = 0;          /* spherical 3D? */
  119. int win_display3d, win_overlay3d; /* 3D flags */
  120.  
  121. extern int win_cycledir, win_cyclerand;
  122.  
  123. extern int calc_status;
  124.  
  125. int xdots, ydots, colors, maxiter;
  126. int ytop, ybottom, xleft, xright;
  127. int xposition, yposition, win_xoffset, win_yoffset, xpagesize, ypagesize;
  128. int win_xdots, win_ydots;
  129. extern int fractype;
  130. extern double param[4];
  131. extern double xxmin, xxmax, yymin, yymax, xx3rd, yy3rd;
  132. double jxxmin, jxxmax, jyymin, jyymax, jxx3rd, jyy3rd;
  133. extern int frommandel, bitshift, biomorph;
  134.  
  135. extern char str[255];
  136.  
  137. int cpu, fpu;            /* cpu, fpu flags */
  138.  
  139. extern int win_release;
  140.  
  141. char *win_choices[100];
  142. int win_numchoices, win_choicemade;
  143.  
  144. extern int onthelist[];
  145. extern int CountFractalList;
  146. extern int CurrentFractal;
  147. int MaxFormNameChoices = 80;
  148. char FormNameChoices[80][21];
  149. char FormName[30];
  150. extern char    ifsfilename[];    /* IFS code file */
  151. extern char     ifs3dfilename[];  /* IFS 3D code file */
  152. double far *temp_array;
  153. HANDLE htemp_array;
  154.  
  155. /****************************************************************************
  156.  
  157.     FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
  158.  
  159.     PURPOSE: calls initialization function, processes message loop
  160.  
  161. ****************************************************************************/
  162.  
  163. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  164. HANDLE hInstance;
  165. HANDLE hPrevInstance;
  166. LPSTR lpCmdLine;
  167. int nCmdShow;
  168. {
  169.     int Return;
  170.  
  171.     win_lpCmdLine = lpCmdLine;
  172.  
  173.     if (!hPrevInstance)
  174.         if (!InitApplication(hInstance))
  175.             return (FALSE);
  176.  
  177.     if (!InitInstance(hInstance, nCmdShow))
  178.         return (FALSE);
  179.  
  180.     fractint_main();            /* fire up the main Fractint code */
  181.     if(htemp_array) {
  182.         GlobalUnlock(htemp_array);
  183.         GlobalFree(htemp_array);
  184.     }
  185.     DestroyWindow(hWndCopy);    /* stop everything when it returns */
  186.     
  187.     return(0);                  /* we done when 'fractint_main' returns */
  188. }
  189.  
  190. /****************************************************************************
  191.  
  192.     FUNCTION: InitApplication(HANDLE)
  193.  
  194.     PURPOSE: Initializes window data and registers window class
  195.  
  196. ****************************************************************************/
  197.  
  198. BOOL InitApplication(hInstance)
  199. HANDLE hInstance;
  200. {
  201.     WNDCLASS  wc;
  202.  
  203.     wc.style = CS_VREDRAW | CS_HREDRAW;
  204.     wc.lpfnWndProc = MainWndProc;
  205.     wc.cbClsExtra = 0;
  206.     wc.cbWndExtra = 0;
  207.     wc.hInstance = hInstance;
  208.     wc.hIcon = LoadIcon(hInstance, "FracIcon");
  209.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  210.     wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
  211.     wc.lpszMenuName =  "WinFracMenu";
  212.     wc.lpszClassName = "FractintForWindowsV0010";
  213.  
  214.     return (RegisterClass(&wc) && RegisterMathWindows(hInstance));
  215. }
  216.  
  217.  
  218. /****************************************************************************
  219.  
  220.     FUNCTION:  InitInstance(HANDLE, int)
  221.  
  222.     PURPOSE:  Saves instance handle and creates main window
  223.  
  224. ****************************************************************************/
  225. BOOL InitInstance(hInstance, nCmdShow)
  226.     HANDLE          hInstance;
  227.     int             nCmdShow;
  228. {
  229.     DWORD WinFlags;
  230.     WORD  DeviceCaps;
  231.     int iLoop, jLoop;
  232.     DWORD ThisColor;
  233.     
  234.     float temp;
  235.     char tempname[40];
  236.  
  237.     /* so, what kind of a computer are we on, anyway? */
  238.     WinFlags = GetWinFlags();
  239.     cpu = 88;                             /* determine the CPU type */
  240.     if (WinFlags & WF_CPU186) cpu = 186;
  241.     if (WinFlags & WF_CPU286) cpu = 286;
  242.     if (WinFlags & WF_CPU386) cpu = 386;
  243.     if (WinFlags & WF_CPU486) cpu = 386;
  244.     fpu = 0;                              /* determine the FPU type */
  245.     if (WinFlags & WF_80x87)  fpu = 87;
  246.     if ((WinFlags & WF_CPU486) || (fpu && (cpu == 386))) fpu = 387;
  247.  
  248.     hInst = hInstance;
  249.  
  250.     temp = win_release / 100.0;
  251.     sprintf(tempname,"Fractint for Windows - Vers %5.2f", temp);
  252.  
  253.     hwnd = CreateWindow(
  254.         "FractintForWindowsV0010",
  255.         tempname,
  256.         WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
  257.         160, 120,  /* initial locn instead of CW_USEDEFAULT, CW_USEDEFAULT, */
  258.         320, 240,  /* initial size instead of CW_USEDEFAULT, CW_USEDEFAULT, */
  259.         NULL,
  260.         NULL,
  261.         hInstance,
  262.         NULL
  263.     );
  264.  
  265.     if (!hwnd) {  /* ?? can't create the initial window! */
  266.         return (FALSE);
  267.         }
  268.  
  269.     /* This program doesn't run in "real" mode, so shut down right
  270.        now to keep from mucking up Windows */
  271.     if (!((WinFlags & WF_STANDARD) || (WinFlags & WF_ENHANCED))) {
  272.         MessageBox (
  273.             GetFocus(),
  274.             "This program requires Standard\nor 386-Enhanced Mode",
  275.             "Fractint For Windows",
  276.             MB_ICONSTOP | MB_OK);
  277.         return(FALSE);
  278.         }
  279.     
  280.     xdots   = 200;                   /* for now, let's start with a tiny image */
  281.     ydots   = 150;
  282.     win_xdots = xdots;
  283.     win_ydots = ydots;
  284.     maxiter = 150;                   /* and a few iterations */
  285.     xposition = yposition = 0;       /* dummy up a few pointers */
  286.     xpagesize = ypagesize = 2000;
  287.     set_win_offset();
  288.         
  289.     ShowWindow(hwnd, nCmdShow);
  290.     UpdateWindow(hwnd);
  291.  
  292.     /* let's ensure that we have at lease 40K of free memory */
  293.     {
  294.     HANDLE temphandle;
  295.     if (!(temphandle = GlobalAlloc(GMEM_FIXED,40000L)) ||
  296.         !(htemp_array = GlobalAlloc(GMEM_FIXED, sizeof(double) * 8001))) {
  297.         MessageBox (
  298.             GetFocus(),
  299.             "There isn't enough available\nmemory to run Winfract.",
  300.             "Fractint For Windows",
  301.             MB_ICONSTOP | MB_OK);
  302.         return(FALSE);
  303.         }
  304.         GlobalLock(temphandle);
  305.         GlobalUnlock(temphandle);
  306.         GlobalFree(temphandle);
  307.         temp_array = (double far *)GlobalLock(htemp_array);
  308.     }
  309.  
  310.    MakeHelpPathName(szHelpFileName);
  311.  
  312.     /* so, what kind of a display are we using, anyway? */
  313.     hDC = GetDC(NULL);
  314.     iPalSize    = GetDeviceCaps (hDC, SIZEPALETTE);
  315.     iRasterCaps = GetDeviceCaps (hDC, RASTERCAPS);
  316.     iRasterCaps = (iRasterCaps & RC_PALETTE) ? TRUE : FALSE;
  317.     if (iRasterCaps)
  318.        iNumColors = GetDeviceCaps(hDC, SIZEPALETTE);
  319.     else
  320.        iNumColors = GetDeviceCaps(hDC, NUMCOLORS);
  321.     ReleaseDC(NULL,hDC);
  322.  
  323.     /* fudges for oddball stuff (is there any?) */
  324.     /* also, note that "true color" devices return -1 for NUMCOLORS */
  325.     colors = iNumColors;
  326.     if (colors < 2 || colors > 16) colors = 256;
  327.     if (colors > 2 && colors < 16) colors = 16;
  328.  
  329.      /* Allocate enough memory for a logical palette with
  330.       * PALETTESIZE entries and set the size and version fields
  331.       * of the logical palette structure.
  332.       */
  333.      if (!(hLogPal = GlobalAlloc (GMEM_FIXED,
  334.         (sizeof (LOGPALETTE) +
  335.         (sizeof (PALETTEENTRY) * (PALETTESIZE)))))) {
  336.         MessageBox (
  337.             GetFocus(),
  338.             "There isn't enough available\nmemory to run Winfract..",
  339.             "Fractint For Windows",
  340.             MB_ICONSTOP | MB_OK);
  341.         return(FALSE);
  342.           }
  343.     pLogPal = (LPLOGPALETTE)GlobalLock(hLogPal); 
  344.     pLogPal->palVersion    = 0x300;
  345.     pLogPal->palNumEntries = PALETTESIZE;
  346.     /* fill in intensities for all palette entry colors */
  347.     for (iLoop = 0; iLoop < PALETTESIZE; iLoop++) {
  348.         pLogPal->palPalEntry[iLoop].peRed   = iLoop;
  349.         pLogPal->palPalEntry[iLoop].peGreen = 0;
  350.         pLogPal->palPalEntry[iLoop].peBlue  = 0;
  351.         pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT;
  352.         }
  353.     /* flip the ugly red color #1 with the pretty blue color #4 */
  354.     if (iNumColors < 0 || iNumColors > 4) {
  355.         pLogPal->palPalEntry[1].peRed = 4;
  356.         pLogPal->palPalEntry[4].peRed = 1;
  357.         }
  358.     /*  create a logical color palette according the information
  359.         in the LOGPALETTE structure. */
  360.     hPal = CreatePalette ((LPLOGPALETTE) pLogPal) ;
  361.     hDC = GetDC(GetFocus());
  362.     SetMapMode(hDC,MM_TEXT);
  363.     SelectPalette (hDC, hPal, 1);
  364.     RealizePalette(hDC);
  365.     /* get the "real" colors */
  366.     jLoop = iNumColors;
  367.     if (jLoop < 0) jLoop = -1;
  368.     for (iLoop = 0; iLoop < PALETTESIZE; iLoop++){
  369.         if (++jLoop >= iNumColors)
  370.             if (iNumColors > 0)
  371.                 jLoop = 0;
  372.         ThisColor = GetNearestColor (hDC, PALETTEINDEX (jLoop) );
  373.         win_dacbox[iLoop][0] = dacbox[iLoop][0] =
  374.             ((BYTE)GetRValue (ThisColor)) >> 2;
  375.         win_dacbox[iLoop][1] = dacbox[iLoop][1] =
  376.             ((BYTE)GetGValue (ThisColor)) >> 2;
  377.         win_dacbox[iLoop][2] = dacbox[iLoop][2] =
  378.             ((BYTE)GetBValue (ThisColor)) >> 2;
  379.         }
  380.     ReleaseDC(GetFocus(),hDC);
  381.  
  382.     /* allocate a device-independent bitmap header */
  383.     if (!(hDibInfo = GlobalAlloc(GMEM_FIXED,
  384.         sizeof(BITMAPINFOHEADER)+256*sizeof(PALETTEENTRY)))) {
  385.         MessageBox (
  386.             GetFocus(),
  387.             "There isn't enough available\nmemory to run Winfract...",
  388.             "Fractint For Windows",
  389.             MB_ICONSTOP | MB_OK);
  390.         return(FALSE);
  391.         }
  392.     pDibInfo = (LPBITMAPINFO)GlobalLock(hDibInfo);
  393.     /* fill in the header */
  394.     pDibInfo->bmiHeader.biSize  = (long)sizeof(BITMAPINFOHEADER);
  395.     pDibInfo->bmiHeader.biWidth  = win_xdots;
  396.     pDibInfo->bmiHeader.biHeight = win_ydots;
  397.     pDibInfo->bmiHeader.biSizeImage = (DWORD)win_xdots * win_ydots;
  398.     pDibInfo->bmiHeader.biPlanes = 1;
  399.     pDibInfo->bmiHeader.biBitCount = 8;
  400.     pDibInfo->bmiHeader.biCompression = BI_RGB;
  401.     pDibInfo->bmiHeader.biXPelsPerMeter = 0L;
  402.     pDibInfo->bmiHeader.biYPelsPerMeter = 0L;
  403.     pDibInfo->bmiHeader.biClrUsed = 0L;
  404.     pDibInfo->bmiHeader.biClrImportant = 0L;
  405.     default_dib_palette();
  406.  
  407.     /* allocate and lock a pixel array for the initial bitmap */
  408.     hpixels = (HANDLE) 0;
  409.     pixels = (char huge *) NULL;
  410.     if (clear_screen(0))
  411.         return(TRUE);
  412.  
  413.     MessageBox (
  414.         GetFocus(),
  415.         "There isn't enough available\nmemory to run Winfract....",
  416.         "Fractint For Windows",
  417.          MB_ICONSTOP | MB_OK);
  418.  
  419.     return (FALSE);
  420.  
  421. }
  422.  
  423. /****************************************************************************
  424.  
  425.     FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
  426.  
  427.     PURPOSE:  Processes messages
  428.  
  429. ****************************************************************************/
  430.  
  431. void lmemcpy(  LPSTR to,  LPSTR from, long len)
  432. {
  433. long i;
  434.  
  435. for (i = 0; i < len; i++)
  436.   to[i] = from[i];
  437. }
  438.  
  439. long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
  440. HWND hWnd;                /* handle to main window */
  441. unsigned message;
  442. WORD wParam;
  443. LONG lParam;
  444. {
  445.  
  446.     RECT tempRect;
  447.  
  448.     int IOStatus;                           /* result of file i/o      */
  449.     int Return;
  450.     int i, fchoice;
  451.  
  452.     switch (message) {
  453.  
  454.        case WM_KEYDOWN:
  455.            switch (wParam) {
  456.                case VK_F1:
  457.                /* F1, shifted F1 bring up the Help Index */
  458.                    WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
  459.                    break;
  460.                
  461.                case VK_SPACE:
  462.                /* Space/etc.. toggles Color-cycling parameters */
  463.                    if (time_to_cycle == 1)
  464.                        time_to_cycle = 0;
  465.                    else 
  466.                        if (win_oktocycle())
  467.                             time_to_cycle = 1;
  468.                    break;
  469.                case VK_RIGHT:
  470.                case VK_ADD: 
  471.                    if (win_oktocycle()) {
  472.                        time_to_cycle = 1;
  473.                        win_cycledir = -1;
  474.                        }
  475.                    break;
  476.                case VK_LEFT:
  477.                case VK_SUBTRACT: 
  478.                    if (win_oktocycle()) {
  479.                        time_to_cycle = 1;
  480.                        win_cycledir = 1;
  481.                        }
  482.                    break;
  483.                case VK_RETURN: 
  484.                    if (win_oktocycle()) {
  485.                        time_to_cycle = 1;
  486.                        win_cyclerand = 2;
  487.                        }
  488.                    break;
  489.                }
  490.            break;
  491.  
  492.         case WM_LBUTTONDOWN:           /* message: left mouse button pressed */
  493.  
  494.             /* Start selection of region */
  495.  
  496.             bTrack = TRUE;
  497.             SetRectEmpty(&Rect);
  498.             StartSelection(hWnd, MAKEPOINT(lParam), &Rect,
  499.                 (wParam & MK_SHIFT) ? (SL_EXTEND | Shape) : Shape);
  500.             break;
  501.  
  502.         case WM_MOUSEMOVE:                        /* message: mouse movement */
  503.  
  504.             /* Update the selection region */
  505.  
  506.             if (bTrack)
  507.                 UpdateSelection(hWnd, MAKEPOINT(lParam), &Rect, Shape);
  508.             if(CoordBoxOpen)
  509.                 UpdateCoordBox(lParam);
  510.             break;
  511.  
  512.         case WM_LBUTTONUP:            /* message: left mouse button released */
  513.  
  514.             if (bTrack) {
  515.  
  516.                /* End the selection */
  517.  
  518.                EndSelection(MAKEPOINT(lParam), &Rect);
  519.  
  520.                ClearSelection(hWnd, &Rect, Shape);
  521.                
  522.                if (abs(Rect.bottom - Rect.top ) > 5 &&
  523.                    abs(Rect.right  - Rect.left) > 5) {
  524.                    
  525.                    float win_aspect, zoom_aspect, rel_aspect;
  526.  
  527.                    ytop    = Rect.top;
  528.                    ybottom = Rect.bottom;
  529.                    xleft   = Rect.left;
  530.                    xright  = Rect.right;
  531.                    xleft    = xleft   + win_xoffset;
  532.                    ytop     = ytop    + win_yoffset;
  533.                    xright   = xright  + win_xoffset;
  534.                    ybottom  = ybottom + win_yoffset;
  535.                    
  536.                    /* adjust the zoom-box for aspect ratio */
  537.                    win_aspect = (float)ydots/(float)xdots;
  538.                    zoom_aspect = (float)(ybottom-ytop+1)/(float)(xright-xleft+1);
  539.                    rel_aspect = win_aspect/zoom_aspect;
  540.                    
  541.                    if (rel_aspect > 1.0 && rel_aspect < 1.50) {
  542.                        ybottom = ytop + ((xright-xleft+1)*win_aspect) - 1;
  543.                        if (ybottom >= ydots) ybottom = ydots-1;
  544.                        }
  545.                    if (rel_aspect < 1.0 && rel_aspect > 0.66) {
  546.                        xright = xleft + ((ybottom-ytop+1)/win_aspect) - 1;
  547.                        if (xright >= xdots) xright = xdots-1;
  548.                        }
  549.                    
  550.                    zoomflag = TRUE;
  551.                    time_to_restart = 1;
  552.                    time_to_cycle = 0;
  553.                    calc_status = 0;
  554.                    }
  555.  
  556.                bTrack = FALSE;
  557.  
  558.             }
  559.             break;
  560.  
  561.         case WM_RBUTTONUP:
  562.             {
  563.             int xx, yy;
  564.             xx = LOWORD(lParam);
  565.             yy = HIWORD(lParam);
  566.             if (xx >= xdots || yy >= ydots) 
  567.                 break;
  568.             if (fractalspecific[fractype].tojulia != NOFRACTAL
  569.                 && param[0] == 0.0 && param[1] == 0.0) {
  570.                 /* switch to corresponding Julia set */
  571.                 fractype = fractalspecific[fractype].tojulia;
  572.                 param[0] = xxmin + (xxmax - xxmin) * xx / xdots;
  573.                 param[1] = yymax - (yymax - yymin) * yy / ydots;
  574.                 jxxmin = xxmin; jxxmax = xxmax;
  575.                 jyymax = yymax; jyymin = yymin;
  576.                 jxx3rd = xx3rd; jyy3rd = yy3rd;
  577.                 frommandel = 1;
  578.                 xxmin = fractalspecific[fractype].xmin;
  579.                 xxmax = fractalspecific[fractype].xmax;
  580.                 yymin = fractalspecific[fractype].ymin;
  581.                 yymax = fractalspecific[fractype].ymax;
  582.                 xx3rd = xxmin;
  583.                 yy3rd = yymin;
  584.                 if(biomorph != -1 && bitshift != 29) {
  585.                    xxmin *= 3.0;
  586.                    xxmax *= 3.0;
  587.                    yymin *= 3.0;
  588.                    yymax *= 3.0;
  589.                    xx3rd *= 3.0;
  590.                    yy3rd *= 3.0;
  591.                    }
  592.                 calc_status = 0;
  593.                 }
  594.             else if (fractalspecific[fractype].tomandel != NOFRACTAL) {
  595.                 /* switch to corresponding Mandel set */
  596.                 fractype = fractalspecific[fractype].tomandel;
  597.                 if (frommandel) {
  598.                     xxmin = jxxmin;  xxmax = jxxmax;
  599.                     yymin = jyymin;  yymax = jyymax;
  600.                     xx3rd = jxx3rd;  yy3rd = jyy3rd;
  601.                     }
  602.                 else {
  603.                     double ccreal,ccimag;
  604.                     ccreal = (fractalspecific[fractype].xmax - fractalspecific[fractype].xmin) / 2;
  605.                     ccimag = (fractalspecific[fractype].ymax - fractalspecific[fractype].ymin) / 2;
  606.                     xxmin = xx3rd = param[0] - ccreal;
  607.                     xxmax = param[0] + ccreal;
  608.                     yymin = yy3rd = param[1] - ccimag;
  609.                     yymax = param[1] + ccimag;
  610.                     }
  611.                 frommandel = 0;
  612.                 param[0] = 0;
  613.                 param[1] = 0;
  614.                 calc_status = 0;
  615.                 }
  616.             else {
  617.                 buzzer(2); /* can't switch */
  618.                 break;
  619.                 }
  620.  
  621.             ytop    = 0;
  622.             ybottom = ydots-1;
  623.             xleft   = 0;
  624.             xright  = xdots-1;
  625.  
  626.             time_to_restart  = 1;
  627.             time_to_cycle = 0;
  628.             calc_status = 0;
  629.             }
  630.             break;
  631.  
  632.         case WM_CREATE:
  633.  
  634.             /* the scroll bars are hard-coded to 100 possible values */
  635.             xposition = yposition = 0;      /* initial scroll-bar positions */
  636.             SetScrollRange(hWnd,SB_HORZ,0,100,FALSE);
  637.             SetScrollRange(hWnd,SB_VERT,0,100,FALSE);
  638.             SetScrollPos(hWnd,SB_HORZ,xposition,TRUE);
  639.             SetScrollPos(hWnd,SB_VERT,yposition,TRUE);
  640.             break;
  641.  
  642.         case WM_SIZE:
  643.             xpagesize = LOWORD(lParam);        /* remember the window size */
  644.             ypagesize = HIWORD(lParam);
  645.             set_win_offset();
  646.             break;
  647.         case WM_HSCROLL:
  648.             switch (wParam) {
  649.                case SB_LINEDOWN:       xposition += 1; break;
  650.                case SB_LINEUP:         xposition -= 1; break;
  651.                case SB_PAGEDOWN:       xposition += 10; break;
  652.                case SB_PAGEUP:         xposition -= 10; break;
  653.                case SB_THUMBPOSITION:  xposition = LOWORD(lParam);
  654.                default:                break;
  655.                }
  656.             if (xposition > 100) xposition = 100;
  657.             if (xposition <     0) xposition = 0;
  658.             if (xposition != GetScrollPos(hWnd,SB_HORZ)) {
  659.                SetScrollPos(hWnd,SB_HORZ,xposition,TRUE);
  660.                InvalidateRect(hWnd,NULL,TRUE);
  661.                }
  662.             set_win_offset();
  663.            break;
  664.         case WM_VSCROLL:
  665.             switch (wParam) {
  666.                case SB_LINEDOWN:       yposition += 1; break;
  667.                case SB_LINEUP:         yposition -= 1; break;
  668.                case SB_PAGEDOWN:       yposition += 10; break;
  669.                case SB_PAGEUP:         yposition -= 10; break;
  670.                case SB_THUMBPOSITION:  yposition = LOWORD(lParam);
  671.                default:                break;
  672.                }
  673.             if (yposition > 100) yposition = 100;
  674.             if (yposition <     0) yposition = 0;
  675.             if (yposition != GetScrollPos(hWnd,SB_VERT)) {
  676.                SetScrollPos(hWnd,SB_VERT,yposition,TRUE);
  677.                InvalidateRect(hWnd,NULL,TRUE);
  678.                }
  679.             set_win_offset();
  680.             break;
  681.         case WM_CLOSE:
  682.             goto GlobalExit;
  683.  
  684.         case WM_COMMAND:
  685.             switch (wParam) {
  686.                 case IDM_COORD:
  687.                     CoordinateBox(hWnd);
  688.                     break;
  689.                 case IDM_ABOUT:
  690.                     lpProcAbout = MakeProcInstance(About, hInst);
  691.                     DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
  692.                     FreeProcInstance(lpProcAbout);
  693.                     break;
  694.  
  695.                case IDM_HELP_INDEX:
  696.                    WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
  697.                    break;
  698.  
  699.                case IDM_HELP_KEYBOARD:
  700.            WinHelp(hWnd,szHelpFileName,HELP_KEY,(DWORD)(LPSTR)"keys");
  701.                    break;
  702.  
  703.                case IDM_HELP_HELP:
  704.            WinHelp(hWnd,"WINHELP.HLP",HELP_INDEX,0L);
  705.                    break;
  706.                    
  707.                 case IDM_COPY:
  708.                    /* allocate the memory for the BITMAPINFO structure 
  709.                       (followed by the bitmap bits) */
  710.                    if (!(hClipboard1 = GlobalAlloc(GMEM_FIXED,
  711.                    sizeof(BITMAPINFOHEADER)+colors*sizeof(PALETTEENTRY)
  712.                    + win_bitmapsize))) {
  713.                         cant_clip();
  714.                         return(TRUE);
  715.                         }
  716.                     if (!(lpClipboard1 = 
  717.                         (LPSTR) GlobalLock(hClipboard1))) {
  718.                         GlobalFree(hClipboard1);
  719.                         cant_clip();
  720.                         return(TRUE);
  721.                         }
  722.                     rgb_dib_palette();
  723.                     lmemcpy((LPSTR)lpClipboard1, (LPSTR)pDibInfo,
  724.                         sizeof(BITMAPINFOHEADER)+colors*sizeof(RGBQUAD)
  725.                         );
  726.                     lpClipboard1 += 
  727.                         (sizeof(BITMAPINFOHEADER))+
  728.                         (colors*sizeof(RGBQUAD));
  729.                     lmemcpy((LPSTR)lpClipboard1, (LPSTR)pixels,
  730.                         win_bitmapsize);
  731.                     GlobalUnlock(hClipboard1);
  732.  
  733.                    /* allocate the memory for the palette info */
  734.                    if (!lpClipboard2) {
  735.                        if (!(hClipboard2 = GlobalAlloc (GMEM_FIXED,
  736.                            (sizeof (LOGPALETTE) +
  737.                            (sizeof (PALETTEENTRY) * (PALETTESIZE)))))) {
  738.                             GlobalFree(hClipboard1);
  739.                             cant_clip();
  740.                             return(TRUE);
  741.                             }
  742.                         if (!(lpClipboard2 = 
  743.                             (LPSTR) GlobalLock(hClipboard2))) {
  744.                             GlobalFree(hClipboard1);
  745.                             GlobalFree(hClipboard2);
  746.                             cant_clip();
  747.                             return(TRUE);
  748.                             }
  749.                        }
  750.                    /* fill in the palette info */
  751.                    lpClipboard2[0] = 0;
  752.                    lpClipboard2[1] = 3;
  753.                    lpClipboard2[2] = 0;
  754.                    lpClipboard2[3] = 1;
  755.                    lmemcpy((LPSTR)&lpClipboard2[4],
  756.                         (LPSTR)&pDibInfo->bmiColors[0],
  757.                         PALETTESIZE*sizeof(RGBQUAD)
  758.                         );
  759.                    hClipboard3 = CreatePalette ((LPLOGPALETTE) lpClipboard2);
  760.  
  761.                     if (OpenClipboard(hWnd)) {
  762.                         EmptyClipboard();
  763.                         SetClipboardData(CF_PALETTE, hClipboard3);
  764.                         SetClipboardData(CF_DIB, hClipboard1);
  765.                         CloseClipboard();
  766.                         }
  767.  
  768.                     default_dib_palette();
  769.  
  770.                     break;
  771.  
  772.                 case IDM_NEW:
  773.                 case IDM_OPEN:
  774.                 case IDM_3D:
  775.                 case IDM_3DOVER:
  776.                     win_display3d = 0;
  777.                     win_overlay3d = 0;
  778.                     /* Call OpenDlg() to get the filename */
  779.                     strcpy(DialogTitle,"Select a File to Open");
  780.                     strcpy(FileName, readname);
  781.                     strcpy(DefSpec,"*.gif");
  782.                     strcpy(DefExt,".gif");
  783.                     lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
  784.                     Return = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
  785.                     FreeProcInstance(lpOpenDlg);
  786.                     if (Return && (wParam == IDM_3D || wParam == IDM_3DOVER)) {
  787.                         lpSelect3D = MakeProcInstance(
  788.                             (FARPROC) Select3D, hInst);
  789.                         Return = DialogBox(hInst, "Select3D",
  790.                              hWnd, lpSelect3D);
  791.                         FreeProcInstance(lpSelect3D);
  792.                         if (Return && !win_3dspherical) {
  793.                             lpSelect3DPlanar = MakeProcInstance(
  794.                                 (FARPROC) Select3DPlanar, hInst);
  795.                             Return = DialogBox(hInst, "Select3DPlanar",
  796.                                  hWnd, lpSelect3DPlanar);
  797.                             FreeProcInstance(lpSelect3DPlanar);
  798.                             }
  799.                         if (Return && win_3dspherical) {
  800.                             lpSelect3DSpherical = MakeProcInstance(
  801.                                 (FARPROC) Select3DSpherical, hInst);
  802.                             Return = DialogBox(hInst, "Select3DSpherical",
  803.                                  hWnd, lpSelect3DSpherical);
  804.                             FreeProcInstance(lpSelect3DSpherical);
  805.                             }
  806.                         }
  807.                     if (Return) {
  808.                         strcpy(readname,FileName);
  809.                         time_to_load = 1;
  810.                         time_to_cycle = 0;
  811.                         if (wParam == IDM_3D || wParam == IDM_3DOVER)
  812.                             win_display3d = 1;
  813.                         if (wParam == IDM_3DOVER)
  814.                             win_overlay3d = 1;
  815.                         }
  816.                     break;
  817.  
  818.                 case IDM_MAPIN:
  819.                 case IDM_MAPOUT:
  820.                     if (!win_oktocycle())
  821.                         break;
  822.                     /* Call OpenDlg() to get the filename */
  823.                     strcpy(DialogTitle,"Select a File to Open");
  824.                     strcpy(FileName, "default");
  825.                     if (wParam == IDM_MAPOUT)
  826.                         strcpy(FileName, "mymap");
  827.                     strcpy(DefSpec,"*.map");
  828.                     strcpy(DefExt,".map");
  829.                     lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
  830.                     Return = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
  831.                     FreeProcInstance(lpOpenDlg);
  832.                     if (Return && wParam == IDM_MAPIN) {
  833.                         ValidateLuts(FileName);
  834.                         spindac(0,1);
  835.                         }
  836.                     if (Return && wParam == IDM_MAPOUT) {
  837.                         FILE *dacfile;
  838.             dacfile = fopen(FileName,"w");
  839.             if (dacfile == NULL) {
  840.                 break;
  841.                 }
  842.             fprintf(dacfile,"  0   0   0\n");
  843.             for (i = 1; i < 256; i++)
  844.                 fprintf(dacfile, "%3d %3d %3d\n",
  845.                 dacbox[i][0] << 2,
  846.                 dacbox[i][1] << 2,
  847.                 dacbox[i][2] << 2);
  848.             fclose(dacfile);
  849.                         }
  850.                     break;
  851.  
  852.                 case IDM_SAVE:
  853.                 case IDM_SAVEAS:
  854.                     /* Call the SaveAsDlg() function to get the new filename */
  855.                     strcpy(DialogTitle,"Select a File to Save");
  856.                     strcpy(FileName, readname);
  857.                     strcpy(DefSpec,"*.gif");
  858.                     strcpy(DefExt,".gif");
  859.                     lpSaveAsDlg = MakeProcInstance(SaveAsDlg, hInst);
  860.                     Return = DialogBox(hInst, "SaveAs", hWnd, lpSaveAsDlg);
  861.                     FreeProcInstance(lpSaveAsDlg);
  862.                     Return = time_to_save; /* ?? ugly klooge */
  863.                     if (Return) {
  864.                         strcpy(readname,FileName);
  865.                         time_to_save = 1;
  866.                         time_to_cycle = 0;
  867.                         }
  868.                     break;                                  /* User canceled */
  869.  
  870.                 case IDM_PRINT:
  871.                     time_to_print = 1;
  872.                     time_to_cycle = 0;
  873.                     break;
  874.  
  875.                 case IDM_FORMULA:
  876.                     strcpy(DialogTitle,"Select a Fractal Formula");
  877.                     win_numchoices = CountFractalList;
  878.                     win_choicemade = 0;
  879.                     CurrentFractal = fractype;
  880.                     for (i = 0; i < win_numchoices; i++) {
  881.                         win_choices[i] = fractalspecific[onthelist[i]].name;
  882.                         if (onthelist[i] == fractype ||
  883.                             fractalspecific[onthelist[i]].tofloat == fractype)
  884.                             win_choicemade = i;
  885.                         }
  886.                     lpSelectFractal = MakeProcInstance(SelectFractal, hInst);
  887.                     Return = DialogBox(hInst, "SelectFractal",
  888.                         hWnd, lpSelectFractal);
  889.                     FreeProcInstance(lpSelectFractal);
  890.                     fchoice = win_choicemade;
  891.                     if (Return && onthelist[fchoice] == IFS) {
  892.                         /* obtain the IFS filename */
  893.                         strcpy(DialogTitle,"Select an IFS Filename");
  894.                         strcpy(FileName, FormFileName);
  895.                         strcpy(DefSpec,"*.ifs");
  896.                         strcpy(DefExt,".ifs");
  897.                         lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
  898.                         Return = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
  899.                         FreeProcInstance(lpOpenDlg);
  900.                         if (Return) {
  901.                             strcpy(ifsfilename, FileName);
  902.                             ifsgetfile();
  903.                             }
  904.                         }
  905.                     if (Return && onthelist[fchoice] == IFS3D) {
  906.                         /* obtain the IFS filename */
  907.                         strcpy(DialogTitle,"Select an IFS Filename");
  908.                         strcpy(FileName, FormFileName);
  909.                         strcpy(DefSpec,"*.ifs");
  910.                         strcpy(DefExt,".ifs");
  911.                         lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
  912.                         Return = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
  913.                         FreeProcInstance(lpOpenDlg);
  914.                         if (Return) {
  915.                             strcpy(ifs3dfilename, FileName);
  916.                             ifs3dgetfile();
  917.                             }
  918.                         }
  919.                     if (Return && (onthelist[fchoice] == FORMULA || 
  920.                         onthelist[fchoice] == FFORMULA)) {
  921.                         /* obtain the formula filename */
  922.                         strcpy(DialogTitle,"Select a Formula File");
  923.                         strcpy(FileName, FormFileName);
  924.                         strcpy(DefSpec,"*.frm");
  925.                         strcpy(DefExt,".frm");
  926.                         lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
  927.                         Return = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
  928.                         FreeProcInstance(lpOpenDlg);
  929.                         if (Return) {
  930.                             strcpy(FormFileName, FileName);
  931.                             get_formula_names();
  932.                             strcpy(DialogTitle,"Select a Formula");
  933.                             win_choicemade = 0;
  934.                             lpSelectFractal = MakeProcInstance(SelectFractal, hInst);
  935.                             Return = DialogBox(hInst, "SelectFractal",
  936.                                 hWnd, lpSelectFractal);
  937.                             FreeProcInstance(lpSelectFractal);
  938.                             if (Return) 
  939.                                 Return = parse_formula_names();
  940.                             }
  941.                         }
  942.                     if (Return && (onthelist[fchoice] == LSYSTEM)) {
  943.                         /* obtain the lsystem formula filename */
  944.                         strcpy(DialogTitle,"Select an Lsystem File");
  945.                         strcpy(FileName, LFileName);
  946.                         strcpy(DefSpec,"*.l");
  947.                         strcpy(DefExt,".l");
  948.                         lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
  949.                         Return = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
  950.                         FreeProcInstance(lpOpenDlg);
  951.                         if (Return) {
  952.                             strcpy(LFileName, FileName);
  953.                             get_lsys_name();
  954.                             strcpy(DialogTitle,"Select a Formula");
  955.                             win_choicemade = 0;
  956.                             lpSelectFractal = MakeProcInstance(SelectFractal, hInst);
  957.                             Return = DialogBox(hInst, "SelectFractal",
  958.                                 hWnd, lpSelectFractal);
  959.                             FreeProcInstance(lpSelectFractal);
  960.                             if (Return) {
  961.                                 strcpy(LName, win_choices[win_choicemade]);
  962.                                 Return = !LLoad();
  963.                                 }
  964.                             }
  965.                         }
  966.                     if (Return) {
  967.                         CurrentFractal = onthelist[fchoice];
  968.                         lpSelectFracParams = MakeProcInstance(SelectFracParams,
  969.                             hInst);
  970.                         Return = DialogBox(hInst, "SelectFracParams",
  971.                             hWnd, lpSelectFracParams);
  972.                         FreeProcInstance(lpSelectFracParams);
  973.                         }
  974.                     if (Return) {
  975.             restoredac();
  976.                         time_to_reinit = 1;
  977.                         time_to_cycle = 0;
  978.                         calc_status = 0;
  979.                         }
  980.                     break;
  981.  
  982.                 case IDM_IMAGE:
  983.             lpSelectImage = MakeProcInstance(SelectImage, hInst);
  984.             Return = DialogBox(hInst, "SelectImage",
  985.                 hWnd, lpSelectImage);
  986.             FreeProcInstance(lpSelectImage);
  987.             if (Return) {
  988.                 restoredac();
  989.                 time_to_restart = 1;
  990.                                 time_to_cycle = 0;
  991.                                 calc_status = 0;
  992.                 }
  993.                         break;
  994.  
  995.                 case IDM_DOODADS:
  996.             lpSelectDoodads = MakeProcInstance(SelectDoodads, hInst);
  997.             Return = DialogBox(hInst, "SelectDoodads",
  998.                 hWnd, lpSelectDoodads);
  999.             FreeProcInstance(lpSelectDoodads);
  1000.             if (Return) {
  1001.                 restoredac();
  1002.                 time_to_restart = 1;
  1003.                                 time_to_cycle = 0;
  1004.                                 calc_status = 0;
  1005.                 }
  1006.                         break;
  1007.  
  1008.                 case IDM_CYCLE:
  1009.                     if (!win_oktocycle())
  1010.                         break;
  1011.                     lpSelectCycle = MakeProcInstance(SelectCycle, hInst);
  1012.                     Return = DialogBox(hInst, "SelectCycle",
  1013.                     hWnd, lpSelectCycle);
  1014.                     FreeProcInstance(lpSelectCycle);
  1015.                     break;
  1016.  
  1017.                 case IDM_MATH_TOOLS:
  1018.                     MathToolBox(hWnd);
  1019.                     break;
  1020.  
  1021.                 case IDS_STATUS:
  1022.                     lpProcStatus = MakeProcInstance(Status, hInst);
  1023.                     DialogBox(hInst, "ShowStatus", hWnd, lpProcStatus);
  1024.                     FreeProcInstance(lpProcStatus);
  1025.                     break;
  1026.  
  1027.                 GlobalExit:
  1028.                 case IDM_EXIT:
  1029.                     time_to_quit = 1;
  1030.                     time_to_cycle = 0;
  1031.                     ValidateRect(hWnd, NULL);
  1032.                     hWndCopy = hWnd;
  1033.                     /* the main routine will actually call 'DestroyWindow()' */
  1034.                     break;
  1035.  
  1036.                 case IDC_EDIT:
  1037.                     if (HIWORD (lParam) == EN_ERRSPACE) {
  1038.                         MessageBox (
  1039.                               GetFocus ()
  1040.                             , "Out of memory."
  1041.                             , "Fractint For Windows"
  1042.                             , MB_ICONSTOP | MB_OK
  1043.                         );
  1044.                     }
  1045.                     break;
  1046.  
  1047.             } 
  1048.             break;
  1049.  
  1050.         case WM_PAINT:
  1051.             if (screen_to_be_cleared && last_written_y < 0) {
  1052.                  /* an empty window */
  1053.                  screen_to_be_cleared = 0;
  1054.                  GetUpdateRect(hWnd, &tempRect, TRUE);
  1055.                  hDC = BeginPaint(hWnd,&ps);
  1056.                  if (last_written_y == -2)
  1057.                      last_written_y = -1;
  1058.                  else
  1059.                      BitBlt(hDC, 0, 0, xdots, ydots,
  1060.                          NULL, 0, 0, BLACKNESS);
  1061.                  ValidateRect(hWnd, &tempRect);
  1062.                  EndPaint(hWnd,&ps);
  1063.                  break;
  1064.                  }
  1065.             screen_to_be_cleared = 0;
  1066.             GetUpdateRect(hWnd, &tempRect, FALSE);
  1067.             hDC = BeginPaint(hWnd,&ps);
  1068.             if (last_written_y >= 0) {
  1069.               int i, j, top, bottom, left, right, xcount, ycount;
  1070.               /* bit-blit the invalidated bitmap area */
  1071.               int fromleft, fromtop, fromright, frombottom;
  1072.               long firstpixel;
  1073.               top    = tempRect.top;
  1074.               bottom = tempRect.bottom;
  1075.               left   = tempRect.left;
  1076.               right  = tempRect.right;
  1077.               if (bottom >  ydots) bottom = ydots;
  1078.               if (right  >= xdots) right  = xdots-1;
  1079.               if (top    >  ydots) top    = ydots;
  1080.               if (left   >= xdots) left   = xdots;
  1081.               fromleft  = left  + win_xoffset;
  1082.               fromright = right + win_xoffset;
  1083.               fromtop    = top    + win_yoffset;
  1084.               frombottom = bottom + win_yoffset;
  1085.               xcount = fromright - fromleft + 1;
  1086.               ycount = frombottom - fromtop;
  1087.               firstpixel = win_ydots - frombottom;
  1088.               firstpixel = firstpixel * bytes_per_pixelline;
  1089.               if (left < xdots && top < ydots) {
  1090.                   SelectPalette (hDC, hPal, 0);
  1091.                   RealizePalette(hDC);
  1092.                   SetMapMode(hDC,MM_TEXT);
  1093.                   SetDIBitsToDevice(hDC,
  1094.                        left, top,
  1095.                        xcount, ycount,
  1096.                        fromleft, 0,
  1097.                        0, ydots,
  1098.                        &pixels[firstpixel], (LPBITMAPINFO)pDibInfo,
  1099.                        DIB_PAL_COLORS);
  1100.                   }
  1101.               } 
  1102.             ValidateRect(hWnd, &tempRect);
  1103.             EndPaint(hWnd,&ps);
  1104.             break;
  1105.  
  1106.         case WM_DESTROY:
  1107.             /* delete the handle to the logical palette if it has any
  1108.                color entries and quit. */
  1109.             if (pLogPal->palNumEntries)
  1110.             DeleteObject (hPal);
  1111.             time_to_quit = 1;
  1112.             time_to_cycle = 0;
  1113.             WinHelp(hWnd,szHelpFileName,HELP_QUIT,0L);
  1114.             if (win_systempaletteused) 
  1115.                 win_stop_cycling();
  1116.             PostQuitMessage(0);
  1117.             break;
  1118.  
  1119.         case WM_ACTIVATE:
  1120.             if (!wParam) {  /* app. is being de-activated */
  1121.                 if (win_systempaletteused) 
  1122.                     win_stop_cycling();
  1123.                 break;
  1124.                 }
  1125.         case WM_QUERYNEWPALETTE:
  1126.             /* If palette realization causes a palette change,
  1127.              * we need to do a full redraw.
  1128.              */
  1129.              if (last_written_y >= 0) {
  1130.                  hDC = GetDC (hWnd);
  1131.                  SelectPalette (hDC, hPal, 0);
  1132.                  i = RealizePalette(hDC);
  1133.                  ReleaseDC (hWnd, hDC);
  1134.                  if (i) {
  1135.                      InvalidateRect (hWnd, (LPRECT) (NULL), 1);
  1136.                      return 1;
  1137.                      }
  1138.                  else
  1139.                      return FALSE;
  1140.                  }
  1141.              else
  1142.                  return FALSE;
  1143.              break;
  1144.  
  1145.         case WM_PALETTECHANGED:
  1146.             if (wParam != hWnd){
  1147.                 if (last_written_y >= 0) {
  1148.                     hDC = GetDC (hWnd);
  1149.                     SelectPalette (hDC, hPal, 0);
  1150.                     i = RealizePalette (hDC);
  1151.                     if (i)
  1152.                         UpdateColors (hDC);
  1153.                     else
  1154.                         InvalidateRect (hWnd, (LPRECT) (NULL), 1);
  1155.                     ReleaseDC (hWnd, hDC);
  1156.                     }
  1157.                 }
  1158.             break;
  1159.  
  1160.         default:
  1161.             return (DefWindowProc(hWnd, message, wParam, lParam));
  1162.     }
  1163.     return (NULL);
  1164. }
  1165.  
  1166. win_oktocycle()
  1167. {
  1168. if (!(iRasterCaps) || iNumColors < 16) {
  1169.     stopmsg(0,
  1170.         "I'm sorry, but color-cycling and\ncolor maps require a palette-based\nvideo driver."
  1171.          );
  1172.     return(0);
  1173.     }
  1174. return(1);
  1175. }
  1176.  
  1177. extern int win_animate_flag;
  1178.  
  1179. win_stop_cycling()
  1180. {
  1181. HDC hDC;                      /* handle to device context           */
  1182.  
  1183. hDC = GetDC(GetFocus());
  1184. SetSystemPaletteUse(hDC,SYSPAL_STATIC);
  1185. ReleaseDC(GetFocus(),hDC);
  1186.  
  1187. time_to_cycle = 0;
  1188. win_animate_flag = 0;
  1189. restoredac();
  1190. win_systempaletteused = FALSE;
  1191. SetSysColors(COLOR_ENDCOLORS,win_syscolorindex,win_syscolorold);
  1192. }
  1193.  
  1194. mono_dib_palette()
  1195. {
  1196. int i, j, k;        /* fill in the palette index values */
  1197.     for (i = 0; i < 128; i = i+2) {
  1198.         pDibInfo->bmiColors[i  ].rgbBlue      =   0;
  1199.         pDibInfo->bmiColors[i  ].rgbGreen     =   0;
  1200.         pDibInfo->bmiColors[i  ].rgbRed       =   0;
  1201.         pDibInfo->bmiColors[i  ].rgbReserved  =   0;
  1202.         pDibInfo->bmiColors[i+1].rgbBlue      = 255;
  1203.         pDibInfo->bmiColors[i+1].rgbGreen     = 255;
  1204.         pDibInfo->bmiColors[i+1].rgbRed       = 255;
  1205.         pDibInfo->bmiColors[i+1].rgbReserved  =   0;
  1206.         }
  1207. }
  1208.  
  1209. default_dib_palette()
  1210. {
  1211. int i, j, k;        /* fill in the palette index values */
  1212. int far *palette_values;    /* pointer to palette values */
  1213.  
  1214.     palette_values = (int far *)&pDibInfo->bmiColors[0];
  1215.     k = 0;
  1216.     for (i = 0; i < 256; i++) {
  1217.         palette_values[i] = k;
  1218.         if (++k >= iNumColors)
  1219.            if (iNumColors > 0)
  1220.                k = 0;
  1221.         }
  1222. }
  1223.  
  1224. rgb_dib_palette()
  1225. {
  1226. int i;        /* fill in the palette index values */
  1227.  
  1228.     for (i = 0; i < 256; i++) {
  1229.         pDibInfo->bmiColors[i].rgbRed       = dacbox[i][0] << 2;
  1230.         pDibInfo->bmiColors[i].rgbGreen     = dacbox[i][1] << 2;
  1231.         pDibInfo->bmiColors[i].rgbBlue      = dacbox[i][2] << 2;
  1232.         pDibInfo->bmiColors[i].rgbReserved  =   0;
  1233.         }
  1234. }
  1235.  
  1236.  
  1237. /****************************************************************************
  1238.  
  1239.    FUNCTION:   MakeHelpPathName
  1240.  
  1241.    PURPOSE:    Winfract assumes that the .HLP help file is in the same
  1242.                directory as the Winfract executable.This function derives
  1243.                the full path name of the help file from the path of the
  1244.                executable.
  1245.  
  1246. ****************************************************************************/
  1247.  
  1248. void MakeHelpPathName(szFileName)
  1249. char * szFileName;
  1250. {
  1251.    char *  pcFileName;
  1252.    int     nFileNameLen;
  1253.  
  1254.    nFileNameLen = GetModuleFileName(hInst,szFileName,EXE_NAME_MAX_SIZE);
  1255.    pcFileName = szFileName + nFileNameLen;
  1256.  
  1257.    while (pcFileName > szFileName) {
  1258.        if (*pcFileName == '\\' || *pcFileName == ':') {
  1259.            *(++pcFileName) = '\0';
  1260.            break;
  1261.        }
  1262.    nFileNameLen--;
  1263.    pcFileName--;
  1264.    }
  1265.  
  1266.    if ((nFileNameLen+13) < EXE_NAME_MAX_SIZE) {
  1267.        lstrcat(szFileName, "winfract.hlp");
  1268.    }
  1269.  
  1270.    else {
  1271.        lstrcat(szFileName, "?");
  1272.    }
  1273.  
  1274.    return;
  1275. }
  1276.  
  1277. set_win_offset()
  1278. {
  1279. win_xoffset = ((long)xposition*((long)xdots-(long)xpagesize))/100L;
  1280. win_yoffset = ((long)yposition*((long)ydots-(long)ypagesize))/100L;
  1281. if (win_xoffset+xpagesize > xdots) win_xoffset = xdots-xpagesize;
  1282. if (win_yoffset+ypagesize > ydots) win_yoffset = ydots-ypagesize;
  1283. if (xpagesize >= xdots) win_xoffset = 0;
  1284. if (ypagesize >= ydots) win_yoffset = 0;
  1285. }
  1286.  
  1287.  
  1288. /*
  1289.   Read a formula file, picking off the formula names.
  1290.   Formulas use the format "  name = { ... }  name = { ... } "
  1291. */
  1292.  
  1293. int get_formula_names()     /* get the fractal formula names */
  1294. {
  1295.    int numformulas, i;
  1296.    FILE *File;
  1297.    char msg[81], tempstring[201];
  1298.  
  1299.    FormName[0] = 0;        /* start by declaring failure */
  1300.    for (i = 0; i < MaxFormNameChoices; i++) {
  1301.       FormNameChoices[i][0] = 0;
  1302.       win_choices[i] = FormNameChoices[i];
  1303.       }
  1304.  
  1305.    if((File = fopen(FormFileName, "rt")) == NULL) {
  1306.       sprintf("I Can't find %s", FormFileName);
  1307.       stopmsg(1,msg);
  1308.       return(-1);
  1309.    }
  1310.  
  1311.    numformulas = 0;
  1312.    while(fscanf(File, " %20[^ \n\t({]", FormNameChoices[numformulas]) != EOF) {
  1313.       int c;
  1314.  
  1315.       while(c = getc(File)) {
  1316.      if(c == EOF || c == '{' || c == '\n')
  1317.         break;
  1318.       }
  1319.       if(c == EOF)
  1320.      break;
  1321.       else if(c != '\n'){
  1322.      numformulas++;
  1323.      if (numformulas >= MaxFormNameChoices) break;
  1324. skipcomments:
  1325.      if(fscanf(File, "%200[^}]", tempstring) == EOF) break;
  1326.      if (getc(File) != '}') goto skipcomments;
  1327.      if (stricmp(FormNameChoices[numformulas-1],"") == 0 ||
  1328.          stricmp(FormNameChoices[numformulas-1],"comment") == 0)
  1329.          numformulas--;
  1330.       }
  1331.    }
  1332.    fclose(File);
  1333.    win_numchoices = numformulas;
  1334.    qsort(FormNameChoices,win_numchoices,21,strcmp);
  1335.    return(0);
  1336. }
  1337.  
  1338. int parse_formula_names()     /* parse a fractal formula name */
  1339. {
  1340.  
  1341.    strcpy(FormName, win_choices[win_choicemade]);
  1342.  
  1343.    if (RunForm(FormName)) {
  1344.        FormName[0] = 0;     /* declare failure */
  1345.        stopmsg(0,"Can't Parse that Formula");
  1346.        return(0);
  1347.        }
  1348.  
  1349. return(1);
  1350. }
  1351.  
  1352. /* --------------------------------------------------------------------- */
  1353.  
  1354. get_lsys_name()        /* get the Lsystem formula name */
  1355. {
  1356.    int Litem;
  1357.    int numformulas, i;
  1358.    FILE *File;
  1359.    char buf[201];
  1360.  
  1361.    for (i = 0; i < MaxFormNameChoices; i++) {
  1362.       FormNameChoices[i][0] = 0;
  1363.       win_choices[i] = FormNameChoices[i];
  1364.       }
  1365.  
  1366.    if ((File = fopen(LFileName, "rt")) == NULL) {
  1367.       sprintf(buf,"I Can't find %s", LFileName);
  1368.       stopmsg(1,buf);
  1369.       LName[0] = 0;
  1370.       return(-1);
  1371.       }
  1372.  
  1373.    numformulas = 0;
  1374.    while (1) {
  1375.       int c;
  1376.       FormNameChoices[numformulas][0] = 0;
  1377.       if (fscanf(File, " %20[^ \n\t({]", FormNameChoices[numformulas]) == EOF)
  1378.      break;
  1379.       while(c = getc(File)) {
  1380.      if(c == EOF || c == '{' || c == '\n')
  1381.         break;
  1382.      }
  1383.       if(c == EOF)
  1384.      break;
  1385.       else if(c != '\n') {
  1386. skipcomments:
  1387.      if(fscanf(File, "%200[^}]", buf) == EOF) break;
  1388.      if (getc(File) != '}') goto skipcomments;
  1389.      if (stricmp(FormNameChoices[numformulas],"") != 0 &&
  1390.          stricmp(FormNameChoices[numformulas],"comment") != 0)
  1391.          if (++numformulas >= MaxFormNameChoices) break;
  1392.      }
  1393.       }
  1394.    fclose(File);
  1395.  
  1396.    win_numchoices = numformulas;
  1397.    qsort(FormNameChoices,win_numchoices,21,strcmp);
  1398.    return(0);
  1399. }
  1400.  
  1401. cant_clip()
  1402. {
  1403. MessageBox (
  1404.    GetFocus(),
  1405.    "Not Enough Free Memory to Copy to the Clipboard",
  1406.    "Fractint For Windows",
  1407.     MB_ICONSTOP | MB_OK);
  1408.     return(TRUE);
  1409. }
  1410.