Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1383 lines
41 KiB

  1. /**************************************************************************
  2. *
  3. * Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
  4. *
  5. * Module Name:
  6. *
  7. * Gdipscsave.cpp
  8. *
  9. * Abstract:
  10. *
  11. * Demonstration GDI+ based screen saver with several different
  12. * fractal patterns
  13. *
  14. * Revision History:
  15. *
  16. * 8/17/2000 peterost - Created it.
  17. *
  18. ***************************************************************************/
  19. #include "gdipscsave.h"
  20. #include <math.h>
  21. #include "../gpinit.inc"
  22. extern HINSTANCE hMainInstance; /* screen saver instance handle */
  23. /**********************************************************************
  24. *
  25. * Handle configuration dialog
  26. *
  27. ***********************************************************************/
  28. BOOL WINAPI ScreenSaverConfigureDialog (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  29. {
  30. static HWND hNumber; /* handle to number of fractals scroll bar */
  31. static HWND hOK; /* handle to OK push button */
  32. switch(message)
  33. {
  34. case WM_INITDIALOG:
  35. /* Retrieve the application name from the .rc file. */
  36. LoadString(hMainInstance,idsAppName,szAppName,40);
  37. /* Retrieve any redraw speed data from the registry. */
  38. GetFractalConfig (&nFractType, &nNumFracts);
  39. /* Initialize the number of fractals scroll bar control. */
  40. hNumber = GetDlgItem(hDlg, ID_SPEED);
  41. SetScrollRange(hNumber, SB_CTL, MINVEL, MAXVEL, FALSE);
  42. SetScrollPos(hNumber, SB_CTL, nNumFracts, TRUE);
  43. /* Initialize the type of fractals radio buttons */
  44. CheckRadioButton(hDlg, IDC_RADIOTYPE1, IDC_RADIOTYPE5, IDC_RADIOTYPE1+nFractType);
  45. /* Retrieve a handle to the OK push button control. */
  46. hOK = GetDlgItem(hDlg, IDOK);
  47. return TRUE;
  48. case WM_HSCROLL:
  49. /*
  50. * Process scroll bar input, adjusting the nNumFracts
  51. * value as appropriate.
  52. */
  53. switch (LOWORD(wParam))
  54. {
  55. case SB_PAGEUP:
  56. --nNumFracts;
  57. break;
  58. case SB_LINEUP:
  59. --nNumFracts;
  60. break;
  61. case SB_PAGEDOWN:
  62. ++nNumFracts;
  63. break;
  64. case SB_LINEDOWN:
  65. ++nNumFracts;
  66. break;
  67. case SB_THUMBPOSITION:
  68. nNumFracts = HIWORD(wParam);
  69. break;
  70. case SB_BOTTOM:
  71. nNumFracts = MINVEL;
  72. break;
  73. case SB_TOP:
  74. nNumFracts = MAXVEL;
  75. break;
  76. case SB_THUMBTRACK:
  77. case SB_ENDSCROLL:
  78. return TRUE;
  79. break;
  80. }
  81. if ((int) nNumFracts <= MINVEL)
  82. nNumFracts = MINVEL;
  83. if ((int) nNumFracts >= MAXVEL)
  84. nNumFracts = MAXVEL;
  85. SetScrollPos((HWND) lParam, SB_CTL, nNumFracts, TRUE);
  86. break;
  87. case WM_COMMAND:
  88. switch(LOWORD(wParam))
  89. {
  90. case ID_OK:
  91. if (IsDlgButtonChecked(hDlg, IDC_RADIOTYPE1))
  92. nFractType = 0;
  93. else if (IsDlgButtonChecked(hDlg, IDC_RADIOTYPE2))
  94. nFractType = 1;
  95. else if (IsDlgButtonChecked(hDlg, IDC_RADIOTYPE3))
  96. nFractType = 2;
  97. else if (IsDlgButtonChecked(hDlg, IDC_RADIOTYPE4))
  98. nFractType = 3;
  99. else
  100. nFractType = 4;
  101. SetFractalConfig(nFractType, nNumFracts);
  102. case ID_CANCEL:
  103. EndDialog(hDlg, LOWORD(wParam) == IDOK);
  104. return TRUE;
  105. }
  106. }
  107. return FALSE;
  108. }
  109. BOOL WINAPI RegisterDialogClasses(
  110. HANDLE hInst
  111. )
  112. {
  113. return TRUE;
  114. }
  115. LRESULT WINAPI ScreenSaverProcW (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  116. {
  117. static HDC hdc; /* device-context handle */
  118. static RECT rc; /* RECT structure */
  119. static UINT uTimer; /* timer identifier */
  120. static DWORD dwNumDrawn = -1;
  121. switch(message)
  122. {
  123. case WM_CREATE:
  124. // Retrieve the application name from the .rc file.
  125. LoadString(hMainInstance, idsAppName, szAppName, 40);
  126. // Retrieve any configuration data from the registry.
  127. GetFractalConfig (&nFractType, &nNumFracts);
  128. // Set a timer for the screen saver window
  129. uTimer = SetTimer(hwnd, 1, 1000, NULL);
  130. srand( (unsigned)GetTickCount() );
  131. fMandelbrot = rand()%2;
  132. // stream = fopen( "fprintf.out", "w" );
  133. // fprintf(stream, "initialized\n");
  134. break;
  135. case WM_ERASEBKGND:
  136. /*
  137. * The WM_ERASEBKGND message is issued before the
  138. * WM_TIMER message, allowing the screen saver to
  139. * paint the background as appropriate.
  140. */
  141. hdc = GetDC(hwnd);
  142. GetClientRect (hwnd, &rc);
  143. FillRect (hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
  144. ReleaseDC(hwnd,hdc);
  145. break;
  146. case WM_TIMER:
  147. /*
  148. * The WM_TIMER message is issued at REDRAWTIME. This
  149. * code repaints the entire desktop with black brush every time
  150. * nNumFracts fractals have been drawn, and calls the appropriate
  151. * fractal rendering function based on nFractType
  152. */
  153. if (uTimer)
  154. KillTimer(hwnd, uTimer);
  155. hdc = GetDC(hwnd);
  156. GetClientRect(hwnd, &rc);
  157. if (++dwNumDrawn >= nNumFracts)
  158. {
  159. dwNumDrawn = 0;
  160. FillRect(hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
  161. }
  162. switch (nFractType)
  163. {
  164. case 0:
  165. DrawSierpinski(hdc, hwnd, rc, dwNumDrawn);
  166. break;
  167. case 1:
  168. DrawHieghway(hdc, hwnd, rc, dwNumDrawn);
  169. break;
  170. case 2:
  171. DrawTree(hdc, hwnd, rc, dwNumDrawn);
  172. break;
  173. case 3:
  174. DrawPlasma(hdc, hwnd, rc, dwNumDrawn);
  175. break;
  176. case 4:
  177. DrawJulia(hdc, hwnd, rc, dwNumDrawn, fMandelbrot);
  178. break;
  179. }
  180. uTimer = SetTimer(hwnd, 1, REDRAWTIME, NULL);
  181. ReleaseDC(hwnd,hdc);
  182. break;
  183. case WM_DESTROY:
  184. /*
  185. * When the WM_DESTROY message is issued, the screen saver
  186. * must destroy any of the timers that were set at WM_CREATE
  187. * time.
  188. */
  189. // fclose(stream);
  190. if (uTimer)
  191. KillTimer(hwnd, uTimer);
  192. break;
  193. }
  194. // DefScreenSaverProc processes any messages ignored by ScreenSaverProc.
  195. return DefScreenSaverProc(hwnd, message, wParam, lParam);
  196. }
  197. VOID FillSierpinski(HWND hwnd, Graphics *g, PointF one, PointF two, PointF three, int level, Brush *pBrush, Pen *pPen)
  198. {
  199. MSG msg;
  200. if (level == 4 &&
  201. PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_MOUSELAST, PM_NOREMOVE))
  202. {
  203. return;
  204. }
  205. g->DrawLine(pPen, one, two);
  206. g->DrawLine(pPen, two, three);
  207. g->DrawLine(pPen, three, one);
  208. PointF midpoints[3];
  209. midpoints[0].X = (two.X + one.X) / 2;
  210. midpoints[0].Y = (two.Y + one.Y) / 2;
  211. midpoints[1].X = (three.X + two.X) / 2;
  212. midpoints[1].Y = (three.Y + two.Y) / 2;
  213. midpoints[2].X = (one.X + three.X) / 2;
  214. midpoints[2].Y = (one.Y + three.Y) / 2;
  215. GraphicsPath triangle;
  216. triangle.AddPolygon(midpoints, 3);
  217. g->FillPath(pBrush, &triangle);
  218. if (level-- > 0)
  219. {
  220. FillSierpinski(hwnd, g, two, midpoints[0], midpoints[1], level, pBrush, pPen);
  221. FillSierpinski(hwnd, g, three, midpoints[1], midpoints[2], level, pBrush, pPen);
  222. FillSierpinski(hwnd, g, one, midpoints[0], midpoints[2], level, pBrush, pPen);
  223. }
  224. }
  225. VOID DrawSierpinski(HDC hDC, HWND hwnd, RECT rc, int iColor)
  226. {
  227. Graphics g(hDC);
  228. PointF points[3];
  229. Color colors[3] = {
  230. Color(160,255,0,0),
  231. Color(130,0,255,0),
  232. Color(110,0,0,255)};
  233. int nColors = 3, iMinLen = 6;
  234. // Get some good random points. Limit angles to be > 20 degrees, so
  235. // there are no skinny triangles
  236. for (int j = 0; j <= 20; j++)
  237. {
  238. for (int i = 0; i<= 2; i++)
  239. {
  240. points[i].X = (REAL)(rand() % (rc.right - rc.left));
  241. points[i].Y = (REAL)(rand() % (rc.bottom - rc.top));
  242. }
  243. double a,b,c,cosa,cosb,cosc;
  244. a = sqrt(pow(points[0].X - points[1].X, 2) + pow(points[0].Y - points[1].Y, 2));
  245. b = sqrt(pow(points[2].X - points[1].X, 2) + pow(points[2].Y - points[1].Y, 2));
  246. c = sqrt(pow(points[0].X - points[2].X, 2) + pow(points[0].Y - points[2].Y, 2));
  247. iMinLen = (int)min(a,min(b,c));
  248. //fprintf(stream, " %6f %6f %6f %d\n", a, b, c, j);
  249. cosa = (pow(a,2) - pow(b,2) - pow(c,2)) / (-2 * b * c);
  250. cosb = (pow(b,2) - pow(a,2) - pow(c,2)) / (-2 * a * c);
  251. cosc = (pow(c,2) - pow(a,2) - pow(b,2)) / (-2 * a * b);
  252. //fprintf(stream, " %6f %6f %6f %d\n", cosa, cosb, cosc, j);
  253. if ((fabs(cosa) < 0.939) &&
  254. (fabs(cosb) < 0.939) &&
  255. (fabs(cosc) < 0.939) &&
  256. (a > 35))
  257. {
  258. // fprintf(stream, "broke\n");
  259. break;
  260. }
  261. }
  262. PathGradientBrush brush(points, nColors);
  263. brush.SetSurroundColors(colors, &nColors);
  264. Pen pen(Color(90, (255-iColor*90)%256, 0, (iColor*60)%256));
  265. g.SetSmoothingMode(SmoothingModeAntiAlias);
  266. FillSierpinski(hwnd, &g, points[0], points[1], points[2], min(6,max(3,iMinLen/70)), &brush, &pen);
  267. }
  268. VOID DrawHieghway(HDC hDC, HWND hwnd, RECT rc, int iColor)
  269. {
  270. static PointF p1[16390], p2[16390];
  271. int iSize = 2, iLen, iPad = (rc.bottom - rc.top) / 4;
  272. PointF *parr1, *parr2, *ptemp;
  273. // Calculate a starting line that is not too close to the edges of the screen
  274. p1[0].X = (REAL)(iPad + (rand() % (rc.right - rc.left - iPad*2)));
  275. p1[0].Y = (REAL)(iPad + (rand() % (rc.bottom - rc.top - iPad*2)));
  276. iLen = (rand() % (min(rc.right - rc.left, rc.bottom - rc.top) / 2)) + iPad/2;
  277. if (rand() & 1)
  278. {
  279. p1[1].X = p1[0].X;
  280. if (p1[0].Y > (rc.bottom - rc.top)/2)
  281. p1[1].Y = p1[0].Y - iLen;
  282. else
  283. p1[1].Y = p1[0].Y + iLen;
  284. }
  285. else
  286. {
  287. if (p1[0].X > (rc.right - rc.left)/2)
  288. p1[1].X = p1[0].X - iLen;
  289. else
  290. p1[1].X = p1[0].X + iLen;
  291. p1[1].Y = p1[0].Y;
  292. }
  293. PointF pgrad1(p1[0].X, p1[0].Y), pgrad2(p1[1].X, p1[1].Y);
  294. //fprintf(stream, " %6f %6f %6f %6f\n", p1[0].X, p1[0].Y, p1[1].X, p1[1].Y);
  295. parr1 = p1;
  296. parr2 = p2;
  297. // Create dragon pattern to a level which is more or less dependent on the
  298. // overall size of the pattern.
  299. for (int i=0; i<max(MINHEIGHWAYLEVEL,min(sqrt(iLen/2), MAXHEIGHWAYLEVEL)); i++)
  300. {
  301. IterateHieghway(parr1, parr2, &iSize);
  302. ptemp = parr1;
  303. parr1 = parr2;
  304. parr2 = ptemp;
  305. }
  306. // Draw the resultant pattern with a gradient pen with random colors.
  307. Graphics g(hDC);
  308. LinearGradientBrush brush(pgrad1, pgrad2,
  309. Color(230, (rand()%200)+55, (rand()%128)+55, rand()%256),
  310. Color(180, (rand()%100)+155, rand()%256, (rand()%200)+55));
  311. brush.SetWrapMode(WrapModeTileFlipXY);
  312. Pen pen(&brush);
  313. // fprintf(stream, " %d %d \n", iLen, iSize);
  314. MSG msg;
  315. for (int j=0; j<(iSize-1); j++)
  316. {
  317. g.DrawLine(&pen, parr1[j], parr1[j+1]);
  318. // Drawing takes a long time, so check for queued message periodically
  319. if (j%1000 == 0 &&
  320. PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_MOUSELAST, PM_NOREMOVE))
  321. {
  322. break;
  323. }
  324. }
  325. }
  326. VOID IterateHieghway(PointF *points, PointF *newpoints, int *iSize)
  327. {
  328. int j = 0;
  329. REAL x1,x2,y1,y2;
  330. BOOL right = TRUE;
  331. for (int i = 0; i < (*iSize - 1); i++)
  332. {
  333. x1 = points[i].X;
  334. x2 = points[i+1].X;
  335. y1 = points[i].Y;
  336. y2 = points[i+1].Y;
  337. newpoints[j].X = x1;
  338. newpoints[j++].Y = y1;
  339. if (y1 == y2)
  340. {
  341. newpoints[j].X = (x2 + x1) / 2;
  342. if (x2 > x1)
  343. if (right)
  344. newpoints[j++].Y = y1 + (x2-x1)/2;
  345. else
  346. newpoints[j++].Y = y1 - (x2-x1)/2;
  347. else // if (x1 > x2)
  348. if (right)
  349. newpoints[j++].Y = y1 - (x1-x2)/2;
  350. else
  351. newpoints[j++].Y = y1 + (x1-x2)/2;
  352. }
  353. else if (x1 == x2)
  354. {
  355. newpoints[j].Y = (y2 + y1) / 2;
  356. if (y2 > y1)
  357. if (right)
  358. newpoints[j++].X = x1 - (y2-y1)/2;
  359. else
  360. newpoints[j++].X = x1 + (y2-y1)/2;
  361. else // if (y1 > y2)
  362. if (right)
  363. newpoints[j++].X = x1 + (y1-y2)/2;
  364. else
  365. newpoints[j++].X = x1 - (y1-y2)/2;
  366. }
  367. else
  368. {
  369. if ((x1 > x2 && y1 > y2) ||
  370. (x2 > x1 && y2 > y1))
  371. {
  372. if (right)
  373. {
  374. newpoints[j].X = x1;
  375. newpoints[j++].Y = y2;
  376. }
  377. else
  378. {
  379. newpoints[j].X = x2;
  380. newpoints[j++].Y = y1;
  381. }
  382. }
  383. else // if ((x2 > x1 && y1 > y2) ||
  384. // (x1 > x2 && y2 > y1))
  385. {
  386. if (right)
  387. {
  388. newpoints[j].X = x2;
  389. newpoints[j++].Y = y1;
  390. }
  391. else
  392. {
  393. newpoints[j].X = x1;
  394. newpoints[j++].Y = y2;
  395. }
  396. }
  397. }
  398. right = !right;
  399. }
  400. newpoints[j].X = x2;
  401. newpoints[j++].Y = y2;
  402. *iSize = j;
  403. }
  404. VOID DrawTree(HDC hDC, HWND hwnd, RECT rc, int iColor)
  405. {
  406. /* PointF points[] = {PointF(50,100),
  407. PointF(70,100),
  408. PointF(68,70),
  409. PointF(58,56),
  410. PointF(80,47),
  411. PointF(65,24),
  412. PointF(58,27),
  413. PointF(68,43),
  414. PointF(47,52),
  415. PointF(55,70),
  416. PointF(50,100)};
  417. PointF scale[] = {PointF((REAL)0.7, (REAL)0.7),
  418. PointF((REAL)0.7, (REAL)0.7),
  419. PointF((REAL)0.7, (REAL)0.7)};
  420. REAL rotate[] = {-65, -10, 65};
  421. PointF translate[] = {PointF(-100,2), PointF(20,-45), PointF(35,-167)};
  422. */
  423. PointF points[3][11] = {PointF(50,100),
  424. PointF(65,100),
  425. PointF(62,30),
  426. PointF(53,30),
  427. PointF(50,100),
  428. PointF(0,0),
  429. PointF(0,0),
  430. PointF(0,0),
  431. PointF(0,0),
  432. PointF(0,0),
  433. PointF(0,0),
  434. PointF(50,100),
  435. PointF(70,100),
  436. PointF(68,70),
  437. PointF(58,56),
  438. PointF(80,47),
  439. PointF(65,24),
  440. PointF(58,27),
  441. PointF(68,43),
  442. PointF(47,52),
  443. PointF(55,70),
  444. PointF(50,100),
  445. PointF(0,100),
  446. PointF(15,100),
  447. PointF(12,30),
  448. PointF(3,30),
  449. PointF(0,100),
  450. PointF(0,0),
  451. PointF(0,0),
  452. PointF(0,0),
  453. PointF(0,0),
  454. PointF(0,0),
  455. PointF(0,0)};
  456. int numPoints[3] = {5,11,5};
  457. int numBranches[3] = {3,4,3};
  458. int numLevels[3] = {7,7,9};
  459. PointF scale[3][4] = {PointF((REAL)0.7, (REAL)0.7),
  460. PointF((REAL)0.7, (REAL)0.7),
  461. PointF((REAL)0.7, (REAL)0.7),
  462. PointF(0,0),
  463. PointF((REAL)0.75, (REAL)0.75),
  464. PointF((REAL)0.6, (REAL)0.6),
  465. PointF((REAL)0.8, (REAL)0.8),
  466. PointF((REAL)0.35, (REAL)0.35),
  467. PointF((REAL)0.65, (REAL)0.65),
  468. PointF((REAL)0.6, (REAL)0.6),
  469. PointF((REAL)0.6, (REAL)0.6),
  470. PointF(0,0)};
  471. REAL rotate[3][4] = {1, -35, 27, 0,
  472. -65, -10, 65, 20,
  473. 0, -55, 55, 0};
  474. PointF translate[3][4] = {PointF(24,-50),
  475. PointF(-33,10),
  476. PointF(50,-67),
  477. PointF(0,0),
  478. PointF(-100,2),
  479. PointF(25,-40),
  480. PointF(25,-160),
  481. PointF(180,25),
  482. PointF(4,-55),
  483. PointF(-95,-30),
  484. PointF(95,-50),
  485. PointF(0,0)};
  486. //fprintf(stream, "%f %f %f %f \n", points[0][0].X, points[0][1].X, points[0][2].X, points[0][3].X);
  487. Graphics g(hDC);
  488. GraphicsPath path;
  489. REAL rScale = (REAL)(rand() % (rc.bottom - rc.top)) / 350;
  490. if (rScale < 0.2)
  491. rScale = 0.2f;
  492. REAL xTrans = (REAL)(rand() % ((rc.right - rc.left) * 2/3)) + ((rc.right - rc.left) * 1/6);
  493. REAL yTrans = (REAL)(rand() % ((rc.bottom - rc.top) * 2/3)) + ((rc.bottom - rc.top) * 1/6);
  494. REAL rRotate = (REAL)(rand() % 360);
  495. int iTree = rand() % 3;
  496. //fprintf(stream, " %6f %6f %6f %6f\n", rScale, xTrans, yTrans, rRotate);
  497. path.AddPolygon(points[iTree],numPoints[iTree]);
  498. g.TranslateTransform(xTrans, yTrans);
  499. g.ScaleTransform(rScale, rScale);
  500. g.RotateTransform(rRotate);
  501. DrawBranch(hwnd, &g, &path, rScale < 1 ? numLevels[iTree]-1 : numLevels[iTree],
  502. scale[iTree], rotate[iTree], translate[iTree], numBranches[iTree],
  503. iColor);
  504. }
  505. VOID DrawBranch(HWND hwnd, Graphics *g, GraphicsPath *path, int iLevel,
  506. PointF *scale, REAL *rotate, PointF *translate,
  507. int iBranches, int iColor)
  508. {
  509. MSG msg;
  510. if (iLevel == 0 ||
  511. (iLevel == 6 &&
  512. PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_MOUSELAST, PM_NOREMOVE)))
  513. {
  514. return;
  515. }
  516. SolidBrush brush(Color(200, rand()%256,(255-iLevel*20)%256,(iColor*125)%200 + rand()%50));
  517. g->FillPath(&brush, path);
  518. for (int i = 0; i<iBranches; i++)
  519. {
  520. GraphicsState state = g->Save();
  521. g->ScaleTransform(scale[i].X, scale[i].Y);
  522. g->RotateTransform(rotate[i]);
  523. g->TranslateTransform(translate[i].X, translate[i].Y);
  524. DrawBranch(hwnd, g, path,iLevel-1,scale,rotate,translate,iBranches,iColor);
  525. g->Restore(state);
  526. }
  527. }
  528. VOID DrawJulia(HDC hDC, HWND hwnd, RECT rc, int iColor, BOOL fMandelbrot)
  529. {
  530. Graphics g(hDC);
  531. REAL cx=(REAL)0.3,cy=(REAL)0.588888;
  532. REAL x0,y0=-1.25,xI,yI=1.25;
  533. REAL xCenter, yCenter, delta=(REAL)(0.2/pow(2.5,iColor));
  534. REAL scrnx=(REAL)(rc.right-rc.left), scrny=(REAL)(rc.bottom-rc.top);
  535. REAL nx=scrnx,ny=scrny;
  536. int niter=45+8*(iColor+1),i,ncolors=28;
  537. Bitmap bitmap((int)nx, (int)ny, PixelFormat32bppARGB);
  538. if (fMandelbrot)
  539. {
  540. xCenter=(REAL)-0.561;
  541. yCenter=(REAL)-0.6432;
  542. x0 = (REAL)-1.75;
  543. xI = (REAL)1.0;
  544. }
  545. else
  546. {
  547. x0 = (REAL)-1.25;
  548. xI = (REAL)1.25;
  549. xCenter=(REAL)-0.11014;
  550. yCenter=(REAL)-0.509;
  551. }
  552. if (iColor > 0)
  553. {
  554. x0=(REAL)(xCenter-delta);
  555. xI=(REAL)(xCenter+delta);
  556. y0=(REAL)(yCenter-delta);
  557. yI=(REAL)(yCenter+delta);
  558. }
  559. // bitmap.LockBits
  560. /* SolidBrush brushs[] =
  561. {SolidBrush(Color(255,128,0,0)),
  562. SolidBrush(Color(255,255,0,0)),
  563. SolidBrush(Color(255,0,128,0)),
  564. SolidBrush(Color(255,0,255,0)),
  565. SolidBrush(Color(255,0,0,128)),
  566. SolidBrush(Color(255,0,0,255)),
  567. SolidBrush(Color(255,128,128,0)),
  568. SolidBrush(Color(255,255,255,0)),
  569. SolidBrush(Color(255,0,128,128)),
  570. SolidBrush(Color(255,0,255,255)),
  571. SolidBrush(Color(255,128,0,128)),
  572. SolidBrush(Color(255,255,0,255))};
  573. SolidBrush brushs[] =
  574. {SolidBrush(Color(255,248,40,18)),
  575. SolidBrush(Color(255,245,117,21)),
  576. SolidBrush(Color(255,255,171,18)),
  577. SolidBrush(Color(255,246,235,20)),
  578. SolidBrush(Color(255,213,255,13)),
  579. SolidBrush(Color(255,93,253,13)),
  580. SolidBrush(Color(255,13,253,218)),
  581. SolidBrush(Color(255,14,190,252)),
  582. SolidBrush(Color(255,15,116,255)),
  583. SolidBrush(Color(255,15,15,255)),
  584. SolidBrush(Color(255,207,15,250)),
  585. SolidBrush(Color(255,255,80,245))};
  586. Color colors[] =
  587. {Color(255,248,40,18),
  588. Color(255,245,117,21),
  589. Color(255,255,171,18),
  590. Color(255,246,235,20),
  591. Color(255,213,255,13),
  592. Color(255,93,253,13),
  593. Color(255,13,253,218),
  594. Color(255,14,190,252),
  595. Color(255,15,116,255),
  596. Color(255,15,15,255),
  597. Color(255,207,15,250),
  598. Color(255,255,80,245)};
  599. Color colors[] =
  600. {Color(255,0,0,0),
  601. Color(255,0,0,180),
  602. Color(255,0,30,150),
  603. Color(255,0,60,120),
  604. Color(255,0,90,90),
  605. Color(255,0,120,60),
  606. Color(255,0,150,30),
  607. Color(255,0,180,0),
  608. Color(255,30,150,0),
  609. Color(255,60,120,0),
  610. Color(255,90,90,0),
  611. Color(255,120,60,0),
  612. Color(255,150,30,0),
  613. Color(255,180,0,0),
  614. Color(255,150,0,30),
  615. Color(255,120,0,60),
  616. Color(255,90,0,90),
  617. Color(255,60,0,120),
  618. Color(255,30,0,150)};
  619. */ Color colors[] =
  620. {Color(255,0,0,0),
  621. Color(255,0,0,180),
  622. Color(255,0,20,160),
  623. Color(255,0,40,140),
  624. Color(255,0,60,120),
  625. Color(255,0,80,100),
  626. Color(255,0,100,80),
  627. Color(255,0,120,60),
  628. Color(255,0,140,40),
  629. Color(255,0,160,20),
  630. Color(255,0,180,0),
  631. Color(255,20,160,0),
  632. Color(255,40,140,0),
  633. Color(255,60,120,0),
  634. Color(255,80,100,0),
  635. Color(255,100,80,0),
  636. Color(255,120,60,0),
  637. Color(255,140,40,0),
  638. Color(255,160,20,0),
  639. Color(255,180,0,0),
  640. Color(255,160,0,20),
  641. Color(255,140,0,40),
  642. Color(255,120,0,60),
  643. Color(255,100,0,80),
  644. Color(255,80,0,100),
  645. Color(255,60,0,120),
  646. Color(255,40,0,140),
  647. Color(255,20,0,160),
  648. };
  649. /* Color colors[] =
  650. {Color(255,0,0,0),
  651. Color(255,0,89,186),
  652. Color(255,0,155,186),
  653. Color(255,0,186,155),
  654. Color(255,0,186,27),
  655. Color(255,186,186,0),
  656. Color(255,186,155,0),
  657. Color(255,186,118,0),
  658. Color(255,186,60,0),
  659. Color(255,186,0,0),
  660. Color(255,186,0,186),
  661. Color(255,97,0,186),
  662. Color(255,0,4,186)};
  663. Color colors[2];
  664. colors[0]=Color(255,rand()%256,rand()%256,rand()%256);
  665. */
  666. REAL dx,dy,px,py,x,y;
  667. REAL xx,yy,xsquared,ysquared;
  668. dx=(xI-x0)/nx;
  669. dy=(yI-y0)/ny;
  670. for (py=0; py<ny; py++)
  671. {
  672. MSG msg;
  673. if ((int)py % 50 == 0 &&
  674. PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_MOUSELAST, PM_NOREMOVE))
  675. return;
  676. for (px=0; px<nx; px++)
  677. {
  678. x=x0+(px*dx);
  679. y=y0+(py*dy);
  680. if (fMandelbrot)
  681. {
  682. cx=x;
  683. cy=y;
  684. x=0;
  685. y=0;
  686. }
  687. xsquared=0;
  688. ysquared=0;
  689. for(i=0; (i<niter)&&(xsquared+ysquared < 4); i++)
  690. {
  691. xsquared= x*x;
  692. ysquared= y*y;
  693. xx=xsquared - ysquared + cx;
  694. yy = x * y * 2 + cy;
  695. x = xx;
  696. y = yy;
  697. }
  698. if (i==niter)
  699. i = 0;
  700. else
  701. i = (i % (ncolors-1)) + 1;
  702. bitmap.SetPixel((int)px, (int)py, colors[i]);
  703. // g->FillRectangle((Brush*)&(brushs[i]), (int)px,(int)py,(int)1,(int)1);
  704. }
  705. }
  706. g.DrawImage(&bitmap, 0,0);
  707. }
  708. //index must be in range 0...5f9 (length 5fa)
  709. //#define PLASMA_INDEX_MOD 0x5fa
  710. //#define PLASMA_INDEX_MOD 0x2fd
  711. INT PLASMA_TYPE;
  712. INT PLASMA_INDEX_MOD;
  713. ARGB IndexToSpectrum(INT index)
  714. {
  715. //index = (index + PLASMA_INDEX_MOD) % PLASMA_INDEX_MOD;
  716. if ((index < 0) || (index >= PLASMA_INDEX_MOD))
  717. DebugBreak();
  718. INT r,g,b;
  719. switch (PLASMA_TYPE)
  720. {
  721. case 0:
  722. r = max(0, min(0xff, (0x1fe - abs(0x2fd - ((index+0x2fd) % PLASMA_INDEX_MOD)))));
  723. g = max(0, min(0xff, (0x1fe - abs(0x2fd - ((index+0xff) % PLASMA_INDEX_MOD)))));
  724. b = max(0, min(0xff, (0x1fe - abs(0x2fd - ((index+0x4fb) % PLASMA_INDEX_MOD)))));
  725. if (!((r == 0xff) || (g == 0xff) || (b == 0xff)))
  726. DebugBreak();
  727. if ((r == 0xff) && (g == 0) && (b == 0) && (index != 0))
  728. DebugBreak();
  729. break;
  730. case 1:
  731. r = 0;
  732. g = 0;
  733. b = 0;
  734. if (index < 0xff)
  735. {
  736. r = 0xff - index;
  737. g = index;
  738. }
  739. else if (index < 0x1fe)
  740. {
  741. g = 0xff - (index - 0xff);
  742. b = index - 0xff;
  743. }
  744. else
  745. {
  746. b = 0xff - (index - 0x1fe);
  747. r = index - 0x1fe;
  748. }
  749. break;
  750. case 2:
  751. r = 0xff;
  752. b = 0xff;
  753. g = 0xff;
  754. if (index < 0xff)
  755. {
  756. r = index;
  757. g = 0xff - index;
  758. }
  759. else if (index < 0x1fe)
  760. {
  761. g = index - 0xff;
  762. b = 0xff - (index - 0xff);
  763. }
  764. else
  765. {
  766. b = index - 0x1fe;
  767. r = 0xff - (index - 0x1fe);
  768. }
  769. break;
  770. }
  771. /*
  772. return (0xff000000 |
  773. (BYTE)r << 16 |
  774. (BYTE)g << 8 |
  775. (BYTE)b);
  776. */
  777. return (((rand() % 255) + 1) << 24 |
  778. (BYTE)r << 16 |
  779. (BYTE)g << 8 |
  780. (BYTE)b);
  781. }
  782. INT SpectrumToIndex(ARGB argb)
  783. {
  784. BYTE r = (BYTE)((argb & 0x00ff0000) >> 16);
  785. BYTE g = (BYTE)((argb & 0x0000ff00) >> 8);
  786. BYTE b = (BYTE)(argb & 0x000000ff);
  787. switch(PLASMA_TYPE)
  788. {
  789. case 0:
  790. //Is red high?
  791. if (0xff == r)
  792. {
  793. //...and is blue present?
  794. if (b > 0)
  795. {
  796. return PLASMA_INDEX_MOD - b;
  797. }
  798. else
  799. {
  800. return g;
  801. }
  802. }
  803. //how 'bout green?
  804. if (0xff == g)
  805. {
  806. if (r > 0)
  807. {
  808. return 0x1fe - r;
  809. }
  810. else
  811. {
  812. return 0x1fe + b;
  813. }
  814. }
  815. //else blue
  816. if (0xff == b)
  817. {
  818. if (g > 0)
  819. {
  820. return 0x3fc - g;
  821. }
  822. else
  823. {
  824. return 0x3fc + r;
  825. }
  826. }
  827. //WTH?
  828. DebugBreak();
  829. break;
  830. case 1:
  831. if (r == 0xff)
  832. {
  833. return 0;
  834. }
  835. if (g != 0)
  836. {
  837. if (r > 0)
  838. {
  839. return g;
  840. }
  841. else
  842. {
  843. return 0xff + b;
  844. }
  845. }
  846. if (b != 0)
  847. {
  848. return 0x1fe + r;
  849. }
  850. break;
  851. case 2:
  852. if (b == 0xff)
  853. {
  854. return r;
  855. }
  856. if (r == 0xff)
  857. {
  858. return 0xff + g;
  859. }
  860. if (g == 0xff)
  861. {
  862. return 0x1fe + b;
  863. }
  864. break;
  865. }
  866. DebugBreak();
  867. return -1;
  868. }
  869. INT MakeColor(INT c1, INT c2, INT deltamax)
  870. {
  871. INT c = ((c1 + c2) >> 1) + ((deltamax > 0) ? ((rand() % (2*deltamax)) - deltamax) : 0);
  872. if (c < 0)
  873. c = 0;
  874. if (c > (PLASMA_INDEX_MOD - 1))
  875. c = PLASMA_INDEX_MOD - 1;
  876. if ((c < 0) || (c > PLASMA_INDEX_MOD - 1))
  877. DebugBreak();
  878. return c;
  879. }
  880. INT MakeColor(INT c1, INT c2, INT c3, INT c4, INT deltamax)
  881. {
  882. INT c = ((c1 + c2 + c3 + c4) >> 2) + ((deltamax > 0) ? ((rand() % (2*deltamax)) - deltamax) : 0);
  883. if (c < 0)
  884. c = 0;
  885. if (c > (PLASMA_INDEX_MOD - 1))
  886. c = PLASMA_INDEX_MOD - 1;
  887. if ((c < 0) || (c > PLASMA_INDEX_MOD - 1))
  888. DebugBreak();
  889. return c;
  890. }
  891. BYTE MakeAlpha(BYTE a1, BYTE a2, INT deltamax)
  892. {
  893. deltamax = (deltamax * 0xff) / PLASMA_INDEX_MOD;
  894. BYTE a = (((int)a1 + (int)a2) >> 1) + ((deltamax > 0) ? ((rand() % (2*deltamax)) - deltamax) : 0);
  895. if (a < 1)
  896. a = 1;
  897. if (a > 0xff)
  898. a = 0xff;
  899. return a;
  900. }
  901. BYTE MakeAlpha(BYTE a1, BYTE a2, BYTE a3, BYTE a4, INT deltamax)
  902. {
  903. deltamax = (deltamax * 0xff) / PLASMA_INDEX_MOD;
  904. BYTE a = (((int)a1 + (int)a2 + (int)a3 + (int)a4) >> 2) + ((deltamax > 0) ? ((rand() % (2*deltamax)) - deltamax) : 0);
  905. if (a < 1)
  906. a = 1;
  907. if (a > 0xff)
  908. a = 0xff;
  909. return a;
  910. }
  911. //Note that this only works on squares! You want something else? Scale the graphics.
  912. //BOOL HalfPlasma(HWND& hwnd, Graphics& g,BitmapData &bmpd, INT x0, INT y0, INT x1, INT y1, const Color& c00, const Color& c10, const Color& c01, const Color& c11,REAL scale)
  913. BOOL HalfPlasma(HWND& hwnd, Graphics& g,BitmapData &bmpd, INT x0, INT y0, INT x1, INT y1,REAL scale)
  914. {
  915. MSG msg;
  916. // Drawing takes a long time, so check for queued message periodically
  917. if (PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_MOUSELAST, PM_NOREMOVE))
  918. return FALSE;
  919. if (((x0 + 1) >= x1) &&
  920. ((y0 + 1) >= y1))
  921. {
  922. return TRUE;
  923. }
  924. INT c00 = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x0));
  925. INT c10 = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x1));
  926. INT c01 = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x0));
  927. INT c11 = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x1));
  928. INT ch0, c0h, c1h, ch1, chh;
  929. BYTE a00 = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x0) & 0xff000000) >> 24);
  930. BYTE a10 = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x1) & 0xff000000) >> 24);
  931. BYTE a01 = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x0) & 0xff000000) >> 24);
  932. BYTE a11 = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x1) & 0xff000000) >> 24);
  933. BYTE ah0, a0h, a1h, ah1, ahh;
  934. INT deltamax = (INT)((x1 - x0)/scale);
  935. INT half = (x1 + 1 - x0) >> 1;
  936. INT xh = x0 + half;
  937. INT yh = y0 + half;
  938. if (0 == (*((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + xh) & 0xff000000))
  939. {
  940. ch0 = MakeColor(c00,c10,deltamax);
  941. ah0 = MakeAlpha(a00,a10,deltamax);
  942. *((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + xh) = (IndexToSpectrum(ch0) & 0x00ffffff) | (ah0 << 24);
  943. }
  944. else
  945. {
  946. ch0 = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + xh));
  947. ah0 = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + xh) & 0xff000000) >> 24);
  948. }
  949. if (0 == (*((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x0) & 0xff000000))
  950. {
  951. c0h = MakeColor(c00, c01, deltamax);
  952. a0h = MakeAlpha(a00, a01, deltamax);
  953. *((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x0) = (IndexToSpectrum(c0h) & 0x00ffffff) | (a0h << 24);
  954. }
  955. else
  956. {
  957. c0h = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x0));
  958. a0h = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x0) & 0xff000000) >> 24);
  959. }
  960. if (0 == (*((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x1) & 0xff000000))
  961. {
  962. c1h = MakeColor(c10,c11,deltamax);
  963. a1h = MakeAlpha(a10,a11,deltamax);
  964. *((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x1) = (IndexToSpectrum(c1h) & 0x00ffffff) | (a1h << 24);
  965. }
  966. else
  967. {
  968. c1h = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x1));
  969. a1h = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + x1) & 0xff000000) >> 24);
  970. }
  971. if (0 == (*((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + xh) & 0xff000000))
  972. {
  973. ch1 = MakeColor(c01,c11,deltamax);
  974. ah1 = MakeAlpha(a01,a11,deltamax);
  975. *((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + xh) = (IndexToSpectrum(ch1) & 0x00ffffff) | (ah1 << 24);
  976. }
  977. else
  978. {
  979. ch1 = SpectrumToIndex(*((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + xh));
  980. ah1 = (BYTE)((*((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + xh) & 0xff000000) >> 24);
  981. }
  982. if (0 == (*((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + xh) & 0xff000000))
  983. {
  984. chh = MakeColor(ch0,c0h,c1h,ch1,deltamax);
  985. ahh = MakeAlpha(ah0,a0h,a1h,ah1,deltamax);
  986. *((ARGB*)((BYTE*)bmpd.Scan0 + yh*bmpd.Stride) + xh) = (IndexToSpectrum(chh) & 0x00ffffff) | (ahh << 24);
  987. }
  988. if (!HalfPlasma(hwnd, g, bmpd,x0,y0,xh,yh,scale)) return FALSE;
  989. if (!HalfPlasma(hwnd, g, bmpd,xh,y0,x1,yh,scale)) return FALSE;
  990. if (!HalfPlasma(hwnd, g, bmpd,x0,yh,xh,y1,scale)) return FALSE;
  991. if (!HalfPlasma(hwnd, g, bmpd,xh,yh,x1,y1,scale)) return FALSE;
  992. return TRUE;
  993. }
  994. INT fx = 0;
  995. INT fy = 0;
  996. VOID DrawPlasma(HDC hDC, HWND hwnd, RECT rc, int iColor)
  997. {
  998. Graphics g(hDC);
  999. INT x0,y0,x1,y1;
  1000. REAL scale;
  1001. BYTE alpha = 255;
  1002. BOOL abort = FALSE;
  1003. INT w = 1;
  1004. INT size = min((rc.right - rc.left), (rc.bottom-rc.top));
  1005. while(size > 0)
  1006. {
  1007. size >>= 1;
  1008. w <<= 1;
  1009. }
  1010. if (rand() % 2)
  1011. {
  1012. w = min(w,1 << ((rand() % 5) + 4));
  1013. }
  1014. else
  1015. {
  1016. w = min(w,32);
  1017. }
  1018. Bitmap bmp(w,w,PixelFormat32bppARGB);
  1019. Rect rect(0,0,w,w);
  1020. BitmapData bmpd;
  1021. bmp.LockBits(rect,0,PixelFormat32bppARGB,&bmpd);
  1022. for (INT x = 0; x < w; x++)
  1023. {
  1024. for (INT y = 0; y < w; y++)
  1025. {
  1026. *((ARGB*)((BYTE*)bmpd.Scan0 + y*bmpd.Stride) + x) = Color::MakeARGB(0,0,0,0);
  1027. }
  1028. }
  1029. x0 = 0;
  1030. y0 = 0;
  1031. x1 = x0 + w - 1;
  1032. y1 = y0 + w - 1;
  1033. switch(PLASMA_TYPE = (rand() % 3))
  1034. {
  1035. case 0:
  1036. PLASMA_INDEX_MOD = 0x5fa;
  1037. break;
  1038. case 1:
  1039. case 2:
  1040. PLASMA_INDEX_MOD = 0x2fd;
  1041. break;
  1042. }
  1043. scale = ((REAL)(w))/((REAL)PLASMA_INDEX_MOD);
  1044. REAL sx = ((REAL)(rc.right-rc.left))/((REAL)(x1 - x0 + 1));
  1045. REAL sy = ((REAL)(rc.bottom-rc.top))/((REAL)(y1 - y0 + 1));
  1046. g.SetSmoothingMode(SmoothingModeAntiAlias);
  1047. BYTE intMode = rand() % 3;
  1048. switch(intMode)
  1049. {
  1050. case 2:
  1051. g.SetInterpolationMode(InterpolationModeHighQualityBicubic);
  1052. break;
  1053. case 1:
  1054. g.SetInterpolationMode(InterpolationModeHighQualityBilinear);
  1055. break;
  1056. case 0:
  1057. g.SetInterpolationMode(InterpolationModeNearestNeighbor);
  1058. break;
  1059. }
  1060. /*
  1061. *((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x0) = IndexToSpectrum(rand() % PLASMA_INDEX_MOD) ;
  1062. *((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x1) = IndexToSpectrum(rand() % PLASMA_INDEX_MOD);
  1063. *((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x0) = IndexToSpectrum(rand() % PLASMA_INDEX_MOD);
  1064. *((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x1) = IndexToSpectrum(rand() % PLASMA_INDEX_MOD);
  1065. */
  1066. *((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x0) = (IndexToSpectrum(rand() % PLASMA_INDEX_MOD) & 0x00ffffff) | ((rand() % 255) << 24);
  1067. *((ARGB*)((BYTE*)bmpd.Scan0 + y0*bmpd.Stride) + x1) = (IndexToSpectrum(rand() % PLASMA_INDEX_MOD) & 0x00ffffff) | ((rand() % 255) << 24);;
  1068. *((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x0) = (IndexToSpectrum(rand() % PLASMA_INDEX_MOD) & 0x00ffffff) | ((rand() % 255) << 24);;
  1069. *((ARGB*)((BYTE*)bmpd.Scan0 + y1*bmpd.Stride) + x1) = (IndexToSpectrum(rand() % PLASMA_INDEX_MOD) & 0x00ffffff) | ((rand() % 255) << 24);;
  1070. abort = !HalfPlasma(hwnd,g,bmpd,x0,y0,x1,y1,scale);
  1071. bmp.UnlockBits(&bmpd);
  1072. PointF points[3];
  1073. if (!abort)
  1074. {
  1075. // Get some good random points. Limit angles to be > 20 degrees, so
  1076. // there are no skinny rects
  1077. for (int j = 0; j <= 20; j++)
  1078. {
  1079. for (int i = 0; i<= 2; i++)
  1080. {
  1081. points[i].X = (REAL)(rand() % (rc.right - rc.left));
  1082. points[i].Y = (REAL)(rand() % (rc.bottom - rc.top));
  1083. }
  1084. double a,b,c,cosa,cosb,cosc;
  1085. a = sqrt(pow(points[0].X - points[1].X, 2) + pow(points[0].Y - points[1].Y, 2));
  1086. b = sqrt(pow(points[2].X - points[1].X, 2) + pow(points[2].Y - points[1].Y, 2));
  1087. c = sqrt(pow(points[0].X - points[2].X, 2) + pow(points[0].Y - points[2].Y, 2));
  1088. int iMinLen = (int)min(a,min(b,c));
  1089. cosa = (pow(a,2) - pow(b,2) - pow(c,2)) / (-2 * b * c);
  1090. cosb = (pow(b,2) - pow(a,2) - pow(c,2)) / (-2 * a * c);
  1091. cosc = (pow(c,2) - pow(a,2) - pow(b,2)) / (-2 * a * b);
  1092. if ((fabs(cosa) < 0.939) &&
  1093. (fabs(cosb) < 0.939) &&
  1094. (fabs(cosc) < 0.939) &&
  1095. (a > 35))
  1096. {
  1097. break;
  1098. }
  1099. }
  1100. //g.DrawImage(&bmp,points,3);
  1101. INT halfKernel = intMode;
  1102. g.DrawImage(&bmp, points, 3, (REAL)-halfKernel, (REAL)-halfKernel,
  1103. (REAL)(w+halfKernel), (REAL)(w+halfKernel), UnitPixel, NULL, NULL, NULL);
  1104. }
  1105. }
  1106. VOID GetFractalConfig (DWORD *nType, DWORD *nSize)
  1107. {
  1108. #define MYBUFFSIZE 32
  1109. HKEY hKey;
  1110. HRESULT hr;
  1111. DWORD dwType;
  1112. DWORD dwBuffLen = sizeof(DWORD);
  1113. hr = RegCreateKeyEx(HKEY_CURRENT_USER,
  1114. HKEY_PREFERENCES,
  1115. NULL,NULL,
  1116. REG_OPTION_NON_VOLATILE,
  1117. KEY_READ | KEY_WRITE,NULL,&hKey, NULL);
  1118. if (ERROR_SUCCESS != hr)
  1119. {
  1120. *nSize = 4;
  1121. *nType = 0;
  1122. goto Done;
  1123. }
  1124. hr = RegQueryValueEx(hKey, TEXT("FractalScnSvrType"),NULL,&dwType,
  1125. (LPBYTE)nType, &dwBuffLen);
  1126. if (ERROR_SUCCESS != hr || dwType != REG_DWORD)
  1127. {
  1128. *nSize = 4;
  1129. *nType = 0;
  1130. goto Done;
  1131. }
  1132. dwBuffLen = MYBUFFSIZE;
  1133. hr = RegQueryValueEx(hKey, TEXT("FractalScnSvrNumber"),NULL,&dwType,
  1134. (LPBYTE)nSize, &dwBuffLen);
  1135. if (ERROR_SUCCESS != hr || dwType != REG_DWORD)
  1136. {
  1137. *nSize = 4;
  1138. }
  1139. Done:
  1140. RegCloseKey(hKey);
  1141. }
  1142. VOID SetFractalConfig (DWORD nType, DWORD nSize)
  1143. {
  1144. HKEY hKey;
  1145. HRESULT hr;
  1146. DWORD dwType = REG_DWORD;
  1147. hr = RegCreateKeyEx(HKEY_CURRENT_USER,
  1148. HKEY_PREFERENCES,
  1149. NULL,NULL,
  1150. REG_OPTION_NON_VOLATILE,
  1151. KEY_READ | KEY_WRITE,NULL,&hKey, NULL);
  1152. if (ERROR_SUCCESS != hr)
  1153. {
  1154. goto Done;
  1155. }
  1156. hr = RegSetValueEx(hKey, TEXT("FractalScnSvrType"),NULL,dwType,
  1157. (LPBYTE)&nType, sizeof(DWORD));
  1158. if (ERROR_SUCCESS != hr || dwType != REG_DWORD)
  1159. {
  1160. goto Done;
  1161. }
  1162. hr = RegSetValueEx(hKey, TEXT("FractalScnSvrNumber"),NULL,dwType,
  1163. (LPBYTE)&nSize, sizeof(DWORD));
  1164. Done:
  1165. RegCloseKey(hKey);
  1166. }