home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------
- PMMANDEL.C -- OS/2 Presentation Manager Mandelbrot Set Program
- (c) Charles Petzold, 1990
-
- Compile using Microsoft C 6.0 for OS/2 1.2
- ----------------------------------------------------------------*/
-
- #define INCL_DOS
- #define INCL_WIN
- #define INCL_GPI
- #include <os2.h>
- #include <process.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "pmmandel.h"
-
- #define STACKSIZE (4096 * sizeof (int))
- #define DEF_MAX_ITERATIONS 500
- #define WM_IMAGE_COMPLETED (WM_USER + 1)
-
- typedef struct
- {
- double dxMin, dxMax, dyMin, dyMax ;
- }
- COORDDLGSTRUC ;
-
- typedef COORDDLGSTRUC *PCOORDDLGSTRUC ;
-
- typedef struct
- {
- BOOL fEnable16, fEnable256 ;
- SHORT sNumColors ;
- }
- COLORDLGSTRUC ;
-
- typedef COLORDLGSTRUC *PCOLORDLGSTRUC ;
-
- typedef struct
- {
- COORDDLGSTRUC cords ;
- COLORDLGSTRUC clrds ;
- BOOL fRestart, fTerminate ;
- HPS hpsClient, hpsMemory ;
- HWND hwndClient ;
- SHORT cxMaxClient, cyMaxClient, cxClient, cyClient, cyChar ;
- ULONG semTriggerDraw, semDoingDraw ;
- USHORT nMaxIterations ;
- }
- THREADPARAMS ;
-
- typedef THREADPARAMS *PTHREADPARAMS ;
-
- MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
- MRESULT EXPENTRY CoordDlgProc (HWND, USHORT, MPARAM, MPARAM) ;
- MRESULT EXPENTRY ColorDlgProc (HWND, USHORT, MPARAM, MPARAM) ;
- MRESULT EXPENTRY IterDlgProc (HWND, USHORT, MPARAM, MPARAM) ;
- MRESULT EXPENTRY AboutDlgProc (HWND, USHORT, MPARAM, MPARAM) ;
- VOID InvertBlock (HPS, POINTL, POINTL) ;
- VOID CreateIcon (HPS) ;
- VOID CalcThread (PTHREADPARAMS) ;
- USHORT Mandelbrot (struct complex, USHORT) ;
-
- CHAR szMessageTitle [] = "PM Mandelbrot Set" ;
- HAB hab ;
-
- int main (void)
- {
- static char szClientClass [] = "PMMandel" ;
- static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
- FCF_SIZEBORDER | FCF_MINMAX |
- FCF_SHELLPOSITION | FCF_TASKLIST |
- FCF_ICON | FCF_MENU ;
- HMQ hmq ;
- HWND hwndClient, hwndFrame ;
- QMSG qmsg ;
-
- hab = WinInitialize (0) ;
- hmq = WinCreateMsgQueue (hab, 0) ;
-
- WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
-
- hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
- &flFrameFlags, szClientClass, NULL,
- 0L, 0, ID_RESOURCE, &hwndClient) ;
-
- if (hwndFrame != NULL)
- {
- while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
- WinDispatchMsg (hab, &qmsg) ;
-
- WinDestroyWindow (hwndFrame) ;
- }
-
- WinDestroyMsgQueue (hmq) ;
- WinTerminate (hab) ;
- return 0 ;
- }
-
- MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- static BOOL fBlocking ;
- static CHAR szBuffer [80] ;
- static CHAR szCoordFormat[] = " Real: %#11.8f, %#11.8f "
- " Img: %#11.8f, %#11.8f " ;
- static HBITMAP hbm ;
- static HDC hdcClient, hdcMemory ;
- static int iThreadStack [STACKSIZE / sizeof (int)] ;
- static POINTL ptlBeg, ptlEnd ;
- static SHORT cyDesc, xMousePosBegin ;
- static THREADPARAMS tp = { -2.25, 1.75, -1.5, 1.5 } ;
- static TID tid ;
- BITMAPINFOHEADER bmp ;
- double dTemp ;
- LONG lNumColors, alBitmapFormats[2] ;
- POINTL ptl, aptl[TXTBOX_COUNT] ;
- SIZEL sizl ;
-
- switch (msg)
- {
- case WM_CREATE:
- // Create presention space for window
-
- hdcClient = WinOpenWindowDC (hwnd) ;
- sizl.cx = 0 ;
- sizl.cy = 0 ;
- tp.hpsClient = GpiCreatePS (hab, hdcClient, &sizl,
- PU_PELS | GPIF_DEFAULT |
- GPIT_MICRO | GPIA_ASSOC) ;
-
- // Get font and text dimensions for status line
-
- GpiQueryTextBox (tp.hpsClient,
- (LONG) sprintf (szBuffer, szCoordFormat,
- 0.0, 0.0, 0.0, 0.0),
- szBuffer, TXTBOX_COUNT, aptl) ;
-
- xMousePosBegin = (SHORT) aptl[TXTBOX_CONCAT].x ;
- cyDesc = - (SHORT) aptl[TXTBOX_BOTTOMLEFT].y ;
- tp.cyChar = (SHORT) (aptl[TXTBOX_TOPLEFT].y + cyDesc) ;
-
- // Create memory DC and PS for bitmap
-
- hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
- sizl.cx = 0 ;
- sizl.cy = 0 ;
- tp.hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl,
- PU_PELS | GPIF_DEFAULT |
- GPIT_MICRO | GPIA_ASSOC) ;
-
- // Determine size and format of shadow bitmap
-
- tp.cxMaxClient = (SHORT)
- WinQuerySysValue (HWND_DESKTOP, SV_CXFULLSCREEN) ;
-
- tp.cyMaxClient = (SHORT)
- (WinQuerySysValue (HWND_DESKTOP, SV_CYFULLSCREEN) -
- WinQuerySysValue (HWND_DESKTOP, SV_CYMENU)) -
- tp.cyChar ;
-
- GpiQueryDeviceBitmapFormats (tp.hpsClient, 2L, alBitmapFormats);
-
- // Create shadow bitmap for storing window image
- // and set it in memory presentation space
-
- bmp.cbFix = sizeof bmp ;
- bmp.cx = tp.cxMaxClient ;
- bmp.cy = tp.cyMaxClient ;
- bmp.cPlanes = (SHORT) alBitmapFormats[0] ;
- bmp.cBitCount = (SHORT) alBitmapFormats[1] ;
-
- hbm = GpiCreateBitmap (tp.hpsMemory, &bmp, 0L, NULL, NULL) ;
-
- if (hbm == NULL)
- {
- WinMessageBox (HWND_DESKTOP, hwnd,
- "Could not create bitmap for storing image.",
- szMessageTitle, 0,
- MB_OK | MB_MOVEABLE | MB_ICONEXCLAMATION) ;
-
- return MRFROMSHORT (1) ;
- }
-
- GpiSetBitmap (tp.hpsMemory, hbm) ;
- GpiErase (tp.hpsMemory) ;
-
- // Determine color capability of video display
- // and use them to set color dialog structure
-
- DevQueryCaps (hdcClient, CAPS_COLORS, 1L, &lNumColors) ;
-
- if (lNumColors == 2)
- {
- tp.clrds.fEnable16 = FALSE ;
- tp.clrds.fEnable256 = FALSE ;
- tp.clrds.sNumColors = 2 ;
- }
- else if (lNumColors >= 16 && lNumColors < 256)
- {
- tp.clrds.fEnable16 = TRUE ;
- tp.clrds.fEnable256 = FALSE ;
- tp.clrds.sNumColors = 16 ;
- }
- else
- {
- tp.clrds.fEnable16 = TRUE ;
- tp.clrds.fEnable256 = TRUE ;
- tp.clrds.sNumColors = 256 ;
- }
-
- // Initialize structure fields for thread
-
- tp.fRestart = TRUE ;
- tp.fTerminate = FALSE ;
- tp.nMaxIterations = DEF_MAX_ITERATIONS ;
- tp.hwndClient = hwnd ;
- DosSemSet (&tp.semDoingDraw) ;
- DosSemClear (&tp.semTriggerDraw) ;
-
- // Start second thread
-
- tid = _beginthread (CalcThread, iThreadStack, STACKSIZE, &tp) ;
-
- if (tid == -1)
- {
- WinMessageBox (HWND_DESKTOP, hwnd,
- "Could not create second thread.",
- szMessageTitle, 0,
- MB_OK | MB_MOVEABLE | MB_ICONEXCLAMATION) ;
-
- return MRFROMSHORT (1) ;
- }
-
- return 0 ;
-
- case WM_SIZE:
- // Save new size of client window
-
- DosEnterCritSec () ;
-
- tp.cxClient = SHORT1FROMMP (mp2) ;
- tp.cyClient = SHORT2FROMMP (mp2) ;
-
- DosExitCritSec () ;
- return 0 ;
-
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd)
- {
- case IDM_COORDINATES:
- DosEnterCritSec () ;
-
- if (WinDlgBox (HWND_DESKTOP, hwnd, CoordDlgProc,
- 0, IDD_COORDINATES, &tp.cords))
- {
- tp.fRestart = TRUE ;
- DosSemClear (&tp.semTriggerDraw) ;
- WinInvalidateRect (hwnd, NULL, FALSE) ;
- }
-
- DosExitCritSec () ;
- return 0 ;
-
- case IDM_COLORS:
- DosEnterCritSec () ;
-
- if (WinDlgBox (HWND_DESKTOP, hwnd, ColorDlgProc,
- 0, IDD_COLORS, &tp.clrds))
- {
- tp.fRestart = TRUE ;
- DosSemClear (&tp.semTriggerDraw) ;
- WinInvalidateRect (hwnd, NULL, FALSE) ;
- }
-
- DosExitCritSec () ;
- return 0 ;
-
- case IDM_ITERATIONS:
- DosEnterCritSec () ;
-
- if (WinDlgBox (HWND_DESKTOP, hwnd, IterDlgProc,
- 0, IDD_ITERATIONS, &tp.nMaxIterations))
- {
- tp.fRestart = TRUE ;
- DosSemClear (&tp.semTriggerDraw) ;
- WinInvalidateRect (hwnd, NULL, FALSE) ;
- }
-
- DosExitCritSec () ;
- return 0 ;
-
- case IDM_ABOUT:
- WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
- 0, IDD_ABOUT, NULL) ;
-
- return 0 ;
- }
- break ;
-
- case WM_BUTTON1DBLCLK:
- if (!fBlocking)
- {
- DosEnterCritSec () ;
-
- fBlocking = TRUE ;
- WinSetCapture (HWND_DESKTOP, hwnd) ;
-
- ptlBeg.x = ptlEnd.x = MOUSEMSG(&msg)->x ;
- ptlBeg.y = ptlEnd.y = MOUSEMSG(&msg)->y ;
- }
- break ;
-
- case WM_MOUSEMOVE:
- // If blocking, erase prev block and invert block
-
- if (fBlocking)
- {
- InvertBlock (tp.hpsClient, ptlBeg, ptlEnd) ;
-
- ptlEnd.x = MOUSEMSG(&msg)->x ;
- ptlEnd.y = MOUSEMSG(&msg)->y ;
-
- InvertBlock (tp.hpsClient, ptlBeg, ptlEnd) ;
- }
- else
- DosEnterCritSec () ;
-
- // Display mouse coordinates in status line
-
- GpiSetBackMix (tp.hpsClient, BM_OVERPAINT) ;
-
- ptl.x = xMousePosBegin ;
- ptl.y = tp.cyClient - tp.cyChar + cyDesc ;
-
- GpiCharStringAt (tp.hpsClient, &ptl,
- (LONG) sprintf (szBuffer, "Mou: %#11.8f, %#11.8f",
- tp.cords.dxMin + MOUSEMSG(&msg)->x *
- (tp.cords.dxMax - tp.cords.dxMin) / tp.cxMaxClient,
- tp.cords.dyMin + MOUSEMSG(&msg)->y *
- (tp.cords.dyMax - tp.cords.dyMin) / tp.cyMaxClient),
- szBuffer) ;
-
- if (!fBlocking)
- DosExitCritSec () ;
-
- break ;
-
- case WM_BUTTON1DOWN:
- if (fBlocking)
- {
- fBlocking = FALSE ;
-
- WinSetCapture (HWND_DESKTOP, NULL) ;
-
- ptlEnd.x = MOUSEMSG(&msg)->x ;
- ptlEnd.y = MOUSEMSG(&msg)->y ;
-
- InvertBlock (tp.hpsClient, ptlBeg, ptlEnd) ;
-
- // calculate new coordinates
-
- dTemp = tp.cords.dxMin + min (ptlBeg.x, ptlEnd.x) *
- (tp.cords.dxMax - tp.cords.dxMin) / tp.cxMaxClient ;
-
- tp.cords.dxMax = tp.cords.dxMin +
- max (ptlBeg.x, ptlEnd.x) *
- (tp.cords.dxMax - tp.cords.dxMin) / tp.cxMaxClient ;
-
- tp.cords.dxMin = dTemp ;
-
- dTemp = tp.cords.dyMin + min (ptlBeg.y, ptlEnd.y) *
- (tp.cords.dyMax - tp.cords.dyMin) / tp.cyMaxClient ;
-
- tp.cords.dyMax = tp.cords.dyMin +
- max (ptlBeg.y, ptlEnd.y) *
- (tp.cords.dyMax - tp.cords.dyMin) / tp.cyMaxClient ;
-
- tp.cords.dyMin = dTemp ;
-
- // restart the calculation
-
- tp.fRestart = TRUE ;
- DosSemClear (&tp.semTriggerDraw) ;
- WinInvalidateRect (hwnd, NULL, FALSE) ;
- DosExitCritSec () ;
- }
- break ;
-
- case WM_CHAR:
- // stop the blocking
- if (fBlocking)
- {
- fBlocking = FALSE ;
-
- InvertBlock (tp.hpsClient, ptlBeg, ptlEnd) ;
-
- WinSetCapture (HWND_DESKTOP, NULL) ;
-
- DosExitCritSec () ;
- }
- return 0 ;
-
- case WM_IMAGE_COMPLETED:
- WinMessageBox (HWND_DESKTOP, hwnd, "The image is completed.",
- szMessageTitle, 0,
- MB_OK | MB_MOVEABLE | MB_ICONASTERISK) ;
- return 0 ;
-
- case WM_PAINT:
- DosEnterCritSec () ;
- WinBeginPaint (hwnd, tp.hpsClient, NULL) ;
- GpiErase (tp.hpsClient) ;
-
- // Copy bitmap to client window
-
- aptl[0].x = 0 ;
- aptl[0].y = 0 ;
- aptl[1].x = tp.cxClient ;
- aptl[1].y = tp.cyClient - tp.cyChar ;
- aptl[2].x = 0 ;
- aptl[2].y = 0 ;
-
- GpiBitBlt (tp.hpsClient, tp.hpsMemory, 3L, aptl,
- ROP_SRCCOPY, BBO_IGNORE) ;
-
- // Display status line
-
- ptl.x = 0 ;
- ptl.y = tp.cyClient - tp.cyChar + cyDesc ;
-
- GpiCharStringAt (tp.hpsClient, &ptl,
- (LONG) sprintf (szBuffer, szCoordFormat,
- tp.cords.dxMin, tp.cords.dxMax,
- tp.cords.dyMin, tp.cords.dyMax),
- szBuffer) ;
-
- WinEndPaint (tp.hpsClient) ;
- DosExitCritSec () ;
- return 0 ;
-
- case WM_DESTROY:
- tp.fTerminate = TRUE ;
- tp.fRestart = TRUE ;
- DosSemClear (&tp.semTriggerDraw) ;
-
- DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
-
- GpiSetBitmap (tp.hpsMemory, NULL) ;
- GpiDestroyPS (tp.hpsClient) ;
- GpiDestroyPS (tp.hpsMemory) ;
- DevCloseDC (hdcMemory) ;
- GpiDeleteBitmap (hbm) ;
- return 0 ;
- }
- return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
- }
-
- MRESULT EXPENTRY CoordDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- static CHAR szBuffer [40] ;
- static PCOORDDLGSTRUC pcords ;
-
- switch (msg)
- {
- case WM_INITDLG:
- pcords = (PCOORDDLGSTRUC) PVOIDFROMMP (mp2) ;
-
- sprintf (szBuffer, "%10.7f", pcords->dxMin) ;
- WinSetDlgItemText (hwnd, IDD_XMIN, szBuffer) ;
-
- sprintf (szBuffer, "%10.7f", pcords->dxMax) ;
- WinSetDlgItemText (hwnd, IDD_XMAX, szBuffer) ;
-
- sprintf (szBuffer, "%10.7f", pcords->dyMin) ;
- WinSetDlgItemText (hwnd, IDD_YMIN, szBuffer) ;
-
- sprintf (szBuffer, "%10.7f", pcords->dyMax) ;
- WinSetDlgItemText (hwnd, IDD_YMAX, szBuffer) ;
- return 0 ;
-
- case WM_COMMAND:
- switch (SHORT1FROMMP (mp1))
- {
- case DID_OK:
- WinQueryDlgItemText (hwnd, IDD_XMIN,
- sizeof szBuffer, szBuffer) ;
- pcords->dxMin = atof (szBuffer) ;
-
- WinQueryDlgItemText (hwnd, IDD_XMAX,
- sizeof szBuffer, szBuffer) ;
- pcords->dxMax = atof (szBuffer) ;
-
- WinQueryDlgItemText (hwnd, IDD_YMIN,
- sizeof szBuffer, szBuffer) ;
- pcords->dyMin = atof (szBuffer) ;
-
- WinQueryDlgItemText (hwnd, IDD_YMAX,
- sizeof szBuffer, szBuffer) ;
- pcords->dyMax = atof (szBuffer) ;
-
- WinDismissDlg (hwnd, TRUE) ;
- return 0 ;
-
- case DID_CANCEL:
- WinDismissDlg (hwnd, FALSE) ;
- return 0 ;
- }
- break ;
- }
- return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
- }
-
- MRESULT EXPENTRY ColorDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- static PCOLORDLGSTRUC pclrds ;
- static SHORT sNumColors, sID ;
-
- switch (msg)
- {
- case WM_INITDLG:
- pclrds = (PCOLORDLGSTRUC) PVOIDFROMMP (mp2) ;
-
- if (!pclrds->fEnable16)
- WinEnableWindow (WinWindowFromID (hwnd, IDD_COLOR16),
- FALSE) ;
-
- if (!pclrds->fEnable256)
- WinEnableWindow (WinWindowFromID (hwnd, IDD_COLOR256),
- FALSE) ;
-
- sNumColors = pclrds->sNumColors ;
-
- if (sNumColors == 2)
- sID = IDD_COLOR2 ;
-
- else if (sNumColors == 16)
- sID = IDD_COLOR16 ;
-
- else if (sNumColors == 256)
- sID = IDD_COLOR256 ;
-
- WinSendDlgItemMsg (hwnd, sID, BM_SETCHECK,
- MPFROM2SHORT (TRUE, 0), NULL) ;
-
- WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, sID)) ;
- return MRFROMSHORT (1) ;
-
- case WM_CONTROL:
- switch (SHORT1FROMMP (mp1))
- {
- case IDD_COLOR2: sNumColors = 2 ; break ;
- case IDD_COLOR16: sNumColors = 16 ; break ;
- case IDD_COLOR256: sNumColors = 256 ; break ;
- }
- return 0 ;
-
- case WM_COMMAND:
- switch (SHORT1FROMMP (mp1))
- {
- case DID_OK:
- pclrds->sNumColors = sNumColors ;
- WinDismissDlg (hwnd, TRUE) ;
- return 0 ;
-
- case DID_CANCEL:
- WinDismissDlg (hwnd, FALSE) ;
- return 0 ;
- }
- break ;
- }
- return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
- }
-
- MRESULT EXPENTRY IterDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- static CHAR szBuffer [10] ;
- static PUSHORT pnMaxIterations ;
-
- switch (msg)
- {
- case WM_INITDLG:
- pnMaxIterations = (PUSHORT) PVOIDFROMMP (mp2) ;
-
- WinSendDlgItemMsg (hwnd, IDD_ITER, EM_SETTEXTLIMIT,
- MPFROMSHORT (sizeof szBuffer - 1), NULL) ;
-
- WinSetDlgItemShort (hwnd, IDD_ITER, *pnMaxIterations, FALSE) ;
- return 0 ;
-
- case WM_COMMAND:
- switch (SHORT1FROMMP (mp1))
- {
- case DID_OK:
- WinQueryDlgItemShort (hwnd, IDD_ITER,
- pnMaxIterations, FALSE) ;
-
- if (*pnMaxIterations == 0)
- {
- WinMessageBox (HWND_DESKTOP, hwnd,
- "Zero Iterations? Get real!",
- szMessageTitle, 0,
- MB_OK | MB_MOVEABLE | MB_ICONEXCLAMATION) ;
-
- return 0 ;
- }
-
- WinDismissDlg (hwnd, TRUE) ;
- return 0 ;
-
- case DID_CANCEL:
- WinDismissDlg (hwnd, FALSE) ;
- return 0 ;
- }
- break ;
- }
- return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
- }
-
- MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- switch (msg)
- {
- case WM_COMMAND:
- switch (SHORT1FROMMP (mp1))
- {
- case DID_OK:
- case DID_CANCEL:
- WinDismissDlg (hwnd, TRUE) ;
- return 0 ;
- }
- break ;
- }
- return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
- }
-
- VOID InvertBlock (HPS hps, POINTL ptlBeg, POINTL ptlEnd)
- {
- RECTL rcl ;
-
- if (ptlBeg.x != ptlEnd.x && ptlBeg.y != ptlEnd.y)
- {
- rcl.xLeft = min (ptlBeg.x, ptlEnd.x) ;
- rcl.xRight = max (ptlBeg.x, ptlEnd.x) ;
- rcl.yBottom = min (ptlBeg.y, ptlEnd.y) ;
- rcl.yTop = max (ptlBeg.y, ptlEnd.y) ;
-
- WinInvertRect (hps, &rcl) ;
- }
- }
-
- VOID CalcThread (PTHREADPARAMS ptp)
- {
- static LONG alColor16 [] = { CLR_DARKBLUE, CLR_DARKGREEN, CLR_DARKCYAN,
- CLR_DARKRED, CLR_DARKPINK, CLR_BROWN,
- CLR_DARKGRAY, CLR_PALEGRAY, CLR_BLUE,
- CLR_GREEN, CLR_CYAN, CLR_RED,
- CLR_PINK, CLR_YELLOW, CLR_WHITE } ;
-
- static LONG alColor256[] = { 0x000055, 0x0000AA, 0x0000FF, 0x002400,
- 0x002455, 0x0024AA, 0x0024FF, 0x004900,
- 0x004955, 0x0049AA, 0x0049FF, 0x006D00,
- 0x006D55, 0x006DAA, 0x006DFF, 0x009200,
- 0x009255, 0x0092AA, 0x0092FF, 0x00B600,
- 0x00B655, 0x00B6AA, 0x00B6FF, 0x00DB00,
- 0x00DB55, 0x00DBAA, 0x00DBFF, 0x00FF00,
- 0x00FF55, 0x00FFAA, 0x00FFFF, 0x240000,
- 0x240055, 0x2400AA, 0x2400FF, 0x242400,
- 0x242455, 0x2424AA, 0x2424FF, 0x244900,
- 0x244955, 0x2449AA, 0x2449FF, 0x246D00,
- 0x246D55, 0x246DAA, 0x246DFF, 0x249200,
- 0x249255, 0x2492AA, 0x2492FF, 0x24B600,
- 0x24B655, 0x24B6AA, 0x24B6FF, 0x24DB00,
- 0x24DB55, 0x24DBAA, 0x24DBFF, 0x24FF00,
- 0x24FF55, 0x24FFAA, 0x24FFFF, 0x490000,
- 0x490055, 0x4900AA, 0x4900FF, 0x492400,
- 0x492455, 0x4924AA, 0x4924FF, 0x494900,
- 0x494955, 0x4949AA, 0x4949FF, 0x496D00,
- 0x496D55, 0x496DAA, 0x496DFF, 0x499200,
- 0x499255, 0x4992AA, 0x4992FF, 0x49B600,
- 0x49B655, 0x49B6AA, 0x49B6FF, 0x49DB00,
- 0x49DB55, 0x49DBAA, 0x49DBFF, 0x49FF00,
- 0x49FF55, 0x49FFAA, 0x49FFFF, 0x6D0000,
- 0x6D0055, 0x6D00AA, 0x6D00FF, 0x6D2400,
- 0x6D2455, 0x6D24AA, 0x6D24FF, 0x6D4900,
- 0x6D4955, 0x6D49AA, 0x6D49FF, 0x6D6D00,
- 0x6D6D55, 0x6D6DAA, 0x6D6DFF, 0x6D9200,
- 0x6D9255, 0x6D92AA, 0x6D92FF, 0x6DB600,
- 0x6DB655, 0x6DB6AA, 0x6DB6FF, 0x6DDB00,
- 0x6DDB55, 0x6DDBAA, 0x6DDBFF, 0x6DFF00,
- 0x6DFF55, 0x6DFFAA, 0x6DFFFF, 0x920000,
- 0x920055, 0x9200AA, 0x9200FF, 0x922400,
- 0x922455, 0x9224AA, 0x9224FF, 0x924900,
- 0x924955, 0x9249AA, 0x9249FF, 0x926D00,
- 0x926D55, 0x926DAA, 0x926DFF, 0x929200,
- 0x929255, 0x9292AA, 0x9292FF, 0x92B600,
- 0x92B655, 0x92B6AA, 0x92B6FF, 0x92DB00,
- 0x92DB55, 0x92DBAA, 0x92DBFF, 0x92FF00,
- 0x92FF55, 0x92FFAA, 0x92FFFF, 0xB60000,
- 0xB60055, 0xB600AA, 0xB600FF, 0xB62400,
- 0xB62455, 0xB624AA, 0xB624FF, 0xB64900,
- 0xB64955, 0xB649AA, 0xB649FF, 0xB66D00,
- 0xB66D55, 0xB66DAA, 0xB66DFF, 0xB69200,
- 0xB69255, 0xB692AA, 0xB692FF, 0xB6B600,
- 0xB6B655, 0xB6B6AA, 0xB6B6FF, 0xB6DB00,
- 0xB6DB55, 0xB6DBAA, 0xB6DBFF, 0xB6FF00,
- 0xB6FF55, 0xB6FFAA, 0xB6FFFF, 0xDB0000,
- 0xDB0055, 0xDB00AA, 0xDB00FF, 0xDB2400,
- 0xDB2455, 0xDB24AA, 0xDB24FF, 0xDB4900,
- 0xDB4955, 0xDB49AA, 0xDB49FF, 0xDB6D00,
- 0xDB6D55, 0xDB6DAA, 0xDB6DFF, 0xDB9200,
- 0xDB9255, 0xDB92AA, 0xDB92FF, 0xDBB600,
- 0xDBB655, 0xDBB6AA, 0xDBB6FF, 0xDBDB00,
- 0xDBDB55, 0xDBDBAA, 0xDBDBFF, 0xDBFF00,
- 0xDBFF55, 0xDBFFAA, 0xDBFFFF, 0xFF0000,
- 0xFF0055, 0xFF00AA, 0xFF00FF, 0xFF2400,
- 0xFF2455, 0xFF24AA, 0xFF24FF, 0xFF4900,
- 0xFF4955, 0xFF49AA, 0xFF49FF, 0xFF6D00,
- 0xFF6D55, 0xFF6DAA, 0xFF6DFF, 0xFF9200,
- 0xFF9255, 0xFF92AA, 0xFF92FF, 0xFFB600,
- 0xFFB655, 0xFFB6AA, 0xFFB6FF, 0xFFDB00,
- 0xFFDB55, 0xFFDBAA, 0xFFDBFF, 0xFFFF00,
- 0xFFFF55, 0xFFFFAA, 0xFFFFFF } ;
- struct complex cmplxPoint ;
- HAB hab ;
- LONG lColorUse ;
- POINTL aptl[3] ;
- SHORT i, x, y ;
- USHORT nIteration ;
-
- hab = WinInitialize (0) ;
-
- while (!ptp->fTerminate)
- {
- DosSemWait (&ptp->semTriggerDraw, SEM_INDEFINITE_WAIT) ;
-
- if (ptp->fTerminate)
- break ;
-
- DosSemSet (&ptp->semDoingDraw) ;
-
- DosEnterCritSec () ;
-
- GpiErase (ptp->hpsMemory) ;
-
- if (ptp->clrds.sNumColors == 256)
- {
- GpiCreateLogColorTable (ptp->hpsClient, LCOL_PURECOLOR,
- LCOLF_RGB, 0L, 0L, NULL) ;
- GpiCreateLogColorTable (ptp->hpsMemory, LCOL_PURECOLOR,
- LCOLF_RGB, 0L, 0L, NULL) ;
- }
- else
- {
- GpiCreateLogColorTable (ptp->hpsClient, LCOL_RESET,
- LCOLF_INDRGB, 0L, 0L, NULL) ;
- GpiCreateLogColorTable (ptp->hpsMemory, LCOL_RESET,
- LCOLF_INDRGB, 0L, 0L, NULL) ;
- }
-
- ptp->fRestart = FALSE ;
-
- DosExitCritSec () ;
-
- // Loop for fat-bits down to pixels.
-
- for (i = 64 ; i > 0 ; i /= 2)
- {
- // Loop for rows
-
- for (y = 0 ; y < ptp->cyMaxClient ; y += i)
- {
- // Loop for columns
-
- for (x = 0 ; x < ptp->cxMaxClient ; x += i)
- {
- // If bit already drawn, skip it
-
- if ((i != 64) && (x & 1 == 0) && (y & 1 == 0))
- continue ;
-
- // Calculate the complex point
-
- DosEnterCritSec () ;
-
- cmplxPoint.x = ptp->cords.dxMin + x *
- (ptp->cords.dxMax - ptp->cords.dxMin) /
- ptp->cxMaxClient ;
-
- cmplxPoint.y = ptp->cords.dyMin + y *
- (ptp->cords.dyMax - ptp->cords.dyMin) /
- ptp->cyMaxClient ;
-
- // Find the number of iterations
-
- nIteration = Mandelbrot (cmplxPoint,
- ptp->nMaxIterations) ;
-
- // Determine the color to use
-
- if (ptp->clrds.sNumColors == 2)
-
- lColorUse = (nIteration == ptp->nMaxIterations ?
- CLR_BLACK : CLR_WHITE) ;
-
- else if (ptp->clrds.sNumColors == 16)
-
- lColorUse = (nIteration == ptp->nMaxIterations ?
- CLR_BLACK : alColor16 [nIteration % 15]) ;
-
- else if (ptp->clrds.sNumColors == 256)
-
- lColorUse = (nIteration == ptp->nMaxIterations ?
- RGB_BLACK : alColor256 [nIteration % 255]) ;
-
- GpiSetColor (ptp->hpsMemory, lColorUse) ;
-
- // Draw on the bitmap
-
- aptl[0].x = x ;
- aptl[0].y = y ;
-
- if (i > 1)
- {
- aptl[1].x = min (x + i, ptp->cxMaxClient) ;
- aptl[1].y = min (y + i, ptp->cyMaxClient) ;
-
- GpiBitBlt (ptp->hpsMemory, NULL,
- 2L, aptl, ROP_PATCOPY, 0L) ;
- }
- else
- GpiSetPel (ptp->hpsMemory, aptl) ;
-
- DosExitCritSec () ;
-
- if (ptp->fRestart)
- break ;
- }
-
- if (ptp->fRestart)
- break ;
-
- DosEnterCritSec () ;
-
- // For each row, draw the bitmap on the window
-
- if (y < ptp->cyClient - ptp->cyChar)
- {
- aptl[0].x = 0 ;
- aptl[0].y = y ;
-
- aptl[1].x = ptp->cxClient ;
- aptl[1].y = min (y + i, ptp->cyClient - ptp->cyChar) ;
-
- aptl[2].x = 0 ;
- aptl[2].y = y ;
-
- GpiBitBlt (ptp->hpsClient, ptp->hpsMemory,
- 3L, aptl, ROP_SRCCOPY, 0L);
- }
-
- DosExitCritSec () ;
- }
-
- if (ptp->fRestart)
- break ;
- }
-
- if (!ptp->fRestart)
- {
- DosSemSet (&ptp->semTriggerDraw) ;
- WinPostMsg (ptp->hwndClient, WM_IMAGE_COMPLETED, NULL, NULL) ;
- }
-
- DosSemClear (&ptp->semDoingDraw) ;
- }
-
- WinTerminate (hab) ;
- _endthread () ;
- }
-
- USHORT Mandelbrot (struct complex cmplxPoint, USHORT nMaxIterations)
- {
- struct complex cmplxSquare, cmplxTemp, cmplxAccum ;
- USHORT n ;
-
- cmplxAccum = cmplxPoint ;
-
- // "Cheat" a little for speed
-
- if (cmplxPoint.x >= -0.750 && cmplxPoint.x <= 0.250 &&
- cmplxPoint.y >= -0.625 && cmplxPoint.y <= 0.625)
- {
- cmplxTemp = cmplxPoint ;
- cmplxTemp.x += .125 ;
-
- if (cabs (cmplxTemp) < .625)
- return nMaxIterations ;
- }
-
- else if (cmplxPoint.x >= -1.250 && cmplxPoint.x <= -0.750 &&
- cmplxPoint.y >= -0.250 && cmplxPoint.y <= 0.250)
- {
- cmplxTemp = cmplxPoint ;
- cmplxTemp.x += 1.0 ;
-
- if (cabs (cmplxTemp) < .25)
- return nMaxIterations ;
- }
- // Done cheating
-
- for (n = 0 ; n < nMaxIterations ; n++)
- {
- cmplxSquare.x = cmplxAccum.x * cmplxAccum.x ;
- cmplxSquare.y = cmplxAccum.y * cmplxAccum.y ;
-
- if (cmplxSquare.x + cmplxSquare.y >= 4.0)
- break ;
-
- cmplxAccum.y = 2 * cmplxAccum.x * cmplxAccum.y + cmplxPoint.y ;
- cmplxAccum.x = cmplxSquare.x - cmplxSquare.y + cmplxPoint.x ;
- }
-
- return n ;
- }