⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chmaze.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			#endif
		}
	}
	else
	{
		WriteStatus( PROGRESS_MSG_0 );
		//WriteStatus("Anchor cancelled");			// just for debugging
		//TRACE("Anchor cancelled\n");			// just for debugging
	}

	#if defined(CH_USE_3DR)
	delete m_pAnchor;
	#endif
#else
#pragma message("Not ending anchors")
#endif
	m_boolInMouseAnchor = false;
	m_pAnchor = 0;
}

/* Reset camera to starting location */
ChMazeWnd* ChMazeWnd::ResetCamera()
{
	GetSceneNavigator()->SetState(ChVrmlStateTransition::s_start);
	GetCameraControl()->Reset();
	return this;
}

void ChMazeWnd::StartMouseMove( int iX, int iY )
{
	CDC*	pDC;
											/* We can't be in both mouse move
												and anchor states */
	// -- ASSERT( !IsInMouseAnchor() );
											// Set flag for state
	m_boolInMouseMove = true;
											// Set flag for rendering
	SetMoving( true );
											// Save initial mouse pos
	m_ptMouseStart.x = iX;
	m_ptMouseStart.y = iY;
	m_ptLastMouse = m_ptMouse = m_ptMouseStart;

											// Draw crosshair
	pDC = GetDC();

	DrawMouseMoveCrosshair( pDC );
	DrawMouseMoveVector( pDC );

	ReleaseDC( pDC );
											// Start the timer

	m_uiMoveTimer = SetTimer( moveTimerID, moveTimerDuration, 0 );
}


void ChMazeWnd::UpdateMouseMove( int iX, int iY )
{
	float	fVertMove;
	float	fHorzMove;
	bool	boolShift;
	bool	boolControl;
	bool	boolMoved;

	if (GetSettings()->GetViewerMode() != examine)
	{
		if ((m_ptMouseStart.x != iX) || (m_ptMouseStart.y != iY))
		{
			m_ptLastMouse = m_ptMouse;
			m_ptMouse.x = iX;
			m_ptMouse.y = iY;

			boolShift = !!(GetKeyState( VK_SHIFT ) & 0x8000);
			boolControl = !!(GetKeyState( VK_CONTROL ) & 0x8000);

			fHorzMove = CalcMouseHorzMove();
			fVertMove = CalcMouseVertMove();

			if (!boolShift && !boolControl)		// No modifiers
			{
				GetCameraControl()->MoveForward( CalcAccel( fVertMove ), false );
				GetCameraControl()->Yaw( fHorzMove );

				boolMoved = true;
			}
			else if (boolShift && !boolControl)	// Shift key only
			{
				GetCameraControl()->MoveUp( CalcAccel( fVertMove ), false );
				GetCameraControl()->MoveLeft( CalcAccel( fHorzMove ) );

				boolMoved = true;
			}
			else if (!boolShift && boolControl)	// Control key only
			{
				GetCameraControl()->Roll( -CalcAccel( fHorzMove ), false );	// It will disable if walking
				GetCameraControl()->Pitch( fVertMove );

				boolMoved = true;
			}
			else								// Shift and Control
			{
				boolMoved = false;
			}
		}
	}
	else
	{
		if ((m_ptLastMouse.x != iX) || (m_ptLastMouse.y != iY))
		{
			m_ptMouse.x = iX;
			m_ptMouse.y = iY;
			RECT r;

			GetClientRect(&r);
			GetCameraControl()->RotateBall(m_ptLastMouse, m_ptMouse, r.bottom - r.top);	

			boolMoved = true;
			m_ptLastMouse = m_ptMouse;
		}
	}
}


void ChMazeWnd::EndMouseMove( int iX, int iY )
{
											// Clear flag for state
	m_boolInMouseMove = false;
											// Clear flag for rendering
	SetMoving( false );

	GetRenderContext()->SetDirty();
	Invalidate( false );
											// Stop the timer
	if (m_uiMoveTimer)
	{
		KillTimer( m_uiMoveTimer );
		m_uiMoveTimer = 0;
	}
}


void ChMazeWnd::DrawMouseMoveCrosshair( CDC* pDC )
{
	CPen	pen( PS_SOLID, 0, RGB( 0xff, 0, 0 ) );
	CPen*	pOldPen;
											 // We only draw if the navigator 
											 // wants us to
	if (m_pNavigators[GetSettings()->GetViewerMode()]->IsInAnchoredMove() && GetSettings()->GetMoveVector())
	{
		ASSERT( 0 != pDC );

		pOldPen = pDC->SelectObject( &pen );

		int iX, iY;
		m_pNavigators[GetSettings()->GetViewerMode()]->GetMouseAnchorLoc(iX, iY);

		pDC->MoveTo( iX - m_sCrosshairHalfWidth, iY );
		pDC->LineTo( iX + m_sCrosshairHalfWidth, iY );
		pDC->MoveTo( iX, iY - m_sCrosshairHalfHeight );
		pDC->LineTo( iX, iY + m_sCrosshairHalfHeight );

		pDC->SelectObject( pOldPen );
	}
}


void ChMazeWnd::DrawMouseMoveVector( CDC* pDC )
{
	if (m_pNavigators[GetSettings()->GetViewerMode()]->IsInAnchoredMove() && GetSettings()->GetMoveVector())
	{
		ASSERT( 0 != pDC );

		CPoint ptMouseStart, ptMouse;
		int iX, iY;
		m_pNavigators[GetSettings()->GetViewerMode()]->GetMouseAnchorLoc(iX, iY);
		ptMouseStart.x = iX; ptMouseStart.y	= iY;		
		m_pNavigators[GetSettings()->GetViewerMode()]->GetMouseLoc(iX, iY);
		ptMouse.x	=	iX;  ptMouse.y = iY;

		if (ptMouseStart != ptMouse)
		{
			CPen	pen( PS_SOLID, 0, RGB( 0xff, 0, 0 ) );
			CPen*	pOldPen = pDC->SelectObject( &pen );

			pDC->MoveTo( ptMouseStart.x, ptMouseStart.y );
			pDC->LineTo( ptMouse.x, ptMouse.y );

			pDC->SelectObject( pOldPen );
		}

		m_ptLastMouse = m_ptMouse;
	}
}


float ChMazeWnd::CalcMouseHorzMove()
{
	float		fMove;

	fMove = m_ptMouseStart.x - m_ptMouse.x;
	fMove /= (float)m_sCrosshairHalfWidth;

	return fMove;
}


float ChMazeWnd::CalcMouseVertMove()
{											// Positive is up
	float		fMove;

	fMove = m_ptMouseStart.y - m_ptMouse.y;
	fMove /= (float)m_sCrosshairHalfHeight;

	return fMove;
}


float ChMazeWnd::CalcAccel( float fVal )
{
	float worldSize = 1.;
	if(!GetBounds()->IsEmpty())
	{
		GxVec3f				lower, upper;
		GetBounds()->GetWorldBounds(lower, upper);
		upper -= lower;
		worldSize = upper.magnitude();
	}

	float fMove = (worldSize * fVal * GetUserSpeedFactor()) / (defStepsPerWorld * defMoveAmount);
	return fMove;
}

bool ChMazeWnd::GetURL( const string& strURL, chparam userData,
				const char* pstrDefURL )
{

	#if (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
	bool boolCached = false;

	if ( userData )
	{

		ChGraphicHTTPReq *pHTTPReq	 = (ChGraphicHTTPReq *)userData;
		if ( pHTTPReq->GetType() == ChGraphicHTTPReq::texture )
		{

			#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
			ChGraphicStreamManager* pStream = (ChGraphicStreamManager*)GetMainInfo()->GetStream();
			#else
			ChGraphicStreamManager* pStream = m_pGraphicStream;
			#endif
			ChMazeTextureHTTPReq* pReq = ( ChMazeTextureHTTPReq*)pHTTPReq;
			// use cache only if it is not keep size
			if ( pStream && !(pReq->GetOption() & ChMazeTextureHTTPReq::textureKeepSize) )
			{
				ChURLParts urlParts;
				urlParts.GetURLParts( strURL, pstrDefURL );

				ChRLImage* pImage = pStream->GetCachedImage( urlParts.GetURL() );

				if ( pImage )
				{  // we have the image use it
					ChQvTextureRenderData* pRenderData = 
						(ChQvTextureRenderData*)(pReq->GetTextureNode()->GetRenderData());

					pRenderData->LoadTexture( GetRenderContext(), pImage );

					boolCached = true;

					delete pReq;
		
				}
			}
		}
	}

	if ( !boolCached )
	#endif
	{

		#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
		ChURLParts urlParts;
		urlParts.GetURLParts( strURL, pstrDefURL );

		return GetMainInfo()->GetCore()->GetURL( urlParts.GetURL(),  0, 
									GetMainInfo()->GetStream(), userData );
		#else

		GetHTTPConn()->GetURL( strURL, (chparam)userData, LPCTSTR(pstrDefURL) );
		return false;
		#endif
	}

	return true;
}

float  ChMazeWnd::GetMoveAmountDistance()
{									 // maybe can use calcAccel???
	float fVal = 2.;
	float worldSize = 1.;
	if(GetScene())
	{
		if(!GetBounds()->IsEmpty())
		{
			GxVec3f				lower, upper;
			GetBounds()->GetWorldBounds(lower, upper);
			upper -= lower;
			worldSize = upper.magnitude();
		}
	}
	float fMove = (worldSize * fVal * GetUserSpeedFactor()) / (defStepsPerWorld);
	return fMove;
}

float  ChMazeWnd::GetMoveAmountAngle()
{										
	return float(GetUserSpeedFactor());
}

float  ChMazeWnd::GetUserSpeedFactor()
{
	return m_fUserSpeedFactor;
}

void  ChMazeWnd::SetUserSpeedFactor(float fSpeed)
{
	m_fUserSpeedFactor = peg(fSpeed, minUserSpeed, maxUserSpeed);
}

void  ChMazeWnd::ResetUserSpeedFactor()
{
	m_fUserSpeedFactor = defUserSpeed;
}

ChMazeWnd * ChMazeWnd::GoFaster(bool boolFaster /* = true */)
{
	const float accel = 1. + 1. / 16.;

	float		fSpeed = GetUserSpeedFactor();
	if (boolFaster)
	{

		fSpeed *= accel;

		SetUserSpeedFactor( fSpeed );
	}
	else	
	{
		fSpeed /= accel;

		SetUserSpeedFactor( fSpeed );
	}
	return this;
}

Ch3DCollisionMode ChMazeWnd::GetCollisionMode( )
{
#if 0
	if(GetSettings()->GetOverrideCollisionMode() || m_sceneCollisionMode == invalidCollisionMode)
	{
		return GetSettings()->GetCollisionMode();
	}
	else
	{
		return m_sceneCollisionMode;
	}
#endif
		return GetSettings()->GetCollisionMode();
}

void ChMazeWnd::EndFrameTime()
{
	#if defined(CH_VRML_VIEWER)	|| defined(CH_VRML_PLUGIN )
	DWORD	luNow = GetTickCount();
	DWORD	luElapsed = luNow - m_luTime;
	string	strStatus;
	double	frameRate = luElapsed ? 1.0 / (float)luElapsed : 1.0;

	frameRate *= 1000.0;	  // ticks are in milliseconds

	strStatus.Format( "Frames per second: %.2f", frameRate );
		#if  defined(CH_VRML_PLUGIN )
			#pragma message("Not setting frame rate ")
		#else
		((CFrameWnd*)(AfxGetMainWnd()))->SetMessageText( strStatus );
		#endif
	#else
	GetMainInfo()->EndFrameTime();
	#endif
}

void ChMazeWnd::StartFrameTime()
{ 
	#if defined(CH_VRML_VIEWER)	|| defined( CH_VRML_PLUGIN )
	m_luTime = GetTickCount();
	#else
	m_luTime = GetTickCount();
	GetMainInfo()->StartFrameTime();
	#endif
}

ChMazeWnd* ChMazeWnd::SetHeadlight( bool boolOn )
{
	GetSettings()->SetHeadlightSwitch(boolOn);
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	m_RC.AdjustHeadlight();
	#endif
	return this;
}

#if defined(CH_VRML_EVENTS)	 && !defined( CH_VRML_PLUGIN )
ChVrmlBrowser * ChMazeWnd::GetBrowser()
{
	if(!m_pVrmlBrowser) m_pVrmlBrowser = new ChStubBrowser(&m_RC);
	
	return m_pVrmlBrowser;
}
#endif

bool ChMazeWnd::GetVelocity(GxVec3f &velocity)
{
	if(!GetScene())
	{
		velocity.set(0,0,0);
		return false;	
	}
	return GetSceneNavigator()->GetVelocity(velocity);
}
bool ChMazeWnd::GetAngularVelocity(GxVec3f &axis, float &slewRate)
{
	if(!GetScene())
	{
		axis.set(0,0,0);
		slewRate = 0.;
		return false;	
	}
	return GetSceneNavigator()->GetAngularVelocity(axis, slewRate);
}

/*----------------------------------------------------------------------------
	ChMazeWnd message handlers
----------------------------------------------------------------------------*/

void ChMazeWnd::OnSize( UINT nType, int cx, int cy )
{
	ChGraphicView::OnSize(nType, cx, cy);
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	m_RC.Resize(cx, cy);
	#endif

	GetRenderContext()->SetDirty();
	InvalidateRect(0, false);
}


void ChMazeWnd::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags )
{
	// TODO: Add your message handler code here and/or call default

	ChGraphicView::OnChar( nChar, nRepCnt, nFlags );
}


void ChMazeWnd::OnLButtonDblClk( UINT nFlags, CPoint point )
{
	// TODO: Add your message handler code here and/or call default

	ChGraphicView::OnLButtonDblClk( nFlags, point );
}


void ChMazeWnd::OnLButtonDown( UINT nFlags, CPoint point )
{
											/* In pueblo, we always have a scene if
											visible. Not so in viewers, which might be loaded 
											empty. In this case, ignore mouse downs; you
											can't move around if you're nowhere, one
											must have space and existence in order to move. */
	if(!GetScene()) return;	
											/* Set capture so we absolutely
												get the mouse up event */
	SetCapture();

	bool boolProcessed = m_pNavigators[GetSettings()->GetViewerMode()]->
		ProcessMouseEvent(WM_LBUTTONDOWN, point.x, point.y, nFlags);


	#if 0

	if (IsAnchor( point.x, point.y ))
	{
		StartAnchor( point.x, point.y );
	}
	//else
	{
		StartMouseMove( point.x, point.y );
	}
	#endif
}


void ChMazeWnd::OnLButtonUp( UINT nFlags, CPoint point )
{
											/* We can't be in both mouse move
												and anchor states */

	// -- ASSERT( !(IsInMouseAnchor() && IsInMouseMove()) );
	if(!GetScene()) return;	
	bool boolEither = m_pNavigators[GetSettings()->GetViewerMode()]->
		ProcessMouseEvent(WM_LBUTTONUP, point.x, point.y, nFlags);

	#if 0
	bool boolEither = IsInMouseAnchor() || IsInMouseMove();
	if (IsInMouseMove())
	{
		EndMouseMove( point.x, point.y );
	}
	if (IsInMouseAnchor())
	{
		EndAnchor( point.x, point.y );
	}
	#endif
	// -- else
	if(!boolEither)
	{
		ChGraphicView::OnLButtonUp( nFlags, point );
	}
	if(!(nFlags & (MK_MBUTTON | MK_RBUTTON | MK_LBUTTON)))ReleaseCapture();
}


void ChMazeWnd::OnMouseMove( UINT nFlags, CPoint point )
{
	if(!GetScene()) return;
	
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	m_boolMouseMove = true;

	#else
	IsAnchor(point.x, point.y);		// update the status line
	#endif

	bool boolProcessed = m_pNavigators[GetSettings()->GetViewerMode()]->
		ProcessMouseEvent(WM_MOUSEMOVE, point.x, point.y, nFlags);

	if(!boolProcessed)	ChGraphicView::OnMouseMove( nFlags, point );

											/* We can't be in both mouse move
												and anchor states */

	// -- ASSERT( !(IsInMouseAnchor() && IsInMouseMove()) );
	#if 0
	if (IsInMouseAnchor())
	{
		UpdateAnchor( point.x, point.y );
	}
	// -- else 
	if (IsInMouseMove())
	{
//		UpdateMouseMove( point.x, point.y );
	}
	else
	{
		bool boolAnchor = IsAnchor( point.x, point.y );

		ChGraphicView::OnMouseMove( nFlags, point );
	}
	#endif
}


void ChMazeWnd::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
{
	bool			boolProcessed = true;
	ChPosition		pos;
	ChKeyMapItem*	pItem;
	chflag32		flMods = 0;

	if (GetKeyState( VK_SHIFT ) & 0x8000)
	{
		flMods |= ACTION_MOD_SHIFT;
	}

	if (GetKeyState( VK_CONTROL ) & 0x8000)
	{
		flMods |= ACTION_MOD_CONTROL;
	}

	pos = m_keyMap.FindItem( nChar, flMods );
	if (pos)
	{
		pItem = m_keyMap.GetItem( pos );

		ASSERT( pItem );

		switch( (KeyAction)pItem->GetUserData() )
		{

			case goFaster:
			{
				GoFaster(true);
				break;
			}

			case goSlower:
			{
				GoFaster(false);
				break;
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -