528 lines
12 KiB
C++
528 lines
12 KiB
C++
|
/**************************************************************************\
|
||
|
*
|
||
|
* Module Name: logon.cxx
|
||
|
*
|
||
|
* Copyright (c) 1997 Microsoft Corporation
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <math.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include "logon.hxx"
|
||
|
#include "logobj.hxx"
|
||
|
#include "util.hxx"
|
||
|
|
||
|
static GLIRECT nullRect = {0};
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* LOG_OBJECT
|
||
|
*
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
//#define DEEP_FRAME 1
|
||
|
|
||
|
LOG_OBJECT::LOG_OBJECT()
|
||
|
{
|
||
|
pTex = NULL;
|
||
|
|
||
|
// Set some default size values...
|
||
|
|
||
|
fImageSize.width = fImageSize.height = OBJECT_WIDTH;
|
||
|
bShowContext = FALSE; // Only show image to start
|
||
|
fCurContextWidth = 0.0f;
|
||
|
fMaxContextWidth = OBJECT_WIDTH / 2.0f;
|
||
|
|
||
|
#if DEEP_FRAME
|
||
|
fFrameSize.width = fFrameSize.height = FRAME_SIZE;
|
||
|
#else
|
||
|
fFrameSize.width = fFrameSize.height = 0.0f;
|
||
|
#endif
|
||
|
bFramed = FALSE;
|
||
|
// fFrameDepth is depth offset in z-direction. Since the frame is usually
|
||
|
// drawn further away from the viewer (down -z axis), it is negative.
|
||
|
#if DEEP_FRAME
|
||
|
fFrameDepth = - 3.3f;
|
||
|
#else
|
||
|
fFrameDepth = - FRAME_DEPTH;
|
||
|
#endif
|
||
|
bSwapHints = FALSE;
|
||
|
dest[0] = dest[1] = dest[2] = 0.0f;
|
||
|
ResetMotion();
|
||
|
|
||
|
rect = nullRect;
|
||
|
|
||
|
// Calc initial coords
|
||
|
|
||
|
CalcCoords();
|
||
|
}
|
||
|
|
||
|
LOG_OBJECT::~LOG_OBJECT()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::ShowFrame( BOOL bShow )
|
||
|
{
|
||
|
if( bFramed == bShow )
|
||
|
return;
|
||
|
|
||
|
// new state
|
||
|
bFramed = bShow;
|
||
|
if( bFramed ) {
|
||
|
// mf : could optimize by not redoing this if framesize constant...
|
||
|
CalcFrameCoords();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::ShowContext( BOOL bShow )
|
||
|
{
|
||
|
if( bShowContext == bShow )
|
||
|
return;
|
||
|
|
||
|
// new state
|
||
|
bShowContext = bShow;
|
||
|
CalcCoords();
|
||
|
//mf: !!! readjust dest to reflect this ?
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::SetDest( float x, float y, float z )
|
||
|
{
|
||
|
dest[0] = x;
|
||
|
dest[1] = y;
|
||
|
dest[2] = z;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::SetDest( POINT3D *pDest )
|
||
|
{
|
||
|
dest[0] = pDest->x;
|
||
|
dest[1] = pDest->y;
|
||
|
dest[2] = pDest->z;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::GetDest( POINT3D *pDest )
|
||
|
{
|
||
|
pDest->x = dest[0];
|
||
|
pDest->y = dest[1];
|
||
|
pDest->z = dest[2];
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::OffsetDest( float x, float y, float z )
|
||
|
{
|
||
|
dest[0] += x;
|
||
|
dest[1] += y;
|
||
|
dest[2] += z;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::SetTexture( TEXTURE *pTexture )
|
||
|
{
|
||
|
pTex = pTexture;
|
||
|
if( !pTex )
|
||
|
return;
|
||
|
|
||
|
// Set the size of the object based on the aspect ratio of the texture
|
||
|
// The textures for all the objects should have the same dimensions.
|
||
|
|
||
|
float aspectRatio = pTex->GetAspectRatio(); // width/height
|
||
|
|
||
|
// The texture is assumed to have an image on the right, and context on
|
||
|
// the left, of equal size
|
||
|
|
||
|
// We'll keep the width consant, and vary height according to aspect
|
||
|
|
||
|
fImageSize.width = OBJECT_WIDTH / 2.0f;
|
||
|
fImageSize.height = OBJECT_WIDTH / aspectRatio;
|
||
|
|
||
|
fMaxContextWidth = fImageSize.width;
|
||
|
fCurContextWidth = fMaxContextWidth;
|
||
|
|
||
|
CalcCoords();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::SetContextSize( float fPortion )
|
||
|
{
|
||
|
// This sets the visible portion of the context ( 0.0 - 1.0 )
|
||
|
|
||
|
fCurContextWidth = fPortion * fMaxContextWidth;
|
||
|
|
||
|
// Recalc coords
|
||
|
CalcCoords();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::SetImageSize( FSIZE *pSize )
|
||
|
{
|
||
|
fImageSize = *pSize;
|
||
|
float fPortion = fCurContextWidth / fMaxContextWidth;
|
||
|
fMaxContextWidth = fImageSize.width;
|
||
|
fCurContextWidth = fPortion * fMaxContextWidth;
|
||
|
CalcCoords();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::Translate()
|
||
|
{
|
||
|
glTranslatef(dest[0]+offset[0], dest[1]+offset[1], dest[2]+offset[2]);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::Rotate()
|
||
|
{
|
||
|
if( ang != 0.0f )
|
||
|
glRotatef(ang, rotAxis[0], rotAxis[1], rotAxis[2]);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::Draw()
|
||
|
{
|
||
|
Draw( FALSE );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::Draw( BOOL bUpdateWinRect )
|
||
|
{
|
||
|
// Draws object in its current position
|
||
|
|
||
|
// An object either has its context showing on the right or not. If not,
|
||
|
// then origin is the centre of the image, else origin is on border of
|
||
|
// image and context
|
||
|
|
||
|
pTex->MakeCurrent(); // Set the objects texture
|
||
|
glPushMatrix();
|
||
|
Translate();
|
||
|
Rotate();
|
||
|
if( bUpdateWinRect ) {
|
||
|
UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
|
||
|
CalcWinRect( FALSE );
|
||
|
}
|
||
|
DrawFace();
|
||
|
if( bFramed )
|
||
|
DrawFrame();
|
||
|
glPopMatrix();
|
||
|
if( bSwapHints )
|
||
|
AddSwapHintRect( &rect );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::DrawFace()
|
||
|
{
|
||
|
glNormal3f( 0.0f, 0.0f, 1.0f );
|
||
|
glBegin( GL_QUADS );
|
||
|
glTexCoord2fv( (float *) &texPoint[0] );
|
||
|
glVertex2fv( (float *) &point[0] );
|
||
|
glTexCoord2fv( (float *) &texPoint[1] );
|
||
|
glVertex2fv( (float *) &point[1] );
|
||
|
glTexCoord2fv( (float *) &texPoint[2] );
|
||
|
glVertex2fv( (float *) &point[2] );
|
||
|
glTexCoord2fv( (float *) &texPoint[3] );
|
||
|
glVertex2fv( (float *) &point[3] );
|
||
|
glEnd();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::DrawFrame()
|
||
|
{
|
||
|
glDisable( GL_TEXTURE_2D );
|
||
|
glEnable( GL_LIGHTING );
|
||
|
|
||
|
glBegin( GL_QUADS );
|
||
|
|
||
|
glNormal3fv( (float *) &frameNormal[0] );
|
||
|
glVertex3fv( (float *) &point[0] );
|
||
|
glVertex3fv( (float *) &point[4] );
|
||
|
glVertex3fv( (float *) &point[7] );
|
||
|
glVertex3fv( (float *) &point[3] );
|
||
|
|
||
|
glNormal3fv( (float *) &frameNormal[1] );
|
||
|
glVertex3fv( (float *) &point[1] );
|
||
|
glVertex3fv( (float *) &point[5] );
|
||
|
glVertex3fv( (float *) &point[4] );
|
||
|
glVertex3fv( (float *) &point[0] );
|
||
|
|
||
|
glNormal3fv( (float *) &frameNormal[2] );
|
||
|
glVertex3fv( (float *) &point[2] );
|
||
|
glVertex3fv( (float *) &point[6] );
|
||
|
glVertex3fv( (float *) &point[5] );
|
||
|
glVertex3fv( (float *) &point[1] );
|
||
|
|
||
|
glNormal3fv( (float *) &frameNormal[3] );
|
||
|
glVertex3fv( (float *) &point[3] );
|
||
|
glVertex3fv( (float *) &point[7] );
|
||
|
glVertex3fv( (float *) &point[6] );
|
||
|
glVertex3fv( (float *) &point[2] );
|
||
|
|
||
|
glEnd();
|
||
|
|
||
|
glDisable( GL_LIGHTING );
|
||
|
glEnable( GL_TEXTURE_2D );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::CalcWinRect()
|
||
|
{
|
||
|
CalcWinRect( TRUE );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::CalcWinRect( BOOL bTransform )
|
||
|
{
|
||
|
POINT3D ptOut[8];
|
||
|
int nPts = bFramed ? 8 : 4;
|
||
|
|
||
|
if( bTransform ) {
|
||
|
// Need to transorm object according to current translation & rotation
|
||
|
glPushMatrix();
|
||
|
Translate();
|
||
|
Rotate();
|
||
|
UpdateLocalTransforms( UPDATE_MODELVIEW_MATRIX_BIT );
|
||
|
glPopMatrix();
|
||
|
}
|
||
|
|
||
|
TransformObjectToWindow( point, ptOut, nPts );
|
||
|
|
||
|
// Update the rect member
|
||
|
CalcMinMaxRect( ptOut, &rect, nPts );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::CalcCoords()
|
||
|
{
|
||
|
POINT3D *pt;
|
||
|
|
||
|
// Calculate object coords based on current state of the object. If
|
||
|
// bShowContext, then origin is in centre of object, else it's in centre
|
||
|
// of image part of object.
|
||
|
// Also calculate frame coords if applicable.
|
||
|
|
||
|
// Points are ordered CCW from top right for each face
|
||
|
|
||
|
pt = point;
|
||
|
pt[0].z = pt[1].z = pt[2].z = pt[3].z = 0.0f;
|
||
|
|
||
|
// Calc front face points
|
||
|
|
||
|
if( ! bShowContext ) {
|
||
|
POINT2D image = { fImageSize.width / 2.0f, fImageSize.height / 2.0f };
|
||
|
|
||
|
pt[0].x = image.x;
|
||
|
pt[0].y = image.y;
|
||
|
pt[1].x = -image.x;
|
||
|
pt[1].y = image.y;
|
||
|
pt[2].x = -image.x;
|
||
|
pt[2].y = -image.y;
|
||
|
pt[3].x = image.x;
|
||
|
pt[3].y = -image.y;
|
||
|
} else {
|
||
|
POINT2D image = { fImageSize.width, fImageSize.height / 2.0f };
|
||
|
|
||
|
pt[0].x = image.x;
|
||
|
pt[0].y = image.y;
|
||
|
pt[1].x = -fCurContextWidth;
|
||
|
pt[1].y = image.y;
|
||
|
pt[2].x = -fCurContextWidth;
|
||
|
pt[2].y = -image.y;
|
||
|
pt[3].x = image.x;
|
||
|
pt[3].y = -image.y;
|
||
|
}
|
||
|
|
||
|
// Calc frame points
|
||
|
|
||
|
if( bFramed ) {
|
||
|
CalcFrameCoords();
|
||
|
}
|
||
|
|
||
|
// Always need the texture coords
|
||
|
//mf: optimize...
|
||
|
CalcTexCoords();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::CalcFrameCoords()
|
||
|
{
|
||
|
POINT3D *frontPt = point;
|
||
|
POINT3D *pt = point + 4;
|
||
|
|
||
|
pt[0].z = pt[1].z = pt[2].z = pt[3].z = fFrameDepth;
|
||
|
|
||
|
pt[0].x = frontPt[0].x + fFrameSize.width;
|
||
|
pt[0].y = frontPt[0].y + fFrameSize.height;
|
||
|
pt[1].x = frontPt[1].x - fFrameSize.width;
|
||
|
pt[1].y = frontPt[1].y + fFrameSize.height;
|
||
|
pt[2].x = frontPt[2].x - fFrameSize.width;
|
||
|
pt[2].y = frontPt[2].y - fFrameSize.height;
|
||
|
pt[3].x = frontPt[3].x + fFrameSize.width;
|
||
|
pt[3].y = frontPt[3].y - fFrameSize.height;
|
||
|
|
||
|
// May as well do the normals too
|
||
|
CalcFrameNormals();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::CalcFrameNormals()
|
||
|
{
|
||
|
POINT3D *pNorm = frameNormal;
|
||
|
|
||
|
float fDepth = fFrameDepth;
|
||
|
float fFramex = fFrameSize.width;
|
||
|
float fFramey = fFrameSize.height;
|
||
|
|
||
|
// Calc the face normals for the sides of the frame. The faces are
|
||
|
// ordered CCW from the right face.
|
||
|
|
||
|
float norm1 = (float) fabs( fDepth );
|
||
|
|
||
|
pNorm[0].x = norm1;
|
||
|
pNorm[0].y = 0.0f;
|
||
|
pNorm[0].x = fFramex;
|
||
|
|
||
|
pNorm[1].x = 0.0f;
|
||
|
pNorm[1].y = norm1;
|
||
|
pNorm[1].x = fFramey;
|
||
|
|
||
|
pNorm[0].x = -norm1;
|
||
|
pNorm[0].y = 0.0f;
|
||
|
pNorm[0].x = fFramex;
|
||
|
|
||
|
pNorm[1].x = 0.0f;
|
||
|
pNorm[1].y = -norm1;
|
||
|
pNorm[1].x = fFramey;
|
||
|
|
||
|
mtk_NormalizePoints( pNorm, 4 );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::CalcTexCoords()
|
||
|
{
|
||
|
// Calculate texture coords based on current state of the object.
|
||
|
|
||
|
// The texture spans across the front face, and includes the image on right,
|
||
|
// and context on left. The 't' coords are constant, but the 's' coord
|
||
|
// varies, depending on if or how much context is shown.
|
||
|
|
||
|
// Again, points are ordered CCW from top right for each face
|
||
|
|
||
|
// Calc ratio of image over total width of object
|
||
|
float ratio = fImageSize.width / (fImageSize.width + fMaxContextWidth);
|
||
|
|
||
|
float sStart = 1.0f - ratio;
|
||
|
|
||
|
if( bShowContext ) {
|
||
|
sStart -= (fCurContextWidth / fMaxContextWidth) * (1.0f - ratio);
|
||
|
}
|
||
|
|
||
|
texPoint[0].s = texPoint[3].s = 1.0f;
|
||
|
texPoint[1].s = texPoint[2].s = sStart;
|
||
|
|
||
|
texPoint[0].t = texPoint[1].t = 1.0f;
|
||
|
texPoint[2].t = texPoint[3].t = 0.0f;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::GetRect( GLIRECT *pRect )
|
||
|
{
|
||
|
*pRect = rect;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
void
|
||
|
LOG_OBJECT::GetPos( POINT3D *curpos )
|
||
|
{
|
||
|
float *fpos = (float *) curpos;
|
||
|
|
||
|
for( int i = 0; i < 3; i ++ )
|
||
|
fpos[i] = dest[i] + offset[i];
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* NextFlyIteration
|
||
|
*
|
||
|
* Calcs next offset and angle for a 'fly'sequence
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
BOOL
|
||
|
LOG_OBJECT::NextFlyIteration()
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if( !iter ) {
|
||
|
// Done iterating
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// Calculate new iterations
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
offset[i] = Clamp( iter, offset[i] );
|
||
|
}
|
||
|
ang = Clamp( iter, ang);
|
||
|
iter--;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* ResetMotion
|
||
|
*
|
||
|
* Resets all position and motion params to 0
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::ResetMotion()
|
||
|
{
|
||
|
offset[0] = offset[1] = offset[2] = 0.0f;
|
||
|
rotAxis[0] = rotAxis[1] = rotAxis[2] = 0.0f;
|
||
|
ang = 0.0f;
|
||
|
iter = 0;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
*
|
||
|
* Ranomnly chooses motion params for a fly sequence
|
||
|
*
|
||
|
* The motion is 'damped', since near the end of the fly sequence the object
|
||
|
* is constrained to 0 rotation and the dest[] position
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::SetDampedFlyMotion( float deviation )
|
||
|
{
|
||
|
SetDampedFlyMotion( deviation, NULL );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
LOG_OBJECT::SetDampedFlyMotion( float deviation, POINT3D *pOffset )
|
||
|
{
|
||
|
if( pOffset ) {
|
||
|
// Use supplied offset
|
||
|
offset[0] = pOffset->x;
|
||
|
offset[1] = pOffset->y;
|
||
|
offset[2] = pOffset->z;
|
||
|
} else {
|
||
|
// Calc a random offset
|
||
|
offset[0] = MyRand();
|
||
|
offset[1] = MyRand();
|
||
|
offset[2] = MyRand();
|
||
|
}
|
||
|
|
||
|
ang = 260.0f * MyRand();
|
||
|
|
||
|
rotAxis[0] = MyRand();
|
||
|
rotAxis[1] = MyRand();
|
||
|
rotAxis[2] = MyRand();
|
||
|
iter = (int) (deviation * MyRand() + 60.0f);
|
||
|
}
|