//#############################################################################
void LaneDetector::ExtractBorder(Mat image)
{
    int leftUp = 0, leftDown = 0, rightUp = image.cols - 1, rightDown = image.cols - 1;
    int lowerBound = image.rows - 1;

    while (leftUp < image.cols && image.at<tUInt8>(0, leftUp) == 5)
    {
        leftUp++;
    }

    while (leftDown < image.cols && image.at<tUInt8>(lowerBound, leftDown) == 5)
    {
        leftDown++;
    }

    while (rightUp > 0 && image.at<tUInt8>(0, rightUp) == 5)
    {
        rightUp--;
    }

    while (rightDown > 0 && image.at<tUInt8>(lowerBound, rightDown) == 5)
    {
        rightDown--;
    }

    Point2f LeftUp(leftUp + 1, 1);
    Point2f LeftDown(leftDown + 1, lowerBound - 1);
    Point2f RightDown(rightDown - 1, lowerBound - 1);
    Point2f RightUp(rightUp - 1, 1);

    border.Initialize(LeftUp, RightUp, LeftDown, RightDown);
}
Beispiel #2
0
bool CMouseControl::LeftClick ()
{
	if (CheckClickArea ()) {
		LeftDown ();
		LeftUp ();
		return true;
	}

	return false;
}
bool    TranslateCommand::PreTranslateMessage(MSG* pMsg)
{
	try { //#try
	  /*if (pMsg->message==WM_KEYUP||
	  pMsg->message==WM_CHAR)
	  return false;*/

	  if (pMsg->message==WM_KEYUP||pMsg->message==WM_KEYDOWN ||
		pMsg->message==WM_CHAR)
	  {
		if (pMsg->wParam==VK_RETURN)
		{
		  OnEnter();
		  return true;
		}
		if (pMsg->wParam==VK_ESCAPE)
		{
		  m_app->StopCommander();
		  return true;
		}
		if (m_step==1 && m_panel)
		  m_panel->SendMessage(pMsg->message,
				pMsg->wParam,
				pMsg->lParam);
		if (pMsg->message==WM_KEYDOWN)
		  return false;
		else
		  return true;
	  }
	  else
	  {
		if (pMsg->hwnd == m_app->GetViewPort()->GetWindow()->m_hWnd)
		{
		  switch(pMsg->message)
		  {
		  case WM_MOUSEMOVE:
			MouseMove(pMsg->wParam,GET_X_LPARAM(pMsg->lParam),GET_Y_LPARAM(pMsg->lParam));
			return true;
		  case WM_LBUTTONDOWN:
			LeftClick(pMsg->wParam,GET_X_LPARAM(pMsg->lParam),GET_Y_LPARAM(pMsg->lParam));
			return true;
		  case WM_LBUTTONUP:
			LeftUp(GET_X_LPARAM(pMsg->lParam),GET_Y_LPARAM(pMsg->lParam));
			return true;
		  default:
			return false;
		  }
		}
	  }
  }
	catch(...){
	}
  return false;
}
Beispiel #4
0
void CBSumCaret::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags, CView* pView)
{
	switch ( nChar ) {
	case VK_CONTROL:
		m_ControlOn = 0;
		break;
	case VK_SHIFT:
		m_ShiftOn = 0;
		LeftUp( m_XPosition, m_YPosition, pView );
		break;
	}
}
Beispiel #5
0
void Region::init(int type, vector<double> params_)
{
	typ=type;
	params=params_;
	Point LeftDown(params[0],params[1]);
	Point LeftUp(params[2],params[3]);
	Point RightUp(params[4],params[5]);
	Point RightDown(params[6],params[7]);
	modparams.push_back(LeftDown);
	modparams.push_back(LeftUp);
	modparams.push_back(RightUp);
	modparams.push_back(RightDown);
}
Beispiel #6
0
void Region::draw()
{
	if(typ==1)
	{
		Point LeftDown(params[0],params[1]);
		Point LeftUp(params[2],params[3]);
		Point RightUp(params[4],params[5]);
		Point RigthDown(params[6],params[7]);
		drawLine(LeftDown,LeftUp,0,1,1);
		drawLine(LeftUp,RightUp,0,1,1);
		drawLine(RightUp,RigthDown,0,1,1);
		drawLine(RigthDown,LeftDown,0,1,1);
	}
}
void ATotemCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (TimeSinceHit > 0.0f)
	{
		TimeSinceHit -= DeltaTime;
	}
	else
	{
		PreviousHit.controller = nullptr;
		PreviousHit.type = AbilityType::NONE;
		PreviousHit.name = "";
	}

	if (bThirdPersonDeathCamLerp)
	{
		if (Controller)
		{
			Controller->SetControlRotation(FRotator(-1.0f * DeathCamAngle, 0, 0));
		}
	}

	if (bThirdPersonCamLerp || bThirdPersonDeathCamLerp )
	{
		CameraBoom->TargetArmLength = FMath::Lerp<float>(CameraBoom->TargetArmLength, ThirdPersonCamDistance, DeltaTime*4.0f);
	}
	else
	{
		CameraBoom->TargetArmLength = FMath::Lerp<float>(CameraBoom->TargetArmLength, 0, DeltaTime*4.0f);
	}

	if (bIsDead && (ThirdPersonCamDistance!= ThirdPersonDeathCamDistance))
	{
		ThirdPersonCamDistance = ThirdPersonDeathCamDistance;
	}

	if ( ((FMath::Abs(CameraBoom->TargetArmLength - ThirdPersonCamDistance) < 0.5f) && bIsDead && bThirdPersonDeathCamLerp))
	{
		ATotemPlayerController *PC = Cast<ATotemPlayerController>(Controller);
		if (PC)
		{
			if (HasAuthority())
			{
				PC->HandleDead(FVector(0, 0, 0), FRotator(0, 0, 0));
			}
			bThirdPersonDeathCamLerp = false;
		}
	}

	if (bDeathEffectFired && RayCastOnGround() )
	{
		FireMaterialEffect();
		bDeathEffectFired = false;
	}

	if ((CameraBoom->TargetArmLength > 0.5f) && (!bIsShamanVisible))
	{
		if (GEngine->GetGamePlayer(GetWorld(), 0)->PlayerController == Controller)
		{
			MakeSelfVisible();
			bIsShamanVisible = true;
		}
	}
	
	if ((CameraBoom->TargetArmLength <= 0.5f) && (bIsShamanVisible))
	{
		if (GEngine->GetGamePlayer(GetWorld(), 0)->PlayerController == Controller)
		{
			MakeSelfInvisible();
			bIsShamanVisible = false;
		}
	}

	if (Controller && FirstTick)
	{
		if (GEngine->GetGamePlayer(GetWorld(), 0)->PlayerController == Controller)
		{
			MakeSelfInvisible();
			bIsShamanVisible = false;
		}
		FirstTick = false;
	}

	ATotemPlayerState *TotemPlayerState = Cast<ATotemPlayerState>(PlayerState);
	if (TotemPlayerState && bFirstSpawn)
	{
		SetActorLocation(TotemPlayerState->StartingLocation);
		SetActorRotation(TotemPlayerState->StartingRotation);
		bFirstSpawn = false;
	}

	if (bReborn && HasAuthority())
	{
		TotalRebornDuration -= DeltaTime;
		if (TotalRebornDuration < 0.0f)
		{
			bReborn = false;
			ExitReborn();
		}
	}


	if (HasAuthority())
	{
		if (bBeingKnockedBack)
		{
			TimeSinceKnockedBack -= DeltaTime;
			if (TimeSinceKnockedBack < 0.0f)
			{
				bBeingKnockedBack = false;
			}
		}
#if (WRITE_METRICS > 1)
		if (DeltaTime >= .025)
		{
			ATotemPlayerController* control = Cast<ATotemPlayerController>(Controller);
			if(control)
			{
				ATotemPlayerState* state = Cast<ATotemPlayerState>(control->PlayerState);
				if(state)
				{
					std::string team;
					switch (state->Team)
					{
					case ETeam::RED_TEAM:
						team = "Red";
						break;
					case ETeam::BLUE_TEAM:
						team = "Blue";
						break;
					default:
						team = "None";
						break;
					}
					Metrics::WriteToFile(std::string(TCHAR_TO_UTF8(*(state->MyName))), team, std::string("Frame rate hit"), std::string(std::to_string(DeltaTime) + "ms"), std::string(std::to_string(1.0f/DeltaTime) + "fps"));
				}
			}
		}
#endif
	}


	//Keep track of how long has passed since the last attack
	TimeSinceAttack += DeltaTime;
	ShotPressedDuration += DeltaTime;

	//If shot is pressed and enough time has been pressed
	if (ShotPressed && TimeSinceAttack >= TimeBetweenShots)
	{
		//And you either can rapid fire or no shot has been fired since the shot button was pressed
		if (CanRapidFire || !ShotFired)
		{
			OnFire();
			ShotFired = true;
			TimeSinceAttack = 0.0f;
		}
	}
	else if (!ShotPressed)
	{
		ShotPressedDuration = 0;
	}

	//If get hit by cyclone, then the shaman cannnot move
	if (HasAuthority())
	{
		TArray<AActor* > OverlappedActors;
		TArray<ACyclone* > OverlappedCyclones;
		GetOverlappingActors(OverlappedActors);
		for (int32 i = 0; i < OverlappedActors.Num(); i++)
		{
			ACyclone* Cyclone = Cast<ACyclone>(OverlappedActors[i]);
			if (Cyclone && !Cyclone->IsPendingKill())
			{
				//overlap myself doesn't count
				if (Cyclone->GetOwner() != GetController())
				{
					OverlappedCyclones.Add(Cyclone);
				}
			}
		}

		if (OverlappedCyclones.Num() == 0)
		{
			//Do this to prevent bCanMove be replictated every frame
			if (!bCanMove)
			{
				bCanMove = true;
			}
			AttachCyclone = nullptr;
		}
		else if (OverlappedCyclones.Num() > 0)
		{
			if (bCanMove)
			{
				bCanMove = false;
			}
			if (AttachCyclone)
			{
				FVector CycloneVelocity = AttachCyclone->ProjectileMovement->Velocity;
				ATotemPlayerController* own = Cast<ATotemPlayerController>(AttachCyclone->GetOwner());
				if (own)
				{
					ReduceHealth(AttachCyclone->Damage * DeltaTime, own, AbilityType::WIND, FName(TEXT("Cyclone"))); //every second reduce Damage amount of health
				}
				LaunchCharacter(CycloneVelocity, true, true);
			}
			//CharacterMovement->Velocity = CycloneVelocity;
		}
	}

	//temporary solution, maybe later we need more fancy stuff.
	if (bIsDead && HasAuthority())
	{
		CurrentDeadBodyDuration -= DeltaTime;
		if (CurrentDeadBodyDuration <= 0)
		{
			Destroy();
		}
	}

	if (bClickedThisFrame)
	{
		bClickedThisFrame = false;
		if (Controller)
		{
			APlayerController* control = Cast<APlayerController>(Controller);
			if (control)
			{
				if (!control->IsInputKeyDown(EKeys::LeftMouseButton))
				{
					LeftUp();
				}
			}
		}
	}

	if (bRightButtonDownThisFrame)
	{
		bRightButtonDownThisFrame = false;
		if (Controller)
		{
			APlayerController* control = Cast<APlayerController>(Controller);
			if (control)
			{
				if (!control->IsInputKeyDown(EKeys::RightMouseButton))
				{
					RightUp();
				}
			}
		}
	}

	//CheckShiftKey();

}
Beispiel #8
0
void CMouseControl::LeftClick ()
{
	LeftDown ();
	sleep_milliseconds(m_sendActionWait);
	LeftUp ();
}
Beispiel #9
0
void MenuItem::RightUp(Point p, dword w)
{
	LeftUp(p, w);
}
Beispiel #10
0
void CBSumCaret::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags, CView* pView)
{

	UINT txi = m_xi * nRepCnt;   
	UINT txs = m_xs * nRepCnt;
	DWORD tyi = m_yi * nRepCnt;
	DWORD tys = m_ys * nRepCnt;
	UINT OldXPos = m_XPosition;
	DWORD OldYPos = m_YPosition;
	int nomove = 0, comment = 0;
	UINT smaxx = m_maxx;
	DWORD smaxy = m_maxy;
	UINT sminx = m_minx;
	DWORD sminy = m_miny;
	char tChar;

	// Arange for clipping function	
	if ( m_Clipping ) {
		/*
		m_maxx = m_ClipRect.BottomRight().x;
		m_maxy = m_ClipRect.BottomRight().y - m_CaretHeight;
		m_minx = m_ClipRect.TopLeft().x - 2;
		m_miny = m_ClipRect.TopLeft().y;
		*/
		m_maxx = m_ClipXPosition + m_ClipXSize;
		m_maxy = m_ClipYPosition + m_ClipYSize - m_CaretHeight;
//		m_minx = m_ClipXPosition - 2;
		m_minx = m_ClipXPosition;
		m_miny = m_ClipYPosition;
	}

	// Move m_Position based on char and max's
	switch ( nChar ) {
	case VK_UP:
		if ( (m_miny + tyi) <= m_YPosition ) {
			m_YPosition -= tyi;
		}
		break;
	case VK_DOWN:
		if ( (m_YPosition + tyi) < m_maxy ) {
			m_YPosition += tyi;
		}
		break;
	case VK_LEFT:
		if ( m_ControlOn ) {
			if ( (m_minx + txs) <= m_XPosition ) {
				m_XPosition -= txs;
			} else {
				while ( (m_minx + txi) <= m_XPosition ) {
					m_XPosition -= txi;
				}
			}				
		} else {
			if ( (m_minx + txi) <= m_XPosition ) {
				m_XPosition -= txi;
			}
		}
		break;
	case VK_RIGHT:
		if ( m_ControlOn ) {
			if ( (m_XPosition + txs) < m_maxx ) {
				m_XPosition += txs;
			} else {
				while ( (m_XPosition + txi) < m_maxx ) {
					m_XPosition += txi;
				}
			}				
		} else {
			if ( (m_XPosition + txi) < m_maxx ) {
				m_XPosition += txi;
			}
		}
		break;
	case VK_CONTROL:
		m_ControlOn = 1;
		nomove = 1;
		break;
	case VK_SHIFT:
		m_ShiftOn = 1;
		if ( !(nFlags & 0x4000) ) {
			LeftDown( m_XPosition, m_YPosition, pView );
		}
		nomove = 1;
		break;
	case VK_END:
		if ( m_ControlOn ) {
			m_YPosition = m_maxy;
		} else {
			while ( (m_XPosition + txi) < m_maxx ) {
				m_XPosition += txi;
			}
		}
		break;
	case VK_HOME:
		if ( m_ControlOn ) {
			m_YPosition = m_miny;
		} else {
			while ( (m_minx + txi) <= m_XPosition ) {
				m_XPosition -= txi;
			}
		}
		break;
	case VK_NEXT:
		if ( (m_YPosition + tys) < m_maxy ) {
			m_YPosition += tys;
		} else {
			while ( (m_YPosition + tyi) < m_maxy ) {
				m_YPosition += tyi;
			}
		}				
		break;
	case VK_PRIOR:
		if ( (m_miny + tys) <= m_YPosition ) {
			m_YPosition -= tys;
		} else {
			while ( (m_miny + tyi) <= m_YPosition ) {
				m_YPosition -= tyi;
			}
		}				
		break;
	case VK_RETURN:
		if ( !m_ShiftOn ) {
			// Simulate Mouse double click calls.
			LeftDown( m_XPosition, m_YPosition, pView );
			LeftUp( m_XPosition, m_YPosition, pView );
			Select( m_XPosition, m_YPosition, pView );
			LeftUp( m_XPosition, m_YPosition, pView );
		}
		nomove = 1;
		break;
	default:		// Here we going to test for alpha ...
		if ( isprint ( (tChar = MakeAscii(nChar, nFlags)) ) ) {
			comment = 1;
		}
		if ( tChar == 8 ) {
			if ( (m_minx + txi) < m_XPosition ) {
				m_XPosition -= txi;
			}
		}			
		break;
	}

	// Undo clipping function
	if ( m_Clipping ) {
		m_maxx = smaxx;
		m_maxy = smaxy;
		m_minx = sminx;
		m_miny = sminy;
	}

	// Comment processing	
	if ( comment ) {
		if ( Comment( tChar, m_XPosition, m_YPosition, pView ) ) {
			// Advance caret only if char taken
			if ( (m_XPosition + txi) < m_maxx ) {
				m_XPosition += txi;
			}
		}

//		return;
	}

	// Check if keystroke resulted in movement
	if ( !nomove ) {

		// If selecting, then call move virtual function
		if ( m_ShiftOn ) {
			Move ( m_XPosition, m_YPosition, pView );
		}
		
		// Check for screen scroll bars positions
	    // CPoint tPos = m_Position;

	    if ( 
			(m_YPosition - m_ScrollYPosition + m_CaretHeight) >= m_ViewYSize 
			&& m_YPosition >= m_ScrollYPosition 
		) {
	
			if ( (m_YPosition + m_CaretHeight) > m_maxy ) {
	    		m_YPosition -= m_CaretHeight;
		    	m_ScrollYPosition = m_maxy - m_ViewYSize;
	    	} else {
		    	m_ScrollYPosition += m_YPosition - OldYPos;
		    }
		    	
	    	((CSummaryView*)pView)->ScrollToPosition ( m_ScrollXPosition, m_ScrollYPosition );
	    	((CSummaryView*)pView)->GetScrollPosition( &m_ScrollXPosition, &m_ScrollYPosition);

		} else if ( m_YPosition < m_ScrollYPosition  ) {

// Changed because of end at second to last line, then page up till error ..
//			if ( m_YPosition < (DWORD)m_CaretHeight ) {
			if ( OldYPos - m_YPosition > m_ScrollYPosition ) {
		    	m_ScrollYPosition = 0;
	    	} else {
		    	m_ScrollYPosition -= OldYPos - m_YPosition;
		    }
	    	
	    	((CSummaryView*)pView)->ScrollToPosition ( m_ScrollXPosition, m_ScrollYPosition );
	    	((CSummaryView*)pView)->GetScrollPosition( &m_ScrollXPosition, &m_ScrollYPosition);
	    
		} else if ( m_XPosition - m_ScrollXPosition >= m_ViewXSize && m_XPosition >= m_ScrollXPosition ) {
	    	m_ScrollXPosition += m_XPosition - OldXPos;
			if ( m_XPosition + m_xi == m_maxx ) {
				m_ScrollXPosition += m_xi;
			}
	    	
	    	((CSummaryView*)pView)->ScrollToPosition ( m_ScrollXPosition, m_ScrollYPosition );
	    	((CSummaryView*)pView)->GetScrollPosition( &m_ScrollXPosition, &m_ScrollYPosition);
		
		} else if ( m_XPosition < m_ScrollXPosition ) {
			if ( OldXPos - m_XPosition > m_ScrollXPosition ) {
				m_ScrollXPosition = 0;
			} else {
		    	m_ScrollXPosition -= OldXPos - m_XPosition;
			}
	    	
	    	((CSummaryView*)pView)->ScrollToPosition ( m_ScrollXPosition, m_ScrollYPosition );
	    	((CSummaryView*)pView)->GetScrollPosition( &m_ScrollXPosition, &m_ScrollYPosition);
		}
	}
		

	// Check if Scroll Call need to be made.
	// CRect tRect ( m_ScrollPos, m_ViewSize );


	if ( !((m_XPosition >= m_ScrollXPosition && m_XPosition < (m_ScrollXPosition + m_ViewXSize)) 
		&&
		(m_YPosition >= m_ScrollYPosition && m_YPosition < (m_ScrollYPosition + m_ViewYSize)))
	) {

		// CPoint tPos = m_ScrollPos;
		UINT tXPos = m_ScrollXPosition;
		DWORD tYPos = m_ScrollYPosition;
		UINT tX = 0;
		if ( m_maxx > m_ViewXSize ) tX = m_maxx - m_ViewXSize;
		DWORD tY = 0;
		if ( m_maxy > m_ViewYSize ) tY = m_maxy - m_ViewYSize;
		tYPos = m_YPosition < tY ? m_YPosition: tY;
		tXPos = m_XPosition < tX ? m_XPosition: tX;
    	((CSummaryView*)pView)->ScrollToPosition ( tXPos, tYPos );
    	((CSummaryView*)pView)->GetScrollPosition( &m_ScrollXPosition, &m_ScrollYPosition);
	}


	// Set the caret to the current position
	CaretPos ();
{
	POSITION tPos = ((CSummaryView*)pView)->m_RowViewList.GetHeadPosition();
	CGPRowView *tGP;

	while ( tPos != NULL ) {
		tGP = (CGPRowView *)((CSummaryView*)pView)->m_RowViewList.GetNext(tPos);
		if ( tGP->IsPointWithin( m_XPosition, m_YPosition ) ) {
			tGP->SetStatusBar(nFlags, m_XPosition, m_YPosition );
			break;
		}
	}
}
}
Beispiel #11
0
void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFlags, bool fCenter)
{
	// Control state
	ControlDown=false; if (dwKeyFlags & MK_CONTROL) ControlDown=true;
	ShiftDown=false; if (dwKeyFlags & MK_SHIFT) ShiftDown=true;
	AltDown=false; if(dwKeyFlags & MK_ALT) AltDown=true;
	// Active
	if (!Active || !fMouseOwned) return;
	// Execute caption
	if (KeepCaption) KeepCaption--; else { Caption.Clear(); CaptionBottomY=0; }
	// Check player
	if (Player>NO_OWNER)
	{
		pPlayer=::Players.Get(Player);
		if (!pPlayer) { Active=false; return; }
	}
	else
		pPlayer = nullptr;
	// Check viewport
	if (!(Viewport=::Viewports.GetViewport(Player))) return;
	// get view position
	C4Rect rcViewport = Viewport->GetOutputRect();
	fctViewport.Set(nullptr, rcViewport.x, rcViewport.y, rcViewport.Wdt, rcViewport.Hgt);
	ViewX=Viewport->GetViewX(); ViewY=Viewport->GetViewY();
	fctViewportGame = Viewport->last_game_draw_cgo;
	fctViewportGUI = Viewport->last_gui_draw_cgo;
	// First time viewport attachment: center mouse
#ifdef USE_WIN32_WINDOWS
	if (!InitCentered || fCenter)
	{
		iX = Viewport->ViewWdt/2;
		iY = Viewport->ViewHgt/2;
		if (!Application.isEditor)
		{
			int32_t iMidX = Viewport->OutX + iX;
			int32_t iMidY = Viewport->OutY + iY;
			RECT rtWindow;
			if (GetWindowRect(Application.pWindow->hWindow, &rtWindow))
			{
				iMidX += rtWindow.left; iMidY += rtWindow.top;
			}
			SetCursorPos(iMidX, iMidY);
		}
		InitCentered = true;
	}
#else
	if (!InitCentered || fCenter)
	{
		iX = Viewport->ViewWdt/2;
		iY = Viewport->ViewHgt/2;
		InitCentered = true;
	}
#endif
	// passive mode: scrolling and player buttons only
	if (IsPassive())
	{
		if (iButton != C4MC_Button_Wheel)
		{
			VpX=iX; VpY=iY;
			GameX=ViewX+VpX/Viewport->Zoom; GameY=ViewY+VpY/Viewport->Zoom;
			GuiX=float(VpX)/Viewport->GetGUIZoom(); GuiY=float(VpY)/Viewport->GetGUIZoom();
		}
		UpdateScrolling();
		if (iButton == C4MC_Button_LeftDown) LeftDown();
		else if (iButton == C4MC_Button_LeftUp) LeftUp();
		else UpdateCursorTarget();
		return;
	}

	if (iButton != C4MC_Button_Wheel)
	{
		// Position
		VpX=iX; VpY=iY;
		GameX=ViewX+VpX/Viewport->Zoom; GameY=ViewY+VpY/Viewport->Zoom;
		GuiX=float(VpX)/Viewport->GetGUIZoom(); GuiY=float(VpY)/Viewport->GetGUIZoom();
		// Scrolling
		UpdateScrolling();
		// Fog of war
		UpdateFogOfWar();

		// Blocked by fog of war: evaluate button up, dragging and region controls only
		if (FogOfWar && Drag == C4MC_Drag_None)
		{
			// Left button up
			if (iButton==C4MC_Button_LeftUp)
			{
				LeftButtonDown=false;
				// End any drag
				Drag=C4MC_Drag_None;
			}
			// Right button up
			if (iButton==C4MC_Button_RightUp)
			{
				RightButtonDown=false;
			}
		}
	}

	// Move execution by button/drag status
	switch (iButton)
	{
		//------------------------------------------------------------------------------------------
	case C4MC_Button_None:
		switch (Drag)
		{
		case C4MC_Drag_Unhandled: break; // nothing to do
		case C4MC_Drag_None: DragNone(); break;
		case C4MC_Drag_Script: DragScript(); break;
		}
		break;
		//------------------------------------------------------------------------------------------
	case C4MC_Button_LeftDown: LeftDown(); break;
		//------------------------------------------------------------------------------------------
	case C4MC_Button_LeftUp: LeftUp(); break;
		//------------------------------------------------------------------------------------------
	case C4MC_Button_LeftDouble: LeftDouble(); break;
		//------------------------------------------------------------------------------------------
	case C4MC_Button_RightDown: RightDown(); break;
		//------------------------------------------------------------------------------------------
	case C4MC_Button_RightUp: RightUp(); break;
		//------------------------------------------------------------------------------------------
	case C4MC_Button_Wheel: Wheel(dwKeyFlags); break;
	}

	// are custom menus active?
	bool menuProcessed = false;
	if (pPlayer)
		// adjust by viewport X/Y because the GUI windows calculate their positions (and thus check input) based on that
		menuProcessed = ::Game.ScriptGuiRoot->MouseInput(iButton, iX, iY, dwKeyFlags);

	if (menuProcessed)
		Cursor = C4MC_Cursor_Select;

	// if not caught by a menu
	if (!menuProcessed)
		// script handling of mouse control for everything but regular movement (which is sent at control frame intervals only)
		if (iButton != C4MC_Button_None)
			// not if blocked by selection object
			if (!TargetObject)
				// safety (can't really happen in !IsPassive, but w/e
				if (pPlayer && pPlayer->ControlSet)
				{
					if (!menuProcessed && pPlayer->ControlSet->IsMouseControlAssigned(iButton))
					{
						int wheel_dir = 0;
						if (iButton == C4MC_Button_Wheel) wheel_dir = (short)(dwKeyFlags >> 16);
						pPlayer->Control.DoMouseInput(0 /* only 1 mouse supported so far */, iButton, GameX, GameY, GuiX, GuiY, (dwKeyFlags & MK_CONTROL) != 0, (dwKeyFlags & MK_SHIFT) != 0, (dwKeyFlags & MK_ALT) != 0, wheel_dir);
					}
				}