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.

543 lines
14 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: logend.cxx
  3. *
  4. * Copyright (c) 1997 Microsoft Corporation
  5. *
  6. \**************************************************************************/
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <sys/types.h>
  11. #include <stdlib.h>
  12. #include <time.h>
  13. #include "logon.hxx"
  14. static LOG_OBJECT *pHotObj;
  15. //#define FADING_CLEAR 1
  16. #define REDUCE_SIZE 1
  17. /******************** NEXT SEQUENCE ***************************************\
  18. *
  19. \**************************************************************************/
  20. static void ResetObjects()
  21. {
  22. ClearAll();
  23. // Move all objects to rest position
  24. #ifdef REDUCE_SIZE
  25. FSIZE imageSize;
  26. imageSize.width = imageSize.height = OBJECT_WIDTH / 2.0f;
  27. pHotObj->SetImageSize( &imageSize );
  28. #endif
  29. pHotObj->ResetMotion();
  30. SetObjectRestPositions();
  31. CalcObjectWindowRects();
  32. #ifdef FADING_CLEAR
  33. // Set clear color back to bg
  34. glClearColor( bgColor.r, bgColor.g, bgColor.b, bgColor.a );
  35. ClearAll();
  36. #endif
  37. Flush();
  38. }
  39. static BOOL
  40. LastKey(int key, GLenum mask)
  41. {
  42. switch( key ) {
  43. case TK_ESCAPE :
  44. mtkWin->Return();
  45. break;
  46. case TK_SPACE :
  47. if( bDebugMode ) {
  48. // Have to restore objects to centered state...
  49. ResetObjects();
  50. bRunAgain = TRUE;
  51. mtkWin->Return();
  52. }
  53. break;
  54. default :
  55. if( bDebugMode )
  56. return AttributeKey( key, mask );
  57. }
  58. return GL_FALSE;
  59. }
  60. static BOOL RunHoldSequence()
  61. {
  62. mtkWin->SetAnimateFunc( NULL );
  63. mtkWin->SetDisplayFunc( NULL );
  64. mtkWin->SetKeyDownFunc( LastKey );
  65. return mtkWin->Exec();
  66. }
  67. /******************** END FLY SEQUENCE ************************************\
  68. *
  69. * The 3 unselected objects move away, while selected one stays where it is.
  70. * Partway throught the move away, the selected one starts moving towards the
  71. * lower right corner, shrinking in size.
  72. *
  73. \**************************************************************************/
  74. static int iStartHotMotion, iDrawCounter;
  75. static BOOL bHotObjMoving;
  76. #ifdef REDUCE_SIZE
  77. // The image is reduced to its 32x32 icon size as it flies
  78. #define SMALL_BITMAP_SIZE 32
  79. static float deltaSize;
  80. static float curSize;
  81. #endif
  82. #ifdef FADING_CLEAR
  83. static RGBA curClearColor;
  84. static RGBA deltaClearColor;
  85. #endif
  86. static void
  87. ClearEndFly()
  88. {
  89. #ifdef FADING_CLEAR
  90. ClearAll();
  91. #else
  92. ClearWindow();
  93. #endif
  94. }
  95. static void
  96. InitHotFlyMotion( LOG_OBJECT *pObj )
  97. {
  98. // Calc destination (lower right corner of window)
  99. POINT3D destWin, dest;
  100. #define FMAGIC_WINZ 0.990991f // mf: by inspection...
  101. //mf: if used 1.0f above, bad things happened
  102. UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
  103. #ifdef REDUCE_SIZE
  104. // Figure out the final size of the object
  105. FSIZE finalSize;
  106. finalSize.height = (float) SMALL_BITMAP_SIZE;
  107. if( bFlyWithContext )
  108. finalSize.width = 2.0f * (float) SMALL_BITMAP_SIZE;
  109. else
  110. finalSize.width = (float) SMALL_BITMAP_SIZE;
  111. POINT3D blWin = { 0.0f, 0.0f, FMAGIC_WINZ };
  112. POINT3D trWin = { finalSize.width, finalSize.height, FMAGIC_WINZ };
  113. POINT3D bl, tr;
  114. TransformWindowToObject( &blWin, &bl );
  115. TransformWindowToObject( &trWin, &tr );
  116. float endSize = (float) fabs( tr.y - bl.y ); // y delta should be same
  117. // with or without context
  118. curSize = pObj->fImageSize.height;
  119. deltaSize = curSize - endSize; // divide by iter later...
  120. // Figure out destination in window coords
  121. destWin.x = (float) winSize.width - finalSize.width / 2.0f;
  122. destWin.y = (float) finalSize.height / 2.0f;
  123. destWin.z = FMAGIC_WINZ;
  124. TransformWindowToObject( &destWin, &dest );
  125. #else
  126. // Figure out destination in window coords
  127. GLIRECT rect;
  128. pObj->GetRect( &rect );
  129. destWin.x = (float) winSize.width - ((float) rect.width) / 2.0f;
  130. destWin.y = ((float) rect.height) / 2.0f;
  131. destWin.z = FMAGIC_WINZ;
  132. // Calc corresponding model-view coords (mf: function misnomer)
  133. TransformWindowToObject( &destWin, &dest );
  134. #endif
  135. POINT3D curDest, offset;
  136. pObj->GetDest( &curDest );
  137. offset.x = curDest.x - dest.x;
  138. offset.y = curDest.y - dest.y;
  139. offset.z = 0.0f;
  140. dest.z = 0.0f;
  141. pObj->SetDest( &dest );
  142. float deviation;
  143. deviation = MyRand() / 2;
  144. deviation = deviation * deviation;
  145. pObj->SetDampedFlyMotion( deviation, &offset );
  146. float fEndFlyIter = (float) pHotObj->GetIter();
  147. #ifdef FADING_CLEAR
  148. // Fade clear color to black
  149. curClearColor = bgColor;
  150. deltaClearColor.r = bgColor.r / fEndFlyIter;
  151. deltaClearColor.g = bgColor.g / fEndFlyIter;
  152. deltaClearColor.b = bgColor.b / fEndFlyIter;
  153. #endif
  154. #ifdef REDUCE_SIZE
  155. deltaSize /= fEndFlyIter;
  156. #endif
  157. }
  158. static void
  159. DrawLogonEndFlySequence()
  160. {
  161. BOOL bTransitionOver = TRUE;
  162. LOG_OBJECT *pObj;
  163. ClearEndFly();
  164. for( int i = 0; i < nLogObj; i ++ ) {
  165. pObj = pLogObj[i];
  166. if( pObj->NextFlyIteration() ) {
  167. // This object is moving
  168. bTransitionOver = FALSE; // 1 or more objects still moving
  169. pObj->Draw( bSwapHints );
  170. } else {
  171. // This object has stopped moving - if it's one of the unselected
  172. // objects that has moved offscreen, no need to draw it, but if it's
  173. // the selected object, draw it (since it won't be moving at the
  174. // beginning and we need to redraw it).
  175. if( pObj == pHotObj )
  176. pObj->Draw( bSwapHints );
  177. }
  178. }
  179. Flush();
  180. // Check if its time to start the hot object moving
  181. iDrawCounter++;
  182. if( iDrawCounter == iStartHotMotion ) {
  183. // Start moving the selected object
  184. InitHotFlyMotion( pHotObj );
  185. bHotObjMoving = TRUE;
  186. }
  187. if( bHotObjMoving ) {
  188. #ifdef FADING_CLEAR
  189. curClearColor.r -= deltaClearColor.r;
  190. curClearColor.g -= deltaClearColor.g;
  191. curClearColor.b -= deltaClearColor.b;
  192. glClearColor( curClearColor.r, curClearColor.g, curClearColor.b, 0.0f );
  193. #endif
  194. #ifdef REDUCE_SIZE
  195. FSIZE imageSize;
  196. curSize -= deltaSize;
  197. imageSize.width = imageSize.height = curSize;
  198. pHotObj->SetImageSize( &imageSize );
  199. #endif
  200. }
  201. if( bTransitionOver )
  202. mtkWin->Return();
  203. }
  204. static void
  205. CalcFlyAwayMotion( LOG_OBJECT *pObj, float deviation )
  206. {
  207. // Set destination
  208. POINT3D dest;
  209. // Pick random z destination value
  210. #if 0
  211. // z is in same range as in beginning of init sequence
  212. dest.z = MyRand(); // (-5 to 5)
  213. #else
  214. // Set z so objects are small
  215. dest.z = ss_fRand( -15.0f, 0.0f );
  216. #endif
  217. // Now set x and y so the object is out of the field of view
  218. // Pick random quadrant for object to end up in
  219. // 0 = right, 1 = top, 2 = left, 3 = bottom
  220. int quadrant = ss_iRand( 4 );
  221. // Find x and y boundaries at the z value
  222. float dist, xSize, ySize;
  223. dist = view.fViewDist - dest.z;
  224. ySize = (float) tan( SS_DEG_TO_RAD( view.fovy / 2.0f ) ) * dist;
  225. xSize = view.fAspect * ySize;
  226. // !!! This makes assumptions about object size...
  227. FSIZE max;
  228. max.height = ySize + OBJECT_WIDTH / 4.0f;
  229. if( bFlyWithContext ) {
  230. max.width = xSize + OBJECT_WIDTH / 2.0f;
  231. } else {
  232. max.width = xSize + OBJECT_WIDTH / 4.0f;
  233. }
  234. if( ss_iRand( 2 ) ) {
  235. // set x first
  236. dest.x = ss_fRand( -max.width, max.width );
  237. // adjust y
  238. if( ss_iRand( 2 ) )
  239. dest.y = max.height;
  240. else
  241. dest.y = -max.height;
  242. } else {
  243. // set y first
  244. dest.y = ss_fRand( -max.height, max.height);
  245. // adjust x
  246. if( ss_iRand( 2 ) )
  247. dest.x = max.width;
  248. else
  249. dest.x = -max.width;
  250. }
  251. // Calc offset values... (subtract new dest from current dest)
  252. POINT3D curDest, offset;
  253. pObj->GetDest( &curDest );
  254. offset.x = curDest.x - dest.x;
  255. offset.y = curDest.y - dest.y;
  256. offset.z = curDest.z - dest.z;
  257. pObj->SetDest( &dest );
  258. // Set rotation parameters
  259. pObj->SetDampedFlyMotion( deviation, &offset );
  260. }
  261. static void
  262. InitEndFlyMotion()
  263. {
  264. // The 3 unselected objects fly away, selected one stays where it is
  265. LOG_OBJECT *pObj;
  266. float deviation;
  267. deviation = MyRand() / 2;
  268. deviation = deviation * deviation;
  269. // Clear the screen, to get rid of banner, and context (if !bFlyWithContext)
  270. ClearAll();
  271. int iAverageIter = 0;
  272. for( int i = 0; i < nLogObj; i ++ ) {
  273. pObj = pLogObj[i];
  274. if( ! bFlyWithContext ) {
  275. // Redraw the object without its context
  276. pObj->ShowContext( FALSE );
  277. // again, have to offset. ? maybe ShowContext should do it ?
  278. pObj->OffsetDest( OBJECT_WIDTH / 4.0f, 0.0f, 0.0f );
  279. pObj->Draw();
  280. }
  281. if( pObj == pHotObj ) {
  282. pObj->ResetMotion();
  283. } else {
  284. CalcFlyAwayMotion( pObj, deviation );
  285. iAverageIter += pObj->GetIter();
  286. }
  287. }
  288. // Don't Flush here, since it will generate noticeable flash...
  289. iAverageIter /= 3;
  290. #if 0
  291. // Start hot obj moving halfway through the cycle
  292. iStartHotMotion = iAverageIter / 2;
  293. #else
  294. iStartHotMotion = (int) ( 0.75f * (float)iAverageIter );
  295. #endif
  296. iDrawCounter = 0;
  297. bHotObjMoving = FALSE;
  298. }
  299. static BOOL
  300. RunLogonEndFlySequence()
  301. {
  302. UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
  303. InitEndFlyMotion();
  304. // Set any gl attributes
  305. glDisable(GL_CULL_FACE);
  306. bSwapHints = FALSE;
  307. #ifdef SWAP_HINTS_ON_FLYS
  308. #ifndef FADING_CLEAR
  309. bSwapHints = bSwapHintsEnabled;
  310. #endif
  311. #endif
  312. // mtk callbacks
  313. mtkWin->SetAnimateFunc( DrawLogonEndFlySequence );
  314. mtkWin->SetDisplayFunc( DrawLogonEndFlySequence );
  315. return mtkWin->Exec();
  316. }
  317. /******************** FADE SEQUENCE ***************************************\
  318. *
  319. \**************************************************************************/
  320. static float alphaCol[4];
  321. static int iFadeIters;
  322. static float alphaDelta;
  323. static void InitFade()
  324. {
  325. alphaCol[0] = alphaCol[1] = alphaCol[2] = 0.0f;
  326. #if 1
  327. alphaCol[3] = 1.0f;
  328. #else
  329. // mf: To show alpha clamping problem...
  330. alphaCol[3] = 0.1f;
  331. #endif
  332. iFadeIters = 20;
  333. alphaDelta = 1.0f / (float) (iFadeIters-1);
  334. }
  335. static void DrawEndFadeSequence(void)
  336. {
  337. int i, j;
  338. BOOL bTransitionOver = FALSE;
  339. float updatesPerSecond;
  340. LOG_OBJECT *pObj;
  341. ClearWindow();
  342. for( i = 0; i < nLogObj; i++ ) {
  343. pObj = pLogObj[i];
  344. if( (pObj == pHotObj) ) {
  345. if( bSwapHints ) {
  346. // Don't need to redraw this one
  347. continue;
  348. }
  349. glDisable( GL_BLEND );
  350. } else {
  351. glColor4fv( alphaCol );
  352. glEnable( GL_BLEND );
  353. }
  354. pObj->Draw( FALSE );
  355. }
  356. Flush();
  357. // Decrement counter, setup next alpha color
  358. if( --iFadeIters <= 0 )
  359. bTransitionOver = TRUE;
  360. alphaCol[3] -= alphaDelta;
  361. // Print timing information if required
  362. if( bDebugMode ) {
  363. char szMsg[80];
  364. if( bTransitionOver ) {
  365. sprintf(szMsg, "%s: %.2lf sec",
  366. "Transition time ",
  367. transitionTimer.Stop() );
  368. // Print transition timing info in title bar
  369. SetWindowText( mtkWin->GetHWND(), szMsg );
  370. } else if( frameRateTimer.Update( 1, &updatesPerSecond ) ) {
  371. sprintf(szMsg, "%s: %.2lf frames/sec",
  372. "",
  373. updatesPerSecond );
  374. // Print frame timing info in title bar
  375. SetWindowText( mtkWin->GetHWND(), szMsg );
  376. }
  377. }
  378. if( bTransitionOver ) {
  379. glDisable( GL_BLEND );
  380. mtkWin->Return();
  381. }
  382. }
  383. static BOOL
  384. RunLogonEndFadeSequence()
  385. {
  386. // Set any gl attributes
  387. glEnable(GL_CULL_FACE);
  388. bSwapHints = bSwapHintsEnabled;
  389. // The fadeout will be done with blending to the background color
  390. InitFade();
  391. glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  392. mtkWin->SetDisplayFunc( DrawEndFadeSequence );
  393. mtkWin->SetAnimateFunc( DrawEndFadeSequence );
  394. if( bDebugMode ) {
  395. frameRateTimer.Reset();
  396. frameRateTimer.Start();
  397. transitionTimer.Reset();
  398. transitionTimer.Start();
  399. }
  400. return mtkWin->Exec();
  401. }
  402. /******************** END SEQUENCE ************************************\
  403. *
  404. * Previously the end sequence had 2 steps: Transition away the unselected
  405. * objects, then fly the selected one to lower right corner. These 2 steps
  406. * have now been combined into one sequence.
  407. \**************************************************************************/
  408. //#define FADE_AWAY 1
  409. BOOL
  410. RunLogonUnselectSequence()
  411. {
  412. #ifdef FADE_AWAY
  413. //mf: this is no longer valid
  414. RunLogonEndFadeSequence();
  415. #else
  416. RunLogonEndFlySequence();
  417. #endif
  418. return TRUE;
  419. }
  420. BOOL
  421. RunLogonEndSequence( LOG_OBJECT *pObj )
  422. {
  423. BOOL bRet;
  424. SS_DBGPRINT( "RunLogonEndSequence()\n" );
  425. if( !pObj )
  426. SS_DBGPRINT( "RunLogonEndSequence : pObj arg is NULL\n" );
  427. if( bDebugMode )
  428. bRunAgain = FALSE;
  429. pHotObj = pObj;
  430. // The selected object is pHotObj
  431. // Phase 1 : fade out or fly away non-selected quads
  432. // Phase 2 : fly selected one to lower right
  433. mtkWin->SetMouseMoveFunc( NULL );
  434. mtkWin->SetMouseDownFunc( NULL );
  435. mtkWin->SetKeyDownFunc(EscKey);
  436. if( ! RunLogonUnselectSequence() )
  437. return FALSE;
  438. // in debug mode hold it here, instead of exiting
  439. if( bDebugMode )
  440. return RunHoldSequence();
  441. return TRUE;
  442. }