Windows NT 4.0 source code leak
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.

628 lines
18 KiB

4 years ago
  1. /******************************Module*Header*******************************\
  2. * Module Name: ss3dfo.c
  3. *
  4. * Dispatcher and dialog box for the OpenGL-based 3D Flying Objects screen
  5. * saver.
  6. *
  7. * Created: 18-May-1994 14:54:59
  8. *
  9. * Copyright (c) 1994 Microsoft Corporation
  10. \**************************************************************************/
  11. #include <windows.h>
  12. #include <scrnsave.h>
  13. #include <GL\gl.h>
  14. #include <math.h>
  15. #include <memory.h>
  16. #include <string.h>
  17. #include <stdarg.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <malloc.h>
  21. #include <sys\timeb.h>
  22. #include <time.h>
  23. #include <commdlg.h>
  24. #include <commctrl.h>
  25. #include "ss3dfo.h"
  26. //#define SS_DEBUG 1
  27. // Global strings.
  28. #define GEN_STRING_SIZE 64
  29. static SSContext gssc;
  30. BOOL gbBounce = FALSE; // floating window bounce off side
  31. // Global message loop variables.
  32. MATERIAL Material[16];
  33. #ifdef MEMDEBUG
  34. ULONG totalMem = 0;
  35. #endif
  36. // Global screen saver settings.
  37. void (*updateSceneFunc)(int); // current screen saver update function
  38. void (*delSceneFunc)(void); // current screen saver deletion function
  39. BOOL bColorCycle = FALSE; // color cycling flag
  40. BOOL bSmoothShading = TRUE; // smooth shading flag
  41. UINT uSize = 100; // object size
  42. float fTesselFact = 1.0f; // object tessalation
  43. int UpdateFlags = 0; // extra data sent to update function
  44. int Type = 0; // screen saver index (into function arrays)
  45. // Texture file information
  46. TEXFILE gTexFile = {0};
  47. // Lighting properties.
  48. static const RGBA lightAmbient = {0.21f, 0.21f, 0.21f, 1.0f};
  49. static const RGBA light0Ambient = {0.0f, 0.0f, 0.0f, 1.0f};
  50. static const RGBA light0Diffuse = {0.7f, 0.7f, 0.7f, 1.0f};
  51. static const RGBA light0Specular = {1.0f, 1.0f, 1.0f, 1.0f};
  52. static const GLfloat light0Pos[] = {100.0f, 100.0f, 100.0f, 0.0f};
  53. // Material properties.
  54. static RGBA matlColors[7] = {{1.0f, 0.0f, 0.0f, 1.0f},
  55. {0.0f, 1.0f, 0.0f, 1.0f},
  56. {0.0f, 0.0f, 1.0f, 1.0f},
  57. {1.0f, 1.0f, 0.0f, 1.0f},
  58. {0.0f, 1.0f, 1.0f, 1.0f},
  59. {1.0f, 0.0f, 1.0f, 1.0f},
  60. {0.235f, 0.0f, 0.78f, 1.0f},
  61. };
  62. extern void updateStripScene(int);
  63. extern void updateDropScene(int);
  64. extern void updateLemScene(int);
  65. extern void updateExplodeScene(int);
  66. extern void updateWinScene(int);
  67. extern void updateTexScene(int);
  68. extern void initStripScene(void);
  69. extern void initDropScene(void);
  70. extern void initLemScene(void);
  71. extern void initExplodeScene(void);
  72. extern void initWinScene(void);
  73. extern void initTexScene(void);
  74. extern void delStripScene(void);
  75. extern void delDropScene(void);
  76. extern void delLemScene(void);
  77. extern void delExplodeScene(void);
  78. extern void delWinScene(void);
  79. extern void delTexScene(void);
  80. typedef void (*PTRUPDATE)(int);
  81. typedef void (*ptrdel)();
  82. typedef void (*ptrinit)();
  83. // Each screen saver style puts its hook functions into the function
  84. // arrays below. A consistent ordering of the functions is required.
  85. static PTRUPDATE updateFuncs[] =
  86. {updateWinScene, updateExplodeScene,updateStripScene, updateStripScene,
  87. updateDropScene, updateLemScene, updateTexScene};
  88. static ptrdel delFuncs[] =
  89. {delWinScene, delExplodeScene, delStripScene, delStripScene,
  90. delDropScene, delLemScene, delTexScene};
  91. static ptrinit initFuncs[] =
  92. {initWinScene, initExplodeScene, initStripScene, initStripScene,
  93. initDropScene, initLemScene, initTexScene};
  94. static int idsStyles[] =
  95. {IDS_LOGO, IDS_EXPLODE, IDS_RIBBON, IDS_2RIBBON,
  96. IDS_SPLASH, IDS_TWIST, IDS_FLAG};
  97. #define MAX_TYPE ( sizeof(initFuncs) / sizeof(ptrinit) - 1 )
  98. // Each screen saver style can choose which dialog box controls it wants
  99. // to use. These flags enable each of the controls. Controls not choosen
  100. // will be disabled.
  101. #define OPT_COLOR_CYCLE 0x00000001
  102. #define OPT_SMOOTH_SHADE 0x00000002
  103. #define OPT_TESSEL 0x00000008
  104. #define OPT_SIZE 0x00000010
  105. #define OPT_TEXTURE 0x00000020
  106. #define OPT_STD ( OPT_COLOR_CYCLE | OPT_SMOOTH_SHADE | OPT_TESSEL | OPT_SIZE )
  107. static ULONG gflConfigOpt[] = {
  108. OPT_STD, // Windows logo
  109. OPT_STD, // Explode
  110. OPT_STD, // Strip
  111. OPT_STD, // Strip
  112. OPT_STD, // Drop
  113. OPT_STD, // Twist (lemniscate)
  114. OPT_SMOOTH_SHADE | OPT_TESSEL | OPT_SIZE | OPT_TEXTURE // Texture mapped flag
  115. };
  116. static void updateDialogControls(HWND hDlg);
  117. #ifdef MEMDEBUG
  118. void xprintf(char *str, ...)
  119. {
  120. va_list ap;
  121. char buffer[256];
  122. va_start(ap, str);
  123. vsprintf(buffer, str, ap);
  124. OutputDebugString(buffer);
  125. va_end(ap);
  126. }
  127. #endif
  128. void *SaverAlloc(ULONG size)
  129. {
  130. void *mPtr;
  131. mPtr = malloc(size);
  132. #ifdef MEMDEBUG
  133. totalMem += size;
  134. xprintf("malloc'd %x, size %d\n", mPtr, size);
  135. #endif
  136. return mPtr;
  137. }
  138. void SaverFree(void *pMem)
  139. {
  140. #ifdef MEMDEBUG
  141. totalMem -= _msize(pMem);
  142. xprintf("free %x, size = %d, total = %d\n", pMem, _msize(pMem), totalMem);
  143. #endif
  144. free(pMem);
  145. }
  146. /******************************Public*Routine******************************\
  147. * getIniSettings
  148. *
  149. * Get the screen saver configuration options from .INI file/registry.
  150. *
  151. * History:
  152. * 10-May-1994 -by- Gilman Wong [gilmanw]
  153. * Wrote it.
  154. \**************************************************************************/
  155. static void getIniSettings()
  156. {
  157. int options;
  158. int optMask = 1;
  159. TCHAR szDefaultBitmap[MAX_PATH];
  160. int tessel=0;
  161. LPTSTR psz;
  162. LoadString(hMainInstance, IDS_GENNAME, szScreenSaver, sizeof(szScreenSaver) / sizeof(TCHAR));
  163. if( ss_RegistrySetup( hMainInstance, IDS_SAVERNAME, IDS_INIFILE ) )
  164. {
  165. options = ss_GetRegistryInt( IDS_OPTIONS, -1 );
  166. if (options >= 0)
  167. {
  168. bSmoothShading = ((options & optMask) != 0);
  169. optMask <<= 1;
  170. bColorCycle = ((options & optMask) != 0);
  171. UpdateFlags = (bColorCycle << 1);
  172. }
  173. Type = ss_GetRegistryInt( IDS_OBJTYPE, 0 );
  174. // Sanity check Type. Don't want to index into function arrays
  175. // with a bad index!
  176. Type = min(Type, MAX_TYPE);
  177. // Set flag so that updateStripScene will do two strips instead
  178. // of one.
  179. if (Type == 3)
  180. UpdateFlags |= 0x4;
  181. tessel = ss_GetRegistryInt( IDS_TESSELATION, 100 );
  182. SS_CLAMP_TO_RANGE2( tessel, 0, 200 );
  183. if (tessel <= 100)
  184. fTesselFact = (float)tessel / 100.0f;
  185. else
  186. fTesselFact = 1.0f + (((float)tessel - 100.0f) / 100.0f);
  187. uSize = ss_GetRegistryInt( IDS_SIZE, 50 );
  188. SS_CLAMP_TO_RANGE2( uSize, 0, 100 );
  189. // Determine the default .bmp file
  190. ss_GetDefaultBmpFile( szDefaultBitmap );
  191. // Is there a texture specified in the registry that overrides the
  192. // default?
  193. ss_GetRegistryString( IDS_TEXTURE, szDefaultBitmap, gTexFile.szPathName,
  194. MAX_PATH);
  195. gTexFile.nOffset = ss_GetRegistryInt( IDS_TEXTURE_FILE_OFFSET, 0 );
  196. }
  197. }
  198. /******************************Public*Routine******************************\
  199. * saveIniSettings
  200. *
  201. * Save the screen saver configuration option to the .INI file/registry.
  202. *
  203. * History:
  204. * 10-May-1994 -by- Gilman Wong [gilmanw]
  205. * Wrote it.
  206. \**************************************************************************/
  207. static void saveIniSettings(HWND hDlg)
  208. {
  209. if( ss_RegistrySetup( hMainInstance, IDS_SAVERNAME, IDS_INIFILE ) )
  210. {
  211. int pos, options;
  212. int optMask = 1;
  213. bSmoothShading = IsDlgButtonChecked(hDlg, DLG_SETUP_SMOOTH);
  214. bColorCycle = IsDlgButtonChecked(hDlg, DLG_SETUP_CYCLE);
  215. options = bColorCycle;
  216. options <<= 1;
  217. options |= bSmoothShading;
  218. ss_WriteRegistryInt( IDS_OPTIONS, options );
  219. Type = SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_GETCURSEL,
  220. 0, 0);
  221. ss_WriteRegistryInt( IDS_OBJTYPE, Type );
  222. pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_TESSEL );
  223. ss_WriteRegistryInt( IDS_TESSELATION, pos );
  224. pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_SIZE );
  225. ss_WriteRegistryInt( IDS_SIZE, pos );
  226. ss_WriteRegistryString( IDS_TEXTURE, gTexFile.szPathName );
  227. ss_WriteRegistryInt( IDS_TEXTURE_FILE_OFFSET, gTexFile.nOffset );
  228. }
  229. }
  230. /******************************Public*Routine******************************\
  231. * setupDialogControls
  232. *
  233. * Setup the dialog controls initially.
  234. *
  235. \**************************************************************************/
  236. static void
  237. setupDialogControls(HWND hDlg)
  238. {
  239. int pos;
  240. InitCommonControls();
  241. if ( gflConfigOpt[Type] & OPT_TESSEL )
  242. {
  243. if (fTesselFact <= 1.0f)
  244. pos = (int)(fTesselFact * 100.0f);
  245. else
  246. pos = 100 + (int) ((fTesselFact - 1.0f) * 100.0f);
  247. ss_SetupTrackbar( hDlg, DLG_SETUP_TESSEL, 0, 200, 1, 10, pos );
  248. }
  249. if ( gflConfigOpt[Type] & OPT_SIZE )
  250. {
  251. ss_SetupTrackbar( hDlg, DLG_SETUP_SIZE, 0, 100, 1, 10, uSize );
  252. }
  253. updateDialogControls( hDlg );
  254. }
  255. /******************************Public*Routine******************************\
  256. * updateDialogControls
  257. *
  258. * Update the dialog controls based on the current global state.
  259. *
  260. \**************************************************************************/
  261. static void
  262. updateDialogControls(HWND hDlg)
  263. {
  264. CheckDlgButton(hDlg, DLG_SETUP_SMOOTH, bSmoothShading);
  265. CheckDlgButton(hDlg, DLG_SETUP_CYCLE, bColorCycle);
  266. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_SMOOTH),
  267. gflConfigOpt[Type] & OPT_SMOOTH_SHADE );
  268. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_CYCLE),
  269. gflConfigOpt[Type] & OPT_COLOR_CYCLE );
  270. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_TESSEL),
  271. gflConfigOpt[Type] & OPT_TESSEL);
  272. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS),
  273. gflConfigOpt[Type] & OPT_TESSEL);
  274. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS_MIN),
  275. gflConfigOpt[Type] & OPT_TESSEL);
  276. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS_MAX),
  277. gflConfigOpt[Type] & OPT_TESSEL);
  278. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_SIZE),
  279. gflConfigOpt[Type] & OPT_SIZE);
  280. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE),
  281. gflConfigOpt[Type] & OPT_SIZE);
  282. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE_MIN),
  283. gflConfigOpt[Type] & OPT_SIZE);
  284. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE_MAX),
  285. gflConfigOpt[Type] & OPT_SIZE);
  286. EnableWindow(GetDlgItem(hDlg, DLG_SETUP_TEXTURE),
  287. gflConfigOpt[Type] & OPT_TEXTURE);
  288. }
  289. BOOL WINAPI RegisterDialogClasses(HANDLE hinst)
  290. {
  291. return TRUE;
  292. }
  293. /******************************Public*Routine******************************\
  294. * ScreenSaverConfigureDialog
  295. *
  296. * Processes messages for the configuration dialog box.
  297. *
  298. \**************************************************************************/
  299. BOOL ScreenSaverConfigureDialog(HWND hDlg, UINT message,
  300. WPARAM wParam, LPARAM lParam)
  301. {
  302. int wTmp;
  303. TCHAR szString[GEN_STRING_SIZE];
  304. switch (message) {
  305. case WM_INITDIALOG:
  306. getIniSettings();
  307. setupDialogControls(hDlg);
  308. for (wTmp = 0; wTmp <= MAX_TYPE; wTmp++) {
  309. LoadString(hMainInstance, idsStyles[wTmp], szString, GEN_STRING_SIZE);
  310. SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_ADDSTRING, 0,
  311. (LPARAM) szString);
  312. }
  313. SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_SETCURSEL, Type, 0);
  314. return TRUE;
  315. case WM_COMMAND:
  316. switch (LOWORD(wParam)) {
  317. case DLG_SETUP_TYPES:
  318. switch (HIWORD(wParam))
  319. {
  320. case CBN_EDITCHANGE:
  321. case CBN_SELCHANGE:
  322. Type = SendDlgItemMessage(hDlg, DLG_SETUP_TYPES,
  323. CB_GETCURSEL, 0, 0);
  324. updateDialogControls(hDlg);
  325. break;
  326. default:
  327. break;
  328. }
  329. return FALSE;
  330. case DLG_SETUP_TEXTURE:
  331. ss_SelectTextureFile( hDlg, &gTexFile );
  332. break;
  333. case IDOK:
  334. saveIniSettings(hDlg);
  335. EndDialog(hDlg, TRUE);
  336. break;
  337. case IDCANCEL:
  338. EndDialog(hDlg, FALSE);
  339. break;
  340. case DLG_SETUP_SMOOTH:
  341. case DLG_SETUP_CYCLE:
  342. default:
  343. break;
  344. }
  345. return TRUE;
  346. break;
  347. default:
  348. return 0;
  349. }
  350. return 0;
  351. }
  352. /******************************Public*Routine******************************\
  353. * SetFloaterInfo
  354. *
  355. * Set the size and motion of the floating window
  356. * It stays square in shape
  357. *
  358. \**************************************************************************/
  359. static void
  360. SetFloaterInfo( ISIZE *pParentSize, CHILD_INFO *pChild )
  361. {
  362. float sizeFact;
  363. float sizeScale;
  364. int size;
  365. ISIZE *pChildSize = &pChild->size;
  366. MOTION_INFO *pMotion = &pChild->motionInfo;
  367. sizeScale = (float)uSize / 100.0f; // 0..1
  368. sizeFact = 0.25f + (0.30f * sizeScale);
  369. size = (int) (sizeFact * ( ((float)(pParentSize->width + pParentSize->height)) / 2.0f ));
  370. SS_CLAMP_TO_RANGE2( size, 0, pParentSize->width );
  371. SS_CLAMP_TO_RANGE2( size, 0, pParentSize->height );
  372. pChildSize->width = pChildSize->height = size;
  373. // Floater motion
  374. pMotion->posInc.x = .01f * (float) size;
  375. if( pMotion->posInc.x < 1.0f )
  376. pMotion->posInc.x = 1.0f;
  377. pMotion->posInc.y = pMotion->posInc.x;
  378. pMotion->posIncVary.x = .4f * pMotion->posInc.x;
  379. pMotion->posIncVary.y = pMotion->posIncVary.x;
  380. }
  381. /******************************Public*Routine******************************\
  382. * initMaterial
  383. *
  384. * Initialize the material properties.
  385. *
  386. \**************************************************************************/
  387. void initMaterial(int id, float r, float g, float b, float a)
  388. {
  389. Material[id].ka.r = r;
  390. Material[id].ka.g = g;
  391. Material[id].ka.b = b;
  392. Material[id].ka.a = a;
  393. Material[id].kd.r = r;
  394. Material[id].kd.g = g;
  395. Material[id].kd.b = b;
  396. Material[id].kd.a = a;
  397. Material[id].ks.r = 1.0f;
  398. Material[id].ks.g = 1.0f;
  399. Material[id].ks.b = 1.0f;
  400. Material[id].ks.a = 1.0f;
  401. Material[id].specExp = 128.0f;
  402. }
  403. /******************************Public*Routine******************************\
  404. * _3dfo_Init
  405. *
  406. \**************************************************************************/
  407. static void
  408. _3dfo_Init(void *data)
  409. {
  410. int i;
  411. for (i = 0; i < 7; i++)
  412. initMaterial(i, matlColors[i].r, matlColors[i].g,
  413. matlColors[i].b, matlColors[i].a);
  414. // Set the OpenGL clear color to black.
  415. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  416. #ifdef SS_DEBUG
  417. glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
  418. #endif
  419. // Enable the z-buffer.
  420. glEnable(GL_DEPTH_TEST);
  421. // Select the shading model.
  422. if (bSmoothShading)
  423. glShadeModel(GL_SMOOTH);
  424. else
  425. glShadeModel(GL_FLAT);
  426. // Setup the OpenGL matrices.
  427. glMatrixMode(GL_PROJECTION);
  428. glLoadIdentity();
  429. glMatrixMode(GL_MODELVIEW);
  430. glLoadIdentity();
  431. // Setup the lighting.
  432. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (GLfloat *) &lightAmbient);
  433. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  434. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
  435. glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat *) &light0Ambient);
  436. glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat *) &light0Diffuse);
  437. glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat *) &light0Specular);
  438. glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  439. glEnable(GL_LIGHTING);
  440. glEnable(GL_LIGHT0);
  441. // Setup the material properties.
  442. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *) &Material[0].ks);
  443. glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (GLfloat *) &Material[0].specExp);
  444. // call specific objects init func
  445. (*initFuncs[Type])();
  446. updateSceneFunc = updateFuncs[Type];
  447. }
  448. /******************************Public*Routine******************************\
  449. * _3dfo_Draw
  450. *
  451. \**************************************************************************/
  452. static void
  453. _3dfo_Draw(void *data)
  454. {
  455. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  456. (*updateSceneFunc)(UpdateFlags);
  457. }
  458. /******************************Public*Routine******************************\
  459. * _3dfo_FloaterBounce
  460. *
  461. \**************************************************************************/
  462. static void
  463. _3dfo_FloaterBounce(void *data)
  464. {
  465. gbBounce = TRUE;
  466. }
  467. /******************************Public*Routine******************************\
  468. * ss_Init
  469. *
  470. * Screen saver entry point. Pre-GL initialization
  471. *
  472. \**************************************************************************/
  473. SSContext *
  474. ss_Init(void)
  475. {
  476. getIniSettings();
  477. // Make sure the selected texture file is OK.
  478. if ( gflConfigOpt[Type] & OPT_TEXTURE )
  479. {
  480. // Verify texture file
  481. ss_DisableTextureErrorMsgs();
  482. ss_VerifyTextureFile( &gTexFile );
  483. }
  484. // set callbacks
  485. ss_InitFunc( _3dfo_Init );
  486. ss_UpdateFunc( _3dfo_Draw );
  487. // set configuration info to return
  488. gssc.bDoubleBuf = TRUE;
  489. gssc.depthType = SS_DEPTH16;
  490. gssc.bFloater = TRUE;
  491. gssc.floaterInfo.bMotion = TRUE;
  492. gssc.floaterInfo.ChildSizeFunc = SetFloaterInfo;
  493. ss_FloaterBounceFunc( _3dfo_FloaterBounce );
  494. return &gssc;
  495. }
  496. /**************************************************************************\
  497. * ConfigInit
  498. *
  499. * Dialog box version of ss_Init. Used for setting up any gl drawing on the
  500. * dialog.
  501. *
  502. \**************************************************************************/
  503. BOOL
  504. ss_ConfigInit( HWND hDlg )
  505. {
  506. return TRUE;
  507. }