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.

527 lines
12 KiB

  1. /**************************************************************************\
  2. *
  3. * Module Name: logon.cxx
  4. *
  5. * Copyright (c) 1997 Microsoft Corporation
  6. *
  7. \**************************************************************************/
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <math.h>
  11. #include <stdlib.h>
  12. #include "logon.hxx"
  13. #include "logobj.hxx"
  14. #include "util.hxx"
  15. static GLIRECT nullRect = {0};
  16. /**************************************************************************\
  17. * LOG_OBJECT
  18. *
  19. *
  20. \**************************************************************************/
  21. //#define DEEP_FRAME 1
  22. LOG_OBJECT::LOG_OBJECT()
  23. {
  24. pTex = NULL;
  25. // Set some default size values...
  26. fImageSize.width = fImageSize.height = OBJECT_WIDTH;
  27. bShowContext = FALSE; // Only show image to start
  28. fCurContextWidth = 0.0f;
  29. fMaxContextWidth = OBJECT_WIDTH / 2.0f;
  30. #if DEEP_FRAME
  31. fFrameSize.width = fFrameSize.height = FRAME_SIZE;
  32. #else
  33. fFrameSize.width = fFrameSize.height = 0.0f;
  34. #endif
  35. bFramed = FALSE;
  36. // fFrameDepth is depth offset in z-direction. Since the frame is usually
  37. // drawn further away from the viewer (down -z axis), it is negative.
  38. #if DEEP_FRAME
  39. fFrameDepth = - 3.3f;
  40. #else
  41. fFrameDepth = - FRAME_DEPTH;
  42. #endif
  43. bSwapHints = FALSE;
  44. dest[0] = dest[1] = dest[2] = 0.0f;
  45. ResetMotion();
  46. rect = nullRect;
  47. // Calc initial coords
  48. CalcCoords();
  49. }
  50. LOG_OBJECT::~LOG_OBJECT()
  51. {
  52. }
  53. void
  54. LOG_OBJECT::ShowFrame( BOOL bShow )
  55. {
  56. if( bFramed == bShow )
  57. return;
  58. // new state
  59. bFramed = bShow;
  60. if( bFramed ) {
  61. // mf : could optimize by not redoing this if framesize constant...
  62. CalcFrameCoords();
  63. }
  64. }
  65. void
  66. LOG_OBJECT::ShowContext( BOOL bShow )
  67. {
  68. if( bShowContext == bShow )
  69. return;
  70. // new state
  71. bShowContext = bShow;
  72. CalcCoords();
  73. //mf: !!! readjust dest to reflect this ?
  74. }
  75. void
  76. LOG_OBJECT::SetDest( float x, float y, float z )
  77. {
  78. dest[0] = x;
  79. dest[1] = y;
  80. dest[2] = z;
  81. }
  82. void
  83. LOG_OBJECT::SetDest( POINT3D *pDest )
  84. {
  85. dest[0] = pDest->x;
  86. dest[1] = pDest->y;
  87. dest[2] = pDest->z;
  88. }
  89. void
  90. LOG_OBJECT::GetDest( POINT3D *pDest )
  91. {
  92. pDest->x = dest[0];
  93. pDest->y = dest[1];
  94. pDest->z = dest[2];
  95. }
  96. void
  97. LOG_OBJECT::OffsetDest( float x, float y, float z )
  98. {
  99. dest[0] += x;
  100. dest[1] += y;
  101. dest[2] += z;
  102. }
  103. void
  104. LOG_OBJECT::SetTexture( TEXTURE *pTexture )
  105. {
  106. pTex = pTexture;
  107. if( !pTex )
  108. return;
  109. // Set the size of the object based on the aspect ratio of the texture
  110. // The textures for all the objects should have the same dimensions.
  111. float aspectRatio = pTex->GetAspectRatio(); // width/height
  112. // The texture is assumed to have an image on the right, and context on
  113. // the left, of equal size
  114. // We'll keep the width consant, and vary height according to aspect
  115. fImageSize.width = OBJECT_WIDTH / 2.0f;
  116. fImageSize.height = OBJECT_WIDTH / aspectRatio;
  117. fMaxContextWidth = fImageSize.width;
  118. fCurContextWidth = fMaxContextWidth;
  119. CalcCoords();
  120. }
  121. void
  122. LOG_OBJECT::SetContextSize( float fPortion )
  123. {
  124. // This sets the visible portion of the context ( 0.0 - 1.0 )
  125. fCurContextWidth = fPortion * fMaxContextWidth;
  126. // Recalc coords
  127. CalcCoords();
  128. }
  129. void
  130. LOG_OBJECT::SetImageSize( FSIZE *pSize )
  131. {
  132. fImageSize = *pSize;
  133. float fPortion = fCurContextWidth / fMaxContextWidth;
  134. fMaxContextWidth = fImageSize.width;
  135. fCurContextWidth = fPortion * fMaxContextWidth;
  136. CalcCoords();
  137. }
  138. void
  139. LOG_OBJECT::Translate()
  140. {
  141. glTranslatef(dest[0]+offset[0], dest[1]+offset[1], dest[2]+offset[2]);
  142. }
  143. void
  144. LOG_OBJECT::Rotate()
  145. {
  146. if( ang != 0.0f )
  147. glRotatef(ang, rotAxis[0], rotAxis[1], rotAxis[2]);
  148. }
  149. void
  150. LOG_OBJECT::Draw()
  151. {
  152. Draw( FALSE );
  153. }
  154. void
  155. LOG_OBJECT::Draw( BOOL bUpdateWinRect )
  156. {
  157. // Draws object in its current position
  158. // An object either has its context showing on the right or not. If not,
  159. // then origin is the centre of the image, else origin is on border of
  160. // image and context
  161. pTex->MakeCurrent(); // Set the objects texture
  162. glPushMatrix();
  163. Translate();
  164. Rotate();
  165. if( bUpdateWinRect ) {
  166. UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
  167. CalcWinRect( FALSE );
  168. }
  169. DrawFace();
  170. if( bFramed )
  171. DrawFrame();
  172. glPopMatrix();
  173. if( bSwapHints )
  174. AddSwapHintRect( &rect );
  175. }
  176. void
  177. LOG_OBJECT::DrawFace()
  178. {
  179. glNormal3f( 0.0f, 0.0f, 1.0f );
  180. glBegin( GL_QUADS );
  181. glTexCoord2fv( (float *) &texPoint[0] );
  182. glVertex2fv( (float *) &point[0] );
  183. glTexCoord2fv( (float *) &texPoint[1] );
  184. glVertex2fv( (float *) &point[1] );
  185. glTexCoord2fv( (float *) &texPoint[2] );
  186. glVertex2fv( (float *) &point[2] );
  187. glTexCoord2fv( (float *) &texPoint[3] );
  188. glVertex2fv( (float *) &point[3] );
  189. glEnd();
  190. }
  191. void
  192. LOG_OBJECT::DrawFrame()
  193. {
  194. glDisable( GL_TEXTURE_2D );
  195. glEnable( GL_LIGHTING );
  196. glBegin( GL_QUADS );
  197. glNormal3fv( (float *) &frameNormal[0] );
  198. glVertex3fv( (float *) &point[0] );
  199. glVertex3fv( (float *) &point[4] );
  200. glVertex3fv( (float *) &point[7] );
  201. glVertex3fv( (float *) &point[3] );
  202. glNormal3fv( (float *) &frameNormal[1] );
  203. glVertex3fv( (float *) &point[1] );
  204. glVertex3fv( (float *) &point[5] );
  205. glVertex3fv( (float *) &point[4] );
  206. glVertex3fv( (float *) &point[0] );
  207. glNormal3fv( (float *) &frameNormal[2] );
  208. glVertex3fv( (float *) &point[2] );
  209. glVertex3fv( (float *) &point[6] );
  210. glVertex3fv( (float *) &point[5] );
  211. glVertex3fv( (float *) &point[1] );
  212. glNormal3fv( (float *) &frameNormal[3] );
  213. glVertex3fv( (float *) &point[3] );
  214. glVertex3fv( (float *) &point[7] );
  215. glVertex3fv( (float *) &point[6] );
  216. glVertex3fv( (float *) &point[2] );
  217. glEnd();
  218. glDisable( GL_LIGHTING );
  219. glEnable( GL_TEXTURE_2D );
  220. }
  221. void
  222. LOG_OBJECT::CalcWinRect()
  223. {
  224. CalcWinRect( TRUE );
  225. }
  226. void
  227. LOG_OBJECT::CalcWinRect( BOOL bTransform )
  228. {
  229. POINT3D ptOut[8];
  230. int nPts = bFramed ? 8 : 4;
  231. if( bTransform ) {
  232. // Need to transorm object according to current translation & rotation
  233. glPushMatrix();
  234. Translate();
  235. Rotate();
  236. UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
  237. glPopMatrix();
  238. }
  239. TransformObjectToWindow( point, ptOut, nPts );
  240. // Update the rect member
  241. CalcMinMaxRect( ptOut, &rect, nPts );
  242. }
  243. void
  244. LOG_OBJECT::CalcCoords()
  245. {
  246. POINT3D *pt;
  247. // Calculate object coords based on current state of the object. If
  248. // bShowContext, then origin is in centre of object, else it's in centre
  249. // of image part of object.
  250. // Also calculate frame coords if applicable.
  251. // Points are ordered CCW from top right for each face
  252. pt = point;
  253. pt[0].z = pt[1].z = pt[2].z = pt[3].z = 0.0f;
  254. // Calc front face points
  255. if( ! bShowContext ) {
  256. POINT2D image = { fImageSize.width / 2.0f, fImageSize.height / 2.0f };
  257. pt[0].x = image.x;
  258. pt[0].y = image.y;
  259. pt[1].x = -image.x;
  260. pt[1].y = image.y;
  261. pt[2].x = -image.x;
  262. pt[2].y = -image.y;
  263. pt[3].x = image.x;
  264. pt[3].y = -image.y;
  265. } else {
  266. POINT2D image = { fImageSize.width, fImageSize.height / 2.0f };
  267. pt[0].x = image.x;
  268. pt[0].y = image.y;
  269. pt[1].x = -fCurContextWidth;
  270. pt[1].y = image.y;
  271. pt[2].x = -fCurContextWidth;
  272. pt[2].y = -image.y;
  273. pt[3].x = image.x;
  274. pt[3].y = -image.y;
  275. }
  276. // Calc frame points
  277. if( bFramed ) {
  278. CalcFrameCoords();
  279. }
  280. // Always need the texture coords
  281. //mf: optimize...
  282. CalcTexCoords();
  283. }
  284. void
  285. LOG_OBJECT::CalcFrameCoords()
  286. {
  287. POINT3D *frontPt = point;
  288. POINT3D *pt = point + 4;
  289. pt[0].z = pt[1].z = pt[2].z = pt[3].z = fFrameDepth;
  290. pt[0].x = frontPt[0].x + fFrameSize.width;
  291. pt[0].y = frontPt[0].y + fFrameSize.height;
  292. pt[1].x = frontPt[1].x - fFrameSize.width;
  293. pt[1].y = frontPt[1].y + fFrameSize.height;
  294. pt[2].x = frontPt[2].x - fFrameSize.width;
  295. pt[2].y = frontPt[2].y - fFrameSize.height;
  296. pt[3].x = frontPt[3].x + fFrameSize.width;
  297. pt[3].y = frontPt[3].y - fFrameSize.height;
  298. // May as well do the normals too
  299. CalcFrameNormals();
  300. }
  301. void
  302. LOG_OBJECT::CalcFrameNormals()
  303. {
  304. POINT3D *pNorm = frameNormal;
  305. float fDepth = fFrameDepth;
  306. float fFramex = fFrameSize.width;
  307. float fFramey = fFrameSize.height;
  308. // Calc the face normals for the sides of the frame. The faces are
  309. // ordered CCW from the right face.
  310. float norm1 = (float) fabs( fDepth );
  311. pNorm[0].x = norm1;
  312. pNorm[0].y = 0.0f;
  313. pNorm[0].x = fFramex;
  314. pNorm[1].x = 0.0f;
  315. pNorm[1].y = norm1;
  316. pNorm[1].x = fFramey;
  317. pNorm[0].x = -norm1;
  318. pNorm[0].y = 0.0f;
  319. pNorm[0].x = fFramex;
  320. pNorm[1].x = 0.0f;
  321. pNorm[1].y = -norm1;
  322. pNorm[1].x = fFramey;
  323. mtk_NormalizePoints( pNorm, 4 );
  324. }
  325. void
  326. LOG_OBJECT::CalcTexCoords()
  327. {
  328. // Calculate texture coords based on current state of the object.
  329. // The texture spans across the front face, and includes the image on right,
  330. // and context on left. The 't' coords are constant, but the 's' coord
  331. // varies, depending on if or how much context is shown.
  332. // Again, points are ordered CCW from top right for each face
  333. // Calc ratio of image over total width of object
  334. float ratio = fImageSize.width / (fImageSize.width + fMaxContextWidth);
  335. float sStart = 1.0f - ratio;
  336. if( bShowContext ) {
  337. sStart -= (fCurContextWidth / fMaxContextWidth) * (1.0f - ratio);
  338. }
  339. texPoint[0].s = texPoint[3].s = 1.0f;
  340. texPoint[1].s = texPoint[2].s = sStart;
  341. texPoint[0].t = texPoint[1].t = 1.0f;
  342. texPoint[2].t = texPoint[3].t = 0.0f;
  343. }
  344. void
  345. LOG_OBJECT::GetRect( GLIRECT *pRect )
  346. {
  347. *pRect = rect;
  348. }
  349. #if 0
  350. void
  351. LOG_OBJECT::GetPos( POINT3D *curpos )
  352. {
  353. float *fpos = (float *) curpos;
  354. for( int i = 0; i < 3; i ++ )
  355. fpos[i] = dest[i] + offset[i];
  356. }
  357. #endif
  358. /**************************************************************************\
  359. * NextFlyIteration
  360. *
  361. * Calcs next offset and angle for a 'fly'sequence
  362. *
  363. \**************************************************************************/
  364. BOOL
  365. LOG_OBJECT::NextFlyIteration()
  366. {
  367. int i;
  368. if( !iter ) {
  369. // Done iterating
  370. return FALSE;
  371. }
  372. // Calculate new iterations
  373. for (i = 0; i < 3; i++) {
  374. offset[i] = Clamp( iter, offset[i] );
  375. }
  376. ang = Clamp( iter, ang);
  377. iter--;
  378. return TRUE;
  379. }
  380. /**************************************************************************\
  381. * ResetMotion
  382. *
  383. * Resets all position and motion params to 0
  384. *
  385. \**************************************************************************/
  386. void
  387. LOG_OBJECT::ResetMotion()
  388. {
  389. offset[0] = offset[1] = offset[2] = 0.0f;
  390. rotAxis[0] = rotAxis[1] = rotAxis[2] = 0.0f;
  391. ang = 0.0f;
  392. iter = 0;
  393. }
  394. /**************************************************************************\
  395. *
  396. * Ranomnly chooses motion params for a fly sequence
  397. *
  398. * The motion is 'damped', since near the end of the fly sequence the object
  399. * is constrained to 0 rotation and the dest[] position
  400. *
  401. \**************************************************************************/
  402. void
  403. LOG_OBJECT::SetDampedFlyMotion( float deviation )
  404. {
  405. SetDampedFlyMotion( deviation, NULL );
  406. }
  407. void
  408. LOG_OBJECT::SetDampedFlyMotion( float deviation, POINT3D *pOffset )
  409. {
  410. if( pOffset ) {
  411. // Use supplied offset
  412. offset[0] = pOffset->x;
  413. offset[1] = pOffset->y;
  414. offset[2] = pOffset->z;
  415. } else {
  416. // Calc a random offset
  417. offset[0] = MyRand();
  418. offset[1] = MyRand();
  419. offset[2] = MyRand();
  420. }
  421. ang = 260.0f * MyRand();
  422. rotAxis[0] = MyRand();
  423. rotAxis[1] = MyRand();
  424. rotAxis[2] = MyRand();
  425. iter = (int) (deviation * MyRand() + 60.0f);
  426. }