home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computerworld 1996 March
/
Computerworld_1996-03_cd.bin
/
idg_cd3
/
grafika
/
fraktaly
/
bmand11
/
mand.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-14
|
34KB
|
1,063 lines
/***********************************************
* Mand.C - jcb - started on: 8/21/94 *
* *
* -----Bare's Mandelbrot Program----- *
* *
* Draws the Mandelbrot Set. *
* *
***********************************************/
#include <windows.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "mand.h"
#include <stdio.h>
#include <mem.h>
#define PALETTESIZE 256
#define HDIB HANDLE
#define HPAL HANDLE
#define VerInfo "1.1"
LONG FAR PASCAL _export WndProc(HWND,UINT,WPARAM,LPARAM);
BOOL FAR PASCAL _export AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
BOOL FAR PASCAL _export OptionsDlgProc(HWND,UINT,WPARAM,LPARAM);
// Global Variables:
char szProgName[] = "MandProg";
char szIconName[] = "MandIcon";
char szMenuName[] = "Menu";
HDIB hMandelbrotDIB;
int Do=0;
long int BytesPerLine;
char szBuffer[256];
unsigned int iMaxDel=256;
double topMand,botMand,leftMand,rightMand;
HINSTANCE hInstance;
/***********************************************
* DIB functions *
* *
* Functions that manipulate windows Device *
* Independent Bitmaps. *
* *
***********************************************/
HDIB CreateDIB(int x, int y) {
long int MemBlockSize;
HANDLE hlocBmi;
HDIB hDib;
LPBITMAPINFO lpbmi, lpbmiMyDIB;
hlocBmi = LocalAlloc(LHND | LMEM_ZEROINIT,
sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD)*256);
lpbmi = (LPBITMAPINFO)LocalLock(hlocBmi);
lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbmi->bmiHeader.biWidth = x;
lpbmi->bmiHeader.biHeight = y;
lpbmi->bmiHeader.biPlanes = 1;
lpbmi->bmiHeader.biBitCount = 8;
lpbmi->bmiHeader.biCompression = BI_RGB;
lpbmi->bmiHeader.biSizeImage = (LONG)
((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biBitCount + 31) / 32 * 4)
* lpbmi->bmiHeader.biHeight;
lpbmi->bmiHeader.biXPelsPerMeter = 0;
lpbmi->bmiHeader.biYPelsPerMeter = 0;
lpbmi->bmiHeader.biClrUsed = 256;
lpbmi->bmiHeader.biClrImportant = 256;
BytesPerLine = (LONG)((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biBitCount + 31) / 32 * 4);
MemBlockSize = sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD)*lpbmi->bmiHeader.biClrUsed
+ lpbmi->bmiHeader.biSizeImage;
if (MemBlockSize%65536!=0)
MemBlockSize = ((MemBlockSize+65536) / 65536 ) * 65536;
hDib = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DDESHARE, MemBlockSize);
if (hDib == NULL)
MessageBox(NULL,"GlobalAlloc Failed.","DEBUG", MB_OK);
lpbmiMyDIB = (LPBITMAPINFO)GlobalLock(hDib);
if (lpbmiMyDIB == NULL)
MessageBox(NULL,"Can't Lock hDib. (createDIB)","DEBUG", MB_OK);
memcpy(lpbmiMyDIB,lpbmi,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD));
LocalUnlock(hlocBmi);
LocalFree(hlocBmi);
GlobalUnlock(hDib);
return hDib;
}
int SetDIBPixel(HDIB hdib, int x, int y, int color) {
char huge *PixelLoc;
BITMAPINFO huge *lpbmi;
lpbmi = (BITMAPINFO huge *)GlobalLock(hdib);
if (lpbmi == NULL) {
MessageBox(NULL,"Can't Lock hDib. (SetDIBPixel)","DEBUG", MB_OK);
return 0;
}
if ((x<lpbmi->bmiHeader.biWidth)&&(y<lpbmi->bmiHeader.biHeight)) {
PixelLoc = (char huge *)lpbmi
+ sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD)*256
+ y * BytesPerLine + x;
*(char huge *)PixelLoc = (char)color; // Set Color
GlobalUnlock(hdib);
}
else return 0;
return 1;
}
HDIB CopyDIB(HDIB hSourceDIB) {
DWORD size;
HDIB hDestDIB;
BYTE huge *src;
BYTE huge *dest;
size = GlobalSize(hSourceDIB);
if (size != 0) {
hDestDIB = GlobalAlloc(GMEM_MOVEABLE, size);
if (hDestDIB != (HANDLE)NULL) {
src = (BYTE huge *)GlobalLock(hSourceDIB);
if (src != NULL) {
dest = (BYTE huge *)GlobalLock(hDestDIB);
if (dest != NULL) {
while (size != 0){
*dest = *src;
dest++;
src++;
size--;
}
GlobalUnlock(hDestDIB);
}
else {
GlobalFree(hDestDIB);
hDestDIB = (HANDLE)NULL;
}
GlobalUnlock(hSourceDIB);
}
else {
GlobalFree(hDestDIB);
hDestDIB = (HANDLE)NULL;
}
}
}
else hDestDIB = (HANDLE)NULL;
return hDestDIB;
}
HPAL GetDIBPalette(HDIB hdib) {
HANDLE hLogPal;
NPLOGPALETTE pLogPal;
LPBITMAPINFO lpbmi;
HPAL hPal;
int i;
hLogPal= (HANDLE) LocalAlloc(LMEM_FIXED,(sizeof(LOGPALETTE)+
(sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*(PALETTESIZE))));
pLogPal= (NPLOGPALETTE)LocalLock(hLogPal);
lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
pLogPal->palVersion=0x300;
pLogPal->palNumEntries=lpbmi->bmiHeader.biClrUsed;
for (i=0;i<256;i++) {
pLogPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
pLogPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
pLogPal->palPalEntry[i].peFlags=lpbmi->bmiColors[i].rgbReserved;
}
hPal=CreatePalette(pLogPal);
LocalUnlock(hLogPal);
LocalFree(hLogPal);
GlobalUnlock(hdib);
return hPal;
}
void ShowDIB(HDC hdc,HDIB hdib) {
BITMAPINFO huge *lpbmi;
char huge *Data;
lpbmi = (BITMAPINFO huge *)GlobalLock(hdib);
if (lpbmi == NULL)
MessageBox(NULL,"Can't Lock DIB memory. (ShowDIB)","DEBUG", MB_OK);
Data = (LPSTR)lpbmi
+ sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD)*256;
SetDIBitsToDevice(hdc,0,0,lpbmi->bmiHeader.biWidth,
lpbmi->bmiHeader.biHeight,0,0,0,lpbmi->bmiHeader.biHeight,
Data,lpbmi,DIB_RGB_COLORS);
GlobalUnlock(hdib);
}
void ShowLine(HDC hdc,HDIB hdib,int line) {
BITMAPINFO huge *lpbmi;
char huge *Data;
lpbmi = (BITMAPINFO huge *)GlobalLock(hdib);
if (lpbmi == NULL)
MessageBox(NULL,"Can't Lock DIB memory. (ShowIt)","DEBUG", MB_OK);
Data = (LPSTR)lpbmi
+ sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD)*256;
SetDIBitsToDevice(hdc,0,lpbmi->bmiHeader.biHeight-line-1,
lpbmi->bmiHeader.biWidth,
1,0,line,0,lpbmi->bmiHeader.biHeight,
Data,lpbmi,DIB_RGB_COLORS);
GlobalUnlock(hdib);
}
/***********************************************
* Mandelbrot *
* *
* Calculates and draws the fractal. *
* *
***********************************************/
void Mandelbrot(HDC hdc,HDIB hdib,int xMax, int yMax,
// float left, float top, float right, float bottom) {
double left, double top, double right, double bottom) {
MSG lpMsg;
int x, y, Del;
// float Zr, Zi, Cr, Ci, ZrSq, ZiSq, dist, xScale, yScale;
double Zr, Zi, Cr, Ci, ZrSq, ZiSq, dist2, xScale, yScale;
y=0;
xScale = (right-left)/(float)xMax; yScale = (top-bottom)/(float)yMax;
while(Do==1) {
PeekMessage(&lpMsg,NULL,0,0,PM_REMOVE);
for (x=0;x<xMax;x++) {
Del = 1; dist2 = 0;
Cr = x * xScale+left; Ci = bottom + y * yScale;
Zr = Cr; Zi = Ci;
while ((dist2<4)&&(++Del<iMaxDel)) {
ZrSq = Zr*Zr; ZiSq=Zi*Zi;
Zi = 2*Zr*Zi + Ci;
Zr = ZrSq - ZiSq + Cr;
dist2 = ZrSq + ZiSq;
}
if (Del==iMaxDel) Del=0;
else if (Del > 255) Del = (Del%255)+1;
SetDIBPixel(hdib,x,y,Del);
}
ShowLine(hdc,hdib,y);
y++; if (y>yMax) Do=0;
TranslateMessage(&lpMsg); // allow windows message processing
DispatchMessage(&lpMsg);
}
}
/***********************************************
* Palette functions: *
* *
* Define the various palettes available in *
* Bare' Mandelbrot program. *
* *
***********************************************/
void DefaultPalette(HDIB hdib) {
LPBITMAPINFO lpbmi;
int i;
if (hdib!=NULL) {
lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
if (lpbmi!=NULL) {
lpbmi->bmiColors[0].rgbRed = 0;
lpbmi->bmiColors[0].rgbGreen = 0;
lpbmi->bmiColors[0].rgbBlue = 0;
lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
for (i=1;i<32;i++) { // fade blue to red
lpbmi->bmiColors[i].rgbRed=i*8;
lpbmi->bmiColors[i].rgbGreen=0x00;
lpbmi->bmiColors[i].rgbBlue=255 - (i*8);
lpbmi->bmiColors[i].rgbReserved=PC_RESERVED;
}
for (i=32;i<64;i++) { // fade red to green
lpbmi->bmiColors[i].rgbRed=255 - ((i-32)*8);
lpbmi->bmiColors[i].rgbGreen=(i-32)*8;
lpbmi->bmiColors[i].rgbBlue=0x00;
lpbmi->bmiColors[i].rgbReserved=PC_RESERVED;
}
for (i=64;i<96;i++) { // fade green to blue
lpbmi->bmiColors[i].rgbRed=0x00;
lpbmi->bmiColors[i].rgbGreen=255 - ((i-64)*8);
lpbmi->bmiColors[i].rgbBlue=(i-64)*8;
lpbmi->bmiColors[i].rgbReserved=PC_RESERVED;
}
for (i=96;i<128;i++) { // fade blue to yellow
lpbmi->bmiColors[i].rgbRed = (i-96)*8;
lpbmi->bmiColors[i].rgbGreen = (i-96)*8;
lpbmi->bmiColors[i].rgbBlue = 255 - ((i-96)*8);
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
for (i=128;i<192;i++) { // fade yellow to red
lpbmi->bmiColors[i].rgbRed = 255;
lpbmi->bmiColors[i].rgbGreen = 255 - ((i-128)*4);
lpbmi->bmiColors[i].rgbBlue = 0;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
for (i=192;i<224;i++) { // fade red to purple
lpbmi->bmiColors[i].rgbRed = 255;
lpbmi->bmiColors[i].rgbGreen = 0;
lpbmi->bmiColors[i].rgbBlue = (i-192)*8;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
for (i=224;i<256;i++) { // fade purple to blue
lpbmi->bmiColors[i].rgbRed = 255 - ((i-224)*8);
lpbmi->bmiColors[i].rgbGreen = 0;
lpbmi->bmiColors[i].rgbBlue = 255;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
}
GlobalUnlock(hdib);
}
}
void PurpleGreenPalette(HDIB hdib) {
LPBITMAPINFO lpbmi;
int i;
if (hdib!=NULL) {
lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
for (i=0;i<256;i++) {
lpbmi->bmiColors[i].rgbRed = (i<128) ? (256 -(2*i)) : 0;
lpbmi->bmiColors[i].rgbGreen = i;
lpbmi->bmiColors[i].rgbBlue = 256-i;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
GlobalUnlock(hdib);
}
}
void GreyPalette(HDIB hdib) {
LPBITMAPINFO lpbmi;
int i;
if (hdib!=NULL) {
lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
if (lpbmi!=NULL) {
lpbmi->bmiColors[0].rgbRed = 0;
lpbmi->bmiColors[0].rgbGreen = 0;
lpbmi->bmiColors[0].rgbBlue = 0;
lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
for (i=1;i<32;i++) {
lpbmi->bmiColors[i].rgbRed = i*6+50;
lpbmi->bmiColors[i].rgbGreen = i*6+50;
lpbmi->bmiColors[i].rgbBlue = i*6+50;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
for (i=32;i<64;i++) {
lpbmi->bmiColors[i].rgbRed = 255-6*(i-32);
lpbmi->bmiColors[i].rgbGreen = 255-6*(i-32);
lpbmi->bmiColors[i].rgbBlue = 255-6*(i-32);
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
for (i=64;i<128;i++) {
lpbmi->bmiColors[i].rgbRed = 50+3*(i-64);
lpbmi->bmiColors[i].rgbGreen = 50+3*(i-64);
lpbmi->bmiColors[i].rgbBlue = 50+3*(i-64);
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
for (i=128;i<192;i++) {
lpbmi->bmiColors[i].rgbRed = 256-3*(i-128);
lpbmi->bmiColors[i].rgbGreen = 256-3*(i-128);
lpbmi->bmiColors[i].rgbBlue = 256-3*(i-128);
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
for (i=192;i<256;i++) {
lpbmi->bmiColors[i].rgbRed = 50+3*(i-192);
lpbmi->bmiColors[i].rgbGreen = 50+3*(i-192);
lpbmi->bmiColors[i].rgbBlue = 50+3*(i-192);
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
}
GlobalUnlock(hdib);
}
}
void ZebraPalette(HDIB hdib) {
LPBITMAPINFO lpbmi;
int i;
if (hdib!=NULL) {
lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
if (lpbmi!=NULL) {
for (i=0;i<255;i+=2) {
lpbmi->bmiColors[i].rgbRed = 0;
lpbmi->bmiColors[i].rgbGreen = 0;
lpbmi->bmiColors[i].rgbBlue = 0;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
lpbmi->bmiColors[i+1].rgbRed = 255;
lpbmi->bmiColors[i+1].rgbGreen = 255;
lpbmi->bmiColors[i+1].rgbBlue = 255;
lpbmi->bmiColors[i+1].rgbReserved = PC_RESERVED;
}
}
GlobalUnlock(hdib);
}
}
void RandomPalette(HDIB hdib) {
LPBITMAPINFO lpbmi;
int i;
if (hdib!=NULL) {
lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
if (lpbmi!=NULL) {
lpbmi->bmiColors[0].rgbRed = 0;
lpbmi->bmiColors[0].rgbGreen = 0;
lpbmi->bmiColors[0].rgbBlue = 0;
lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
lpbmi->bmiColors[1].rgbRed = (int)((double)rand()/(double)RAND_MAX*256);
lpbmi->bmiColors[1].rgbGreen = (int)((double)rand()/(double)RAND_MAX*256);
lpbmi->bmiColors[1].rgbBlue = (int)((double)rand()/(double)RAND_MAX*256);
lpbmi->bmiColors[1].rgbReserved = PC_RESERVED;
for (i=2;i<256;i++) {
lpbmi->bmiColors[i].rgbRed = (lpbmi->bmiColors[i-1].rgbRed + (int)((double)rand()/(double)RAND_MAX*10))%256;
lpbmi->bmiColors[i].rgbGreen = (lpbmi->bmiColors[i-1].rgbGreen + (int)((double)rand()/(double)RAND_MAX*10))%256;
lpbmi->bmiColors[i].rgbBlue = (lpbmi->bmiColors[i-1].rgbBlue + (int)((double)rand()/(double)RAND_MAX*10))%256;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
}
GlobalUnlock(hdib);
}
}
void RainbowPalette(HDIB hdib) {
LPBITMAPINFO lpbmi;
int i;
if (hdib!=NULL) {
lpbmi = (LPBITMAPINFO)GlobalLock(hdib);
if (lpbmi!=NULL) {
for (i=0;i<16;i++) {
lpbmi->bmiColors[i].rgbRed = 255;
lpbmi->bmiColors[i].rgbGreen = i*16;
lpbmi->bmiColors[i].rgbBlue = 0;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
lpbmi->bmiColors[i+16].rgbRed = 255-(i*16);
lpbmi->bmiColors[i+16].rgbGreen = 255;
lpbmi->bmiColors[i+16].rgbBlue = 0;
lpbmi->bmiColors[i+16].rgbReserved = PC_RESERVED;
lpbmi->bmiColors[i+32].rgbRed = 0;
lpbmi->bmiColors[i+32].rgbGreen = 255-(i*16);
lpbmi->bmiColors[i+32].rgbBlue = i*16;
lpbmi->bmiColors[i+32].rgbReserved = PC_RESERVED;
lpbmi->bmiColors[i+48].rgbRed = i*16;
lpbmi->bmiColors[i+48].rgbGreen = 0;
lpbmi->bmiColors[i+48].rgbBlue = 255-(i*16);
lpbmi->bmiColors[i+48].rgbReserved = PC_RESERVED;
}
for (i=0;i<64;i++) {
lpbmi->bmiColors[i+64].rgbRed = lpbmi->bmiColors[i].rgbRed;
lpbmi->bmiColors[i+64].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
lpbmi->bmiColors[i+64].rgbBlue = lpbmi->bmiColors[i].rgbBlue ;
lpbmi->bmiColors[i+64].rgbReserved = PC_RESERVED;
lpbmi->bmiColors[i+128].rgbRed = lpbmi->bmiColors[i].rgbRed;
lpbmi->bmiColors[i+128].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
lpbmi->bmiColors[i+128].rgbBlue = lpbmi->bmiColors[i].rgbBlue ;
lpbmi->bmiColors[i+128].rgbReserved = PC_RESERVED;
lpbmi->bmiColors[i+192].rgbRed = lpbmi->bmiColors[i].rgbRed;
lpbmi->bmiColors[i+192].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
lpbmi->bmiColors[i+192].rgbBlue = lpbmi->bmiColors[i].rgbBlue ;
lpbmi->bmiColors[i+192].rgbReserved = PC_RESERVED;
}
lpbmi->bmiColors[0].rgbRed = 0;
lpbmi->bmiColors[0].rgbGreen = 0;
lpbmi->bmiColors[0].rgbBlue = 0;
lpbmi->bmiColors[0].rgbReserved = PC_RESERVED;
}
GlobalUnlock(hdib);
}
}
void RotateColors(HANDLE hPal, PALETTEENTRY *palScratch) {
PALETTEENTRY palTemp;
int i;
palTemp.peRed = palScratch[1].peRed;
palTemp.peGreen = palScratch[1].peGreen;
palTemp.peBlue = palScratch[1].peBlue;
for (i=1;i<255;i++) {
palScratch[i].peRed = palScratch[i+1].peRed;
palScratch[i].peGreen = palScratch[i+1].peGreen;
palScratch[i].peBlue = palScratch[i+1].peBlue;
}
palScratch[255].peRed = palTemp.peRed;
palScratch[255].peGreen = palTemp.peGreen;
palScratch[255].peBlue = palTemp.peBlue;
AnimatePalette(hPal,0,256,palScratch);
}
void DrawStatusBar(HDC hdc, int x, int y, float left, float top,
float right, float bot) {
HBRUSH hbrush, hbrushOld;
HFONT hOldFont, hNewFont;
char szBuffer[256];
int iTabs[5] = {100,150,200,250,300};
hbrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
hbrushOld = SelectObject(hdc,hbrush);
Rectangle(hdc,0,y,x,y+30);
SelectObject(hdc,hbrushOld);
hNewFont=CreateFont(10,0,0,0,FW_BOLD,0,0,0,0,
0,0,0,
0,"Times New Roman");
hOldFont=SelectObject(hdc,hNewFont);
SetBkMode(hdc,TRANSPARENT);
sprintf(szBuffer,"Window: %d,%d\tView Vertical:\t%g,%g",x,y,top,bot);
TabbedTextOut(hdc,10,y+5,szBuffer,strlen(szBuffer),5,iTabs,10);
sprintf(szBuffer,"\tView Horizontal:\t%g,%g",left,right);
TabbedTextOut(hdc,10,y+15,szBuffer,strlen(szBuffer),5,iTabs,10);
SelectObject(hdc,hOldFont);
DeleteObject(hNewFont);
DeleteObject(hbrush);
}
/***********************************************
* WinMain *
* *
* Register WNDCLASS, create window, enter *
* message loop, and do exit clean-up. *
* *
***********************************************/
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPreInst, LPSTR lpszCmdLine,
int nCmdShow)
{
HWND hWnd;
MSG lpMsg;
WNDCLASS wcApp;
time_t t;
srand((unsigned) time(&t));
if (!hPreInst) {
wcApp.lpszClassName=szProgName;
wcApp.hInstance=hInst;
wcApp.lpfnWndProc=WndProc;
wcApp.hCursor=LoadCursor( NULL, IDC_ARROW );
wcApp.hIcon=LoadIcon(hInst, szIconName );
wcApp.lpszMenuName=szMenuName;
wcApp.hbrBackground=(HBRUSH)GetStockObject( BLACK_BRUSH );
wcApp.style=CS_HREDRAW|CS_VREDRAW|CS_BYTEALIGNCLIENT|CS_BYTEALIGNWINDOW;
wcApp.cbClsExtra=0;
wcApp.cbWndExtra=0;
if (!RegisterClass(&wcApp))
return FALSE;
}
/* hWnd = CreateWindow(szProgName, "Bare's Mandelbrot Program",
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,NULL,NULL,
hInst,NULL); */
hWnd = CreateWindow(szProgName, "Bare's Mandelbrot Program",
WS_OVERLAPPEDWINDOW,500,
50,400,
400,NULL,NULL,
hInst,NULL);
if (hWnd==NULL) return FALSE;
hInstance = hInst;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&lpMsg,NULL,0,0)) {
TranslateMessage(&lpMsg);
DispatchMessage(&lpMsg);
}
DestroyIcon(wcApp.hIcon);
DestroyCursor(wcApp.hCursor);
DestroyMenu(GetMenu(hWnd));
UnregisterClass(szProgName,hInst);
return(lpMsg.wParam);
}
/***********************************************
* WndProc *
* *
* Process messages to the main window. *
* *
***********************************************/
LONG FAR PASCAL _export WndProc(HWND hWnd, UINT messg, WPARAM wParam,
LPARAM lParam)
{
static FARPROC lpfnAboutDlgProc, lpfnOptionsDlgProc;
static HWND hInst1;
static int xWinSize, yWinSize, Resize;
// static double topMand,botMand,leftMand,rightMand;
static double oldtopMand,oldbotMand,oldleftMand,oldrightMand;
PAINTSTRUCT ps;
static HDC hdc;
// NPLOGPALETTE pLogPal;
static HANDLE hPal;
HDIB hCopyDIB;
static PALETTEENTRY palScratch[256];
LPBITMAPINFO lpbmi;
static int MouseDown, BoxDrawn, TimerOn;
static int xPos1, yPos1, xPos2, yPos2;
double xScale, yScale;
static POINT pntBox[5];
static HPEN hpen, hpenOld;
HBITMAP hbmpMyBitmap, hbmpOld;
BITMAP bm;
HFONT hOldFont, hNewFont;
char szMessage[80];
HDC MemDC;
int i;
switch (messg) {
case WM_SIZE:
xWinSize=LOWORD(lParam);
yWinSize=HIWORD(lParam)-30;
Resize = TRUE;
break;
case WM_CREATE:
hInst1 = ((LPCREATESTRUCT) lParam)->hInstance;
lpfnAboutDlgProc=MakeProcInstance((FARPROC)AboutDlgProc,hInst1);
lpfnOptionsDlgProc=MakeProcInstance((FARPROC)OptionsDlgProc,hInst1);
MouseDown=FALSE; BoxDrawn=FALSE; Resize = FALSE; TimerOn = FALSE;
topMand=1.3;botMand=-1.3;leftMand=-2;rightMand=.8;
oldtopMand=1.3;oldbotMand=-1.3;oldleftMand=-2;oldrightMand=.8;
break;
case WM_TIMER:
RotateColors(hPal, palScratch);
break;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
DrawStatusBar(hdc,xWinSize,yWinSize,leftMand,topMand,rightMand,botMand);
if (hMandelbrotDIB!=NULL) {
hPal = GetDIBPalette(hMandelbrotDIB);
SelectPalette(hdc,hPal,0);
RealizePalette(hdc);
ShowDIB(hdc,hMandelbrotDIB);
DeleteObject(hPal);
}
else {
hbmpMyBitmap = LoadBitmap(hInstance, "Black_Sun");
GetObject(hbmpMyBitmap, sizeof(BITMAP), &bm);
MemDC = CreateCompatibleDC(hdc);
hbmpOld = SelectObject(MemDC, hbmpMyBitmap);
BitBlt(hdc, 200, 20, bm.bmWidth, bm.bmHeight, MemDC, 0, 0, SRCCOPY);
SelectObject(MemDC, hbmpOld);
DeleteObject(hbmpMyBitmap);
DeleteDC(MemDC);
hNewFont=CreateFont(70,0,0,0,FW_BOLD,0,0,0,0,
0,0,0,0,"Times New Roman");
hOldFont=SelectObject(hdc,hNewFont);
SetTextColor(hdc,PALETTEINDEX(2));
sprintf(szMessage,"Bare's");
TextOut(hdc,10,5,szMessage,strlen(szMessage));
SelectObject(hdc,hOldFont);
DeleteObject(hNewFont);
hNewFont=CreateFont(36,0,100,100,FW_BOLD,0,0,0,0,
0,0,0,0,"Times New Roman");
hOldFont=SelectObject(hdc,hNewFont);
SetTextColor(hdc,PALETTEINDEX(1));
sprintf(szMessage,"Mandelbrot");
TextOut(hdc,10,90,szMessage,strlen(szMessage));
sprintf(szMessage,"Program");
TextOut(hdc,40,120,szMessage,strlen(szMessage));
SelectObject(hdc,hOldFont);
DeleteObject(hNewFont);
hNewFont=CreateFont(18,0,0,0,FW_BOLD,0,0,0,0,
0,0,0,0,"Times New Roman");
hOldFont=SelectObject(hdc,hNewFont);
SetTextColor(hdc,PALETTEINDEX(1));
sprintf(szMessage,"Version: %s",VerInfo);
TextOut(hdc,100,155,szMessage,strlen(szMessage));
sprintf(szMessage,"Build Date: %s",__DATE__);
TextOut(hdc,10,195,szMessage,strlen(szMessage));
sprintf(szMessage,"Written By: J. Christopher Bare");
TextOut(hdc,10,215,szMessage,strlen(szMessage));
SelectObject(hdc,hOldFont);
DeleteObject(hNewFont);
}
ReleaseDC(hWnd,hdc);
ValidateRect(hWnd,NULL);
EndPaint(hWnd,&ps);
BoxDrawn=FALSE;
break;
case WM_LBUTTONDOWN:
if ((!Do)&&(hMandelbrotDIB!=NULL)) {
MouseDown=TRUE;
hdc = GetDC(hWnd);
hpen = CreatePen(PS_DOT, 1, PALETTEINDEX(0));
hpenOld = SelectObject(hdc, hpen);
SetROP2(hdc,R2_XORPEN);
if (BoxDrawn) Polyline(hdc,pntBox,5);
xPos1 = LOWORD(lParam);
yPos1 = HIWORD(lParam);
SetCapture(hWnd);
xPos2 = xPos1; yPos2 = yPos1;
pntBox[0].x = xPos1;pntBox[0].y = yPos1;
pntBox[1].x = xPos2;pntBox[1].y = yPos1;
pntBox[2].x = xPos2;pntBox[2].y = yPos2;
pntBox[3].x = xPos1;pntBox[3].y = yPos2;
pntBox[4].x = xPos1;pntBox[4].y = yPos1;
}
break;
case WM_MOUSEMOVE:
if (MouseDown) {
Polyline(hdc,pntBox,5);
xPos2 = LOWORD(lParam);
yPos2 = HIWORD(lParam);
if (xPos2>=xWinSize) xPos2=xWinSize-1;
else if (xPos2<0) xPos2=0;
if (yPos2>=yWinSize) yPos2=yWinSize-1;
else if (yPos2<0) yPos2 = 0;
pntBox[0].x = xPos1;pntBox[0].y = yPos1;
pntBox[1].x = xPos2;pntBox[1].y = yPos1;
pntBox[2].x = xPos2;pntBox[2].y = yPos2;
pntBox[3].x = xPos1;pntBox[3].y = yPos2;
pntBox[4].x = xPos1;pntBox[4].y = yPos1;
Polyline(hdc,pntBox,5);
}
break;
case WM_LBUTTONUP:
if (MouseDown) {
xPos2 = LOWORD(lParam);
yPos2 = HIWORD(lParam);
if (xPos2>xWinSize) xPos2=xWinSize;
if (xPos2<0) xPos2=0;
if (yPos2>yWinSize) yPos2=yWinSize;
if (yPos2<0) yPos2 = 0;
ReleaseCapture();
MouseDown = FALSE;
BoxDrawn = TRUE;
SetROP2(hdc,R2_COPYPEN);
SelectObject(hdc, hpenOld);
DeleteObject(hpen);
ReleaseDC(hWnd,hdc);
xScale = (oldrightMand-oldleftMand)/xWinSize;
yScale = (oldtopMand-oldbotMand)/yWinSize;
if (xPos1 > xPos2) {
rightMand = xPos1*xScale+oldleftMand; leftMand = xPos2*xScale+oldleftMand;
}
else if (xPos2 > xPos1){
rightMand = xPos2*xScale+oldleftMand; leftMand = xPos1*xScale+oldleftMand;
}
if (yPos1 > yPos2) {
botMand = oldtopMand - yPos1*yScale; topMand = oldtopMand - yPos2*yScale;
}
else if (yPos2 > yPos1) {
botMand = oldtopMand - yPos2*yScale; topMand = oldtopMand - yPos1*yScale;
}
}
break;
case WM_COMMAND:
switch(wParam) {
case CM_ABOUT:
DialogBox(hInst1,"AboutDlg",hWnd,lpfnAboutDlgProc);
break;
case CM_OPTIONS:
DialogBox(hInst1,"OptionsDlg",hWnd,lpfnOptionsDlgProc);
break;
case CM_DEFAULTPALETTE:
if (Do==0) {
DefaultPalette(hMandelbrotDIB);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case CM_PURPLEGREENPALETTE:
if (Do==0) {
PurpleGreenPalette(hMandelbrotDIB);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case CM_RAINBOWPALETTE:
if (Do==0) {
RainbowPalette(hMandelbrotDIB);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case CM_ZEBRAPALETTE:
if (Do==0) {
ZebraPalette(hMandelbrotDIB);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case CM_GREYPALETTE:
if (Do==0) {
GreyPalette(hMandelbrotDIB);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case CM_RANDOMPALETTE:
if (Do==0) {
RandomPalette(hMandelbrotDIB);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case CM_COPY:
hCopyDIB = CopyDIB(hMandelbrotDIB);
if (hCopyDIB!=NULL) {
if (!OpenClipboard(hWnd))
MessageBox(hWnd,"Open Clipboard failed.","DEBUG",MB_OK);
if (!EmptyClipboard())
MessageBox(hWnd,"Empty Clipboard failed.","DEBUG",MB_OK);
SetClipboardData(CF_DIB,hCopyDIB);
SetClipboardData(CF_PALETTE,hPal);
CloseClipboard();
}
break;
case CM_START:
if (Do==0) {
if (Resize) {
GlobalFree(hMandelbrotDIB);
hMandelbrotDIB = CreateDIB(xWinSize,yWinSize);
DefaultPalette(hMandelbrotDIB);
Resize = FALSE;
}
if (hMandelbrotDIB==NULL) {
hMandelbrotDIB = CreateDIB(xWinSize,yWinSize);
DefaultPalette(hMandelbrotDIB);
}
hPal = GetDIBPalette(hMandelbrotDIB);
hdc = GetDC(hWnd);
DrawStatusBar(hdc,xWinSize,yWinSize,leftMand,topMand,
rightMand,botMand);
SelectPalette(hdc,hPal,0);
RealizePalette(hdc);
Do = 1;
Mandelbrot(hdc,hMandelbrotDIB,xWinSize,yWinSize,
leftMand,topMand,rightMand,botMand);
DeleteObject(hPal);
ReleaseDC(hWnd,hdc);
BoxDrawn=FALSE;
oldleftMand=leftMand; oldrightMand=rightMand;
oldtopMand=topMand; oldbotMand = botMand;
}
break;
case CM_STOP:
Do=0;
break;
case CM_RESET:
topMand=1.3;botMand=-1.3;leftMand=-2;rightMand=.8;
oldtopMand=1.3;oldbotMand=-1.3;oldleftMand=-2;oldrightMand=.8;
break;
case CM_ANIMATE:
if (TimerOn) {
DeleteObject(hPal);
ReleaseDC(hWnd,hdc);
KillTimer(hWnd,ID_TIMER);
TimerOn=FALSE;
lpbmi = (LPBITMAPINFO)GlobalLock(hMandelbrotDIB);
if (lpbmi!=NULL) {
for (i=0;i<256;i++) {
lpbmi->bmiColors[i].rgbRed = palScratch[i].peRed;
lpbmi->bmiColors[i].rgbGreen = palScratch[i].peGreen;
lpbmi->bmiColors[i].rgbBlue = palScratch[i].peBlue;
lpbmi->bmiColors[i].rgbReserved = PC_RESERVED;
}
}
GlobalUnlock(hMandelbrotDIB);
}
else {
hdc = GetDC(hWnd);
if (GetDeviceCaps(hdc, BITSPIXEL) == 8) {
hPal = GetDIBPalette(hMandelbrotDIB);
SelectPalette(hdc,hPal,0);
RealizePalette(hdc);
lpbmi = (LPBITMAPINFO)GlobalLock(hMandelbrotDIB);
if (lpbmi!=NULL) {
for (i=0;i<256;i++) {
palScratch[i].peRed = lpbmi->bmiColors[i].rgbRed;
palScratch[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
palScratch[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
palScratch[i].peFlags = PC_RESERVED;
}
}
GlobalUnlock(hMandelbrotDIB);
SetTimer(hWnd,ID_TIMER,100,NULL);
TimerOn=TRUE;
}
else {
sprintf(szBuffer,"Palette animation is only possible in 256 color mode.\nBits per pixel = %d",GetDeviceCaps(hdc, BITSPIXEL));
MessageBox(NULL,szBuffer,"Error",MB_OK);
ReleaseDC(hWnd,hdc);
}
}
break;
case CM_EXIT:
// ReleaseDC(hWnd,hdc);
DestroyWindow(hWnd);
return 0;
break;
}
break;
case WM_DESTROY:
if (TimerOn) {
KillTimer(hWnd,ID_TIMER);
DeleteObject(hPal);
ReleaseDC(hWnd,hdc);
}
FreeProcInstance(lpfnAboutDlgProc);
FreeProcInstance(lpfnOptionsDlgProc);
GlobalFree(hMandelbrotDIB);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,messg,wParam,lParam);
}
return(0);
}
/***********************************************
* AboutDlgProc *
* *
* Process messages to the About window. *
* *
***********************************************/
BOOL FAR PASCAL _export AboutDlgProc(HWND hdlg, UINT messg, WPARAM wParam,
LPARAM lParam)
{
HDC AboutDC, MemDC;
HBITMAP hbmpMyBitmap, hbmpOld;
BITMAP bm;
HFONT hOldFont, hNewFont;
char szMessage[512] = { "This program was written in straight C using "
"Borland C++ 4.0, but not using owl or any other "
"libraries. Source code is included. It is "
"shareware and all rights are retained by the "
"author. ItÆs mostly free, but if you send me ten "
"bucks, I will declare you an enlightened and "
"exalted human being. HereÆs how to contact me:\n\n"
"J. Christopher Bare\n"
"610 W. Beaver Ave. #1\n"
"State College, PA 16801\n\n"
"<jcb110@psu.edu>" };
switch (messg) {
case WM_INITDIALOG:
SetDlgItemText(hdlg,IDC_TEXTBOX,szMessage);
sprintf(szMessage,"%s",VerInfo);
SetDlgItemText(hdlg,IDC_VERSION,szMessage);
sprintf(szMessage,"%s",__DATE__);
SetDlgItemText(hdlg,IDC_BUILDDATE,szMessage);
break;
case WM_PAINT:
hbmpMyBitmap = LoadBitmap(hInstance, "MAND_BITMAP");
GetObject(hbmpMyBitmap, sizeof(BITMAP), &bm);
AboutDC = GetDC(hdlg);
MemDC = CreateCompatibleDC(AboutDC);
hbmpOld = SelectObject(MemDC, hbmpMyBitmap);
BitBlt(AboutDC, 20, 20, bm.bmWidth, bm.bmHeight, MemDC, 0, 0, SRCCOPY);
SelectObject(MemDC, hbmpOld);
DeleteObject(hbmpMyBitmap);
DeleteDC(MemDC);
hNewFont=CreateFont(54,0,100,100,FW_BOLD,0,0,0,0,
0,0,0,0,"Times New Roman");
hOldFont=SelectObject(AboutDC,hNewFont);
SetTextColor(AboutDC,PALETTEINDEX(0));
sprintf(szMessage,"Bare's");
TextOut(AboutDC,200,30,szMessage,strlen(szMessage));
sprintf(szMessage,"Mandelbrot");
TextOut(AboutDC,200,75,szMessage,strlen(szMessage));
sprintf(szMessage,"Program");
TextOut(AboutDC,250,115,szMessage,strlen(szMessage));
SelectObject(AboutDC,hOldFont);
DeleteObject(hNewFont);
ReleaseDC(hdlg,AboutDC);
return FALSE;
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
EndDialog(hdlg,TRUE);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
/***********************************************
* OptionsDlgProc *
* *
* Process messages to the Options window. *
* *
***********************************************/
BOOL FAR PASCAL _export OptionsDlgProc(HWND hdlg, UINT messg, WPARAM wParam,
LPARAM lParam)
{
char szMessage[80];
switch (messg) {
case WM_INITDIALOG:
sprintf(szMessage,"%u",iMaxDel);
SetDlgItemText(hdlg,IDC_MAXITER,szMessage);
sprintf(szMessage,"%.10f",topMand);
SetDlgItemText(hdlg,IDC_TOP,szMessage);
sprintf(szMessage,"%.10f",leftMand);
SetDlgItemText(hdlg,IDC_LEFT,szMessage);
sprintf(szMessage,"%.10f",botMand);
SetDlgItemText(hdlg,IDC_BOT,szMessage);
sprintf(szMessage,"%.10f",rightMand);
SetDlgItemText(hdlg,IDC_RIGHT,szMessage);
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
GetDlgItemText(hdlg,IDC_MAXITER,szMessage,80);
if (sscanf(szMessage,"%u",&iMaxDel)!=1) {
MessageBox(hdlg,"Maximum iterations can be any "
"integer from 1 to 65535.","Error",MB_OK);
break;
}
GetDlgItemText(hdlg,IDC_TOP,szMessage,80);
if (sscanf(szMessage,"%f",&topMand)!=1) {
MessageBox(hdlg,"Re-enter the top coordinate.","Error",MB_OK);
break;
}
topMand = atof(szMessage);
GetDlgItemText(hdlg,IDC_LEFT,szMessage,80);
if (sscanf(szMessage,"%f",&leftMand)!=1) {
MessageBox(hdlg,"Re-enter the left coordinate.","Error",MB_OK);
break;
}
leftMand = atof(szMessage);
GetDlgItemText(hdlg,IDC_RIGHT,szMessage,80);
if (sscanf(szMessage,"%f",&rightMand)!=1) {
MessageBox(hdlg,"Re-enter the right coordinate.","Error",MB_OK);
break;
}
rightMand = atof(szMessage);
GetDlgItemText(hdlg,IDC_BOT,szMessage,80);
if (sscanf(szMessage,"%f",&botMand)!=1) {
MessageBox(hdlg,"Re-enter the bottom coordinate.","Error",MB_OK);
break;
}
botMand = atof(szMessage);
EndDialog(hdlg,TRUE);
break;
case IDCANCEL:
EndDialog(hdlg,TRUE);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}