|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: fractal.c
3: *
4: * Fractal generation Screen saver
5: *
6: * Created: 19-Dec-1992 20:43:00
7: * Author: Petrus Wong
8: *
9: * Copyright (c) 1992 Microsoft Corporation
10: *
11: * The screen saver generates the Mandelbrot picture...
12: *
13: * Dependencies:
14: *
15: * (#defines)
16: * (#includes)
17: *
18: \**************************************************************************/
19: #include <windows.h>
20: #include <scrnsave.h>
21: #include <stdio.h>
22: #include <math.h>
23: #include <commdlg.h>
24: #include "fractal.h"
25:
26: LONG APIENTRY ScreenSaverProc(HWND, UINT, WPARAM, LPARAM);
27: BOOL APIENTRY ScreenSaverConfigureDialog(HWND, UINT, WPARAM, LPARAM);
28: BOOL WINAPI RegisterDialogClasses(HANDLE);
29: BOOL StartMandelbrot (PINFO);
30: INT iCreatePenFrPal(HDC, PVOID *, INT, HPALETTE *);
31: BOOL bInitInfo(PINFO);
32: void vLoadStrings(VOID);
33: BOOL SaveBitmapFile(HDC, HBITMAP, PSTR);
34: void ErrorOut(char errstring[30]);
35: BOOL bGetPPStr(char szXFr[MAXDOUBLELEN], char szYFr[MAXDOUBLELEN],
36: char szX2[MAXDOUBLELEN], char szY2[MAXDOUBLELEN],
37: char szSavef[MAXFILELEN], char szIter[MAXDOUBLELEN]);
38: BOOL bInitDlgItems(HWND);
39: BOOL bColorCycle(HDC, PINFO);
40: /******************************Public*Routine******************************\
41: *
42: * ScreenSaverProc
43: *
44: * Effects: Creates a drawing thread.
45: *
46: * Warnings:
47: *
48: * History:
49: * 18-Dec-1992 -by- Petrus Wong
50: * Wrote it.
51: \**************************************************************************/
52:
53: LONG APIENTRY
54: ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
55: {
56: static HBRUSH hBkBr;
57:
58: switch(message)
59: {
60: case WM_CREATE:
61: hBkBr = GetStockObject(BLACK_BRUSH);
62: hpnRed = CreatePen(PS_SOLID, 0, RGB(0xFF, 0, 0));
63: hpnGreen = CreatePen(PS_SOLID, 0, RGB(0, 0xFF, 0));
64: hpnBlack = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
65:
66: vLoadStrings();
67: bInitInfo(&gInfo);
68: break;
69:
70: case WM_ERASEBKGND: {
71: RECT rc;
72:
73: GetClientRect(hWnd, &rc);
74: FillRect((HDC)wParam, &rc, hBkBr);
75: gInfo.bMandel = TRUE;
76: gInfo.hwnd = hWnd;
77: gInfo.hHTPal = CreateHalftonePalette((HDC)wParam);
78: gInfo.hThrd = CreateThread(NULL, 0,
79: (LPTHREAD_START_ROUTINE)StartMandelbrot,
80: &gInfo,
81: STANDARD_RIGHTS_REQUIRED,
82: &gInfo.dwThreadId );
83:
84: if (gInfo.hThrd) {
85: SetThreadPriority(gInfo.hThrd, THREAD_PRIORITY_BELOW_NORMAL);
86: }
87:
88:
89: return 0L;
90: }
91: case WM_DESTROY:
92: DeleteObject(hBkBr);
93: DeleteObject(hpnRed);
94: DeleteObject(hpnGreen);
95: DeleteObject(hpnBlack);
96: TerminateThread(gInfo.hThrd, (DWORD)0L);
97: break;
98: }
99: return (DefScreenSaverProc(hWnd,message,wParam,lParam));
100: }
101:
102:
103: /******************************Public*Routine******************************\
104: *
105: * ScreenSaverConfigureDialog
106: *
107: * Effects:
108: *
109: * Warnings:
110: *
111: * History:
112: * 19-Dec-1992 -by- Petrus Wong
113: * Wrote it.
114: \**************************************************************************/
115:
116: BOOL APIENTRY
117: ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
118: {
119: switch(message)
120: {
121: case WM_INITDIALOG: {
122: vLoadStrings();
123: bInitDlgItems(hDlg);
124: return TRUE;
125: }
126: case WM_COMMAND:
127:
128: switch(LOWORD(wParam))
129: {
130: static char szFile[MAXPATHLEN];
131: static BOOL bSave2DiffFile = FALSE;
132:
133: case ID_SAVEAS: {
134: OPENFILENAME ofn;
135: char szDirName[MAXPATHLEN];
136: char szFileTitle[256];
137: static char *szFilter;
138:
139: szFilter = "DIB files (*.bmp)\0\0";
140:
141: GetSystemDirectory((LPSTR) szDirName, MAXPATHLEN);
142: strcpy(szFile, "*.bmp\0");
143: ofn.lStructSize = sizeof(OPENFILENAME);
144: ofn.hwndOwner = hDlg;
145: ofn.lpstrFilter = szFilter;
146: ofn.lpstrCustomFilter = (LPSTR) NULL;
147: ofn.nMaxCustFilter = 0L;
148: ofn.nFilterIndex = 0L;
149: ofn.lpstrFile = szFile;
150: ofn.nMaxFile = sizeof(szFile);
151: ofn.lpstrFileTitle = szFileTitle;
152: ofn.nMaxFileTitle = sizeof(szFileTitle);
153: ofn.lpstrInitialDir = szDirName;
154: ofn.lpstrTitle = "Save Bitmap As";
155: ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
156: ofn.nFileOffset = 0;
157: ofn.nFileExtension = 0;
158: ofn.lpstrDefExt = (LPSTR)NULL;
159:
160: if (GetSaveFileName(&ofn))
161: bSave2DiffFile = TRUE;
162:
163: break;
164: }
165: case IDOK: {
166: char szXFr[MAXDOUBLELEN];
167: char szYFr[MAXDOUBLELEN];
168: char szX2[MAXDOUBLELEN];
169: char szY2[MAXDOUBLELEN];
170: char szIter[MAXDOUBLELEN];
171:
172: if (bSave2DiffFile)
173: WritePrivateProfileString(szAppName, szSaveFile, szFile, szIniFile);
174:
175: //
176: // Saves new configuartion...
177: //
178: GetDlgItemText(hDlg, ID_XFROM, szXFr, MAXDOUBLELEN);
179: GetDlgItemText(hDlg, ID_YFROM, szYFr, MAXDOUBLELEN);
180: GetDlgItemText(hDlg, ID_XTO, szX2, MAXDOUBLELEN);
181: GetDlgItemText(hDlg, ID_YTO, szY2, MAXDOUBLELEN);
182: GetDlgItemText(hDlg, ID_ITERATION, szIter, MAXDOUBLELEN);
183: WritePrivateProfileString(szAppName, szXFrom, szXFr, szIniFile);
184: WritePrivateProfileString(szAppName, szYFrom, szYFr, szIniFile);
185: WritePrivateProfileString(szAppName, szXTo, szX2, szIniFile);
186: WritePrivateProfileString(szAppName, szYTo, szY2, szIniFile);
187: WritePrivateProfileString(szAppName, szIteration, szIter, szIniFile);
188: }
189: case IDCANCEL:
190: bSave2DiffFile = FALSE;
191: EndDialog(hDlg,LOWORD(wParam) == IDOK);
192: return TRUE;
193: default:
194: break;
195: }
196: default:
197: break;
198: }
199: return FALSE;
200: }
201:
202: /******************************Public*Routine******************************\
203: *
204: * RegisterDialogClasses
205: *
206: * Effects: Register window classes used by the configuration dialog
207: *
208: * Warnings: Return TRUE even if no class needed to be registered.
209: *
210: * History:
211: * 18-Dec-1992 -by- Petrus Wong
212: * Wrote it.
213: \**************************************************************************/
214:
215: BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
216: {
217: return TRUE;
218: }
219:
220: /**************************************************************************\
221: *
222: * StartMandelbrot
223: * 2
224: * Effects: Draw'g the Mandelbrot Set for Q (z) = z + c, where z, c complex
225: *
226: * Warnings:
227: *
228: * History:
229: * 15-Jan-1993 Petrus Wong Added color cycle and removed the red &
230: * black for saving the screen
231: * 19-Dec-1992 Petrus Wong Adapted from the Mandel SDK Sample
232: * 14-Dec-1992 -by- Petrus Wong Enable shadow bitmap
233: * 14-Jun-1992 -by- Petrus Wong Modified to use the pen array and LineTo
234: * 20-Nov-1991 -by- Petrus Wong
235: * Wrote it.
236: \**************************************************************************/
237: BOOL StartMandelbrot(PINFO pInfo)
238: {
239: DWORD dwTick1;
240: HDC hDC;
241: RECT rc;
242: int m, n, i, iPrev;
243: int xCurr, yCurr;
244: int iPen;
245:
246: #ifndef THRDONE
247: INT iNumClr;
248: char text[256];
249: #endif
250:
251: double c1, c2;
252: double x1, y1, x, y, r;
253:
254: HDC hDCMem;
255: HBITMAP hBitmap, hOldBitmap;
256:
257: pInfo->bMandel = TRUE;
258: pInfo->bDrawing = TRUE;
259: hDC = GetDC(pInfo->hwnd);
260:
261: #ifndef THRDONE
262: if ((iNumClr = iCreatePenFrPal(hDC, NULL, 0, &(pInfo->hPal))) != 0) {
263: sprintf( gtext,"iNumClr = %d\n", iNumClr);
264: OutputDebugString( gtext);
265:
266: if ((pInfo->prghPen = (PVOID*) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(HPEN)*iNumClr)) == NULL) {
267: MessageBox(GetFocus(), "Failed in Memory Allocation for pInfo->prghPen!", "Error", MB_OK);
268: } else {
269: if ((pInfo->iPen = iCreatePenFrPal(hDC, pInfo->prghPen, 1, &(pInfo->hPal))) == 0)
270: MessageBox(GetFocus(), "Failed in creating pen!", "Error", MB_OK);
271: }
272: }
273:
274: hDCMem = CreateCompatibleDC(hDC);
275:
276: if (pInfo->hPal) {
277: SelectPalette(hDCMem, pInfo->hPal, FALSE);
278: RealizePalette(hDCMem);
279: }
280: iPen = pInfo->iPen + 1;
281: wsprintf(text, "iPen = %d\n", iPen);
282: //MessageBox(GetFocus(), text, "Error", MB_OK);
283: #endif
284:
285: GetClientRect(pInfo->hwnd, &rc);
286:
287: hBitmap = CreateCompatibleBitmap(hDC, (int)rc.right, (int)rc.bottom);
288: hOldBitmap = SelectObject(hDCMem, hBitmap);
289:
290: //#if 0
291: {
292: int iWidth, i, j;
293:
294: iWidth = (((iWidth = rc.right/iNumClr) == 0) ? 1 : iWidth);
295: sprintf( gtext,"iWidth = %d\n", iWidth);
296: OutputDebugString( gtext);
297:
298: for (i = 0; i < iNumClr; i++) {
299: //for (i = 0; i < 256; i++) {
300: //sprintf( gtext,"i mod iNumClr = %d\n", i % iNumClr);
301: //OutputDebugString( gtext);
302: if ((SelectObject(hDC, (HPEN)(pInfo->prghPen)[i % iNumClr])) == NULL) {
303: sprintf( gtext,"Select Pen failed\n");
304: OutputDebugString( gtext);
305: }
306: SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iNumClr]);
307: for (j = 0; j < iWidth; j++) {
308: MoveToEx(hDC, i*iWidth+j, 0, NULL);
309: LineTo(hDC, i*iWidth+j, rc.bottom);
310: MoveToEx(hDCMem, i*iWidth+j, 0, NULL);
311: LineTo(hDCMem, i*iWidth+j, rc.bottom);
312: }
313:
314: }
315: }
316: //#endif
317:
318: dwTick1 = GetTickCount();
319:
320: sprintf( gtext,"Start Drawing\n");
321: OutputDebugString( gtext);
322: yCurr = rc.top;
323: for (n=rc.top; n<=rc.bottom; n+=pInfo->iStep, yCurr+=pInfo->iStep, iPrev = FIRST_PIXEL) {
324: xCurr = rc.left; // since LineTo excludes last point
325: MoveToEx(hDC, 0, yCurr, NULL);
326: MoveToEx(hDCMem, 0, yCurr, NULL);
327: c2 = Xform((double) n, 0.0, (double) rc.bottom, pInfo->yFrom, pInfo->yTo);
328:
329: for (m=rc.left; m<=rc.right; m++, xCurr++) {
330: c1 = Xform((double) m, 0.0, (double) rc.right, pInfo->xFrom, pInfo->xTo);
331: x = c1;
332: y = c2;
333:
334: for (i=1; i<=pInfo->iIteration; i++) {
335: x1 = (x - y) * (x + y) + c1;
336: y1 = 2 * x * y + c2;
337: r = x1 * x1 + y1 * y1;
338: x = x1;
339: y = y1;
340: if (r > 4.0) {
341: break;
342: }
343: }
344:
345: if (i != iPrev) {
346: if (iPrev != FIRST_PIXEL) {
347: switch(iPrev) {
348: case 1: SelectObject(hDC, (HPEN)(pInfo->prghPen)[0]);
349: SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
350: break;
351: default:
352: if (iPrev >= pInfo->iIteration) {
353: SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPen/3]);
354: SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPen/3]);
355: break;
356: }
357: SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
358: SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPrev % iPen]);
359: //SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPrev % iNumClr]);
360: break;
361: }
362: iPrev = i;
363: LineTo(hDC, xCurr, yCurr);
364: LineTo(hDCMem, xCurr, yCurr);
365: }
366: else
367: iPrev = i; // remember the color for the first pixel
368: }
369: }
370:
371: switch(i)
372: {
373: case 1: SelectObject(hDC, (HPEN)(pInfo->prghPen)[0]);
374: SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[0]);
375: break;
376: default:
377: if (i >= pInfo->iIteration) {
378: SelectObject(hDC, (HPEN)(pInfo->prghPen)[iPen/3]);
379: SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[iPen/3]);
380: break;
381: }
382: SelectObject(hDC, (HPEN)(pInfo->prghPen)[i % iPen]);
383: SelectObject(hDCMem, (HPEN)(pInfo->prghPen)[i % iPen]);
384: //SelectObject(hDC, (HPEN)(pInfo->prghPen)[i % iNumClr]);
385: break;
386: }
387:
388: LineTo(hDC,xCurr,yCurr);
389: LineTo(hDCMem,xCurr,yCurr);
390:
391: }
392:
393:
394:
395: pInfo->dwElapsed = GetTickCount() - dwTick1;
396:
397: if (pInfo->hBmpSaved)
398: DeleteObject(pInfo->hBmpSaved);
399:
400: pInfo->hBmpSaved = SelectObject(hDCMem, hOldBitmap);
401: pInfo->bDrawing = FALSE;
402: SaveBitmapFile(hDC, pInfo->hBmpSaved, pInfo->szSavef);
403: pInfo->bClrCycle = TRUE;
404: if (pInfo->hPal)
405: bColorCycle(hDC, pInfo);
406: ReleaseDC(pInfo->hwnd, hDC);
407:
408: #ifndef THRDONE
409: if (pInfo->prghPen != NULL) {
410: for (i = 0; i <= pInfo->iPen; i++) {
411: DeleteObject((HPEN) (pInfo->prghPen)[i]);
412: }
413: GlobalFree(pInfo->prghPen);
414: }
415: #endif
416:
417: DeleteDC(hDCMem);
418:
419: ExitThread(0);
420: if (!CloseHandle(pInfo->hThrd))
421: MessageBox(GetFocus(), "Failed in CloseHandle!", "Error", MB_OK);
422:
423: return TRUE;
424: }
425:
426:
427: /******************************Public*Routine******************************\
428: *
429: * iCreatePenFrPal
430: *
431: * Effects: Create an array of pens from palette.
432: * If device supports palette, then first creates a logical palette
433: * with a good spread of color. Then select the logical palette into
434: * the DC. Create pen that corresponds to each palette entry.
435: * If system does not support palette, then use the system palette.
436: *
437: * prghPen pointer to an array of hPen
438: * If this is NULL, the required size of the array is
439: * returned. If this is not NULL, the array will be filled
440: * with hPens.
441: *
442: * returns the number of hPens created.
443: *
444: * Warnings:
445: *
446: * History:
447: * 13-Jun-1992 -by- Petrus Wong
448: * Wrote it.
449: \**************************************************************************/
450:
451: INT iCreatePenFrPal(HDC hDC, PVOID *prghPen, INT iWidth, HPALETTE *phPal)
452: {
453: INT iNumClr, iResult, i, iEntry;
454: PLOGPALETTE plogPat;
455: ULONG ulSize;
456:
457: iResult = 0;
458:
459: if (!((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE)) {
460:
461: if (iNumClr = GetSystemPaletteEntries(hDC, 0, 0, NULL)) {
462: if (prghPen == NULL) {
463: return (iNumClr);
464: }
465:
466: if (iWidth < 0) {
467: MessageBox(GetFocus(), "Invalid pen width!", "Error", MB_OK);
468: return 0L;
469: }
470:
471: for (i = 0; i < iNumClr; i++) {
472: prghPen[i] =
473: (PVOID) CreatePen(PS_SOLID, iWidth, PALETTEINDEX(i));
474: iResult = i;
475: #if 0
476: SelectObject(hDC, (HPEN)prghPen[i]);
477: MoveToEx(hDC, i*iWidth, 0, NULL);
478: LineTo(hDC, i*iWidth, 300);
479: #endif
480: }
481: return iResult;
482: }
483:
484: // GetPaletteEntries returns 0
485: iNumClr = 1 << GetDeviceCaps(hDC, BITSPIXEL);
486:
487: if (iNumClr <= 16) {
488: sprintf( gtext,"Assertion failed: iCreatePenFrPal() \n");
489: OutputDebugString( gtext);
490: sprintf( gtext,"iNumClr <= 16! iNumClr = %d\n", iNumClr);
491: OutputDebugString( gtext);
492: return (iNumClr);
493: }
494:
495: // Assuming at least 16 bit device
496: //
497: iNumClr = 768; // COLORREF format: 0x00bbggrr r,g,b=[0,255]
498:
499: if (prghPen == NULL) {
500: return (iNumClr);
501: }
502:
503: if (iWidth < 0) {
504: MessageBox(GetFocus(), "Invalid pen width!", "Error", MB_OK);
505: return 0L;
506: }
507:
508: for (i = 0; i < iNumClr; i++) {
509: if (i < 256) {
510: prghPen[i] =
511: (PVOID) CreatePen(PS_SOLID, iWidth, RGB(i,0,255-i));
512: iResult = i;
513: #if 0
514: SelectObject(hDC, (HPEN)prghPen[i]);
515: MoveToEx(hDC, i*iWidth, 0, NULL);
516: LineTo(hDC, i*iWidth, 300);
517: #endif
518: continue;
519: }
520:
521: if (i < 512) {
522: prghPen[i] =
523: (PVOID) CreatePen(PS_SOLID, iWidth, RGB(511-i,i-256,0));
524: iResult = i;
525: #if 0
526: SelectObject(hDC, (HPEN)prghPen[i]);
527: MoveToEx(hDC, i*iWidth, 0, NULL);
528: LineTo(hDC, i*iWidth, 300);
529: #endif
530: continue;
531: }
532:
533:
534: prghPen[i] =
535: (PVOID) CreatePen(PS_SOLID, iWidth, RGB(0,767-i,i-512));
536: iResult = i;
537: #if 0
538: SelectObject(hDC, (HPEN)prghPen[i]);
539: MoveToEx(hDC, i*iWidth, 0, NULL);
540: LineTo(hDC, i*iWidth, 300);
541: #endif
542: }
543:
544: return iResult;
545: }
546:
547: //
548: // Palette managed device
549: //
550: iEntry = iNumClr = 1 << GetDeviceCaps(hDC, BITSPIXEL);
551:
552: if (iNumClr > 256) {
553: sprintf( gtext,"Assertion failed: iCreatePenFrPal() \n");
554: OutputDebugString( gtext);
555: sprintf( gtext,"iNumClr > 256! iNumClr = %d\n", iNumClr);
556: OutputDebugString( gtext);
557: iEntry=iNumClr = 256;
558: }
559:
560: ulSize = sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*iNumClr;
561:
562: iNumClr -= GetDeviceCaps(hDC, NUMRESERVED);
563:
564: if (prghPen == NULL)
565: return iNumClr;
566:
567: if ((plogPat = (PLOGPALETTE) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, ulSize)) == NULL) {
568: MessageBox(GetFocus(), "Failed in Memory Allocation for plogPat!", "Error", MB_OK);
569: goto ErrExit1;
570: }
571:
572: plogPat->palVersion = 0x300;
573: plogPat->palNumEntries = (WORD) iEntry;
574:
575: {
576: int iFirst, iSecond, iInc;
577:
578: iFirst = iNumClr/3;
579: iSecond = iFirst * 2;
580: iInc = (iNumClr <= 256) ? 3 : 1;
581:
582:
583: for (i = 0; i < iNumClr; i++) {
584: if (i < iFirst) {
585: plogPat->palPalEntry[i+10].peBlue = 255-(i+1)*iInc;
586: plogPat->palPalEntry[i+10].peGreen = 0;
587: plogPat->palPalEntry[i+10].peRed = (i+1)*iInc;
588: plogPat->palPalEntry[i+10].peFlags = PC_RESERVED;
589: continue;
590: }
591: if (i < iSecond) {
592: plogPat->palPalEntry[i+10].peBlue = 0;
593: plogPat->palPalEntry[i+10].peGreen = (i+1-iFirst)*iInc;
594: plogPat->palPalEntry[i+10].peRed = 255-(i+1-iFirst)*iInc;
595: plogPat->palPalEntry[i+10].peFlags = PC_RESERVED;
596: continue;
597: }
598: plogPat->palPalEntry[i+10].peBlue = (i+1-iSecond)*iInc;
599: plogPat->palPalEntry[i+10].peGreen = 255-(i+1-iSecond)*iInc;
600: plogPat->palPalEntry[i+10].peRed = 0;
601: plogPat->palPalEntry[i+10].peFlags = PC_RESERVED;
602: }
603: }
604:
605: DeleteObject(*phPal);
606:
607: if ((*phPal = CreatePalette(plogPat)) == (HPALETTE) NULL) {
608: MessageBox(GetFocus(), "Failed in creating palette!", "Error", MB_OK);
609: goto ErrExit2;
610: }
611: if (*phPal) {
612: SelectPalette(hDC, *phPal, FALSE);
613: RealizePalette(hDC);
614: }
615:
616: for (i = 0; i < iNumClr; i++) {
617: HPEN hPen;
618:
619: hPen = CreatePen(PS_SOLID, iWidth, PALETTEINDEX(i+10));
620: prghPen[i] = (PVOID) hPen;
621: iResult = i;
622: #if 0
623: SelectObject(hDC, hPen);
624: MoveToEx(hDC, i*iWidth, 0, NULL);
625: LineTo(hDC, i*iWidth, 300);
626: #endif
627: }
628:
629: ErrExit2:
630: GlobalFree(plogPat);
631: ErrExit1:
632: return iResult;
633:
634: }
635:
636: /******************************Public*Routine******************************\
637: *
638: * bInitInfo
639: *
640: * Effects: Initialize the Info data structure
641: *
642: * Warnings:
643: *
644: * History:
645: * 19-Dec-1992 Petrus Wong Retrieve setup info fr control.ini
646: * 14-Dec-1992 -by- Petrus Wong Added Rle and pens stuff
647: * 28-Jan-1992 -by- Petrus Wong
648: * Wrote it.
649: \**************************************************************************/
650:
651: BOOL bInitInfo(PINFO pInfo)
652: {
653: char szXFr[MAXDOUBLELEN], szYFr[MAXDOUBLELEN], szX2[MAXDOUBLELEN],
654: szY2[MAXDOUBLELEN], szSavef[MAXPATHLEN], szIter[MAXDOUBLELEN];
655:
656: bGetPPStr(szXFr, szYFr, szX2, szY2, szSavef, szIter);
657: pInfo->xFrom = atof(szXFr);
658: pInfo->xTo = atof(szX2);
659: pInfo->yFrom = atof(szYFr);
660: pInfo->yTo = atof(szY2);
661: pInfo->lxFrom = -4096; // 20.11 fix point
662: pInfo->lxTo = 4096; // representation of
663: pInfo->lyFrom = 4096; // -2, 2, 2, and -2
664: pInfo->lyTo = -4096; //
665: pInfo->iIteration = (INT) atof(szIter);
666: pInfo->iStep = gStep;
667: pInfo->bStretch = gbStretch;
668: pInfo->iStretchMode = giStretchMode;
669: pInfo->hwnd = NULL;
670: pInfo->hThrd = NULL;
671: pInfo->bDrawing = FALSE;
672: pInfo->dwThreadId = 0;
673: pInfo->dwElapsed = 0L;
674: pInfo->c1 = 0.0;
675: pInfo->c2 = 0.0;
676: pInfo->lc1 = 0L;
677: pInfo->lc2 = 0L;
678: pInfo->hBmpSaved = NULL;
679: pInfo->bMandel = TRUE;
680: pInfo->bSetDIBsToDevice = FALSE;
681: pInfo->hPal = NULL;
682: pInfo->prghPen = NULL;
683: pInfo->iPen = 0;
684: pInfo->bClrCycle = FALSE;
685: wsprintf((LPSTR) &(pInfo->szSavef), szSavef);
686: return TRUE;
687: }
688:
689:
690:
691:
692: /******************************Public*Routine******************************\
693: *
694: * vLoadStrings
695: *
696: * Effects: Load strings from resource
697: *
698: * Warnings:
699: *
700: * History:
701: * 19-Dec-1992 -by- Petrus Wong
702: * Wrote it.
703: \**************************************************************************/
704:
705: void vLoadStrings(VOID)
706: {
707: LoadString(hMainInstance, idsAppName, szAppName, APPNAMEBUFFERLEN);
708: LoadString(hMainInstance, idsName, szName, TITLEBARNAMELEN);
709: LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);
710: LoadString(hMainInstance, idsScreenSaver, szScreenSaver, 22);
711: LoadString(hMainInstance, idsHelpFile, szHelpFile, MAXFILELEN);
712: LoadString(hMainInstance, idsNoHelpMemory, szNoHelpMemory, BUFFLEN);
713: LoadString(hMainInstance, idsXFrom, szXFrom, MAXDOUBLELEN);
714: LoadString(hMainInstance, idsYFrom, szYFrom, MAXDOUBLELEN);
715: LoadString(hMainInstance, idsXTo, szXTo, MAXDOUBLELEN);
716: LoadString(hMainInstance, idsYTo, szYTo, MAXDOUBLELEN);
717: LoadString(hMainInstance, idsSaveAs, szSaveFile, MAXPATHLEN);
718: LoadString(hMainInstance, idsIteration, szIteration, MAXDOUBLELEN);
719: }
720:
721:
722:
723: /******************************Public*Routine******************************\
724: * SaveBitmapFile
725: *
726: *
727: * Effects: Save pInfo->hBmpSaved into disk specified by pszFileName
728: *
729: * Warnings: assumes hBmpSaved is not selected into window's DC other than
730: * pInfo->hwnd's DC
731: *
732: * History:
733: * 14-Jan-1992 -by- Petrus Wong
734: * Wrote it.
735: \**************************************************************************/
736:
737: BOOL SaveBitmapFile(HDC hDC, HBITMAP hBmp, PSTR pszFileName)
738: {
739: int hFile;
740: OFSTRUCT ofReOpenBuff;
741: HBITMAP hTmpBmp, hBmpOld;
742: BOOL bSuccess;
743: BITMAPFILEHEADER bfh;
744: PBITMAPINFO pbmi;
745: PBYTE pBits;
746: BITMAPINFO bmi;
747: PBYTE pjTmp, pjTmpBmi;
748: ULONG sizBMI;
749:
750:
751: bSuccess = TRUE;
752: if (!hBmp) {
753: MessageBox(GetFocus(), "There's no Bitmap to save!", "Error", MB_OK);
754: return FALSE;
755: }
756:
757: //
758: // Let the graphics engine to retrieve the dimension of the bitmap for us
759: // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO
760: // if BitCount != 0, color table will be retrieved
761: //
762: bmi.bmiHeader.biSize = 0x28; // GDI need this to work
763: bmi.bmiHeader.biBitCount = 0; // don't get the color table
764: if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)NULL, &bmi, DIB_RGB_COLORS)) == 0) {
765: MessageBox(GetFocus(), "GetDIBits failed!", "Error", MB_OK);
766: return FALSE;
767: }
768:
769: //
770: // Now that we know the size of the image, alloc enough memory to retrieve
771: // the actual bits
772: //
773: if ((pBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
774: bmi.bmiHeader.biSizeImage)) == NULL) {
775: MessageBox(GetFocus(), "Failed in Memory Allocation for pBits!", "Error", MB_OK);
776: return FALSE;
777: }
778:
779: //
780: // Note: 24 bits per pixel has no color table. So, we don't have to
781: // allocate memory for retrieving that. Otherwise, we do.
782: //
783: pbmi = &bmi; // assume no color table
784: if (bmi.bmiHeader.biBitCount != 24) { // has color table
785: sizBMI = sizeof(BITMAPINFO)+sizeof(RGBQUAD)*(1<<bmi.bmiHeader.biBitCount);
786: //
787: // I need more memory for the color table
788: //
789: if ((pbmi = (PBITMAPINFO)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizBMI )) == NULL) {
790: MessageBox(GetFocus(), "Failed in Memory Allocation for pbmi!", "Error", MB_OK);
791: bSuccess = FALSE;
792: goto ErrExit1;
793: }
794: //
795: // Now that we've a bigger chunk of memory, let's copy the Bitmap
796: // info header data over
797: //
798: pjTmp = (PBYTE)pbmi;
799: pjTmpBmi = (PBYTE)&bmi;
800: sizBMI = sizeof(BITMAPINFOHEADER);
801:
802: while(sizBMI--)
803: {
804: *(((PBYTE)pjTmp)++) = *((pjTmpBmi)++);
805: }
806:
807: }
808:
809: //
810: // Let's open the file and get ready for writing
811: //
812: if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff,
813: OF_CREATE | OF_WRITE)) == -1) {
814: MessageBox(GetFocus(), "Failed in OpenFile!", "Error", MB_OK);
815: ErrorOut("OpenFile");
816: goto ErrExit2;
817: }
818:
819: //
820: // But first, fill in the info for the BitmapFileHeader
821: //
822: bfh.bfType = 0x4D42; // 'BM'
823: bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*
824: ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount))+
825: pbmi->bmiHeader.biSizeImage;
826: bfh.bfReserved1 =
827: bfh.bfReserved2 = 0;
828: bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
829: sizeof(RGBQUAD)*((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount));
830:
831: //
832: // Write out the file header now
833: //
834: if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) {
835: MessageBox(GetFocus(), "Failed in WriteFile!", "Error", MB_OK);
836: bSuccess = FALSE;
837: goto ErrExit3;
838: }
839:
840: //
841: // Bitmap can't be selected into a DC when calling GetDIBits
842: // Assume that the hDC is the DC where the bitmap would have been selected
843: // if indeed it has been selected
844: //
845: if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) {
846: hBmpOld = SelectObject(hDC, hTmpBmp);
847: if ((GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)pBits, pbmi, DIB_RGB_COLORS))==0){
848: MessageBox(GetFocus(), "Failed in GetDIBits!", "Error", MB_OK);
849: bSuccess = FALSE;
850: goto ErrExit4;
851: }
852: } else {
853: MessageBox(GetFocus(), "Failed in creating bitmap!", "Error", MB_OK);
854: bSuccess = FALSE;
855: goto ErrExit3;
856: }
857:
858: //
859: // Now write out the BitmapInfoHeader and color table, if any
860: //
861: if (_lwrite(hFile, (LPSTR)pbmi, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) *
862: ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1 << pbmi->bmiHeader.biBitCount))) == -1) {
863: MessageBox(GetFocus(), "Failed in WriteFile!", "Error", MB_OK);
864: bSuccess = FALSE;
865: goto ErrExit4;
866: }
867:
868: //
869: // write the bits also
870: //
871: if (_lwrite(hFile, (LPSTR)pBits, pbmi->bmiHeader.biSizeImage) == -1) {
872: MessageBox(GetFocus(), "Failed in WriteFile!", "Error", MB_OK);
873: bSuccess = FALSE;
874: goto ErrExit4;
875: }
876:
877:
878: ErrExit4:
879: SelectObject(hDC, hBmpOld);
880: DeleteObject(hTmpBmp);
881: ErrExit3:
882: _lclose(hFile);
883: ErrExit2:
884: GlobalFree(pbmi);
885: ErrExit1:
886: GlobalFree(pBits);
887: return bSuccess;
888: }
889:
890: /************************************************************************
891: * void ErrorOut(char errstring[30])
892: *
893: * Purpose: Print out an meainful error code by means of
894: * GetLastError and printf
895: *
896: * Inputs: errstring - the action that failed, passed by the
897: * calling proc.
898: *
899: * Returns: none
900: *
901: * Calls: GetLastError
902: *
903: * History:
904: *
905: \************************************************************************/
906:
907:
908: void ErrorOut(char errstring[30])
909: {
910: DWORD Error;
911: CHAR str[80];
912:
913: Error= GetLastError();
914: wsprintf((LPSTR) str, "Error on %s = %d\n", errstring, Error);
915: MessageBox(GetFocus(), (LPSTR)str, "Error", MB_OK);
916: }
917:
918: BOOL bInitDlgItems(HWND hDlg)
919: {
920: char szXFr[MAXDOUBLELEN], szYFr[MAXDOUBLELEN], szX2[MAXDOUBLELEN],
921: szY2[MAXDOUBLELEN], szSavef[MAXPATHLEN], szIter[MAXDOUBLELEN];
922: BOOL bSuccess;
923:
924: bSuccess = bGetPPStr(szXFr, szYFr, szX2, szY2, szSavef, szIter);
925: SetDlgItemText(hDlg, ID_XFROM, szXFr);
926: SetDlgItemText(hDlg, ID_YFROM, szYFr);
927: SetDlgItemText(hDlg, ID_XTO, szX2);
928: SetDlgItemText(hDlg, ID_YTO, szY2);
929: SetDlgItemText(hDlg, ID_ITERATION, szIter);
930:
931: return bSuccess;
932: }
933:
934:
935: /******************************Public*Routine******************************\
936: *
937: * bGetPPStr
938: *
939: * Effects: GetPrivateProfileString from control.ini
940: *
941: * Warnings:
942: *
943: * History:
944: * 19-Dec-1992 -by- Petrus Wong
945: * Wrote it.
946: \**************************************************************************/
947:
948: BOOL bGetPPStr(char szXFr[MAXDOUBLELEN], char szYFr[MAXDOUBLELEN],
949: char szX2[MAXDOUBLELEN], char szY2[MAXDOUBLELEN],
950: char szSavef[MAXPATHLEN], char szIter[MAXDOUBLELEN])
951: {
952: char szDefXFr[MAXDOUBLELEN];
953: char szDefYFr[MAXDOUBLELEN];
954: char szDefX2[MAXDOUBLELEN];
955: char szDefY2[MAXDOUBLELEN];
956: char szDefSavef[MAXPATHLEN];
957: char szDefIter[MAXDOUBLELEN];
958:
959: sprintf(szDefXFr, "-2.00");
960: sprintf(szDefYFr, "1.00");
961: sprintf(szDefX2, "1.00");
962: sprintf(szDefY2, "-1.00");
963: sprintf(szDefSavef, "c:\\fractal.bmp");
964: sprintf(szDefIter, "500");
965: GetPrivateProfileString(szAppName, szXFrom, szDefXFr, szXFr, MAXDOUBLELEN, szIniFile);
966: GetPrivateProfileString(szAppName, szYFrom, szDefYFr, szYFr, MAXDOUBLELEN, szIniFile);
967: GetPrivateProfileString(szAppName, szXTo, szDefX2, szX2, MAXDOUBLELEN, szIniFile);
968: GetPrivateProfileString(szAppName, szYTo, szDefY2, szY2, MAXDOUBLELEN, szIniFile);
969: GetPrivateProfileString(szAppName, szSaveFile, szDefSavef, szSavef, MAXPATHLEN, szIniFile);
970: GetPrivateProfileString(szAppName, szIteration, szDefIter, szIter, MAXDOUBLELEN, szIniFile);
971: return TRUE;
972: }
973:
974:
975:
976: /******************************Public*Routine******************************\
977: *
978: * bColorCycle
979: *
980: * Effects: Create a logical palette with a good spread of color
981: * Animate the palette, shift the palette entries and animate
982: * again for 256 times altogether.
983: * This creates the color cycling effect.
984: *
985: * Warnings: Only works in device that support palette.
986: *
987: * History:
988: * 15-Jan-1993 Petrus Wong Adaped from the SDK Mandel sample
989: * 24-Apr-1992 -by- Petrus Wong
990: * Wrote it.
991: \**************************************************************************/
992:
993: BOOL bColorCycle(HDC hDC, PINFO pInfo)
994: {
995: INT iEntry, i, iNumClr;
996: PLOGPALETTE plogPat;
997: ULONG ulSize;
998: BOOL bSuccess;
999: HPALETTE hPal, hPalOld;
1000: PALETTEENTRY peTemp;
1001: BOOL bQuit;
1002:
1003:
1004: UINT uRC;
1005:
1006: bSuccess = TRUE;
1007: iEntry = 1<<GetDeviceCaps(hDC, BITSPIXEL);
1008: iNumClr = 236; // 256 minus 20 reserved colors
1009: ulSize = sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256;
1010:
1011: if ((plogPat = (PLOGPALETTE) GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, ulSize)) == NULL) {
1012: MessageBox(hMainWindow, "Failed in Memory Allocation for plogPat!", "Error", MB_OK);
1013: bSuccess = FALSE;
1014: goto ErrExit1;
1015: }
1016:
1017: plogPat->palVersion = 0x300;
1018: plogPat->palNumEntries = (WORD) 256;
1019: {
1020: int iFirst, iSecond, iInc;
1021:
1022: iFirst = iNumClr/3;
1023: iSecond = iFirst * 2;
1024: iInc = (iNumClr <= 256) ? 3 : 1;
1025:
1026: for (i = 0; i < iNumClr; i++) {
1027: if (i < iFirst) {
1028: plogPat->palPalEntry[i+10].peBlue = 255-(i+1)*iInc;
1029: plogPat->palPalEntry[i+10].peGreen = 0;
1030: plogPat->palPalEntry[i+10].peRed = (i+1)*iInc;
1031: plogPat->palPalEntry[i+10].peFlags = PC_RESERVED;
1032: continue;
1033: }
1034: if (i < iSecond) {
1035: plogPat->palPalEntry[i+10].peBlue = 0;
1036: plogPat->palPalEntry[i+10].peGreen = (i+1-iFirst)*iInc;
1037: plogPat->palPalEntry[i+10].peRed = 255-(i+1-iFirst)*iInc;
1038: plogPat->palPalEntry[i+10].peFlags = PC_RESERVED;
1039: continue;
1040: }
1041: plogPat->palPalEntry[i+10].peBlue = (i+1-iSecond)*iInc;
1042: plogPat->palPalEntry[i+10].peGreen = 255-(i+1-iSecond)*iInc;
1043: plogPat->palPalEntry[i+10].peRed = 0;
1044: plogPat->palPalEntry[i+10].peFlags = PC_RESERVED;
1045: }
1046: }
1047:
1048: if ((hPal = CreatePalette(plogPat)) == (HPALETTE) NULL) {
1049: MessageBox(hMainWindow, "Failed in creating palette!", "Error", MB_OK);
1050: bSuccess = FALSE;
1051: goto ErrExit2;
1052: }
1053:
1054: hPalOld = SelectPalette(hDC, hPal, FALSE);
1055: RealizePalette(hDC);
1056: //SelectPalette(hDC, hPalOld, FALSE);
1057:
1058: bQuit = FALSE;
1059: while (TRUE && !bQuit) {
1060: if (!pInfo->bClrCycle) {
1061: //sprintf( gtext,"NOT to animate palette\n");
1062: //OutputDebugString( gtext );
1063: bQuit = TRUE;
1064: }
1065:
1066: if (!bQuit) {
1067: //sprintf( gtext,"About to animate palette\n");
1068: //OutputDebugString( gtext );
1069:
1070:
1071: peTemp = plogPat->palPalEntry[10];
1072: for (i = 0; i < iNumClr; i++) {
1073: plogPat->palPalEntry[i+10] = plogPat->palPalEntry[i+10+1];
1074: }
1075: plogPat->palPalEntry[i+10] = peTemp;
1076:
1077: Sleep(25);
1078:
1079: if (!AnimatePalette(hPal, 0, 256, plogPat->palPalEntry)) {
1080: sprintf( gtext,"Anmiate palette failed\n");
1081: OutputDebugString( gtext );
1082: }
1083:
1084: if ((uRC = RealizePalette(hDC)) == -1) {
1085: sprintf( gtext,"Realize palette failed\n");
1086: OutputDebugString( gtext );
1087: }
1088:
1089: if (!UpdateColors(hDC)) {
1090: sprintf( gtext,"Update Colors failed\n");
1091: OutputDebugString( gtext );
1092: }
1093:
1094: }
1095:
1096: }
1097:
1098: SelectPalette(hDC, hPalOld, 0);
1099: DeleteObject(hPal);
1100: ErrExit2:
1101: GlobalFree(plogPat);
1102: ErrExit1:
1103: return bSuccess;
1104:
1105: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.