Source code of Windows XP (NT5)
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.

1474 lines
44 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: FlyingObjects.cpp
  3. //
  4. // Desc: Fun screen saver
  5. //
  6. // Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #include <windows.h>
  9. #include <tchar.h>
  10. #include <d3d8.h>
  11. #include <d3dx8.h>
  12. #include <d3d8rgbrast.h>
  13. #include <time.h>
  14. #include <stdio.h>
  15. #include <commctrl.h>
  16. #include <scrnsave.h>
  17. #include "d3dsaver.h"
  18. #include "FlyingObjects.h"
  19. #include "mesh.h"
  20. #include "Resource.h"
  21. #include "dxutil.h"
  22. extern void updateStripScene(int flags, FLOAT fElapsedTime);
  23. extern void updateDropScene(int flags, FLOAT fElapsedTime);
  24. extern void updateLemScene(int flags, FLOAT fElapsedTime);
  25. extern void updateExplodeScene(int flags, FLOAT fElapsedTime);
  26. extern void updateWinScene(int flags, FLOAT fElapsedTime);
  27. extern void updateWin2Scene(int flags, FLOAT fElapsedTime);
  28. extern void updateTexScene(int flags, FLOAT fElapsedTime);
  29. extern BOOL initStripScene(void);
  30. extern BOOL initDropScene(void);
  31. extern BOOL initLemScene(void);
  32. extern BOOL initExplodeScene(void);
  33. extern BOOL initWinScene(void);
  34. extern BOOL initWin2Scene(void);
  35. extern BOOL initTexScene(void);
  36. extern void delStripScene(void);
  37. extern void delDropScene(void);
  38. extern void delLemScene(void);
  39. extern void delExplodeScene(void);
  40. extern void delWinScene(void);
  41. extern void delWin2Scene(void);
  42. extern void delTexScene(void);
  43. typedef void (*PTRUPDATE)(int flags, FLOAT fElapsedTime);
  44. typedef void (*ptrdel)();
  45. typedef BOOL (*ptrinit)();
  46. // Each screen saver style puts its hook functions into the function
  47. // arrays below. A consistent ordering of the functions is required.
  48. static PTRUPDATE updateFuncs[] =
  49. {/*updateWinScene,*/ updateWin2Scene, updateExplodeScene,updateStripScene, updateStripScene,
  50. updateDropScene, updateLemScene, updateTexScene};
  51. static ptrdel delFuncs[] =
  52. {/*delWinScene,*/ delWin2Scene, delExplodeScene, delStripScene, delStripScene,
  53. delDropScene, delLemScene, delTexScene};
  54. static ptrinit initFuncs[] =
  55. {/*initWinScene,*/ initWin2Scene, initExplodeScene, initStripScene, initStripScene,
  56. initDropScene, initLemScene, initTexScene};
  57. static int idsStyles[] =
  58. {IDS_LOGO, IDS_EXPLODE, IDS_RIBBON, IDS_2RIBBON,
  59. IDS_SPLASH, IDS_TWIST, IDS_FLAG};
  60. #define MAX_TYPE ( sizeof(initFuncs) / sizeof(ptrinit) - 1 )
  61. // Each screen saver style can choose which dialog box controls it wants
  62. // to use. These flags enable each of the controls. Controls not choosen
  63. // will be disabled.
  64. #define OPT_COLOR_CYCLE 0x00000001
  65. #define OPT_SMOOTH_SHADE 0x00000002
  66. #define OPT_TESSEL 0x00000008
  67. #define OPT_SIZE 0x00000010
  68. #define OPT_TEXTURE 0x00000020
  69. #define OPT_STD ( OPT_COLOR_CYCLE | OPT_SMOOTH_SHADE | OPT_TESSEL | OPT_SIZE )
  70. static ULONG gflConfigOpt[] = {
  71. // OPT_STD, // Windows logo
  72. 0, // New Windows logo
  73. OPT_STD, // Explode
  74. OPT_STD, // Strip
  75. OPT_STD, // Strip
  76. OPT_STD, // Drop
  77. OPT_STD, // Twist (lemniscate)
  78. OPT_SMOOTH_SHADE | OPT_TESSEL | OPT_SIZE | OPT_TEXTURE // Texture mapped flag
  79. };
  80. static void updateDialogControls(HWND hDlg);
  81. CFlyingObjectsScreensaver* g_pMyFlyingObjectsScreensaver = NULL;
  82. INT g_xScreenOrigin = 0;
  83. INT g_yScreenOrigin = 0;
  84. INT g_iDevice = -1;
  85. FLOATRECT* g_pFloatRect = NULL;
  86. BOOL gbBounce = FALSE; // floating window bounce off side
  87. // Global message loop variables.
  88. D3DMATERIAL8 Material[16];
  89. #ifdef MEMDEBUG
  90. ULONG totalMem = 0;
  91. #endif
  92. void (*updateSceneFunc)(int flags, FLOAT fElapsedTime); // current screen saver update function
  93. void (*delSceneFunc)(void); // current screen saver deletion function
  94. BOOL bColorCycle = FALSE; // color cycling flag
  95. DeviceObjects* g_pDeviceObjects = NULL;
  96. BOOL g_bMoveToOrigin = FALSE;
  97. BOOL g_bAtOrigin = FALSE;
  98. BOOL bSmoothShading = TRUE; // smooth shading flag
  99. UINT uSize = 100; // object size
  100. float fTesselFact = 2.0f; // object tessalation
  101. int UpdateFlags = 0; // extra data sent to update function
  102. int Type = 0; // screen saver index (into function arrays)
  103. LPDIRECT3DDEVICE8 m_pd3dDevice = NULL;
  104. LPDIRECT3DINDEXBUFFER8 m_pIB = NULL;
  105. LPDIRECT3DVERTEXBUFFER8 m_pVB = NULL;
  106. LPDIRECT3DVERTEXBUFFER8 m_pVB2 = NULL;
  107. // Texture file information
  108. TEXFILE gTexFile = {0};
  109. // Lighting properties.
  110. static const RGBA lightAmbient = {0.21f, 0.21f, 0.21f, 1.0f};
  111. static const RGBA light0Ambient = {0.0f, 0.0f, 0.0f, 1.0f};
  112. static const RGBA light0Diffuse = {0.7f, 0.7f, 0.7f, 1.0f};
  113. static const RGBA light0Specular = {1.0f, 1.0f, 1.0f, 1.0f};
  114. static const FLOAT light0Pos[] = {100.0f, 100.0f, 100.0f, 0.0f};
  115. // Material properties.
  116. static RGBA matlColors[7] = {{1.0f, 0.0f, 0.0f, 1.0f},
  117. {0.0f, 1.0f, 0.0f, 1.0f},
  118. {0.0f, 0.0f, 1.0f, 1.0f},
  119. {1.0f, 1.0f, 0.0f, 1.0f},
  120. {0.0f, 1.0f, 1.0f, 1.0f},
  121. {1.0f, 0.0f, 1.0f, 1.0f},
  122. {0.235f, 0.0f, 0.78f, 1.0f},
  123. };
  124. static D3DMATERIAL8 s_mtrl =
  125. {
  126. 1.0f, 1.0f, 1.0f, 1.0f, // Diffuse
  127. 1.0f, 1.0f, 1.0f, 1.0f, // Ambient
  128. 1.0f, 1.0f, 1.0f, 1.0f, // Specular
  129. 0.0f, 0.0f, 0.0f, 0.0f, // Emissive
  130. 30.0f // Power
  131. };
  132. #define BUF_SIZE 255
  133. TCHAR g_szSectName[BUF_SIZE];
  134. TCHAR g_szFname[BUF_SIZE];
  135. //-----------------------------------------------------------------------------
  136. // Name: myglMaterialfv()
  137. // Desc:
  138. //-----------------------------------------------------------------------------
  139. VOID myglMaterialfv(INT face, INT pname, FLOAT* params)
  140. {
  141. if( pname == GL_AMBIENT_AND_DIFFUSE)
  142. {
  143. s_mtrl.Ambient.r = s_mtrl.Diffuse.r = params[0];
  144. s_mtrl.Ambient.g = s_mtrl.Diffuse.g = params[1];
  145. s_mtrl.Ambient.b = s_mtrl.Diffuse.b = params[2];
  146. s_mtrl.Ambient.a = s_mtrl.Diffuse.a = params[3];
  147. }
  148. else if( pname == GL_SPECULAR )
  149. {
  150. s_mtrl.Specular.r = params[0];
  151. s_mtrl.Specular.g = params[1];
  152. s_mtrl.Specular.b = params[2];
  153. s_mtrl.Specular.a = params[3];
  154. }
  155. else if( pname == GL_SHININESS )
  156. {
  157. s_mtrl.Power = params[0];
  158. }
  159. m_pd3dDevice->SetMaterial(&s_mtrl);
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Name: myglMaterialf()
  163. // Desc:
  164. //-----------------------------------------------------------------------------
  165. VOID myglMaterialf(INT face, INT pname, FLOAT param)
  166. {
  167. if( pname == GL_SHININESS )
  168. {
  169. s_mtrl.Power = param;
  170. }
  171. m_pd3dDevice->SetMaterial(&s_mtrl);
  172. }
  173. /******************************Public*Routine******************************\
  174. * HsvToRgb
  175. *
  176. * HSV to RGB color space conversion. From pg. 593 of Foley & van Dam.
  177. *
  178. \**************************************************************************/
  179. void ss_HsvToRgb(float h, float s, float v, RGBA *color )
  180. {
  181. float i, f, p, q, t;
  182. // set alpha value, so caller doesn't have to worry about undefined value
  183. color->a = 1.0f;
  184. if (s == 0.0f) // assume h is undefined
  185. color->r = color->g = color->b = v;
  186. else {
  187. if (h >= 360.0f)
  188. h = 0.0f;
  189. h = h / 60.0f;
  190. i = (float) floor(h);
  191. f = h - i;
  192. p = v * (1.0f - s);
  193. q = v * (1.0f - (s * f));
  194. t = v * (1.0f - (s * (1.0f - f)));
  195. switch ((int)i) {
  196. case 0:
  197. color->r = v;
  198. color->g = t;
  199. color->b = p;
  200. break;
  201. case 1:
  202. color->r = q;
  203. color->g = v;
  204. color->b = p;
  205. break;
  206. case 2:
  207. color->r = p;
  208. color->g = v;
  209. color->b = t;
  210. break;
  211. case 3:
  212. color->r = p;
  213. color->g = q;
  214. color->b = v;
  215. break;
  216. case 4:
  217. color->r = t;
  218. color->g = p;
  219. color->b = v;
  220. break;
  221. case 5:
  222. color->r = v;
  223. color->g = p;
  224. color->b = q;
  225. break;
  226. default:
  227. break;
  228. }
  229. }
  230. }
  231. void *SaverAlloc(ULONG size)
  232. {
  233. void *mPtr;
  234. mPtr = malloc(size);
  235. #ifdef MEMDEBUG
  236. totalMem += size;
  237. xprintf("malloc'd %x, size %d\n", mPtr, size);
  238. #endif
  239. return mPtr;
  240. }
  241. void SaverFree(void *pMem)
  242. {
  243. #ifdef MEMDEBUG
  244. totalMem -= _msize(pMem);
  245. xprintf("free %x, size = %d, total = %d\n", pMem, _msize(pMem), totalMem);
  246. #endif
  247. free(pMem);
  248. }
  249. // Minimum and maximum image sizes
  250. #define MINIMAGESIZE 10
  251. #define MAXIMAGESIZE 100
  252. // A slider range
  253. typedef struct _RANGE
  254. {
  255. int min_val;
  256. int max_val;
  257. int step;
  258. int page_step;
  259. } RANGE;
  260. RANGE complexity_range = {MINSUBDIV, MAXSUBDIV, 1, 2};
  261. RANGE image_size_range = {MINIMAGESIZE, MAXIMAGESIZE, 1, 10};
  262. /******************************Public*Routine******************************\
  263. * initMaterial
  264. *
  265. * Initialize the material properties.
  266. *
  267. \**************************************************************************/
  268. void initMaterial(int id, float r, float g, float b, float a)
  269. {
  270. Material[id].Ambient.r = r;
  271. Material[id].Ambient.g = g;
  272. Material[id].Ambient.b = b;
  273. Material[id].Ambient.a = a;
  274. Material[id].Diffuse.r = r;
  275. Material[id].Diffuse.g = g;
  276. Material[id].Diffuse.b = b;
  277. Material[id].Diffuse.a = a;
  278. Material[id].Specular.r = 1.0f;
  279. Material[id].Specular.g = 1.0f;
  280. Material[id].Specular.b = 1.0f;
  281. Material[id].Specular.a = 1.0f;
  282. Material[id].Power = 128.0f;
  283. }
  284. /******************************Public*Routine******************************\
  285. * _3dfo_Init
  286. *
  287. \**************************************************************************/
  288. BOOL CFlyingObjectsScreensaver::_3dfo_Init(void *data)
  289. {
  290. int i;
  291. for (i = 0; i < 7; i++)
  292. initMaterial(i, matlColors[i].r, matlColors[i].g,
  293. matlColors[i].b, matlColors[i].a);
  294. /*
  295. // Set the OpenGL clear color to black.
  296. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  297. #ifdef SS_DEBUG
  298. glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
  299. #endif
  300. // Enable the z-buffer.
  301. glEnable(GL_DEPTH_TEST);
  302. */
  303. // Select the shading model.
  304. if (bSmoothShading)
  305. {
  306. m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
  307. }
  308. else
  309. {
  310. m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
  311. }
  312. /* // Setup the OpenGL matrices.
  313. glMatrixMode(GL_PROJECTION);
  314. glLoadIdentity();
  315. glMatrixMode(GL_MODELVIEW);
  316. glLoadIdentity();
  317. // Setup the lighting.
  318. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (FLOAT *) &lightAmbient);
  319. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  320. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
  321. glLightfv(GL_LIGHT0, GL_AMBIENT, (FLOAT *) &light0Ambient);
  322. glLightfv(GL_LIGHT0, GL_DIFFUSE, (FLOAT *) &light0Diffuse);
  323. glLightfv(GL_LIGHT0, GL_SPECULAR, (FLOAT *) &light0Specular);
  324. glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  325. glEnable(GL_LIGHTING);
  326. glEnable(GL_LIGHT0);
  327. */
  328. // m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE(lightAmbient.r,
  329. // lightAmbient.g, lightAmbient.b, lightAmbient.a ) );
  330. D3DLIGHT8 light;
  331. ZeroMemory( &light, sizeof(D3DLIGHT8) );
  332. light.Type = D3DLIGHT_POINT;
  333. light.Range = 1000.0f;
  334. light.Position.x = light0Pos[0];
  335. light.Position.y = light0Pos[1];
  336. light.Position.z = light0Pos[2];
  337. light.Ambient.r = lightAmbient.r;
  338. light.Ambient.g = lightAmbient.g;
  339. light.Ambient.b = lightAmbient.b;
  340. light.Ambient.a = light0Ambient.a;
  341. light.Diffuse.r = light0Diffuse.r;
  342. light.Diffuse.g = light0Diffuse.g;
  343. light.Diffuse.b = light0Diffuse.b;
  344. light.Diffuse.a = light0Diffuse.a;
  345. light.Specular.r = light0Specular.r;
  346. light.Specular.g = light0Specular.g;
  347. light.Specular.b = light0Specular.b;
  348. light.Specular.a = light0Specular.a;
  349. light.Attenuation0 = 1.0f;
  350. light.Attenuation1 = 0.0f;
  351. light.Attenuation2 = 0.0f;
  352. m_pd3dDevice->SetLight(0, &light);
  353. m_pd3dDevice->LightEnable(0, TRUE);
  354. // m_pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE);
  355. // Setup the material properties.
  356. m_pd3dDevice->SetMaterial( &Material[0] );
  357. /* glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (FLOAT *) &Material[0].ks);
  358. glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (FLOAT *) &Material[0].specExp);
  359. */
  360. // call specific objects init func
  361. if (! (*initFuncs[Type])() )
  362. return FALSE;
  363. updateSceneFunc = updateFuncs[Type];
  364. return TRUE;
  365. }
  366. /******************************Public*Routine******************************\
  367. * WriteSettings
  368. *
  369. * Save the screen saver configuration option to the .INI file/registry.
  370. *
  371. * History:
  372. * 10-May-1994 -by- Gilman Wong [gilmanw]
  373. * Wrote it.
  374. \**************************************************************************/
  375. VOID CFlyingObjectsScreensaver::WriteSettings(HWND hDlg)
  376. {
  377. HKEY hkey;
  378. if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
  379. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
  380. {
  381. int pos, options;
  382. int optMask = 1;
  383. bSmoothShading = IsDlgButtonChecked(hDlg, DLG_SETUP_SMOOTH);
  384. bColorCycle = IsDlgButtonChecked(hDlg, DLG_SETUP_CYCLE);
  385. options = bColorCycle;
  386. options <<= 1;
  387. options |= bSmoothShading;
  388. DXUtil_WriteIntRegKey( hkey, TEXT("Options"), options );
  389. Type = (int)SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_GETCURSEL,
  390. 0, 0);
  391. DXUtil_WriteIntRegKey( hkey, TEXT("Type"), Type );
  392. pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_TESSEL );
  393. DXUtil_WriteIntRegKey( hkey, TEXT("Tesselation"), pos );
  394. pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_SIZE );
  395. DXUtil_WriteIntRegKey( hkey, TEXT("Size"), pos );
  396. DXUtil_WriteStringRegKey( hkey, TEXT("Texture"), gTexFile.szPathName );
  397. DXUtil_WriteIntRegKey( hkey, TEXT("TextureFileOffset"), gTexFile.nOffset );
  398. WriteScreenSettings( hkey );
  399. RegCloseKey( hkey );
  400. }
  401. }
  402. /******************************Public*Routine******************************\
  403. * SetupTrackbar
  404. *
  405. * Setup a common control trackbar
  406. \**************************************************************************/
  407. void
  408. ss_SetupTrackbar( HWND hDlg, int item, int lo, int hi, int lineSize,
  409. int pageSize, int pos )
  410. {
  411. SendDlgItemMessage(
  412. hDlg,
  413. item,
  414. TBM_SETRANGE,
  415. (WPARAM) TRUE,
  416. (LPARAM) MAKELONG( lo, hi )
  417. );
  418. SendDlgItemMessage(
  419. hDlg,
  420. item,
  421. TBM_SETPOS,
  422. (WPARAM) TRUE,
  423. (LPARAM) pos
  424. );
  425. SendDlgItemMessage(
  426. hDlg,
  427. item,
  428. TBM_SETPAGESIZE,
  429. (WPARAM) 0,
  430. (LPARAM) pageSize
  431. );
  432. SendDlgItemMessage(
  433. hDlg,
  434. item,
  435. TBM_SETLINESIZE,
  436. (WPARAM) 0,
  437. (LPARAM) lineSize
  438. );
  439. }
  440. /******************************Public*Routine******************************\
  441. * GetTrackbarPos
  442. *
  443. * Get the current position of a common control trackbar
  444. \**************************************************************************/
  445. int
  446. ss_GetTrackbarPos( HWND hDlg, int item )
  447. {
  448. return
  449. (int)SendDlgItemMessage(
  450. hDlg,
  451. item,
  452. TBM_GETPOS,
  453. 0,
  454. 0
  455. );
  456. }
  457. /******************************Public*Routine******************************\
  458. * setupDialogControls
  459. *
  460. * Setup the dialog controls initially.
  461. *
  462. \**************************************************************************/
  463. static void
  464. setupDialogControls(HWND hDlg)
  465. {
  466. int pos;
  467. InitCommonControls();
  468. if (fTesselFact <= 1.0f)
  469. pos = (int)(fTesselFact * 100.0f);
  470. else
  471. pos = 100 + (int) ((fTesselFact - 1.0f) * 100.0f);
  472. ss_SetupTrackbar( hDlg, DLG_SETUP_TESSEL, 0, 200, 1, 10, pos );
  473. ss_SetupTrackbar( hDlg, DLG_SETUP_SIZE, 0, 100, 1, 10, uSize );
  474. updateDialogControls( hDlg );
  475. }
  476. /******************************Public*Routine******************************\
  477. * updateDialogControls
  478. *
  479. * Update the dialog controls based on the current global state.
  480. *
  481. \**************************************************************************/
  482. static void
  483. updateDialogControls(HWND hDlg)
  484. {
  485. CheckDlgButton(hDlg, DLG_SETUP_SMOOTH, bSmoothShading);
  486. CheckDlgButton(hDlg, DLG_SETUP_CYCLE, bColorCycle);
  487. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_SMOOTH),
  488. gflConfigOpt[Type] & OPT_SMOOTH_SHADE );
  489. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_CYCLE),
  490. gflConfigOpt[Type] & OPT_COLOR_CYCLE );
  491. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_TESSEL),
  492. gflConfigOpt[Type] & OPT_TESSEL);
  493. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS),
  494. gflConfigOpt[Type] & OPT_TESSEL);
  495. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS_MIN),
  496. gflConfigOpt[Type] & OPT_TESSEL);
  497. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS_MAX),
  498. gflConfigOpt[Type] & OPT_TESSEL);
  499. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_SIZE),
  500. gflConfigOpt[Type] & OPT_SIZE);
  501. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE),
  502. gflConfigOpt[Type] & OPT_SIZE);
  503. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE_MIN),
  504. gflConfigOpt[Type] & OPT_SIZE);
  505. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE_MAX),
  506. gflConfigOpt[Type] & OPT_SIZE);
  507. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_TEXTURE),
  508. gflConfigOpt[Type] & OPT_TEXTURE);
  509. }
  510. /******************************Public*Routine******************************\
  511. *
  512. * ScreenSaverConfigureDialog
  513. *
  514. * Standard screensaver hook
  515. *
  516. * History:
  517. * Wed Jul 19 14:56:41 1995 -by- Drew Bliss [drewb]
  518. * Created
  519. *
  520. \**************************************************************************/
  521. BOOL CALLBACK CFlyingObjectsScreensaver::ScreenSaverConfigureDialog(HWND hDlg, UINT message,
  522. WPARAM wParam, LPARAM lParam)
  523. {
  524. int wTmp;
  525. TCHAR szString[GEN_STRING_SIZE];
  526. switch (message) {
  527. case WM_INITDIALOG:
  528. g_pMyFlyingObjectsScreensaver->ReadSettings();
  529. setupDialogControls(hDlg);
  530. for (wTmp = 0; wTmp <= MAX_TYPE; wTmp++) {
  531. LoadString(NULL, idsStyles[wTmp], szString, GEN_STRING_SIZE);
  532. SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_ADDSTRING, 0,
  533. (LPARAM) szString);
  534. }
  535. SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_SETCURSEL, Type, 0);
  536. return TRUE;
  537. case WM_COMMAND:
  538. switch (LOWORD(wParam)) {
  539. case DLG_SETUP_TYPES:
  540. switch (HIWORD(wParam))
  541. {
  542. case CBN_EDITCHANGE:
  543. case CBN_SELCHANGE:
  544. Type = (int)SendDlgItemMessage(hDlg, DLG_SETUP_TYPES,
  545. CB_GETCURSEL, 0, 0);
  546. updateDialogControls(hDlg);
  547. break;
  548. default:
  549. break;
  550. }
  551. return FALSE;
  552. case DLG_SETUP_TEXTURE:
  553. ss_SelectTextureFile( hDlg, &gTexFile );
  554. break;
  555. case DLG_SETUP_MONITORSETTINGS:
  556. g_pMyFlyingObjectsScreensaver->DoScreenSettingsDialog( hDlg );
  557. break;
  558. case IDOK:
  559. g_pMyFlyingObjectsScreensaver->WriteSettings( hDlg );
  560. EndDialog(hDlg, TRUE);
  561. break;
  562. case IDCANCEL:
  563. EndDialog(hDlg, FALSE);
  564. break;
  565. case DLG_SETUP_SMOOTH:
  566. case DLG_SETUP_CYCLE:
  567. default:
  568. break;
  569. }
  570. return TRUE;
  571. break;
  572. default:
  573. return 0;
  574. }
  575. return 0;
  576. }
  577. //-----------------------------------------------------------------------------
  578. // Name: WinMain()
  579. // Desc: Entry point to the program. Initializes everything, and goes into a
  580. // message-processing loop. Idle time is used to render the scene.
  581. //-----------------------------------------------------------------------------
  582. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  583. {
  584. HRESULT hr;
  585. CFlyingObjectsScreensaver flyingobjectsSS;
  586. if( FAILED( hr = flyingobjectsSS.Create( hInst ) ) )
  587. {
  588. flyingobjectsSS.DisplayErrorMsg( hr );
  589. return 0;
  590. }
  591. return flyingobjectsSS.Run();
  592. }
  593. //-----------------------------------------------------------------------------
  594. // Name: CFlyingObjectsScreensaver()
  595. // Desc: Constructor
  596. //-----------------------------------------------------------------------------
  597. CFlyingObjectsScreensaver::CFlyingObjectsScreensaver( )
  598. {
  599. g_pMyFlyingObjectsScreensaver = this;
  600. g_pFloatRect = &m_floatrect;
  601. ZeroMemory( m_DeviceObjectsArray, sizeof(m_DeviceObjectsArray) );
  602. m_pDeviceObjects = NULL;
  603. LoadString( NULL, IDS_DESCRIPTION, m_strWindowTitle, 200 );
  604. m_bUseDepthBuffer = TRUE;
  605. lstrcpy( m_strRegPath, TEXT("Software\\Microsoft\\Screensavers\\Flying Objects") );
  606. m_floatrect.xSize = 0.0f;
  607. InitCommonControls();
  608. bSmoothShading = FALSE;
  609. bColorCycle = FALSE;
  610. UpdateFlags = (bColorCycle << 1);
  611. Type = 0;
  612. fTesselFact = 2.0f;
  613. uSize = 50;
  614. ss_GetDefaultBmpFile( gTexFile.szPathName );
  615. gTexFile.nOffset = 0;
  616. ss_LoadTextureResourceStrings();
  617. srand((UINT)time(NULL)); // seed random number generator
  618. }
  619. //-----------------------------------------------------------------------------
  620. // Name: RegisterSoftwareDevice()
  621. // Desc: This can register the D3D8RGBRasterizer or any other
  622. // pluggable software rasterizer.
  623. //-----------------------------------------------------------------------------
  624. HRESULT CFlyingObjectsScreensaver::RegisterSoftwareDevice()
  625. {
  626. m_pD3D->RegisterSoftwareDevice( D3D8RGBRasterizer );
  627. return S_OK;
  628. }
  629. //-----------------------------------------------------------------------------
  630. // Name: SetMaterialColor()
  631. // Desc:
  632. //-----------------------------------------------------------------------------
  633. HRESULT CFlyingObjectsScreensaver::SetMaterialColor(FLOAT* pfColors)
  634. {
  635. D3DMATERIAL8 mtrl;
  636. ZeroMemory( &mtrl, sizeof(mtrl) );
  637. mtrl.Diffuse.r = mtrl.Ambient.r = pfColors[0];
  638. mtrl.Diffuse.g = mtrl.Ambient.g = pfColors[1];
  639. mtrl.Diffuse.b = mtrl.Ambient.b = pfColors[2];
  640. mtrl.Diffuse.a = mtrl.Ambient.a = pfColors[3];
  641. mtrl.Specular.r = 1.0f;
  642. mtrl.Specular.g = 1.0f;
  643. mtrl.Specular.b = 1.0f;
  644. mtrl.Specular.a = 1.0f;
  645. mtrl.Power = 30.0f;
  646. return m_pd3dDevice->SetMaterial(&mtrl);
  647. }
  648. //-----------------------------------------------------------------------------
  649. // Name: FrameMove()
  650. // Desc: Called once per frame, the call is the entry point for animating
  651. // the scene.
  652. //-----------------------------------------------------------------------------
  653. HRESULT CFlyingObjectsScreensaver::FrameMove()
  654. {
  655. // update floatrect
  656. RECT rcBounceBounds;
  657. if( m_floatrect.xSize == 0.0f )
  658. {
  659. // Initialize floatrect
  660. RECT rcBounds;
  661. DWORD dwParentWidth;
  662. DWORD dwParentHeight;
  663. rcBounds = m_rcRenderTotal;
  664. dwParentWidth = rcBounds.right - rcBounds.left;
  665. dwParentHeight = rcBounds.bottom - rcBounds.top;
  666. FLOAT sizeFact;
  667. FLOAT sizeScale;
  668. DWORD size;
  669. sizeScale = (FLOAT)uSize / 150.0f;
  670. // sizeFact = 0.25f + (0.5f * sizeScale); // range 25-75%
  671. // size = (DWORD) (sizeFact * ( ((FLOAT)(dwParentWidth + dwParentHeight)) / 2.0f ));
  672. // sizeFact = 0.25f + (0.75f * sizeScale); // range 25-100%
  673. // Note: there are bouncing problems when size is 100% (gbBounce is always
  674. // true) -- things "jitter" too much. So limit size to 95% for this screensaver.
  675. sizeFact = 0.25f + (0.70f * sizeScale); // range 25-95%
  676. size = (DWORD) (sizeFact * ( dwParentWidth > dwParentHeight ? dwParentHeight : dwParentWidth ) );
  677. if( size > dwParentWidth )
  678. size = dwParentWidth;
  679. if( size > dwParentHeight )
  680. size = dwParentHeight;
  681. // Start floatrect centered on first RenderUnit's screen
  682. if( !m_bWindowed )
  683. {
  684. INT iMonitor = m_RenderUnits[0].iMonitor;
  685. rcBounds = m_Monitors[iMonitor].rcScreen;
  686. }
  687. m_floatrect.xMin = rcBounds.left + ((rcBounds.right - rcBounds.left) - size) / 2.0f;
  688. m_floatrect.yMin = rcBounds.top + ((rcBounds.bottom - rcBounds.top) - size) / 2.0f;
  689. m_floatrect.xOrigin = m_floatrect.xMin;
  690. m_floatrect.yOrigin = m_floatrect.yMin;
  691. m_floatrect.xSize = (FLOAT)size;
  692. m_floatrect.ySize = (FLOAT)size;
  693. m_floatrect.xVel = 0.01f * (FLOAT) size;
  694. if( rand() % 2 == 0 )
  695. m_floatrect.xVel = -m_floatrect.xVel;
  696. m_floatrect.yVel = 0.01f * (FLOAT) size;
  697. if( rand() % 2 == 0 )
  698. m_floatrect.yVel = -m_floatrect.yVel;
  699. m_floatrect.xVelMax = m_floatrect.xVel;
  700. m_floatrect.yVelMax = m_floatrect.yVel;
  701. }
  702. rcBounceBounds = m_rcRenderTotal;
  703. FLOAT xMinOld = m_floatrect.xMin;
  704. FLOAT yMinOld = m_floatrect.yMin;
  705. if( g_bMoveToOrigin )
  706. {
  707. if( m_floatrect.xVel < 0 && m_floatrect.xMin < m_floatrect.xOrigin ||
  708. m_floatrect.xVel > 0 && m_floatrect.xMin > m_floatrect.xOrigin )
  709. {
  710. m_floatrect.xVel = -m_floatrect.xVel;
  711. }
  712. if( m_floatrect.yVel < 0 && m_floatrect.yMin < m_floatrect.yOrigin ||
  713. m_floatrect.yVel > 0 && m_floatrect.yMin > m_floatrect.yOrigin )
  714. {
  715. m_floatrect.yVel = -m_floatrect.yVel;
  716. }
  717. m_floatrect.xMin += m_floatrect.xVel * 20.0f * m_fElapsedTime;
  718. m_floatrect.yMin += m_floatrect.yVel * 20.0f * m_fElapsedTime;
  719. if( m_floatrect.xVel < 0 && m_floatrect.xMin < m_floatrect.xOrigin ||
  720. m_floatrect.xVel > 0 && m_floatrect.xMin > m_floatrect.xOrigin )
  721. {
  722. m_floatrect.xMin = m_floatrect.xOrigin;
  723. m_floatrect.xVel = 0.0f;
  724. }
  725. if( m_floatrect.yVel < 0 && m_floatrect.yMin < m_floatrect.yOrigin ||
  726. m_floatrect.yVel > 0 && m_floatrect.yMin > m_floatrect.yOrigin )
  727. {
  728. m_floatrect.yMin = m_floatrect.yOrigin;
  729. m_floatrect.yVel = 0.0f;
  730. }
  731. if( m_floatrect.xMin == m_floatrect.xOrigin &&
  732. m_floatrect.yMin == m_floatrect.yOrigin )
  733. {
  734. g_bAtOrigin = TRUE;
  735. }
  736. }
  737. else
  738. {
  739. g_bAtOrigin = FALSE;
  740. if( m_floatrect.xVel == 0.0f )
  741. {
  742. m_floatrect.xVel = m_floatrect.xVelMax;
  743. if( rand() % 2 == 0 )
  744. m_floatrect.xVel = -m_floatrect.xVel;
  745. }
  746. if( m_floatrect.yVel == 0.0f )
  747. {
  748. m_floatrect.yVel = m_floatrect.yVelMax;
  749. if( rand() % 2 == 0 )
  750. m_floatrect.yVel = -m_floatrect.yVel;
  751. }
  752. m_floatrect.xMin += m_floatrect.xVel * 20.0f * m_fElapsedTime;
  753. m_floatrect.yMin += m_floatrect.yVel * 20.0f * m_fElapsedTime;
  754. if( m_floatrect.xVel < 0 && m_floatrect.xMin < rcBounceBounds.left ||
  755. m_floatrect.xVel > 0 && (m_floatrect.xMin + m_floatrect.xSize) > rcBounceBounds.right )
  756. {
  757. gbBounce = TRUE;
  758. m_floatrect.xMin = xMinOld; // undo last move
  759. m_floatrect.xVel = -m_floatrect.xVel; // change direction
  760. }
  761. if( m_floatrect.yVel < 0 && m_floatrect.yMin < rcBounceBounds.top ||
  762. m_floatrect.yVel > 0 && (m_floatrect.yMin + m_floatrect.ySize) > rcBounceBounds.bottom )
  763. {
  764. gbBounce = TRUE;
  765. m_floatrect.yMin = yMinOld; // undo last move
  766. m_floatrect.yVel = -m_floatrect.yVel; // change direction
  767. }
  768. }
  769. return S_OK;
  770. }
  771. VOID SetProjectionMatrixInfo( BOOL bOrtho, FLOAT fWidth,
  772. FLOAT fHeight, FLOAT fNear, FLOAT fFar )
  773. {
  774. g_pMyFlyingObjectsScreensaver->m_bOrtho = bOrtho;
  775. g_pMyFlyingObjectsScreensaver->m_fWidth = fWidth;
  776. g_pMyFlyingObjectsScreensaver->m_fHeight = fHeight;
  777. g_pMyFlyingObjectsScreensaver->m_fNear = fNear;
  778. g_pMyFlyingObjectsScreensaver->m_fFar = fFar;
  779. }
  780. //-----------------------------------------------------------------------------
  781. // Name: Render()
  782. // Desc: Called once per frame, the call is the entry point for 3d
  783. // rendering. This function sets up render states, clears the
  784. // viewport, and renders the scene.
  785. //-----------------------------------------------------------------------------
  786. HRESULT CFlyingObjectsScreensaver::Render()
  787. {
  788. D3DVIEWPORT8 vp;
  789. // First, clear the entire back buffer to the background color
  790. vp.X = 0;
  791. vp.Y = 0;
  792. vp.Width = m_rcRenderCurDevice.right - m_rcRenderCurDevice.left;
  793. vp.Height = m_rcRenderCurDevice.bottom - m_rcRenderCurDevice.top;
  794. vp.MinZ = 0.0f;
  795. vp.MaxZ = 1.0f;
  796. m_pd3dDevice->SetViewport( &vp );
  797. m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0L );
  798. // Now determine what part of the floatrect, if any, intersects the current screen
  799. RECT rcFloatThisScreen;
  800. RECT rcFloatThisScreenClipped;
  801. rcFloatThisScreen.left = (INT)m_floatrect.xMin;
  802. rcFloatThisScreen.top = (INT)m_floatrect.yMin;
  803. rcFloatThisScreen.right = rcFloatThisScreen.left + (INT)m_floatrect.xSize;
  804. rcFloatThisScreen.bottom = rcFloatThisScreen.top + (INT)m_floatrect.ySize;
  805. if( !IntersectRect(&rcFloatThisScreenClipped, &rcFloatThisScreen, &m_rcRenderCurDevice) )
  806. {
  807. return S_OK; // no intersection, so nothing further to render on this screen
  808. }
  809. // Convert rcFloatThisScreen from screen to window coordinates
  810. OffsetRect(&rcFloatThisScreen, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top);
  811. OffsetRect(&rcFloatThisScreenClipped, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top);
  812. // Now set up the viewport to render to the clipped rect
  813. vp.X = rcFloatThisScreenClipped.left;
  814. vp.Y = rcFloatThisScreenClipped.top;
  815. vp.Width = rcFloatThisScreenClipped.right - rcFloatThisScreenClipped.left;
  816. vp.Height = rcFloatThisScreenClipped.bottom - rcFloatThisScreenClipped.top;
  817. vp.MinZ = 0.0f;
  818. vp.MaxZ = 1.0f;
  819. m_pd3dDevice->SetViewport( &vp );
  820. // m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000080, 1.0f, 0L );
  821. // Now set up the projection matrix to only render the onscreen part of the
  822. // rect to the viewport
  823. D3DXMATRIX matProj;
  824. FLOAT l,r,b,t;
  825. l = -m_fWidth / 2;
  826. r = m_fWidth / 2;
  827. b = -m_fHeight / 2;
  828. t = m_fHeight / 2;
  829. FLOAT cxUnclipped = (rcFloatThisScreen.right + rcFloatThisScreen.left) / 2.0f;
  830. FLOAT cyUnclipped = (rcFloatThisScreen.bottom + rcFloatThisScreen.top) / 2.0f;
  831. l *= (rcFloatThisScreenClipped.left - cxUnclipped) / (rcFloatThisScreen.left - cxUnclipped);
  832. r *= (rcFloatThisScreenClipped.right - cxUnclipped) / (rcFloatThisScreen.right - cxUnclipped);
  833. t *= (rcFloatThisScreenClipped.top - cyUnclipped) / (rcFloatThisScreen.top - cyUnclipped);
  834. b *= (rcFloatThisScreenClipped.bottom - cyUnclipped) / (rcFloatThisScreen.bottom - cyUnclipped);
  835. if( m_bOrtho )
  836. {
  837. D3DXMatrixOrthoOffCenterLH( &matProj, l, r, b, t, m_fNear, m_fFar );
  838. }
  839. else
  840. {
  841. D3DXMatrixPerspectiveOffCenterLH( &matProj, l, r, b, t, m_fNear, m_fFar );
  842. }
  843. m_pd3dDevice->SetTransform( D3DTS_PROJECTION , &matProj );
  844. // Make elapsed time be zero unless time has really advanced since
  845. // the last call, so things don't move faster in multimon situations.
  846. // The right way to do this would be to separate the animation code from
  847. // the rendering code.
  848. FLOAT fElapsedTime;
  849. static FLOAT s_fTimeLast = 0.0f;
  850. if( m_fTime == s_fTimeLast )
  851. fElapsedTime = 0.0f;
  852. else
  853. fElapsedTime = m_fElapsedTime;
  854. s_fTimeLast = m_fTime;
  855. // Begin the scene
  856. if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  857. {
  858. ::m_pd3dDevice = m_pd3dDevice;
  859. ::m_pIB = m_pDeviceObjects->m_pIB;
  860. ::m_pVB = m_pDeviceObjects->m_pVB;
  861. ::m_pVB2 = m_pDeviceObjects->m_pVB2;
  862. updateSceneFunc( UpdateFlags, fElapsedTime );
  863. // End the scene.
  864. m_pd3dDevice->EndScene();
  865. }
  866. return S_OK;
  867. }
  868. //-----------------------------------------------------------------------------
  869. // Name: SetDevice()
  870. // Desc:
  871. //-----------------------------------------------------------------------------
  872. VOID CFlyingObjectsScreensaver::SetDevice( UINT iDevice )
  873. {
  874. m_pDeviceObjects = &m_DeviceObjectsArray[iDevice];
  875. g_pDeviceObjects = m_pDeviceObjects;
  876. INT iMonitor = m_RenderUnits[iDevice].iMonitor;
  877. g_xScreenOrigin = m_Monitors[iMonitor].rcScreen.left;
  878. g_yScreenOrigin = m_Monitors[iMonitor].rcScreen.top;
  879. g_iDevice = iDevice;
  880. }
  881. //-----------------------------------------------------------------------------
  882. // Name: LoadTextureFromResource()
  883. // Desc:
  884. //-----------------------------------------------------------------------------
  885. HRESULT LoadTextureFromResource( LPDIRECT3DDEVICE8 pd3dDevice,
  886. TCHAR* strRes, TCHAR* strResType, LPDIRECT3DTEXTURE8* ppTex )
  887. {
  888. HRESULT hr;
  889. HMODULE hModule = NULL;
  890. HRSRC rsrc;
  891. HGLOBAL hgData;
  892. LPVOID pvData;
  893. DWORD cbData;
  894. rsrc = FindResource( hModule, strRes, strResType );
  895. if( rsrc != NULL )
  896. {
  897. cbData = SizeofResource( hModule, rsrc );
  898. if( cbData > 0 )
  899. {
  900. hgData = LoadResource( hModule, rsrc );
  901. if( hgData != NULL )
  902. {
  903. pvData = LockResource( hgData );
  904. if( pvData != NULL )
  905. {
  906. if( FAILED( hr = D3DXCreateTextureFromFileInMemory( pd3dDevice,
  907. pvData, cbData, ppTex ) ) )
  908. {
  909. return hr;
  910. }
  911. }
  912. }
  913. }
  914. }
  915. if( *ppTex == NULL)
  916. return E_FAIL;
  917. return S_OK;
  918. }
  919. //-----------------------------------------------------------------------------
  920. // Name: RestoreDeviceObjects()
  921. // Desc:
  922. //-----------------------------------------------------------------------------
  923. HRESULT CFlyingObjectsScreensaver::RestoreDeviceObjects()
  924. {
  925. if( m_pd3dDevice == NULL )
  926. return S_OK;
  927. ::m_pd3dDevice = m_pd3dDevice;
  928. /*
  929. D3DLIGHT8 light;
  930. D3DUtil_InitLight( light, D3DLIGHT_POINT, 2.0, 2.0, 10.0 );
  931. light.Specular.r = 1.0f;
  932. light.Specular.g = 1.0f;
  933. light.Specular.b = 1.0f;
  934. light.Specular.a = 1.0f;
  935. light.Attenuation0 = 1.0f;
  936. m_pd3dDevice->SetLight(0, &light);
  937. m_pd3dDevice->LightEnable(0, TRUE);
  938. */
  939. // Set some basic renderstates
  940. m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE , TRUE );
  941. m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , TRUE );
  942. m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR(0x20202020) );
  943. /* if( config.two_sided == GL_FRONT_AND_BACK )
  944. m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  945. else
  946. m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
  947. */
  948. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG1 );
  949. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_DIFFUSE );
  950. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE );
  951. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
  952. m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_COLOROP , D3DTOP_DISABLE );
  953. m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
  954. D3DMATERIAL8 mtrl;
  955. ZeroMemory( &mtrl, sizeof(mtrl) );
  956. mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
  957. mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
  958. mtrl.Diffuse.b = mtrl.Ambient.b = 1.0f;
  959. mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
  960. m_pd3dDevice->SetMaterial(&mtrl);
  961. if( !_3dfo_Init(NULL) )
  962. return E_FAIL;
  963. if( Type == 6 )
  964. {
  965. if( FAILED( D3DXCreateTextureFromFile( m_pd3dDevice, gTexFile.szPathName,
  966. &m_pDeviceObjects->m_pTexture ) ) )
  967. {
  968. LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_DEFTEX), TEXT("JPG"),
  969. &m_pDeviceObjects->m_pTexture );
  970. }
  971. }
  972. else if( Type == 0 )
  973. {
  974. LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDR_FLATFLAG), TEXT("DDS"),
  975. &m_pDeviceObjects->m_pTexture );
  976. LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDR_WINLOGO), TEXT("PNG"),
  977. &m_pDeviceObjects->m_pTexture2 );
  978. }
  979. m_pd3dDevice->SetTexture( 0, m_pDeviceObjects->m_pTexture );
  980. if( FAILED( m_pd3dDevice->CreateIndexBuffer( MAX_INDICES * sizeof(WORD),
  981. D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pDeviceObjects->m_pIB ) ) )
  982. {
  983. return E_FAIL;
  984. }
  985. if( FAILED( m_pd3dDevice->CreateVertexBuffer( MAX_VERTICES * sizeof(MYVERTEX),
  986. D3DUSAGE_WRITEONLY, D3DFVF_MYVERTEX, D3DPOOL_MANAGED, &m_pDeviceObjects->m_pVB ) ) )
  987. {
  988. return E_FAIL;
  989. }
  990. if( FAILED( m_pd3dDevice->CreateVertexBuffer( MAX_VERTICES * sizeof(MYVERTEX2),
  991. D3DUSAGE_WRITEONLY, D3DFVF_MYVERTEX2, D3DPOOL_MANAGED, &m_pDeviceObjects->m_pVB2 ) ) )
  992. {
  993. return E_FAIL;
  994. }
  995. return S_OK;
  996. }
  997. //-----------------------------------------------------------------------------
  998. // Name: InvalidateDeviceObjects()
  999. // Desc:
  1000. //-----------------------------------------------------------------------------
  1001. HRESULT CFlyingObjectsScreensaver::InvalidateDeviceObjects()
  1002. {
  1003. SAFE_RELEASE( m_pDeviceObjects->m_pTexture );
  1004. SAFE_RELEASE( m_pDeviceObjects->m_pTexture2 );
  1005. SAFE_RELEASE( m_pDeviceObjects->m_pIB );
  1006. SAFE_RELEASE( m_pDeviceObjects->m_pVB );
  1007. SAFE_RELEASE( m_pDeviceObjects->m_pVB2 );
  1008. return S_OK;
  1009. }
  1010. //-----------------------------------------------------------------------------
  1011. // Name: ReadSettings()
  1012. // Desc:
  1013. //-----------------------------------------------------------------------------
  1014. VOID CFlyingObjectsScreensaver::ReadSettings()
  1015. {
  1016. int options;
  1017. int optMask = 1;
  1018. int tessel=0;
  1019. // Read OpenGL settings first, so OS upgrade cases work
  1020. ss_ReadSettings();
  1021. HKEY hkey;
  1022. if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
  1023. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
  1024. {
  1025. options = bSmoothShading | bColorCycle<<1;
  1026. DXUtil_ReadIntRegKey( hkey, TEXT("Options"), (DWORD*)&options, options );
  1027. if (options >= 0)
  1028. {
  1029. bSmoothShading = ((options & optMask) != 0);
  1030. optMask <<= 1;
  1031. bColorCycle = ((options & optMask) != 0);
  1032. UpdateFlags = (bColorCycle << 1);
  1033. }
  1034. DXUtil_ReadIntRegKey( hkey, TEXT("Type"), (DWORD*)&Type, Type );
  1035. // Sanity check Type. Don't want to index into function arrays
  1036. // with a bad index!
  1037. Type = (int)min(Type, MAX_TYPE);
  1038. // Set flag so that updateStripScene will do two strips instead
  1039. // of one.
  1040. if (Type == 3)
  1041. UpdateFlags |= 0x4;
  1042. tessel = (int) (fTesselFact * 100);
  1043. DXUtil_ReadIntRegKey( hkey, TEXT("Tesselation"), (DWORD*)&tessel, tessel );
  1044. SS_CLAMP_TO_RANGE2( tessel, 0, 200 );
  1045. if (tessel <= 100)
  1046. fTesselFact = (float)tessel / 100.0f;
  1047. else
  1048. fTesselFact = 1.0f + (((float)tessel - 100.0f) / 100.0f);
  1049. DXUtil_ReadIntRegKey( hkey, TEXT("Size"), (DWORD*)&uSize, uSize );
  1050. if (uSize > 100)
  1051. uSize = 100;
  1052. // Static size for new winlogo
  1053. if (Type == 0)
  1054. {
  1055. uSize = 75;
  1056. bSmoothShading = TRUE;
  1057. }
  1058. // SS_CLAMP_TO_RANGE2( uSize, 0, 100 ); /* can't be less than zero since it is a UINT */
  1059. // Is there a texture specified in the registry that overrides the
  1060. // default?
  1061. DXUtil_ReadStringRegKey( hkey, TEXT("Texture"), (TCHAR*)&gTexFile.szPathName,
  1062. MAX_PATH, gTexFile.szPathName );
  1063. DXUtil_ReadIntRegKey( hkey, TEXT("TextureFileOffset"), (DWORD*)&gTexFile.nOffset, gTexFile.nOffset );
  1064. ReadScreenSettings( hkey );
  1065. RegCloseKey( hkey );
  1066. }
  1067. }
  1068. //-----------------------------------------------------------------------------
  1069. // Name: ss_ReadSettings()
  1070. // Desc:
  1071. //-----------------------------------------------------------------------------
  1072. VOID CFlyingObjectsScreensaver::ss_ReadSettings()
  1073. {
  1074. int options;
  1075. int optMask = 1;
  1076. TCHAR szDefaultBitmap[MAX_PATH];
  1077. int tessel=0;
  1078. if( ss_RegistrySetup( IDS_SAVERNAME, IDS_INIFILE ) )
  1079. {
  1080. options = ss_GetRegistryInt( IDS_OPTIONS, -1 );
  1081. if (options >= 0)
  1082. {
  1083. bSmoothShading = ((options & optMask) != 0);
  1084. optMask <<= 1;
  1085. bColorCycle = ((options & optMask) != 0);
  1086. UpdateFlags = (bColorCycle << 1);
  1087. }
  1088. Type = ss_GetRegistryInt( IDS_OBJTYPE, 0 );
  1089. // Sanity check Type. Don't want to index into function arrays
  1090. // with a bad index!
  1091. Type = (int)min(Type, MAX_TYPE);
  1092. // Set flag so that updateStripScene will do two strips instead
  1093. // of one.
  1094. if (Type == 3)
  1095. UpdateFlags |= 0x4;
  1096. tessel = ss_GetRegistryInt( IDS_TESSELATION, 100 );
  1097. SS_CLAMP_TO_RANGE2( tessel, 0, 200 );
  1098. if (tessel <= 100)
  1099. fTesselFact = (float)tessel / 100.0f;
  1100. else
  1101. fTesselFact = 1.0f + (((float)tessel - 100.0f) / 100.0f);
  1102. uSize = ss_GetRegistryInt( IDS_SIZE, 50 );
  1103. if (uSize > 100)
  1104. uSize = 100;
  1105. // SS_CLAMP_TO_RANGE2( uSize, 0, 100 ); /* can't be less than zero since it is a UINT */
  1106. // Determine the default .bmp file
  1107. ss_GetDefaultBmpFile( szDefaultBitmap );
  1108. // Is there a texture specified in the registry that overrides the
  1109. // default?
  1110. ss_GetRegistryString( IDS_TEXTURE, szDefaultBitmap, gTexFile.szPathName,
  1111. MAX_PATH);
  1112. gTexFile.nOffset = ss_GetRegistryInt( IDS_TEXTURE_FILE_OFFSET, 0 );
  1113. }
  1114. }
  1115. //-----------------------------------------------------------------------------
  1116. // Name: ss_GetRegistryString()
  1117. // Desc:
  1118. //-----------------------------------------------------------------------------
  1119. BOOL CFlyingObjectsScreensaver::ss_RegistrySetup( int section, int file )
  1120. {
  1121. if( LoadString(m_hInstance, section, g_szSectName, BUF_SIZE) &&
  1122. LoadString(m_hInstance, file, g_szFname, BUF_SIZE) )
  1123. {
  1124. TCHAR pBuffer[100];
  1125. DWORD dwRealSize = GetPrivateProfileSection( g_szSectName, pBuffer, 100, g_szFname );
  1126. if( dwRealSize > 0 )
  1127. return TRUE;
  1128. }
  1129. return FALSE;
  1130. }
  1131. //-----------------------------------------------------------------------------
  1132. // Name: ss_GetRegistryString()
  1133. // Desc:
  1134. //-----------------------------------------------------------------------------
  1135. int CFlyingObjectsScreensaver::ss_GetRegistryInt( int name, int iDefault )
  1136. {
  1137. TCHAR szItemName[BUF_SIZE];
  1138. if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) )
  1139. return GetPrivateProfileInt(g_szSectName, szItemName, iDefault, g_szFname);
  1140. return 0;
  1141. }
  1142. //-----------------------------------------------------------------------------
  1143. // Name: ss_GetRegistryString()
  1144. // Desc:
  1145. //-----------------------------------------------------------------------------
  1146. VOID CFlyingObjectsScreensaver::ss_GetRegistryString( int name, LPTSTR lpDefault,
  1147. LPTSTR lpDest, int bufSize )
  1148. {
  1149. TCHAR szItemName[BUF_SIZE];
  1150. if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) )
  1151. GetPrivateProfileString(g_szSectName, szItemName, lpDefault, lpDest,
  1152. bufSize, g_szFname);
  1153. return;
  1154. }
  1155. //-----------------------------------------------------------------------------
  1156. // Name: DoConfig()
  1157. // Desc:
  1158. //-----------------------------------------------------------------------------
  1159. VOID CFlyingObjectsScreensaver::DoConfig()
  1160. {
  1161. if( IDOK == DialogBox( NULL, MAKEINTRESOURCE( DLG_SCRNSAVECONFIGURE ),
  1162. m_hWndParent, (DLGPROC)ScreenSaverConfigureDialog ) )
  1163. {
  1164. }
  1165. }
  1166. //-----------------------------------------------------------------------------
  1167. // Name: ConfirmDevice()
  1168. // Desc:
  1169. //-----------------------------------------------------------------------------
  1170. HRESULT CFlyingObjectsScreensaver::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior,
  1171. D3DFORMAT fmtBackBuffer)
  1172. {
  1173. if( dwBehavior & D3DCREATE_PUREDEVICE )
  1174. return E_FAIL;
  1175. return S_OK;
  1176. }