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.

1373 lines
48 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: Text3D.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 <d3d8.h>
  10. #include <d3dx8.h>
  11. #include <d3dsaver.h>
  12. #include <d3d8rgbrast.h>
  13. #include <time.h>
  14. #include <commdlg.h>
  15. #include <commctrl.h>
  16. #include "Text3D.h"
  17. #include "Resource.h"
  18. #include "dxutil.h"
  19. CTextScreensaver* g_pMyTextScreensaver = NULL;
  20. #define BUF_SIZE 255
  21. TCHAR g_szSectName[BUF_SIZE];
  22. TCHAR g_szFname[BUF_SIZE];
  23. //-----------------------------------------------------------------------------
  24. // Name: WinMain()
  25. // Desc: Entry point to the program. Initializes everything, and goes into a
  26. // message-processing loop. Idle time is used to render the scene.
  27. //-----------------------------------------------------------------------------
  28. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  29. {
  30. HRESULT hr;
  31. CTextScreensaver textSS;
  32. if( FAILED( hr = textSS.Create( hInst ) ) )
  33. {
  34. textSS.DisplayErrorMsg( hr );
  35. return 0;
  36. }
  37. return textSS.Run();
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Name: LoadTextureFromResource()
  41. // Desc:
  42. //-----------------------------------------------------------------------------
  43. HRESULT LoadTextureFromResource( LPDIRECT3DDEVICE8 pd3dDevice,
  44. TCHAR* strRes, TCHAR* strResType, LPDIRECT3DTEXTURE8* ppTex )
  45. {
  46. HRESULT hr;
  47. HMODULE hModule = NULL;
  48. HRSRC rsrc;
  49. HGLOBAL hgData;
  50. LPVOID pvData;
  51. DWORD cbData;
  52. rsrc = FindResource( hModule, strRes, strResType );
  53. if( rsrc != NULL )
  54. {
  55. cbData = SizeofResource( hModule, rsrc );
  56. if( cbData > 0 )
  57. {
  58. hgData = LoadResource( hModule, rsrc );
  59. if( hgData != NULL )
  60. {
  61. pvData = LockResource( hgData );
  62. if( pvData != NULL )
  63. {
  64. if( FAILED( hr = D3DXCreateTextureFromFileInMemory( pd3dDevice,
  65. pvData, cbData, ppTex ) ) )
  66. {
  67. return hr;
  68. }
  69. }
  70. }
  71. }
  72. }
  73. if( *ppTex == NULL)
  74. return E_FAIL;
  75. return S_OK;
  76. }
  77. //-----------------------------------------------------------------------------
  78. // Name: CTextScreensaver()
  79. // Desc: Constructor
  80. //-----------------------------------------------------------------------------
  81. CTextScreensaver::CTextScreensaver()
  82. {
  83. g_pMyTextScreensaver = this;
  84. LoadString( NULL, IDS_DESCRIPTION, m_strWindowTitle, 200 );
  85. InitCommonControls();
  86. ZeroMemory( m_DeviceObjects, sizeof(m_DeviceObjects) );
  87. m_hFont = NULL;
  88. m_bUseDepthBuffer = TRUE;
  89. m_dwMinDepthBits = 16;
  90. m_floatrect.xSize = 0.0f;
  91. lstrcpy( m_strRegPath, TEXT("Software\\Microsoft\\Screensavers\\Text3D") );
  92. m_fAngleX = 0.0f;
  93. m_fAngleY = 0.0f;
  94. m_fAngleZ = 0.0f;
  95. m_dwMeshUpdateCounter = 0;
  96. srand((UINT)time(NULL)); // seed random number generator
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Name: RegisterSoftwareDevice()
  100. // Desc: This can register the D3D8RGBRasterizer or any other
  101. // pluggable software rasterizer.
  102. //-----------------------------------------------------------------------------
  103. HRESULT CTextScreensaver::RegisterSoftwareDevice()
  104. {
  105. m_pD3D->RegisterSoftwareDevice( D3D8RGBRasterizer );
  106. return S_OK;
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Name: FrameMove()
  110. // Desc: Called once per frame, the call is the entry point for animating
  111. // the scene.
  112. //-----------------------------------------------------------------------------
  113. HRESULT CTextScreensaver::FrameMove()
  114. {
  115. DWORD tick = GetTickCount();
  116. DWORD elapsed = tick - m_dwLastTick;
  117. m_dwLastTick = tick;
  118. // update floatrect
  119. RECT rcBounceBounds;
  120. if( m_floatrect.xSize == 0.0f )
  121. {
  122. // Initialize floatrect
  123. RECT rcBounds;
  124. DWORD dwParentWidth;
  125. DWORD dwParentHeight;
  126. rcBounds = m_rcRenderTotal;
  127. dwParentWidth = rcBounds.right - rcBounds.left;
  128. dwParentHeight = rcBounds.bottom - rcBounds.top;
  129. FLOAT sizeFact;
  130. FLOAT sizeScale;
  131. DWORD size;
  132. sizeScale = m_dwSize / 10.0f;
  133. sizeFact = 0.25f + (0.75f * sizeScale); // range 25-100%
  134. size = (DWORD) (sizeFact * ( dwParentWidth > dwParentHeight ? dwParentHeight : dwParentWidth ) );
  135. if( size > dwParentWidth )
  136. size = dwParentWidth;
  137. if( size > dwParentHeight )
  138. size = dwParentHeight;
  139. // Start floatrect centered on first RenderUnit's screen
  140. if( !m_bWindowed )
  141. {
  142. INT iMonitor = m_RenderUnits[0].iMonitor;
  143. rcBounds = m_Monitors[iMonitor].rcScreen;
  144. }
  145. m_floatrect.xMin = rcBounds.left + ((rcBounds.right - rcBounds.left) - size) / 2.0f;
  146. m_floatrect.yMin = rcBounds.top + ((rcBounds.bottom - rcBounds.top) - size) / 2.0f;
  147. m_floatrect.xSize = (FLOAT)size;
  148. m_floatrect.ySize = (FLOAT)size;
  149. m_floatrect.xVel = 0.01f * (FLOAT) size;
  150. if( rand() % 2 == 0 )
  151. m_floatrect.xVel = -m_floatrect.xVel;
  152. m_floatrect.yVel = 0.01f * (FLOAT) size;
  153. if( rand() % 2 == 0 )
  154. m_floatrect.yVel = -m_floatrect.yVel;
  155. }
  156. rcBounceBounds = m_rcRenderTotal;
  157. FLOAT xMinOld = m_floatrect.xMin;
  158. FLOAT yMinOld = m_floatrect.yMin;
  159. m_floatrect.xMin += m_floatrect.xVel * 20.0f * m_fElapsedTime;
  160. m_floatrect.yMin += m_floatrect.yVel * 20.0f * m_fElapsedTime;
  161. if( m_floatrect.xVel < 0 && m_floatrect.xMin < rcBounceBounds.left ||
  162. m_floatrect.xVel > 0 && (m_floatrect.xMin + m_floatrect.xSize) > rcBounceBounds.right )
  163. {
  164. m_floatrect.xMin = xMinOld; // undo last move
  165. m_floatrect.xVel = -m_floatrect.xVel; // change direction
  166. }
  167. if( m_floatrect.yVel < 0 && m_floatrect.yMin < rcBounceBounds.top ||
  168. m_floatrect.yVel > 0 && (m_floatrect.yMin + m_floatrect.ySize) > rcBounceBounds.bottom )
  169. {
  170. m_floatrect.yMin = yMinOld; // undo last move
  171. m_floatrect.yVel = -m_floatrect.yVel; // change direction
  172. }
  173. UpdateAngles( elapsed );
  174. if ( m_bDisplayTime )
  175. {
  176. if ( UpdateTimeString( m_szDisplayString ) )
  177. {
  178. m_dwMeshUpdateCounter++; // provoke a mesh update at render tiem
  179. }
  180. }
  181. return S_OK;
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Name: Render()
  185. // Desc: Called once per frame, the call is the entry point for 3d
  186. // rendering. This function sets up render states, clears the
  187. // viewport, and renders the scene.
  188. //-----------------------------------------------------------------------------
  189. HRESULT CTextScreensaver::Render()
  190. {
  191. D3DVIEWPORT8 vp;
  192. // First, clear the entire back buffer to the background color
  193. vp.X = 0;
  194. vp.Y = 0;
  195. vp.Width = m_rcRenderCurDevice.right - m_rcRenderCurDevice.left;
  196. vp.Height = m_rcRenderCurDevice.bottom - m_rcRenderCurDevice.top;
  197. vp.MinZ = 0.0f;
  198. vp.MaxZ = 1.0f;
  199. m_pd3dDevice->SetViewport( &vp );
  200. m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0L );
  201. // Now determine what part of the floatrect, if any, intersects the current screen
  202. RECT rcFloatThisScreen;
  203. RECT rcFloatThisScreenClipped;
  204. rcFloatThisScreen.left = (INT)m_floatrect.xMin;
  205. rcFloatThisScreen.top = (INT)m_floatrect.yMin;
  206. rcFloatThisScreen.right = rcFloatThisScreen.left + (INT)m_floatrect.xSize;
  207. rcFloatThisScreen.bottom = rcFloatThisScreen.top + (INT)m_floatrect.ySize;
  208. if( !IntersectRect(&rcFloatThisScreenClipped, &rcFloatThisScreen, &m_rcRenderCurDevice) )
  209. {
  210. return S_OK; // no intersection, so nothing further to render on this screen
  211. }
  212. // Convert rcFloatThisScreen from screen to window coordinates
  213. OffsetRect(&rcFloatThisScreen, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top);
  214. OffsetRect(&rcFloatThisScreenClipped, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top);
  215. // Now set up the viewport to render to the clipped rect
  216. vp.X = rcFloatThisScreenClipped.left;
  217. vp.Y = rcFloatThisScreenClipped.top;
  218. vp.Width = rcFloatThisScreenClipped.right - rcFloatThisScreenClipped.left;
  219. vp.Height = rcFloatThisScreenClipped.bottom - rcFloatThisScreenClipped.top;
  220. vp.MinZ = 0.0f;
  221. vp.MaxZ = 1.0f;
  222. m_pd3dDevice->SetViewport( &vp );
  223. // m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0L );
  224. // Now set up the projection matrix to only render the onscreen part of the
  225. // rect to the viewport
  226. D3DXMATRIX matProj;
  227. FLOAT l,r,b,t;
  228. l = -0.8f;
  229. r = 0.8f;
  230. b = 0.8f;
  231. t = -0.8f;
  232. FLOAT cxUnclipped = (rcFloatThisScreen.right + rcFloatThisScreen.left) / 2.0f;
  233. FLOAT cyUnclipped = (rcFloatThisScreen.bottom + rcFloatThisScreen.top) / 2.0f;
  234. l *= (rcFloatThisScreenClipped.left - cxUnclipped) / (rcFloatThisScreen.left - cxUnclipped);
  235. r *= (rcFloatThisScreenClipped.right - cxUnclipped) / (rcFloatThisScreen.right - cxUnclipped);
  236. t *= (rcFloatThisScreenClipped.top - cyUnclipped) / (rcFloatThisScreen.top - cyUnclipped);
  237. b *= (rcFloatThisScreenClipped.bottom - cyUnclipped) / (rcFloatThisScreen.bottom - cyUnclipped);
  238. D3DXMatrixPerspectiveOffCenterLH( &matProj, l, r, t, b, 1.0f, 50.0f );
  239. m_pd3dDevice->SetTransform( D3DTS_PROJECTION , &matProj );
  240. // Mesh updates happen in Render() instead of FrameMove() since they
  241. // are per-device
  242. if( m_pDeviceObjects->m_dwMeshUpdateCounter != m_dwMeshUpdateCounter )
  243. {
  244. BuildTextMesh( m_szDisplayString );
  245. m_pDeviceObjects->m_dwMeshUpdateCounter = m_dwMeshUpdateCounter;
  246. }
  247. m_pd3dDevice->BeginScene();
  248. // Set world matrix
  249. D3DXMATRIX rotx,roty,rotz,trans,trans2;
  250. D3DXMatrixTranslation( &trans , m_fTextOffsetX , m_fTextOffsetY , 0.25f );
  251. D3DXMatrixRotationX( &rotx , m_fAngleX );
  252. D3DXMatrixRotationY( &roty , m_fAngleY );
  253. D3DXMatrixRotationZ( &rotz , m_fAngleZ );
  254. D3DXMatrixTranslation( &trans2, 0, 0, 1.5f + (m_fTextMaxX - m_fTextMinX) );
  255. m_matWorld = trans * rotx * roty * rotz * trans2;
  256. m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX(0) , &m_matWorld );
  257. // Set other per-frame states
  258. SetPerFrameStates();
  259. // Draw mesh
  260. m_pDeviceObjects->m_pObject->DrawSubset( 0 );
  261. m_pd3dDevice->EndScene();
  262. return S_OK;
  263. }
  264. //-----------------------------------------------------------------------------
  265. // Name: RestoreDeviceObjects()
  266. // Desc:
  267. //-----------------------------------------------------------------------------
  268. HRESULT CTextScreensaver::RestoreDeviceObjects()
  269. {
  270. HRESULT rc;
  271. // Set up sensible view matrix
  272. D3DXMatrixLookAtLH( &m_matView , &D3DXVECTOR3(0,0,0) , &D3DXVECTOR3(0,0,1) , &D3DXVECTOR3(0,1,0) );
  273. m_pd3dDevice->SetTransform( D3DTS_VIEW , &m_matView );
  274. // Set some basic renderstates
  275. m_pd3dDevice->SetRenderState( D3DRS_ZENABLE , TRUE );
  276. m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE , D3DZB_TRUE );
  277. m_pd3dDevice->SetRenderState( D3DRS_ZFUNC , D3DCMP_LESSEQUAL );
  278. m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE , TRUE );
  279. m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , m_bSpecular );
  280. // Create the GDI font object
  281. LONG h = m_Font.lfHeight;
  282. m_Font.lfHeight = 100;
  283. m_hFont = CreateFontIndirect( &m_Font );
  284. m_Font.lfHeight = h;
  285. if ( m_hFont == NULL )
  286. return E_FAIL;
  287. // Initialise time string
  288. if ( m_bDisplayTime )
  289. UpdateTimeString( m_szDisplayString );
  290. // Make mesh for text string
  291. if ( FAILED(rc = BuildTextMesh( m_szDisplayString )) )
  292. return rc;
  293. // Update offsets for mesh
  294. m_fTextOffsetX = (m_fTextMinX + m_fTextMaxX) * -0.5f;
  295. m_fTextOffsetY = (m_fTextMinY + m_fTextMaxY) * -0.5f;
  296. // Load appropriate texture (if any)
  297. switch ( m_SurfType )
  298. {
  299. case color:
  300. m_pDeviceObjects->m_pTexture = NULL;
  301. break;
  302. case environment:
  303. if ( m_bUseCustomEnvironment )
  304. {
  305. m_pDeviceObjects->m_pTexture = CreateTextureFromFile( m_szCustomEnvironment );
  306. }
  307. if ( m_pDeviceObjects->m_pTexture == NULL )
  308. {
  309. LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_SPHEREMAP),
  310. TEXT("JPG"), &m_pDeviceObjects->m_pTexture );
  311. }
  312. break;
  313. case texture:
  314. if ( m_bUseCustomTexture )
  315. {
  316. m_pDeviceObjects->m_pTexture = CreateTextureFromFile( m_szCustomTexture );
  317. }
  318. if ( m_pDeviceObjects->m_pTexture == NULL )
  319. {
  320. LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_TEXTURE),
  321. TEXT("JPG"), &m_pDeviceObjects->m_pTexture );
  322. }
  323. break;
  324. default:
  325. return E_FAIL;
  326. }
  327. // Set per-frame states
  328. SetPerFrameStates();
  329. m_dwLastTick = GetTickCount();
  330. return S_OK;
  331. }
  332. //**********************************************************************************
  333. VOID CTextScreensaver::SetPerFrameStates()
  334. {
  335. m_pd3dDevice->SetTexture( 0 , m_pDeviceObjects->m_pTexture );
  336. // Set up texture pipeline
  337. if ( m_SurfType == color )
  338. {
  339. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG1 );
  340. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_DIFFUSE );
  341. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE );
  342. }
  343. else
  344. {
  345. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_MODULATE );
  346. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_TEXTURE );
  347. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE );
  348. }
  349. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
  350. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MAGFILTER , D3DTEXF_LINEAR );
  351. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MINFILTER , D3DTEXF_LINEAR );
  352. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MIPFILTER , D3DTEXF_LINEAR );
  353. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ADDRESSU , D3DTADDRESS_WRAP );
  354. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ADDRESSV , D3DTADDRESS_WRAP );
  355. m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_COLOROP , D3DTOP_DISABLE );
  356. m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
  357. // Set up lighting
  358. m_pd3dDevice->SetRenderState( D3DRS_LIGHTING , TRUE );
  359. if ( !m_bSpecular )
  360. m_pd3dDevice->SetRenderState( D3DRS_AMBIENT , 0x646464 );
  361. else
  362. m_pd3dDevice->SetRenderState( D3DRS_AMBIENT , 0x464646 );
  363. D3DLIGHT8 light;
  364. light.Type = D3DLIGHT_DIRECTIONAL;
  365. light.Diffuse = D3DXCOLOR(1,1,1,0);
  366. light.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  367. light.Ambient = D3DXCOLOR(0,0,0,0);
  368. light.Direction = D3DXVECTOR3(0.5,-0.5,1);
  369. light.Position = D3DXVECTOR3(0,0,0);
  370. light.Range = 10000;
  371. light.Falloff = light.Attenuation0 = light.Attenuation1 = light.Attenuation2 = 0;
  372. light.Phi = light.Theta = 0;
  373. m_pd3dDevice->SetLight( 0 , &light );
  374. m_pd3dDevice->LightEnable( 0 , TRUE );
  375. // Set up material
  376. D3DMATERIAL8 mat;
  377. if ( m_SurfType == color )
  378. {
  379. DWORD dwColor;
  380. if( m_bUseCustomColor )
  381. dwColor = m_SurfaceColor;
  382. else
  383. dwColor = 0x00777777;
  384. mat.Diffuse.r = FLOAT(dwColor&0xff)/255.0f;
  385. mat.Diffuse.g = FLOAT((dwColor>>8)&0xff)/255.0f;
  386. mat.Diffuse.b = FLOAT((dwColor>>16)&0xff)/255.0f;
  387. }
  388. else
  389. {
  390. mat.Diffuse = D3DXCOLOR(1,1,1,0);
  391. }
  392. mat.Ambient = mat.Diffuse;
  393. mat.Specular = D3DXCOLOR(1.0f,1.0f,1.0f,0);
  394. mat.Emissive = D3DXCOLOR(0,0,0,0);
  395. mat.Power = 5;
  396. m_pd3dDevice->SetMaterial( &mat );
  397. // Set up texture coordinate generation if we're environment mapping or just force to passthrough
  398. if ( m_SurfType == environment )
  399. {
  400. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX , D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR );
  401. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS , D3DTTFF_COUNT2 );
  402. D3DXMATRIX envmat;
  403. D3DXMatrixIdentity( &envmat );
  404. envmat._11 = envmat._22 = 0.5f;
  405. envmat._31 = envmat._32 = 0.5f;
  406. m_pd3dDevice->SetTransform( D3DTS_TEXTURE0 , &envmat );
  407. }
  408. else
  409. {
  410. D3DXMATRIX matWorldView;
  411. D3DXMATRIX matWorldViewInv;
  412. matWorldView = m_matWorld * m_matView;
  413. D3DXMatrixInverse( &matWorldViewInv, NULL, &matWorldView );
  414. m_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &matWorldViewInv );
  415. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX , D3DTSS_TCI_CAMERASPACEPOSITION );
  416. m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS , D3DTTFF_COUNT2 );
  417. }
  418. m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE , FALSE );
  419. m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE , FALSE );
  420. m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , m_bSpecular );
  421. m_pd3dDevice->SetRenderState( D3DRS_WRAP0 , D3DWRAP_U|D3DWRAP_V );
  422. m_pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE , FALSE );
  423. m_pd3dDevice->SetTexture( 0, m_pDeviceObjects->m_pTexture );
  424. }
  425. //-----------------------------------------------------------------------------
  426. // Name: InvalidateDeviceObjects()
  427. // Desc:
  428. //-----------------------------------------------------------------------------
  429. HRESULT CTextScreensaver::InvalidateDeviceObjects()
  430. {
  431. SAFE_RELEASE(m_pDeviceObjects->m_pTexture);
  432. SAFE_RELEASE(m_pDeviceObjects->m_pObject);
  433. return S_OK;
  434. }
  435. //-----------------------------------------------------------------------------
  436. // Name: ConfirmDevice()
  437. // Desc:
  438. //-----------------------------------------------------------------------------
  439. HRESULT CTextScreensaver::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior,
  440. D3DFORMAT fmtBackBuffer)
  441. {
  442. // Need D3DVTXPCAPS_TEXGEN for D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
  443. if( ( ( dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) ||
  444. ( dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) ) &&
  445. ( pCaps->VertexProcessingCaps & D3DVTXPCAPS_TEXGEN ) == 0 )
  446. {
  447. return E_FAIL;
  448. }
  449. return S_OK;
  450. }
  451. //-----------------------------------------------------------------------------
  452. // Name: SetDevice()
  453. // Desc:
  454. //-----------------------------------------------------------------------------
  455. VOID CTextScreensaver::SetDevice( UINT iDevice )
  456. {
  457. m_pDeviceObjects = &m_DeviceObjects[iDevice];
  458. }
  459. //***************************************************************************************
  460. IDirect3DTexture8* CTextScreensaver::CreateTextureFromFile( const TCHAR* filename )
  461. {
  462. IDirect3DTexture8* texture;
  463. if ( FAILED(D3DXCreateTextureFromFile( m_pd3dDevice , filename , &texture )) )
  464. return NULL;
  465. else
  466. return texture;
  467. }
  468. //***************************************************************************************
  469. HRESULT CTextScreensaver::BuildTextMesh( const TCHAR* text )
  470. {
  471. // Release any old text mesh we built
  472. SAFE_RELEASE(m_pDeviceObjects->m_pObject);
  473. // Create temporary DC and select the correct font into it
  474. HDC hdc = CreateDC( TEXT("DISPLAY") , NULL , NULL , NULL );
  475. SelectObject( hdc , m_hFont );
  476. TCHAR szText[MAX_DISPLAY_STRING+1];
  477. lstrcpyn( szText, text, MAX_DISPLAY_STRING+1 );
  478. // Build new mesh
  479. FLOAT max_deviation = 5.0f / FLOAT(m_dwMeshQuality+10);
  480. GLYPHMETRICSFLOAT metrics[MAX_DISPLAY_STRING+1];
  481. HRESULT rc;
  482. rc = D3DXCreateText( m_pd3dDevice , hdc , szText , max_deviation, 0.5f , &m_pDeviceObjects->m_pObject , NULL, metrics );
  483. if( FAILED( rc ) )
  484. {
  485. // We might have failed because the string had no glyphs, so try
  486. // the default text instead
  487. LoadString( NULL, IDS_DEFAULTTEXT, szText, MAX_DISPLAY_STRING );
  488. rc = D3DXCreateText( m_pd3dDevice , hdc , szText , max_deviation, 0.5f , &m_pDeviceObjects->m_pObject , NULL, metrics );
  489. }
  490. // Delete temporary DC
  491. DeleteDC( hdc );
  492. if ( FAILED(rc) )
  493. return rc;
  494. // Compute the bounding box for the mesh by stepping through the glyph metrics structures
  495. int len = lstrlen( szText );
  496. m_fTextMinX = 1000000;
  497. m_fTextMaxX = -1000000;
  498. m_fTextMinY = 1000000;
  499. m_fTextMaxY = -1000000;
  500. FLOAT originx = 0;
  501. FLOAT originy = 0;
  502. GLYPHMETRICSFLOAT* pglyph = metrics;
  503. for ( int i = 0 ; i < len ; i++ , pglyph++ )
  504. {
  505. if ( (pglyph->gmfptGlyphOrigin.x + originx) < m_fTextMinX )
  506. m_fTextMinX = (pglyph->gmfptGlyphOrigin.x + originx);
  507. if ( (pglyph->gmfptGlyphOrigin.x + originx + pglyph->gmfBlackBoxX) > m_fTextMaxX )
  508. m_fTextMaxX = (pglyph->gmfptGlyphOrigin.x + originx + pglyph->gmfBlackBoxX);
  509. if ( (pglyph->gmfptGlyphOrigin.y + originy) > m_fTextMaxY )
  510. m_fTextMaxY = (pglyph->gmfptGlyphOrigin.y + originy);
  511. if ( (pglyph->gmfptGlyphOrigin.y + originy - pglyph->gmfBlackBoxY) < m_fTextMinY )
  512. m_fTextMinY = (pglyph->gmfptGlyphOrigin.y + originy - pglyph->gmfBlackBoxY);
  513. originx += pglyph->gmfCellIncX;
  514. originy += pglyph->gmfCellIncY;
  515. }
  516. return S_OK;
  517. }
  518. //*********************************************************************************
  519. VOID CTextScreensaver::UpdateAngles( DWORD elapsed )
  520. {
  521. static FLOAT x,y,z,t;
  522. const FLOAT pi2 = 3.1415926536f * 2.0f;
  523. FLOAT inc = FLOAT(elapsed * m_dwRotationSpeed);
  524. switch ( m_RotType )
  525. {
  526. case spin:
  527. y += inc * 0.00002f;
  528. break;
  529. case seesaw:
  530. t += inc * 0.000025f;
  531. y = (FLOAT(sin((t * pi2))) * 0.17f) + 1.0f;
  532. break;
  533. case wobble:
  534. t += inc * 0.000025f;
  535. y = (FLOAT(sin((t * pi2))) * 0.17f) + 1.0f;
  536. z = (FLOAT(cos((t * pi2))) * 0.09f) + 1.0f;
  537. break;
  538. case tumble:
  539. x += inc * 0.000004f;
  540. y += inc * 0.000018f;
  541. z += inc * 0.000007f;
  542. break;
  543. }
  544. x = x - int(x);
  545. y = y - int(y);
  546. z = z - int(z);
  547. m_fAngleX = x * pi2;
  548. m_fAngleY = y * pi2;
  549. m_fAngleZ = z * pi2;
  550. }
  551. //***************************************************************************************
  552. BOOL CTextScreensaver::UpdateTimeString( TCHAR* string )
  553. {
  554. TCHAR str[MAX_DISPLAY_STRING+1];
  555. GetTimeFormat( LOCALE_USER_DEFAULT, 0, NULL, NULL, str, MAX_DISPLAY_STRING+1 );
  556. if ( lstrcmp( string , str ) )
  557. {
  558. lstrcpy( string , str );
  559. return TRUE;
  560. }
  561. return FALSE;
  562. }
  563. //-----------------------------------------------------------------------------
  564. // Name: ReadSettings()
  565. // Desc:
  566. //-----------------------------------------------------------------------------
  567. VOID CTextScreensaver::ReadSettings()
  568. {
  569. HKEY hkey;
  570. DWORD dwType = REG_DWORD;
  571. DWORD dwLength = sizeof(DWORD);
  572. // Defaults
  573. LoadString( NULL, IDS_DEFAULTTEXT, m_szDisplayString, MAX_DISPLAY_STRING );
  574. m_Font.lfHeight = 96;
  575. m_Font.lfWidth = 0;
  576. m_Font.lfEscapement = 0;
  577. m_Font.lfOrientation = 0;
  578. m_Font.lfWeight = 0;
  579. m_Font.lfItalic = 0;
  580. m_Font.lfUnderline = 0;
  581. m_Font.lfStrikeOut = 0;
  582. m_Font.lfCharSet = DEFAULT_CHARSET;
  583. m_Font.lfOutPrecision = OUT_DEFAULT_PRECIS;
  584. m_Font.lfClipPrecision = OUT_DEFAULT_PRECIS;
  585. m_Font.lfQuality = DEFAULT_QUALITY;
  586. m_Font.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
  587. LoadString( NULL, IDS_FONT, m_Font.lfFaceName, LF_FACESIZE );
  588. m_bDisplayTime = FALSE;
  589. m_dwMeshQuality = 500;
  590. m_SurfType = SurfType(environment);
  591. m_bSpecular = TRUE;
  592. m_dwRotationSpeed = 10;
  593. m_dwSize = 10;
  594. m_RotType = RotType(spin);
  595. m_SurfaceColor = 0x00777777;
  596. m_bUseCustomColor = FALSE;
  597. m_bUseCustomTexture = FALSE;
  598. m_bUseCustomEnvironment = FALSE;
  599. lstrcpy( m_szCustomTexture, TEXT("") );
  600. lstrcpy( m_szCustomEnvironment, TEXT("") );
  601. // Read OpenGL settings first, so OS upgrade cases work
  602. ss_ReadSettings();
  603. if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
  604. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
  605. {
  606. dwLength = (MAX_DISPLAY_STRING + 1) * sizeof(TCHAR);
  607. RegQueryValueEx( hkey, TEXT("DisplayString"), NULL, &dwType, (BYTE*)m_szDisplayString, &dwLength );
  608. dwLength = sizeof(DWORD);
  609. RegQueryValueEx( hkey, TEXT("FontHeight"), NULL, &dwType, (BYTE*)&m_Font.lfHeight, &dwLength );
  610. RegQueryValueEx( hkey, TEXT("FontWeight"), NULL, &dwType, (BYTE*)&m_Font.lfWeight, &dwLength );
  611. RegQueryValueEx( hkey, TEXT("FontItalic"), NULL, &dwType, (BYTE*)&m_Font.lfItalic, &dwLength );
  612. RegQueryValueEx( hkey, TEXT("FontCharSet"), NULL, &dwType, (BYTE*)&m_Font.lfCharSet, &dwLength );
  613. RegQueryValueEx( hkey, TEXT("FontPitchFamily"), NULL, &dwType, (BYTE*)&m_Font.lfPitchAndFamily, &dwLength );
  614. dwLength = sizeof(m_Font.lfFaceName);
  615. RegQueryValueEx( hkey, TEXT("FontFace"), NULL, &dwType, (BYTE*)m_Font.lfFaceName, &dwLength );
  616. dwLength = sizeof(DWORD);
  617. RegQueryValueEx( hkey, TEXT("DisplayTime"), NULL, &dwType, (BYTE*)&m_bDisplayTime, &dwLength );
  618. RegQueryValueEx( hkey, TEXT("MeshQuality"), NULL, &dwType, (BYTE*)&m_dwMeshQuality, &dwLength );
  619. if ( m_dwMeshQuality > 1000 )
  620. m_dwMeshQuality = 1000;
  621. RegQueryValueEx( hkey, TEXT("SurfaceType"), NULL, &dwType, (BYTE*)&m_SurfType, &dwLength );
  622. RegQueryValueEx( hkey, TEXT("Specular"), NULL, &dwType, (BYTE*)&m_bSpecular, &dwLength );
  623. RegQueryValueEx( hkey, TEXT("RotationSpeed"), NULL, &dwType, (BYTE*)&m_dwRotationSpeed, &dwLength );
  624. RegQueryValueEx( hkey, TEXT("Size"), NULL, &dwType, (BYTE*)&m_dwSize, &dwLength );
  625. if( m_dwSize < 1 )
  626. m_dwSize = 1;
  627. if( m_dwSize > 10 )
  628. m_dwSize = 10;
  629. RegQueryValueEx( hkey, TEXT("RotationStyle"), NULL, &dwType, (BYTE*)&m_RotType, &dwLength );
  630. RegQueryValueEx( hkey, TEXT("SurfaceColor"), NULL, &dwType, (BYTE*)&m_SurfaceColor, &dwLength );
  631. RegQueryValueEx( hkey, TEXT("UseCustomColor"), NULL, &dwType, (BYTE*)&m_bUseCustomColor, &dwLength );
  632. RegQueryValueEx( hkey, TEXT("UseCustomTexture"), NULL, &dwType, (BYTE*)&m_bUseCustomTexture, &dwLength );
  633. RegQueryValueEx( hkey, TEXT("UseCustomEnvironment"), NULL, &dwType, (BYTE*)&m_bUseCustomEnvironment, &dwLength );
  634. dwLength = sizeof(m_szCustomTexture);
  635. RegQueryValueEx( hkey, TEXT("CustomTexture"), NULL, &dwType, (BYTE*)m_szCustomTexture, &dwLength );
  636. dwLength = sizeof(m_szCustomEnvironment);
  637. RegQueryValueEx( hkey, TEXT("CustomEnvironment"), NULL, &dwType, (BYTE*)m_szCustomEnvironment, &dwLength );
  638. ReadScreenSettings( hkey );
  639. RegCloseKey( hkey );
  640. }
  641. }
  642. //-----------------------------------------------------------------------------
  643. // Name: ss_ReadSettings()
  644. // Desc:
  645. //-----------------------------------------------------------------------------
  646. VOID CTextScreensaver::ss_ReadSettings()
  647. {
  648. int options;
  649. int optMask = 1;
  650. // Get registry settings
  651. if( ss_RegistrySetup( IDS_SAVERNAME, IDS_INIFILE ) )
  652. {
  653. // get demo type
  654. int demoType = ss_GetRegistryInt( IDS_DEMOTYPE, 0 );
  655. if( demoType == 1 )
  656. {
  657. m_bDisplayTime = TRUE;
  658. }
  659. // get rotation style
  660. m_RotType = (RotType) (ss_GetRegistryInt( IDS_ROTSTYLE, 0 ) + 1); // add 1
  661. if( m_RotType == 1 ) // 1==none,2=right,3=right,4=random->spin
  662. m_RotType = none;
  663. if( m_RotType > 3 )
  664. m_RotType = spin;
  665. // get tesselation
  666. m_dwMeshQuality = ss_GetRegistryInt( IDS_TESSELATION, 0 ); // 0-100
  667. m_dwMeshQuality = m_dwMeshQuality*10 + 1; // 1-1000
  668. if ( m_dwMeshQuality > 1000 )
  669. m_dwMeshQuality = 1000;
  670. // get size
  671. m_dwSize = ss_GetRegistryInt( IDS_SIZE, 0 ); // 0-100
  672. m_dwSize = (unsigned) ( ((m_dwSize / 100.0f) * 90.0f + 10.0f) / 10.0f ); // 1-10
  673. // get speed
  674. m_dwRotationSpeed = ss_GetRegistryInt( IDS_SPEED, 0 ); // 0-100
  675. m_dwRotationSpeed = (unsigned) ( ((m_dwRotationSpeed / 100.0f) * 190.0f + 10.0f) / 10.0f ); // 1-20
  676. // get font, attributes, and charset
  677. ss_GetRegistryString( IDS_FONT_REG, TEXT(""),
  678. m_Font.lfFaceName, LF_FACESIZE );
  679. options = ss_GetRegistryInt( IDS_FONT_ATTRIBUTES, 0 );
  680. if( options >= 0 )
  681. {
  682. optMask = 1;
  683. m_Font.lfWeight = ((options & optMask) != 0) ? FW_BOLD : FW_NORMAL;
  684. optMask <<=1;
  685. m_Font.lfItalic = ((options & optMask) != 0) ? (BYTE) 1 : 0;
  686. }
  687. m_Font.lfCharSet = (BYTE)ss_GetRegistryInt( IDS_CHARSET, 0 );
  688. // get display string
  689. ss_GetRegistryString( IDS_TEXT, TEXT(""), m_szDisplayString, MAX_DISPLAY_STRING );
  690. m_SurfType = (SurfType) ss_GetRegistryInt( IDS_SURFSTYLE, color );
  691. if( m_SurfType >= 1 )
  692. m_SurfType = texture;
  693. // Is there a texture specified in the registry that overrides the default?
  694. ss_GetRegistryString( IDS_TEXTURE, NULL, m_szCustomTexture, MAX_PATH );
  695. if( lstrlen( m_szCustomTexture ) > 0 )
  696. {
  697. m_bUseCustomTexture = TRUE;
  698. }
  699. }
  700. }
  701. //-----------------------------------------------------------------------------
  702. // Name: ss_GetRegistryString()
  703. // Desc:
  704. //-----------------------------------------------------------------------------
  705. BOOL CTextScreensaver::ss_RegistrySetup( int section, int file )
  706. {
  707. if( LoadString(m_hInstance, section, g_szSectName, BUF_SIZE) &&
  708. LoadString(m_hInstance, file, g_szFname, BUF_SIZE) )
  709. {
  710. TCHAR pBuffer[100];
  711. DWORD dwRealSize = GetPrivateProfileSection( g_szSectName, pBuffer, 100, g_szFname );
  712. if( dwRealSize > 0 )
  713. return TRUE;
  714. }
  715. return FALSE;
  716. }
  717. //-----------------------------------------------------------------------------
  718. // Name: ss_GetRegistryInt()
  719. // Desc:
  720. //-----------------------------------------------------------------------------
  721. int CTextScreensaver::ss_GetRegistryInt( int name, int iDefault )
  722. {
  723. TCHAR szItemName[BUF_SIZE];
  724. if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) )
  725. return GetPrivateProfileInt(g_szSectName, szItemName, iDefault, g_szFname);
  726. return 0;
  727. }
  728. //-----------------------------------------------------------------------------
  729. // Name: ss_GetRegistryString()
  730. // Desc:
  731. //-----------------------------------------------------------------------------
  732. VOID CTextScreensaver::ss_GetRegistryString( int name, LPTSTR lpDefault,
  733. LPTSTR lpDest, int bufSize )
  734. {
  735. TCHAR szItemName[BUF_SIZE];
  736. if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) )
  737. GetPrivateProfileString(g_szSectName, szItemName, lpDefault, lpDest,
  738. bufSize, g_szFname);
  739. return;
  740. }
  741. //-----------------------------------------------------------------------------
  742. // Name: DoConfig()
  743. // Desc:
  744. //-----------------------------------------------------------------------------
  745. VOID CTextScreensaver::DoConfig()
  746. {
  747. ReadSettings();
  748. DialogBox( NULL, MAKEINTRESOURCE( IDD_SETTINGS ),
  749. m_hWndParent, SettingsDialogProcStub );
  750. }
  751. INT_PTR CALLBACK CTextScreensaver::SettingsDialogProcStub( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
  752. {
  753. return g_pMyTextScreensaver->SettingsDialogProc( hDlg, message, wParam, lParam );
  754. };
  755. BOOL CTextScreensaver::SettingsDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
  756. {
  757. switch ( message )
  758. {
  759. case WM_INITDIALOG:
  760. InitItems( hDlg );
  761. return FALSE;
  762. case WM_COMMAND:
  763. switch ( HIWORD(wParam) )
  764. {
  765. case BN_CLICKED:
  766. {
  767. switch( LOWORD(wParam) )
  768. {
  769. case IDOK:
  770. ExtractAndWriteSettings( hDlg );
  771. EndDialog( hDlg, TRUE );
  772. break;
  773. case IDCANCEL:
  774. ReadSettings();
  775. EndDialog( hDlg, FALSE );
  776. break;
  777. case IDC_SELECT_FONT:
  778. SelectFont( hDlg );
  779. break;
  780. case IDC_RADIO_TIME:
  781. EnableWindow( GetDlgItem( hDlg , IDC_DISPLAY_STRING ) , FALSE );
  782. break;
  783. case IDC_RADIO_TEXT:
  784. EnableWindow( GetDlgItem( hDlg , IDC_DISPLAY_STRING ) , TRUE );
  785. break;
  786. case IDC_RADIO_COLOR:
  787. case IDC_RADIO_TEXTURE:
  788. case IDC_RADIO_REFLECTION:
  789. case IDC_USE_CUSTOM_COLOR:
  790. case IDC_USE_CUSTOM_TEXTURE:
  791. case IDC_USE_CUSTOM_ENVIRONMENT:
  792. {
  793. if( IsDlgButtonChecked( hDlg, IDC_RADIO_COLOR ) )
  794. m_SurfType = color;
  795. else if( IsDlgButtonChecked( hDlg, IDC_RADIO_TEXTURE ) )
  796. m_SurfType = texture;
  797. else if( IsDlgButtonChecked( hDlg, IDC_RADIO_REFLECTION ) )
  798. m_SurfType = environment;
  799. EnableTextureWindows( hDlg , SurfType(m_SurfType) );
  800. }
  801. break;
  802. case IDC_SURFACE_COLOR:
  803. SelectSurfaceColor( hDlg );
  804. break;
  805. case IDC_BROWSE_TEXTURE:
  806. SelectCustomTexture( hDlg );
  807. break;
  808. case IDC_BROWSE_ENVIRONMENT:
  809. SelectCustomEnvironment( hDlg );
  810. break;
  811. case IDC_SCREENSETTINGS:
  812. DoScreenSettingsDialog( hDlg );
  813. break;
  814. }
  815. }
  816. break;
  817. case EN_CHANGE:
  818. if ( LOWORD(wParam) == IDC_DISPLAY_STRING )
  819. {
  820. GetDlgItemText( hDlg , IDC_DISPLAY_STRING , m_szDisplayString , MAX_DISPLAY_STRING );
  821. }
  822. break;
  823. }
  824. return FALSE;
  825. }
  826. return FALSE;
  827. }
  828. VOID CTextScreensaver::InitItems( HWND hDlg )
  829. {
  830. TCHAR sz[100];
  831. // Set the limit of the text box
  832. SendDlgItemMessage( hDlg, IDC_DISPLAY_STRING, EM_SETLIMITTEXT, MAX_DISPLAY_STRING, 0 );
  833. // Set the text string
  834. SetDlgItemText( hDlg, IDC_DISPLAY_STRING, m_szDisplayString );
  835. // Set the radio button for time/text display
  836. if ( m_bDisplayTime )
  837. {
  838. EnableWindow( GetDlgItem( hDlg, IDC_DISPLAY_STRING ), FALSE );
  839. CheckRadioButton( hDlg, IDC_RADIO_TIME, IDC_RADIO_TEXT, IDC_RADIO_TIME );
  840. }
  841. else
  842. {
  843. EnableWindow( GetDlgItem( hDlg, IDC_DISPLAY_STRING ), TRUE );
  844. CheckRadioButton( hDlg, IDC_RADIO_TIME, IDC_RADIO_TEXT, IDC_RADIO_TEXT );
  845. }
  846. switch( m_SurfType )
  847. {
  848. case color:
  849. CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_COLOR );
  850. break;
  851. case texture:
  852. CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_TEXTURE );
  853. break;
  854. case environment:
  855. CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_REFLECTION );
  856. break;
  857. }
  858. // Check/uncheck the specular box
  859. SendDlgItemMessage( hDlg, IDC_SPECULAR, BM_SETCHECK,
  860. m_bSpecular ? BST_CHECKED : BST_UNCHECKED, 0 );
  861. // Enable/disable surface color button
  862. EnableWindow( GetDlgItem( hDlg, IDC_SURFACE_COLOR ), m_SurfType == color );
  863. // Check/uncheck the custom texture boxes
  864. SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_COLOR, BM_SETCHECK,
  865. m_bUseCustomColor ? BST_CHECKED : BST_UNCHECKED, 0 );
  866. SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_TEXTURE, BM_SETCHECK,
  867. m_bUseCustomTexture ? BST_CHECKED : BST_UNCHECKED, 0 );
  868. SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_ENVIRONMENT, BM_SETCHECK,
  869. m_bUseCustomEnvironment ? BST_CHECKED : BST_UNCHECKED, 0 );
  870. // Enable all the texture windows as appropriate
  871. EnableTextureWindows( hDlg, m_SurfType );
  872. // Fill the rotation style combo box
  873. LoadString( NULL, IDS_NONE, sz, 100 );
  874. SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
  875. LoadString( NULL, IDS_SPIN, sz, 100 );
  876. SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
  877. LoadString( NULL, IDS_SEESAW, sz, 100 );
  878. SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
  879. LoadString( NULL, IDS_WOBBLE, sz, 100 );
  880. SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
  881. LoadString( NULL, IDS_TUMBLE, sz, 100 );
  882. SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
  883. // Set the current rotation style selection
  884. SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_SETCURSEL, m_RotType, 0 );
  885. // Set up the rotation speed slider
  886. SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_SETRANGE, TRUE, MAKELONG(1,20) );
  887. SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_SETPOS, TRUE, m_dwRotationSpeed );
  888. // Set up the resolution slider
  889. SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_SETRANGE, TRUE, MAKELONG(1,10) );
  890. SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_SETPOS, TRUE, m_dwMeshQuality / 100 );
  891. // Set up the size slider
  892. SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_SETRANGE, TRUE, MAKELONG(1,10) );
  893. SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_SETPOS, TRUE, m_dwSize );
  894. }
  895. VOID CTextScreensaver::ExtractAndWriteSettings( HWND hDlg )
  896. {
  897. LRESULT ret;
  898. HKEY hkey = NULL;
  899. m_bSpecular = IsDlgButtonChecked( hDlg, IDC_SPECULAR );
  900. m_bUseCustomColor = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_COLOR );
  901. m_bUseCustomTexture = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_TEXTURE );
  902. m_bUseCustomEnvironment = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_ENVIRONMENT );
  903. if ( (ret = SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_GETCURSEL, 0, 0 )) != CB_ERR )
  904. m_RotType = RotType(ret);
  905. m_dwSize = (DWORD)SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_GETPOS, 0, 0 );
  906. m_dwRotationSpeed = (DWORD)SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_GETPOS, 0, 0 );
  907. m_dwMeshQuality = 100 * (DWORD)SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_GETPOS, 0, 0 );
  908. GetDlgItemText( hDlg, IDC_DISPLAY_STRING, m_szDisplayString, MAX_DISPLAY_STRING + 1 );
  909. if ( IsDlgButtonChecked( hDlg, IDC_RADIO_TIME ) )
  910. m_bDisplayTime = TRUE;
  911. else
  912. m_bDisplayTime = FALSE;
  913. if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
  914. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
  915. {
  916. WriteScreenSettings( hkey );
  917. RegSetValueEx( hkey, TEXT("SurfaceType"), NULL, REG_DWORD, (BYTE*)&m_SurfType, sizeof(DWORD) );
  918. RegSetValueEx( hkey, TEXT("Specular"), NULL, REG_DWORD, (BYTE*)&m_bSpecular, sizeof(DWORD) );
  919. RegSetValueEx( hkey, TEXT("SurfaceColor"), NULL, REG_DWORD, (BYTE*)&m_SurfaceColor, sizeof(DWORD) );
  920. RegSetValueEx( hkey, TEXT("CustomTexture"), NULL, REG_SZ, (BYTE*)&m_szCustomTexture, (lstrlen(m_szCustomTexture) + 1) * sizeof(TCHAR) );
  921. RegSetValueEx( hkey, TEXT("CustomEnvironment"), NULL, REG_SZ, (BYTE*)&m_szCustomEnvironment, (lstrlen(m_szCustomEnvironment) + 1) * sizeof(TCHAR) );
  922. RegSetValueEx( hkey, TEXT("UseCustomColor"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomColor, sizeof(DWORD) );
  923. RegSetValueEx( hkey, TEXT("UseCustomTexture"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomTexture, sizeof(DWORD) );
  924. RegSetValueEx( hkey, TEXT("UseCustomEnvironment"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomEnvironment, sizeof(DWORD) );
  925. RegSetValueEx( hkey, TEXT("MeshQuality"), NULL, REG_DWORD, (BYTE*)&m_dwMeshQuality, sizeof(DWORD) );
  926. RegSetValueEx( hkey, TEXT("Size"), NULL, REG_DWORD, (BYTE*)&m_dwSize, sizeof(DWORD) );
  927. RegSetValueEx( hkey, TEXT("RotationSpeed"), NULL, REG_DWORD, (BYTE*)&m_dwRotationSpeed, sizeof(DWORD) );
  928. RegSetValueEx( hkey, TEXT("RotationStyle"), NULL, REG_DWORD, (BYTE*)&m_RotType, sizeof(DWORD) );
  929. RegSetValueEx( hkey, TEXT("DisplayString"), NULL, REG_SZ, (BYTE*)&m_szDisplayString, (lstrlen(m_szDisplayString) + 1) * sizeof(TCHAR) );
  930. RegSetValueEx( hkey, TEXT("DisplayTime"), NULL, REG_DWORD, (BYTE*)&m_bDisplayTime, sizeof(DWORD) );
  931. RegSetValueEx( hkey, TEXT("FontWeight"), NULL, REG_DWORD, (BYTE*)&m_Font.lfWeight, sizeof(DWORD) );
  932. RegSetValueEx( hkey, TEXT("FontHeight"), NULL, REG_DWORD, (BYTE*)&m_Font.lfHeight, sizeof(DWORD) );
  933. RegSetValueEx( hkey, TEXT("FontItalic"), NULL, REG_DWORD, (BYTE*)&m_Font.lfItalic, sizeof(DWORD) );
  934. RegSetValueEx( hkey, TEXT("FontCharSet"), NULL, REG_DWORD, (BYTE*)&m_Font.lfCharSet, sizeof(DWORD) );
  935. RegSetValueEx( hkey, TEXT("FontPitchFamily"), NULL, REG_DWORD, (BYTE*)&m_Font.lfPitchAndFamily, sizeof(DWORD) );
  936. RegSetValueEx( hkey, TEXT("FontFace"), NULL, REG_SZ, (BYTE*)&m_Font.lfFaceName, (lstrlen(m_Font.lfFaceName) + 1) * sizeof(TCHAR) );
  937. RegCloseKey( hkey );
  938. }
  939. }
  940. //***************************************************************************************
  941. VOID CTextScreensaver::SelectSurfaceColor( HWND hDlg )
  942. {
  943. static COLORREF cust_colors[16];
  944. CHOOSECOLOR choose;
  945. choose.lStructSize = sizeof(choose);
  946. choose.hwndOwner = hDlg;
  947. choose.hInstance = HWND(m_hInstance);
  948. choose.rgbResult = m_SurfaceColor;
  949. choose.lpCustColors = cust_colors;
  950. choose.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;
  951. choose.lCustData = 0;
  952. choose.lpfnHook = NULL;
  953. choose.lpTemplateName = NULL;
  954. if ( ChooseColor( &choose ) )
  955. m_SurfaceColor = choose.rgbResult;
  956. }
  957. //***************************************************************************************
  958. VOID CTextScreensaver::SelectFont( HWND hDlg )
  959. {
  960. CHOOSEFONT choose;
  961. choose.lStructSize = sizeof(choose);
  962. choose.hwndOwner = hDlg;
  963. choose.hDC;
  964. choose.iPointSize = 720;
  965. choose.lpLogFont = &m_Font;
  966. choose.Flags = CF_TTONLY|CF_FORCEFONTEXIST|CF_NOVERTFONTS|CF_SCREENFONTS|CF_INITTOLOGFONTSTRUCT|CF_ENABLETEMPLATE;
  967. choose.lpTemplateName = MAKEINTRESOURCE(DLG_SELECT_FONT);
  968. choose.hInstance = m_hInstance;
  969. if ( ChooseFont( &choose ) )
  970. m_Font = *choose.lpLogFont;
  971. }
  972. //***************************************************************************************
  973. VOID CTextScreensaver::SelectCustomTexture( HWND hDlg )
  974. {
  975. TCHAR fn[MAX_PATH] = TEXT("\0");
  976. TCHAR strTitle[100];
  977. LoadString( NULL, IDS_OPENTEXTURETITLE, strTitle, 100 );
  978. lstrcpy( fn, m_szCustomTexture );
  979. TCHAR filter[200];
  980. LoadString( NULL, IDS_FILEFILTER, filter, 200);
  981. for( TCHAR* pch = filter; *pch != TEXT('\0'); pch++ )
  982. {
  983. if( *pch == TEXT('#') )
  984. *pch = TEXT('\0');
  985. }
  986. TCHAR szWindowsDir[MAX_PATH+1];
  987. if( 0 == GetWindowsDirectory( szWindowsDir, MAX_PATH+1 ) )
  988. szWindowsDir[0] = TEXT('\0');
  989. OPENFILENAME ofn;
  990. memset( &ofn , 0 , sizeof(ofn) );
  991. ofn.lStructSize = sizeof(ofn);
  992. ofn.hwndOwner = hDlg;
  993. ofn.hInstance = m_hInstance;
  994. ofn.lpstrFilter = filter;
  995. ofn.nFilterIndex = 1;
  996. ofn.lpstrFile = fn;
  997. ofn.nMaxFile = sizeof(fn);
  998. ofn.lpstrTitle = strTitle;
  999. ofn.Flags = OFN_ENABLESIZING|OFN_FILEMUSTEXIST;
  1000. ofn.lpstrDefExt = TEXT("mid");
  1001. if( lstrlen( fn ) == 0 )
  1002. ofn.lpstrInitialDir = szWindowsDir;
  1003. if ( GetOpenFileName( &ofn ) )
  1004. lstrcpy( m_szCustomTexture , ofn.lpstrFile );
  1005. }
  1006. //***************************************************************************************
  1007. VOID CTextScreensaver::SelectCustomEnvironment( HWND hDlg )
  1008. {
  1009. TCHAR fn[MAX_PATH] = TEXT("\0");
  1010. TCHAR strTitle[100];
  1011. LoadString( NULL, IDS_OPENENVIRONMENTMAPTITLE, strTitle, 100 );
  1012. TCHAR filter[200];
  1013. LoadString( NULL, IDS_FILEFILTER, filter, 200);
  1014. for( TCHAR* pch = filter; *pch != TEXT('\0'); pch++ )
  1015. {
  1016. if( *pch == TEXT('#') )
  1017. *pch = TEXT('\0');
  1018. }
  1019. TCHAR szWindowsDir[MAX_PATH+1];
  1020. if( 0 == GetWindowsDirectory( szWindowsDir, MAX_PATH+1 ) )
  1021. szWindowsDir[0] = TEXT('\0');
  1022. OPENFILENAME ofn;
  1023. memset( &ofn , 0 , sizeof(ofn) );
  1024. ofn.lStructSize = sizeof(ofn);
  1025. ofn.hwndOwner = hDlg;
  1026. ofn.hInstance = m_hInstance;
  1027. ofn.lpstrFilter = filter;
  1028. ofn.nFilterIndex = 1;
  1029. ofn.lpstrFile = fn;
  1030. ofn.nMaxFile = sizeof(fn);
  1031. ofn.lpstrTitle = strTitle;
  1032. ofn.Flags = OFN_ENABLESIZING|OFN_FILEMUSTEXIST;
  1033. ofn.lpstrDefExt = TEXT("mid");
  1034. if( lstrlen( fn ) == 0 )
  1035. ofn.lpstrInitialDir = szWindowsDir;
  1036. if ( GetOpenFileName( &ofn ) )
  1037. lstrcpy( m_szCustomEnvironment , ofn.lpstrFile );
  1038. }
  1039. //***************************************************************************************
  1040. VOID CTextScreensaver::EnableTextureWindows( HWND hDlg , SurfType sel )
  1041. {
  1042. HWND use_color = GetDlgItem( hDlg , IDC_USE_CUSTOM_COLOR );
  1043. HWND use_texture = GetDlgItem( hDlg , IDC_USE_CUSTOM_TEXTURE );
  1044. HWND use_environ = GetDlgItem( hDlg , IDC_USE_CUSTOM_ENVIRONMENT );
  1045. HWND browse_color = GetDlgItem( hDlg , IDC_SURFACE_COLOR );
  1046. HWND browse_texture = GetDlgItem( hDlg , IDC_BROWSE_TEXTURE );
  1047. HWND browse_environ = GetDlgItem( hDlg , IDC_BROWSE_ENVIRONMENT );
  1048. BOOL color_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_COLOR );
  1049. BOOL texture_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_TEXTURE );
  1050. BOOL environment_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_ENVIRONMENT );
  1051. switch ( sel )
  1052. {
  1053. case environment:
  1054. EnableWindow( use_color , FALSE );
  1055. EnableWindow( use_texture , FALSE );
  1056. EnableWindow( use_environ , TRUE );
  1057. EnableWindow( browse_color , FALSE );
  1058. EnableWindow( browse_texture , FALSE );
  1059. EnableWindow( browse_environ , environment_checked );
  1060. break;
  1061. case texture:
  1062. EnableWindow( use_color , FALSE );
  1063. EnableWindow( use_texture , TRUE );
  1064. EnableWindow( use_environ , FALSE );
  1065. EnableWindow( browse_color , FALSE );
  1066. EnableWindow( browse_texture , texture_checked );
  1067. EnableWindow( browse_environ , FALSE );
  1068. break;
  1069. case color:
  1070. default:
  1071. EnableWindow( use_color , TRUE );
  1072. EnableWindow( use_texture , FALSE );
  1073. EnableWindow( use_environ , FALSE );
  1074. EnableWindow( browse_color , color_checked );
  1075. EnableWindow( browse_texture , FALSE );
  1076. EnableWindow( browse_environ , FALSE );
  1077. break;
  1078. }
  1079. }