Esempio n. 1
0
// called after a poll to execute any shortcuts
void CheckShortcuts()
{
	static bool bWasPressed[ sizeof(SHORTCUTSPL)/sizeof(BUTTON) ][4];
	static bool bMLWasPressed;	// mouselock
	bool bMatching = false;

	if ( g_bConfiguring || !g_bRunning )
		return; // we don't process shortcuts if we're in a config menu or are not running emulation

	// just process if key wasnt pressed before
	for ( int i = 0; i < 4; i++ ) // controllers
	{
		for( int j = 0; j < SC_TOTAL; j++ ) 
		{
			bMatching = IsBtnPressed( g_scShortcuts.Player[i].aButtons[j] );

			if( bMatching && !bWasPressed[j][i] )
				DoShortcut(i, j);

			bWasPressed[j][i] = bMatching;
		}
	}

	bMatching = IsBtnPressed( g_scShortcuts.bMouseLock );

	if( bMatching && !bMLWasPressed )
		DoShortcut(-1, -1); // controller -1 means do mouselock shortcut

	bMLWasPressed = bMatching;
}
Esempio n. 2
0
// Fill in button states and axis states for controller indexController, into the struct pdwData.
// pdwData is a pointer to a 4 byte BUTTONS union, if anyone cares
bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
{
	*pdwData = 0;
	WORD w_Buttons = 0;
	// WORD w_Axes = 0;

	LPCONTROLLER pcController = &g_pcControllers[indexController]; // still needs to be here, but not as important --rabid

	bool b_Value;
	long l_Value = 0;

	long lAxisValueX = ZEROVALUE;
	long lAxisValueY = ZEROVALUE;

	// take this info from the N64 controller struct, regardless of input devices
	float d_ModifierX = (float)pcController->bStickRange / 100.0f;
	float d_ModifierY = (float)pcController->bStickRange / 100.0f;

	int i;

	// do N64-Buttons / modifiers
	for (i = 0; i < pcController->nModifiers; i++ )
	{
		BUTTON btnButton = pcController->pModifiers[i].btnButton;

		b_Value = IsBtnPressed( btnButton );

		bool fChangeMod = false;

		if( pcController->pModifiers[i].bModType == MDT_CONFIG )
		{ // Config-Type
			if( pcController->pModifiers[i].fToggle )
			{
				if( b_Value && !btnButton.fPrevPressed)
				{
					pcController->pModifiers[i].fStatus = !pcController->pModifiers[i].fStatus;
					fChangeMod = true;
				}
			}
			else
			{
				if(	b_Value != (bool)(btnButton.fPrevPressed))
					fChangeMod = true;
			}
		}
		else
		{ // Move / Macro Type
			if( pcController->pModifiers[i].fToggle )
			{
				if( b_Value && !btnButton.fPrevPressed )
					pcController->pModifiers[i].fStatus = !pcController->pModifiers[i].fStatus;
				fChangeMod = ( pcController->pModifiers[i].fStatus != 0 );
			}
			else
			{
				fChangeMod = b_Value;
			}
		}

		if( fChangeMod )
		{
			switch( pcController->pModifiers[i].bModType )
			{
			case MDT_MOVE:
			{
				LPMODSPEC_MOVE args = (LPMODSPEC_MOVE)&pcController->pModifiers[i].dwSpecific;
				d_ModifierX *= args->XModification / 100.0f;
				d_ModifierY *= args->YModification / 100.0f;	
			}
				break;
			case MDT_MACRO:
			{
				LPMODSPEC_MACRO args = (LPMODSPEC_MACRO)&pcController->pModifiers[i].dwSpecific;

				if (args->fRapidFire) // w00t! Rapid Fire here
				{
					if ((unsigned) b_Value != btnButton.fPrevPressed) // New macro pressed
					{
						args->fPrevFireState = 0;
						args->fPrevFireState2 = 0;
					}
					if(!args->fPrevFireState) // This round, a firing is needed
					{
						w_Buttons |= args->aButtons;
						if( args->fAnalogRight )
							lAxisValueX += MAXAXISVALUE;
						else if( args->fAnalogLeft )
							lAxisValueX -= MAXAXISVALUE;

						if( args->fAnalogDown )
							lAxisValueY -= MAXAXISVALUE;
						else if( args->fAnalogUp ) // up
								lAxisValueY += MAXAXISVALUE;
					}

					// Ok, update the firing counters here
					if (args->fRapidFireRate) // Do the rapid fire slowly
					{ // Note that this updates State2 before State... Makes a nice slower square-wave type pulse for the update
						args->fPrevFireState2 = (args->fPrevFireState2 + 1) & 1;
						if (!args->fPrevFireState2)
						{
							args->fPrevFireState = (args->fPrevFireState + 1) & 1;
							DebugWriteA("Slow Rapid Fire - Mark 2\n");
						}
					}
					else // Do a fast rapid fire
					{
						args->fPrevFireState = (args->fPrevFireState + 1) & 1;
						DebugWriteA("Fast Rapid Fire\n");
					}
				}
				else
				{
					w_Buttons |= args->aButtons; // Note this: It lets you push buttons as well as the macro buttons
					if( args->fAnalogRight )
						lAxisValueX += MAXAXISVALUE;
					else if( args->fAnalogLeft )
						lAxisValueX -= MAXAXISVALUE;

					if( args->fAnalogDown )
						lAxisValueY -= MAXAXISVALUE;
					else if( args->fAnalogUp ) // up
						lAxisValueY += MAXAXISVALUE;

					args->fPrevFireState = 0;
				}
			}
				break;
			case MDT_CONFIG:
			{
				LPMODSPEC_CONFIG args = (LPMODSPEC_CONFIG)&pcController->pModifiers[i].dwSpecific;

				if( args->fChangeAnalogConfig )
				{
					BYTE bConfig = (BYTE)args->fAnalogStickMode;
					if( bConfig < PF_AXESETS )
						pcController->bAxisSet = bConfig;
					else
					{
						if( pcController->bAxisSet == PF_AXESETS-1 )
							pcController->bAxisSet = 0;
						else
							++pcController->bAxisSet;
					}

				}
				if( args->fChangeMouseXAxis )
					if (pcController->bMouseMoveX == MM_BUFF)
						pcController->bMouseMoveX = MM_ABS;
					else if (pcController->bMouseMoveX == MM_ABS)
						pcController->bMouseMoveX = MM_BUFF;
				if( args->fChangeMouseYAxis )
					if (pcController->bMouseMoveY == MM_BUFF)
						pcController->bMouseMoveY = MM_ABS;
					else if (pcController->bMouseMoveY == MM_ABS)
						pcController->bMouseMoveY = MM_BUFF;

				if( args->fChangeKeyboardXAxis )
					pcController->fKeyAbsoluteX = !pcController->fKeyAbsoluteX;
				if( args->fChangeKeyboardYAxis )
					pcController->fKeyAbsoluteY = !pcController->fKeyAbsoluteY;
			}
				break;
			}
		}

		btnButton.fPrevPressed = b_Value;
		pcController->pModifiers[i].btnButton = btnButton;
	} // END N64 MODIFIERS for

	// do N64-Buttons / modifiers
	for( i = 0; i < PF_APADR; i++ )
	{
		BUTTON btnButton = pcController->aButton[i];

		b_Value = IsBtnPressed( btnButton );

		w_Buttons |= (((WORD)b_Value) << i);
	} // END N64 BUTTONS for

	long lDeadZoneValue = pcController->bPadDeadZone * RANGERELATIVE / 100;
	float fDeadZoneRelation	= (float)RANGERELATIVE  / (float)( RANGERELATIVE - lDeadZoneValue );

	// do N64 joystick axes
	for ( i = 0; i < 4; i++ )
	{
		//	0 : right
		//	1 : left
		//	2 : down
		//	3 : up

		bool fNegInput = (( i == 1 ) || ( i == 2 )); // Input has to be negated

		BUTTON btnButton = pcController->aButton[PF_APADR + pcController->bAxisSet * 4 + i];
		LPLONG plRawState = (LPLONG)&btnButton.parentDevice->stateAs.joyState;
		
		switch( btnButton.bBtnType )
		{
		case DT_JOYBUTTON:
			l_Value = MAXAXISVALUE;
			b_Value = ( btnButton.parentDevice->stateAs.joyState.rgbButtons[btnButton.bOffset] & 0x80 ) != 0;
			break;

		case DT_JOYSLIDER:
		case DT_JOYAXE:
			l_Value = plRawState[btnButton.bOffset] - ZEROVALUE;

			if( btnButton.bAxisID ) // negative Range
			{
				fNegInput = !fNegInput;

				b_Value = ( l_Value <= -lDeadZoneValue );
				if( b_Value )
					l_Value = (long) ((float)(l_Value + lDeadZoneValue ) * fDeadZoneRelation );
			}
			else
			{
				b_Value = ( l_Value >= lDeadZoneValue );
				if( b_Value )
					l_Value = (long) ((float)(l_Value - lDeadZoneValue ) * fDeadZoneRelation );
			}	
			break;

		case DT_JOYPOV:
			l_Value = MAXAXISVALUE;
			b_Value = GetJoyPadPOV( (PDWORD)&plRawState[btnButton.bOffset] , btnButton.bAxisID );
			break;

		case DT_KEYBUTTON:
			if( btnButton.parentDevice->stateAs.rgbButtons[btnButton.bOffset] & 0x80 )
			{
				b_Value = true;

				if(( pcController->fKeyAbsoluteX && i < 2 )
					|| ( pcController->fKeyAbsoluteY &&  i > 1 ))
				{
					if( pcController->wAxeBuffer[i] < MAXAXISVALUE )
					{
						l_Value = pcController->wAxeBuffer[i] = min(( pcController->wAxeBuffer[i] + N64DIVIDER*3), MAXAXISVALUE );
					}
					else
						l_Value = MAXAXISVALUE;
				}
				else
				{
					if( pcController->wAxeBuffer[i] < MAXAXISVALUE )
					{
						l_Value = pcController->wAxeBuffer[i] = min(( pcController->wAxeBuffer[i] * 2 + N64DIVIDER*5 ), MAXAXISVALUE );
					}
					else
						l_Value = MAXAXISVALUE;
				}
			}
			else
			{
				if(( pcController->fKeyAbsoluteX && i < 2 )
					|| ( pcController->fKeyAbsoluteY && i > 1 ))
				{
					l_Value = pcController->wAxeBuffer[i];
					b_Value = true;
				}
				else
				{
					if( pcController->wAxeBuffer[i] > N64DIVIDER )
					{
						b_Value = true;
						l_Value = pcController->wAxeBuffer[i] = pcController->wAxeBuffer[i] / 2 ;
					}
					else
						b_Value = false;
				}
			}
			break;

		case DT_MOUSEBUTTON:
			l_Value = MAXAXISVALUE;
			b_Value = ( btnButton.parentDevice->stateAs.mouseState.rgbButtons[btnButton.bOffset] & 0x80 ) != 0;
			break;

		case DT_MOUSEAXE:
			if( i < 2 )
				pcController->wAxeBuffer[i] += plRawState[btnButton.bOffset] * pcController->wMouseSensitivityX * MOUSESCALEVALUE;	// l_Value = btnButton.parentDevice->stateAs.mouseState[btnButton.bOffset];
			else
				pcController->wAxeBuffer[i] += plRawState[btnButton.bOffset] * pcController->wMouseSensitivityY * MOUSESCALEVALUE;	// l_Value = btnButton.parentDevice->stateAs.mouseState[btnButton.bOffset];

			l_Value = pcController->wAxeBuffer[i];

			// wAxeBuffer is positive for axes 0 and 3 if buffer remains, else zero
			// wAxeBuffer is negative for axes 1 and 2 if buffer remains, else zero

			if(( pcController->bMouseMoveX == MM_ABS && i < 2 ) || ( pcController->bMouseMoveY == MM_ABS &&  i > 1 ))
				pcController->wAxeBuffer[i] = min( max( MINAXISVALUE, pcController->wAxeBuffer[i]) , MAXAXISVALUE);
			else if (( pcController->bMouseMoveX == MM_BUFF && i < 2 ) || ( pcController->bMouseMoveY == MM_BUFF &&  i > 1 ))
				pcController->wAxeBuffer[i] = pcController->wAxeBuffer[i] * MOUSEBUFFERDECAY / 100;
			else // "deadpan" mouse
			{
				pcController->wAxeBuffer[i] = 0;
			}

			if( btnButton.bAxisID == AI_AXE_N) // the mouse axis has the '-' flag set
			{
				fNegInput = !fNegInput;

				b_Value = ( l_Value < ZEROVALUE );
			}
			else
			{
				b_Value = ( l_Value > ZEROVALUE );
			}

			break;
		
		case DT_UNASSIGNED:
		default:
			b_Value = false;
		}

		if ( b_Value )
		{
			if ( fNegInput )
				l_Value = -l_Value;
			
			if( i < 2 )
				lAxisValueX += l_Value;
			else
				lAxisValueY += l_Value;
		}
	}

	if( pcController->fKeyboard )
	{
		if( pcController->fKeyAbsoluteX )
		{
			if( pcController->wAxeBuffer[0] > pcController->wAxeBuffer[1] )
			{
				pcController->wAxeBuffer[0] -= pcController->wAxeBuffer[1];
				pcController->wAxeBuffer[1] = 0;
			}
			else
			{
				pcController->wAxeBuffer[1] -= pcController->wAxeBuffer[0];
				pcController->wAxeBuffer[0] = 0;
			}
		}
		if( pcController->fKeyAbsoluteY )
		{
			if( pcController->wAxeBuffer[2] > pcController->wAxeBuffer[3] )
			{
				pcController->wAxeBuffer[2] -= pcController->wAxeBuffer[3];
				pcController->wAxeBuffer[3] = 0;
			}
			else
			{
				pcController->wAxeBuffer[3] -= pcController->wAxeBuffer[2];
				pcController->wAxeBuffer[2] = 0;
			}
		}
	}


	if (pcController->bRapidFireEnabled)
	{
		if (pcController->bRapidFireCounter >= pcController->bRapidFireRate)
		{
			w_Buttons = (w_Buttons & 0xFF1F);
			pcController->bRapidFireCounter = 0;
		}
		else
		{
			pcController->bRapidFireCounter = pcController->bRapidFireCounter + 1;
		}
	}

	if( pcController->fRealN64Range && ( lAxisValueX || lAxisValueY ))
	{
		long lAbsoluteX = ( lAxisValueX > 0 ) ? lAxisValueX : -lAxisValueX;
		long lAbsoluteY = ( lAxisValueY > 0 ) ? lAxisValueY : -lAxisValueY;

		long lRangeX;
		long lRangeY;

		if(	lAbsoluteX > lAbsoluteY )
		{
			lRangeX = MAXAXISVALUE;
			lRangeY = lRangeX * lAbsoluteY / lAbsoluteX;
		}
		else
		{
			lRangeY = MAXAXISVALUE;
			lRangeX = lRangeY * lAbsoluteX / lAbsoluteY;
		}

		// TODO: optimize this --rabid
		double dRangeDiagonal = sqrt((double)(lRangeX * lRangeX + lRangeY * lRangeY));
//		__asm{
//			fld fRangeDiagonal
//			fsqrt
//			fstp fRangeDiagonal
//			fwait
//		}
		double dRel = MAXAXISVALUE / dRangeDiagonal;

		*pdwData = MAKELONG(w_Buttons,
							MAKEWORD(	(BYTE)(min( max( MINAXISVALUE, (long)(lAxisValueX * d_ModifierX * dRel )), MAXAXISVALUE) / N64DIVIDER ),
										(BYTE)(min( max( MINAXISVALUE, (long)(lAxisValueY * d_ModifierY * dRel )), MAXAXISVALUE) / N64DIVIDER )));
	}
	else
	{
		*pdwData = MAKELONG(w_Buttons,
							MAKEWORD(	(BYTE)(min( max( MINAXISVALUE, (long)(lAxisValueX * d_ModifierX )), MAXAXISVALUE) / N64DIVIDER ),
										(BYTE)(min( max( MINAXISVALUE, (long)(lAxisValueY * d_ModifierY )), MAXAXISVALUE) / N64DIVIDER )));
	}

	return true;
}