|
|
/******************************Module*Header*******************************\
* Module Name: loghot.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"
#include "resource.h"
static LOG_OBJECT *pHotObj; static void DrawBanner(); static BOOL bFrameObjects; // whether to frame the objects or not
static float colorHot[3] = { 0.0f, 1.0f, 0.0f }; static float colorWhite[3] = { 1.0f, 1.0f, 1.0f };
#define HOT_CURSOR 1
/******************** HOT SEQUENCE ****************************************\
* \**************************************************************************/
static LOG_OBJECT* CheckForHit( int mouseX, int mouseY ) { // Check mouse coords against rect of each object. Return ptr to object
// if within.
mouseY = InvertY( mouseY, winSize.height );
LOG_OBJECT *pObj; GLIRECT rect, *pRect; pRect = ▭
for( int i = 0; i < nLogObj; i++ ) { pObj = pLogObj[i]; pObj->GetRect( pRect ); if( ( mouseX >= pRect->x ) && ( mouseX < (pRect->x + pRect->width) ) && ( mouseY >= pRect->y ) && ( mouseY < (pRect->y + pRect->height) ) ) { // SS_DBGPRINT( "CheckForHit() recording a hit\n" );
return pObj; } } return NULL; }
static void DrawObject( LOG_OBJECT *pObj, BOOL bHot ) { if( !pObj ) return;
// Set ColorMaterial color, in case lighting is on for the frame
if( bHot ) { glColor3fv( colorHot ); } else { glColor3fv( colorWhite ); }
pObj->Draw(); }
// This redraws everything
static void DrawHotSequence(void) { ClearWindow();
LOG_OBJECT *pObj;
for( int i = 0; i < nLogObj; i++ ) { pObj = pLogObj[i]; DrawObject( pObj, (pObj == pHotObj) ); }
Flush(); DrawBanner(); }
static void FinishLogonHotSequence() { #ifndef HOT_CURSOR
// User has selected an object.
// Turn off hilite on current selection and return
DrawObject( pHotObj, FALSE ); Flush(); #endif
mtkWin->Return(); }
static BOOL HotKey(int key, GLenum mask) { switch (key) { case TK_RETURN: if( pHotObj ) FinishLogonHotSequence(); break; case TK_ESCAPE: if( bDebugMode ) Quit(); break; case TK_SPACE: if( bDebugMode ) { bRunAgain = TRUE; FinishLogonHotSequence(); } break; default: if( bDebugMode ) return AttributeKey( key, mask ); return FALSE; } return FALSE; }
static BOOL MouseButton(int mouseX, int mouseY, GLenum button) { // If left button click on an object, run end of logon sequence
if( !(button & TK_LEFTBUTTON) ) return GL_FALSE;
LOG_OBJECT *pObj;
if( pObj = CheckForHit( mouseX, mouseY ) ) { pHotObj = pObj; FinishLogonHotSequence(); }
return FALSE; }
static BOOL MouseMove(int mouseX, int mouseY, GLenum button) { // Handle a mouse move. Redraw only when necessary
LOG_OBJECT *pObj;
LOG_OBJECT *pLastHotObj = pHotObj;
if( pObj = CheckForHit( mouseX, mouseY ) ) { if( pObj == pHotObj ) { // State has not changed
return FALSE; } // New hot object
pHotObj = pObj; SetCursor( hHotCursor ); } else { SetCursor( hNormalCursor ); if( !pHotObj ) { // State has not changed
return FALSE; } // No hot object
pHotObj = NULL; }
#ifndef HOT_CURSOR
if( ! bSwapHints ) // Need to do complete redraw
return TRUE;
// Redraw only the objects that changed
if( pLastHotObj ) { // remove hot indicator from old hot object
DrawObject( pLastHotObj, FALSE ); }
if( pHotObj ) { // add hot indicator to new hot object
DrawObject( pHotObj, TRUE ); }
// Flush the changes
Flush(); #endif
return FALSE; }
static void DrawBanner() { BitBlt( mtkWin->GetHdc(), 0, 0, bannerSize.width, bannerSize.height, hdcMem, 0, 0, SRCCOPY ); GdiFlush(); }
LOG_OBJECT * RunLogonHotSequence() { if( bDebugMode ) bRunAgain = FALSE; // Stop animation, make quads 'hot'
SS_DBGPRINT( "RunLogonHotSequence()\n" );
// If the objects were flown in without context their origins would have
// been in centre of the image part. Since we want to add context now,
// have to offset the destination values. This is done inside next loop
// Calc window rects of the quads
bSwapHints = bSwapHintsEnabled; UpdateLocalTransforms( UPDATE_ALL );
bFrameObjects = FALSE; // no framing currently
LOG_OBJECT *pObj;
for( int i = 0; i < nLogObj; i++ ) { pObj = pLogObj[i]; pObj->ShowContext( TRUE ); if( !bFlyWithContext ) { // offset x dest value to the left (again, size assumption)
pObj->OffsetDest( - OBJECT_WIDTH / 4.0f, 0.0f, 0.0f ); } if( bFrameObjects ) pObj->ShowFrame( TRUE ); pObj->CalcWinRect(); }
pHotObj = NULL;
// Set any gl attributes
if( bFrameObjects ) { glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); bDepth = TRUE; }
// Go to slower but nicer texture drawing while in this mode
for( i = 0; i < nLogObj; i++ ) { pLogObj[i]->pTex->MakeCurrent(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); }
// Set up mtk functions for this sequence
mtkWin->SetAnimateFunc( NULL ); mtkWin->SetKeyDownFunc(HotKey); mtkWin->SetMouseMoveFunc( MouseMove ); mtkWin->SetMouseDownFunc( MouseButton ); mtkWin->SetDisplayFunc( DrawHotSequence );
// Now get the current pointer position and simulate a mouse move with it,
// in case it's over one of the objects.
IPOINT2D ptMouse;
mtkWin->GetMouseLoc( &ptMouse.x, &ptMouse.y ); // Need to check that mouse is inside window
if( (ptMouse.x >= 0) && (ptMouse.x < winSize.width) && (ptMouse.y >= 0) && (ptMouse.y < winSize.height) ) { MouseMove( ptMouse.x, ptMouse.y, 0 ); }
// Draw everything (so nicer textures show up)
DrawHotSequence(); if( !mtkWin->Exec() ) return NULL;
// Restore gl attributes
for( i = 0; i < nLogObj; i++ ) { pLogObj[i]->pTex->MakeCurrent(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); } glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); bDepth = FALSE;
// Turn frames off for the objects
for( i = 0; i < nLogObj; i++ ) { pLogObj[i]->ShowFrame( FALSE ); }
// Dump the cursor
SetCursor( NULL ); return pHotObj; }
|