544 lines
14 KiB
C++
544 lines
14 KiB
C++
/******************************Module*Header*******************************\
|
|
* Module Name: logend.cxx
|
|
*
|
|
* Copyright (c) 1997 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <sys/types.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
#include "logon.hxx"
|
|
|
|
static LOG_OBJECT *pHotObj;
|
|
//#define FADING_CLEAR 1
|
|
#define REDUCE_SIZE 1
|
|
|
|
/******************** NEXT SEQUENCE ***************************************\
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static void ResetObjects()
|
|
{
|
|
ClearAll();
|
|
|
|
// Move all objects to rest position
|
|
#ifdef REDUCE_SIZE
|
|
FSIZE imageSize;
|
|
imageSize.width = imageSize.height = OBJECT_WIDTH / 2.0f;
|
|
pHotObj->SetImageSize( &imageSize );
|
|
#endif
|
|
pHotObj->ResetMotion();
|
|
SetObjectRestPositions();
|
|
CalcObjectWindowRects();
|
|
|
|
#ifdef FADING_CLEAR
|
|
// Set clear color back to bg
|
|
glClearColor( bgColor.r, bgColor.g, bgColor.b, bgColor.a );
|
|
ClearAll();
|
|
#endif
|
|
Flush();
|
|
}
|
|
|
|
static BOOL
|
|
LastKey(int key, GLenum mask)
|
|
{
|
|
switch( key ) {
|
|
case TK_ESCAPE :
|
|
mtkWin->Return();
|
|
break;
|
|
case TK_SPACE :
|
|
if( bDebugMode ) {
|
|
// Have to restore objects to centered state...
|
|
ResetObjects();
|
|
bRunAgain = TRUE;
|
|
mtkWin->Return();
|
|
}
|
|
break;
|
|
default :
|
|
if( bDebugMode )
|
|
return AttributeKey( key, mask );
|
|
}
|
|
return GL_FALSE;
|
|
}
|
|
|
|
|
|
static BOOL RunHoldSequence()
|
|
{
|
|
mtkWin->SetAnimateFunc( NULL );
|
|
mtkWin->SetDisplayFunc( NULL );
|
|
mtkWin->SetKeyDownFunc( LastKey );
|
|
return mtkWin->Exec();
|
|
}
|
|
|
|
|
|
/******************** END FLY SEQUENCE ************************************\
|
|
*
|
|
* The 3 unselected objects move away, while selected one stays where it is.
|
|
* Partway throught the move away, the selected one starts moving towards the
|
|
* lower right corner, shrinking in size.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static int iStartHotMotion, iDrawCounter;
|
|
static BOOL bHotObjMoving;
|
|
#ifdef REDUCE_SIZE
|
|
// The image is reduced to its 32x32 icon size as it flies
|
|
#define SMALL_BITMAP_SIZE 32
|
|
static float deltaSize;
|
|
static float curSize;
|
|
#endif
|
|
|
|
#ifdef FADING_CLEAR
|
|
static RGBA curClearColor;
|
|
static RGBA deltaClearColor;
|
|
#endif
|
|
|
|
|
|
static void
|
|
ClearEndFly()
|
|
{
|
|
#ifdef FADING_CLEAR
|
|
ClearAll();
|
|
#else
|
|
ClearWindow();
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
InitHotFlyMotion( LOG_OBJECT *pObj )
|
|
{
|
|
// Calc destination (lower right corner of window)
|
|
POINT3D destWin, dest;
|
|
|
|
#define FMAGIC_WINZ 0.990991f // mf: by inspection...
|
|
//mf: if used 1.0f above, bad things happened
|
|
|
|
UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
|
|
|
|
#ifdef REDUCE_SIZE
|
|
// Figure out the final size of the object
|
|
FSIZE finalSize;
|
|
finalSize.height = (float) SMALL_BITMAP_SIZE;
|
|
if( bFlyWithContext )
|
|
finalSize.width = 2.0f * (float) SMALL_BITMAP_SIZE;
|
|
else
|
|
finalSize.width = (float) SMALL_BITMAP_SIZE;
|
|
|
|
POINT3D blWin = { 0.0f, 0.0f, FMAGIC_WINZ };
|
|
POINT3D trWin = { finalSize.width, finalSize.height, FMAGIC_WINZ };
|
|
POINT3D bl, tr;
|
|
TransformWindowToObject( &blWin, &bl );
|
|
TransformWindowToObject( &trWin, &tr );
|
|
float endSize = (float) fabs( tr.y - bl.y ); // y delta should be same
|
|
// with or without context
|
|
|
|
curSize = pObj->fImageSize.height;
|
|
deltaSize = curSize - endSize; // divide by iter later...
|
|
|
|
// Figure out destination in window coords
|
|
destWin.x = (float) winSize.width - finalSize.width / 2.0f;
|
|
destWin.y = (float) finalSize.height / 2.0f;
|
|
destWin.z = FMAGIC_WINZ;
|
|
TransformWindowToObject( &destWin, &dest );
|
|
#else
|
|
// Figure out destination in window coords
|
|
GLIRECT rect;
|
|
pObj->GetRect( &rect );
|
|
destWin.x = (float) winSize.width - ((float) rect.width) / 2.0f;
|
|
destWin.y = ((float) rect.height) / 2.0f;
|
|
destWin.z = FMAGIC_WINZ;
|
|
|
|
// Calc corresponding model-view coords (mf: function misnomer)
|
|
TransformWindowToObject( &destWin, &dest );
|
|
#endif
|
|
|
|
|
|
POINT3D curDest, offset;
|
|
pObj->GetDest( &curDest );
|
|
offset.x = curDest.x - dest.x;
|
|
offset.y = curDest.y - dest.y;
|
|
offset.z = 0.0f;
|
|
|
|
dest.z = 0.0f;
|
|
pObj->SetDest( &dest );
|
|
|
|
float deviation;
|
|
deviation = MyRand() / 2;
|
|
deviation = deviation * deviation;
|
|
|
|
pObj->SetDampedFlyMotion( deviation, &offset );
|
|
|
|
float fEndFlyIter = (float) pHotObj->GetIter();
|
|
#ifdef FADING_CLEAR
|
|
// Fade clear color to black
|
|
curClearColor = bgColor;
|
|
deltaClearColor.r = bgColor.r / fEndFlyIter;
|
|
deltaClearColor.g = bgColor.g / fEndFlyIter;
|
|
deltaClearColor.b = bgColor.b / fEndFlyIter;
|
|
#endif
|
|
|
|
#ifdef REDUCE_SIZE
|
|
deltaSize /= fEndFlyIter;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
DrawLogonEndFlySequence()
|
|
{
|
|
BOOL bTransitionOver = TRUE;
|
|
LOG_OBJECT *pObj;
|
|
|
|
ClearEndFly();
|
|
|
|
for( int i = 0; i < nLogObj; i ++ ) {
|
|
pObj = pLogObj[i];
|
|
if( pObj->NextFlyIteration() ) {
|
|
// This object is moving
|
|
bTransitionOver = FALSE; // 1 or more objects still moving
|
|
pObj->Draw( bSwapHints );
|
|
} else {
|
|
// This object has stopped moving - if it's one of the unselected
|
|
// objects that has moved offscreen, no need to draw it, but if it's
|
|
// the selected object, draw it (since it won't be moving at the
|
|
// beginning and we need to redraw it).
|
|
if( pObj == pHotObj )
|
|
pObj->Draw( bSwapHints );
|
|
}
|
|
}
|
|
Flush();
|
|
|
|
// Check if its time to start the hot object moving
|
|
iDrawCounter++;
|
|
if( iDrawCounter == iStartHotMotion ) {
|
|
// Start moving the selected object
|
|
InitHotFlyMotion( pHotObj );
|
|
bHotObjMoving = TRUE;
|
|
}
|
|
|
|
if( bHotObjMoving ) {
|
|
#ifdef FADING_CLEAR
|
|
curClearColor.r -= deltaClearColor.r;
|
|
curClearColor.g -= deltaClearColor.g;
|
|
curClearColor.b -= deltaClearColor.b;
|
|
glClearColor( curClearColor.r, curClearColor.g, curClearColor.b, 0.0f );
|
|
#endif
|
|
#ifdef REDUCE_SIZE
|
|
FSIZE imageSize;
|
|
curSize -= deltaSize;
|
|
imageSize.width = imageSize.height = curSize;
|
|
pHotObj->SetImageSize( &imageSize );
|
|
#endif
|
|
}
|
|
|
|
if( bTransitionOver )
|
|
mtkWin->Return();
|
|
}
|
|
|
|
static void
|
|
CalcFlyAwayMotion( LOG_OBJECT *pObj, float deviation )
|
|
{
|
|
// Set destination
|
|
POINT3D dest;
|
|
|
|
// Pick random z destination value
|
|
#if 0
|
|
// z is in same range as in beginning of init sequence
|
|
dest.z = MyRand(); // (-5 to 5)
|
|
#else
|
|
// Set z so objects are small
|
|
dest.z = ss_fRand( -15.0f, 0.0f );
|
|
#endif
|
|
|
|
// Now set x and y so the object is out of the field of view
|
|
|
|
// Pick random quadrant for object to end up in
|
|
// 0 = right, 1 = top, 2 = left, 3 = bottom
|
|
int quadrant = ss_iRand( 4 );
|
|
|
|
// Find x and y boundaries at the z value
|
|
float dist, xSize, ySize;
|
|
dist = view.fViewDist - dest.z;
|
|
ySize = (float) tan( SS_DEG_TO_RAD( view.fovy / 2.0f ) ) * dist;
|
|
xSize = view.fAspect * ySize;
|
|
|
|
// !!! This makes assumptions about object size...
|
|
FSIZE max;
|
|
max.height = ySize + OBJECT_WIDTH / 4.0f;
|
|
if( bFlyWithContext ) {
|
|
max.width = xSize + OBJECT_WIDTH / 2.0f;
|
|
} else {
|
|
max.width = xSize + OBJECT_WIDTH / 4.0f;
|
|
}
|
|
|
|
if( ss_iRand( 2 ) ) {
|
|
// set x first
|
|
dest.x = ss_fRand( -max.width, max.width );
|
|
// adjust y
|
|
if( ss_iRand( 2 ) )
|
|
dest.y = max.height;
|
|
else
|
|
dest.y = -max.height;
|
|
} else {
|
|
// set y first
|
|
dest.y = ss_fRand( -max.height, max.height);
|
|
// adjust x
|
|
if( ss_iRand( 2 ) )
|
|
dest.x = max.width;
|
|
else
|
|
dest.x = -max.width;
|
|
}
|
|
|
|
// Calc offset values... (subtract new dest from current dest)
|
|
|
|
POINT3D curDest, offset;
|
|
pObj->GetDest( &curDest );
|
|
offset.x = curDest.x - dest.x;
|
|
offset.y = curDest.y - dest.y;
|
|
offset.z = curDest.z - dest.z;
|
|
|
|
pObj->SetDest( &dest );
|
|
|
|
// Set rotation parameters
|
|
|
|
pObj->SetDampedFlyMotion( deviation, &offset );
|
|
}
|
|
|
|
static void
|
|
InitEndFlyMotion()
|
|
{
|
|
// The 3 unselected objects fly away, selected one stays where it is
|
|
|
|
LOG_OBJECT *pObj;
|
|
float deviation;
|
|
deviation = MyRand() / 2;
|
|
deviation = deviation * deviation;
|
|
|
|
// Clear the screen, to get rid of banner, and context (if !bFlyWithContext)
|
|
ClearAll();
|
|
|
|
int iAverageIter = 0;
|
|
for( int i = 0; i < nLogObj; i ++ ) {
|
|
pObj = pLogObj[i];
|
|
|
|
if( ! bFlyWithContext ) {
|
|
// Redraw the object without its context
|
|
pObj->ShowContext( FALSE );
|
|
// again, have to offset. ? maybe ShowContext should do it ?
|
|
pObj->OffsetDest( OBJECT_WIDTH / 4.0f, 0.0f, 0.0f );
|
|
pObj->Draw();
|
|
}
|
|
|
|
if( pObj == pHotObj ) {
|
|
pObj->ResetMotion();
|
|
} else {
|
|
CalcFlyAwayMotion( pObj, deviation );
|
|
iAverageIter += pObj->GetIter();
|
|
}
|
|
}
|
|
// Don't Flush here, since it will generate noticeable flash...
|
|
|
|
iAverageIter /= 3;
|
|
#if 0
|
|
// Start hot obj moving halfway through the cycle
|
|
iStartHotMotion = iAverageIter / 2;
|
|
#else
|
|
iStartHotMotion = (int) ( 0.75f * (float)iAverageIter );
|
|
#endif
|
|
iDrawCounter = 0;
|
|
bHotObjMoving = FALSE;
|
|
}
|
|
|
|
static BOOL
|
|
RunLogonEndFlySequence()
|
|
{
|
|
UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
|
|
|
|
InitEndFlyMotion();
|
|
|
|
// Set any gl attributes
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
bSwapHints = FALSE;
|
|
#ifdef SWAP_HINTS_ON_FLYS
|
|
#ifndef FADING_CLEAR
|
|
bSwapHints = bSwapHintsEnabled;
|
|
#endif
|
|
#endif
|
|
|
|
// mtk callbacks
|
|
|
|
mtkWin->SetAnimateFunc( DrawLogonEndFlySequence );
|
|
mtkWin->SetDisplayFunc( DrawLogonEndFlySequence );
|
|
return mtkWin->Exec();
|
|
}
|
|
|
|
|
|
/******************** FADE SEQUENCE ***************************************\
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static float alphaCol[4];
|
|
static int iFadeIters;
|
|
static float alphaDelta;
|
|
|
|
static void InitFade()
|
|
{
|
|
alphaCol[0] = alphaCol[1] = alphaCol[2] = 0.0f;
|
|
#if 1
|
|
alphaCol[3] = 1.0f;
|
|
#else
|
|
// mf: To show alpha clamping problem...
|
|
alphaCol[3] = 0.1f;
|
|
#endif
|
|
|
|
iFadeIters = 20;
|
|
alphaDelta = 1.0f / (float) (iFadeIters-1);
|
|
}
|
|
|
|
static void DrawEndFadeSequence(void)
|
|
{
|
|
int i, j;
|
|
BOOL bTransitionOver = FALSE;
|
|
float updatesPerSecond;
|
|
LOG_OBJECT *pObj;
|
|
|
|
ClearWindow();
|
|
|
|
for( i = 0; i < nLogObj; i++ ) {
|
|
pObj = pLogObj[i];
|
|
|
|
if( (pObj == pHotObj) ) {
|
|
if( bSwapHints ) {
|
|
// Don't need to redraw this one
|
|
continue;
|
|
}
|
|
glDisable( GL_BLEND );
|
|
} else {
|
|
glColor4fv( alphaCol );
|
|
glEnable( GL_BLEND );
|
|
}
|
|
|
|
pObj->Draw( FALSE );
|
|
}
|
|
|
|
Flush();
|
|
|
|
// Decrement counter, setup next alpha color
|
|
|
|
if( --iFadeIters <= 0 )
|
|
bTransitionOver = TRUE;
|
|
|
|
alphaCol[3] -= alphaDelta;
|
|
|
|
// Print timing information if required
|
|
|
|
if( bDebugMode ) {
|
|
char szMsg[80];
|
|
if( bTransitionOver ) {
|
|
sprintf(szMsg, "%s: %.2lf sec",
|
|
"Transition time ",
|
|
transitionTimer.Stop() );
|
|
|
|
// Print transition timing info in title bar
|
|
SetWindowText( mtkWin->GetHWND(), szMsg );
|
|
} else if( frameRateTimer.Update( 1, &updatesPerSecond ) ) {
|
|
sprintf(szMsg, "%s: %.2lf frames/sec",
|
|
"",
|
|
updatesPerSecond );
|
|
|
|
// Print frame timing info in title bar
|
|
SetWindowText( mtkWin->GetHWND(), szMsg );
|
|
}
|
|
}
|
|
|
|
if( bTransitionOver ) {
|
|
glDisable( GL_BLEND );
|
|
mtkWin->Return();
|
|
}
|
|
}
|
|
|
|
|
|
static BOOL
|
|
RunLogonEndFadeSequence()
|
|
{
|
|
// Set any gl attributes
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
bSwapHints = bSwapHintsEnabled;
|
|
|
|
// The fadeout will be done with blending to the background color
|
|
InitFade();
|
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
|
mtkWin->SetDisplayFunc( DrawEndFadeSequence );
|
|
mtkWin->SetAnimateFunc( DrawEndFadeSequence );
|
|
|
|
if( bDebugMode ) {
|
|
frameRateTimer.Reset();
|
|
frameRateTimer.Start();
|
|
|
|
transitionTimer.Reset();
|
|
transitionTimer.Start();
|
|
}
|
|
return mtkWin->Exec();
|
|
}
|
|
|
|
/******************** END SEQUENCE ************************************\
|
|
*
|
|
* Previously the end sequence had 2 steps: Transition away the unselected
|
|
* objects, then fly the selected one to lower right corner. These 2 steps
|
|
* have now been combined into one sequence.
|
|
\**************************************************************************/
|
|
|
|
//#define FADE_AWAY 1
|
|
|
|
BOOL
|
|
RunLogonUnselectSequence()
|
|
{
|
|
#ifdef FADE_AWAY
|
|
//mf: this is no longer valid
|
|
RunLogonEndFadeSequence();
|
|
#else
|
|
RunLogonEndFlySequence();
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
RunLogonEndSequence( LOG_OBJECT *pObj )
|
|
{
|
|
BOOL bRet;
|
|
|
|
SS_DBGPRINT( "RunLogonEndSequence()\n" );
|
|
|
|
if( !pObj )
|
|
SS_DBGPRINT( "RunLogonEndSequence : pObj arg is NULL\n" );
|
|
|
|
if( bDebugMode )
|
|
bRunAgain = FALSE;
|
|
|
|
pHotObj = pObj;
|
|
|
|
// The selected object is pHotObj
|
|
|
|
// Phase 1 : fade out or fly away non-selected quads
|
|
// Phase 2 : fly selected one to lower right
|
|
|
|
mtkWin->SetMouseMoveFunc( NULL );
|
|
mtkWin->SetMouseDownFunc( NULL );
|
|
mtkWin->SetKeyDownFunc(EscKey);
|
|
|
|
if( ! RunLogonUnselectSequence() )
|
|
return FALSE;
|
|
|
|
// in debug mode hold it here, instead of exiting
|
|
if( bDebugMode )
|
|
return RunHoldSequence();
|
|
|
|
return TRUE;
|
|
}
|