// Returns false when the end of the script is reached
bool IN_AdvanceToNextState(int whichScript)
{
	assert( whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS );
	
	if (rumbleScripts[whichScript].currentState >= rumbleScripts[whichScript].usedStates - 1)
	{
		// Script is at its end, so kill it( which deletes only if autodelete
		IN_KillRumbleScript(whichScript);
		return false;
	}

	// Advance a state
	rumbleScripts[whichScript].currentState++;

	int cmd = rumbleScripts[whichScript].states[rumbleScripts[whichScript].currentState].timeToStop;
	while (cmd < 0)
	{
		cmd = IN_RunSpecialScript(whichScript);
		if (cmd == -1) return true;
		if (cmd == -2) return false;
	}

	rumbleScripts[whichScript].nextStateAt = IN_Time() + cmd;
	return true;
}
// Stops Rumbling for specific controller
void IN_KillRumbleScripts(int controller)
{
	if (!IN_usingRumble()) return;
	if (controller <= -1 || controller >= MAX_RUMBLE_CONTROLLERS) return;
	if (rumbleStatus[controller].killed == true) return;

	for (int i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
	{
		if (rumbleScripts[i].controller == controller)
			IN_KillRumbleScript(i);
	}

	rumbleStatus[controller].killed = IN_RumbleAdjust(controller, 0, 0);
}
// Stops Rumbling on all controllers
void IN_KillRumbleScripts( void )
{
	if (!IN_usingRumble()) return;

	for (int i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
		IN_KillRumbleScript(i);

	for (int j = 0; j < MAX_RUMBLE_CONTROLLERS; j++)
	{
		if (!rumbleStatus[j].killed)
		{
			rumbleStatus[j].killed = IN_RumbleAdjust(j, 0, 0);
		}
	}
}
// Max rumble takes precidence
// Other possibility is some kind of sum of all the speeds 
// Call this once a frame, to update the controller based on the rumble states
void IN_UpdateRumbleFromStates()
{
	//if (!IN_usingRumble()) return;
/*mb	extern int G_ShouldBeRumbling();
	if (!G_ShouldBeRumbling())
		return;
*/
	int usingRumble[2];
	usingRumble[0] = Cvar_VariableIntegerValue("in_useRumble");
	usingRumble[1] = Cvar_VariableIntegerValue("in_useRumble2");
	
	int i;
	int value[MAX_RUMBLE_CONTROLLERS][2];		
	int cur_time = IN_Time();

	memset(value, 0, sizeof(int)*MAX_RUMBLE_CONTROLLERS*2);
	for (i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
	{
		// If rumble is paused on current controller than skip this rumble state
		if ( rumbleStatus[rumbleScripts[i].controller].paused) continue;

//*mb	ClientManager::ActivateByControllerId(rumbleScripts[i].controller);
		if ( !usingRumble[ActiveClientNum()] ) 
		{
			IN_KillRumbleScript(i);
			continue;
		}
/*mb
		if (!ClientManager::ActiveGentity() || !G_ActivePlayerNormal())
		{
			IN_KillRumbleScript(i);
			continue;
		}
*/
		// Unset state so skip
		if ( rumbleScripts[i].nextStateAt == 0) continue;

		// Time is up on this rumble state
		if ( rumbleScripts[i].nextStateAt < cur_time) 
		{
			// If timeToStop is < cur_time and > 0 then end this state otherwise (negative number) always rumble 
			if (rumbleScripts[i].nextStateAt > 0) 
			{	
				rumbleStatus[rumbleScripts[i].controller].changed = true;
				rumbleStatus[rumbleScripts[i].controller].killed = false;
				if (!IN_AdvanceToNextState(i))		// Returns false if reached the end of script
					continue;
			}
		}

		rumblescript_t *curScript = &rumbleScripts[i];

		if (value[curScript->controller][0] < curScript->states[curScript->currentState].arg2)
			value[curScript->controller][0] = curScript->states[curScript->currentState].arg2;
		if (value[curScript->controller][1] < curScript->states[curScript->currentState].arg1)
			value[curScript->controller][1] = curScript->states[curScript->currentState].arg1;
	}
	
	// Go through the 4 controller ports
	for (i = 0; i < MAX_RUMBLE_CONTROLLERS; i++) 
	{
		// paused, so do nothing for this controller
		if ( rumbleStatus[i].paused) continue;

		// Only update the actual hardware if a state has changed
		if (!rumbleStatus[i].changed) continue;
		
		IN_RumbleAdjust(i, value[i][0], value[i][1]);
		
		// State has changed
		rumbleStatus[i].changed = false;
	}
}
// Max rumble takes precidence
// Other possibility is some kind of sum of all the speeds 
// Call this once a frame, to update the controller based on the rumble states
void IN_UpdateRumbleFromStates()
{
	if(VM_Call( uivm, UI_IS_FULLSCREEN ))
	{
		IN_KillRumbleScripts();
		return;
	}

	int usingRumble[2];
	usingRumble[0] = in_useRumble->integer;
	usingRumble[1] = in_useRumble2->integer;
	
	int i;
	int value[MAX_RUMBLE_CONTROLLERS][2];		
	int cur_time = IN_Time();
	bool canKillScripts	= false;

	memset(value, 0, sizeof(int)*MAX_RUMBLE_CONTROLLERS*2);
	for (i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
	{
		// If rumble is paused on current controller than skip this rumble state
		if ( rumbleStatus[rumbleScripts[i].controller].paused) continue;

//*mb	ClientManager::ActivateByControllerId(rumbleScripts[i].controller);
		if ( !usingRumble[ActiveClientNum()] ) 
		{
			IN_KillRumbleScript(i);
			continue;
		}
/*mb
		if (!ClientManager::ActiveGentity() || !G_ActivePlayerNormal())
		{
			IN_KillRumbleScript(i);
			continue;
		}
*/
		// Unset state so skip
		if ( rumbleScripts[i].nextStateAt == 0) continue;

		canKillScripts	= true;

		if(rumbleScripts[i].nextStateAt == -1)
		{
			int cmd = rumbleScripts[i].states[rumbleScripts[i].currentState].timeToStop;
			rumbleScripts[i].nextStateAt = cur_time + cmd;
		}

		// Time is up on this rumble state
		if ( rumbleScripts[i].nextStateAt < cur_time) 
		{
			// If timeToStop is < cur_time and > 0 then end this state otherwise (negative number) always rumble 
			if (rumbleScripts[i].nextStateAt > 0) 
			{	
				rumbleStatus[rumbleScripts[i].controller].changed = true;
				rumbleStatus[rumbleScripts[i].controller].killed = false;
				if (!IN_AdvanceToNextState(i))		// Returns false if reached the end of script
					continue;
			}
		}

		rumblescript_t *curScript = &rumbleScripts[i];

		if (value[curScript->controller][0] < curScript->states[curScript->currentState].arg2)
			value[curScript->controller][0] = curScript->states[curScript->currentState].arg2;
		if (value[curScript->controller][1] < curScript->states[curScript->currentState].arg1)
			value[curScript->controller][1] = curScript->states[curScript->currentState].arg1;
	}
	
	// Go through the 4 controller ports
	for (i = 0; i < MAX_RUMBLE_CONTROLLERS; i++) 
	{
		// paused, so do nothing for this controller
		if ( rumbleStatus[i].paused) continue;

		// Only update the actual hardware if a state has changed
		if (!rumbleStatus[i].changed) continue;
		
		IN_RumbleAdjust(i, value[i][0], value[i][1]);
		
		// State has changed
		rumbleStatus[i].changed = false;
	}

	if(canKillScripts)
	{
		if( (cur_time - rumble_timer) > 5000 )
			IN_KillRumbleScripts();
	}
	else
	{
		rumble_timer	= cur_time;
	}
}
Esempio n. 6
0
void FF_Play(ffFX_e effect)
{
	int s;	// script id
	static int const_rumble[2] = {-1}; // script id for constant rumble
	int client;

	// super huge switch for rumble effects
	switch(effect)
	{
	case fffx_AircraftCarrierTakeOff:
	case fffx_BasketballDribble:
	case fffx_CarEngineIdle:
	case fffx_ChainsawIdle:
	case fffx_ChainsawInAction:
	case fffx_DieselEngineIdle:
	case fffx_Jump:
		s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 50000, 10000, 200);
			IN_AddRumbleState(s, 0, 0, 10);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_Land:
		s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 50000, 10000, 200);
			IN_AddRumbleState(s, 0, 0, 10);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_MachineGun:
		s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 56000, 20000, 230);
			IN_AddRumbleState(s, 0, 0, 10);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_Punched:
	case fffx_RocketLaunch:

	case fffx_SecretDoor:
	case fffx_SwitchClick:	// used by saber
		s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 30000, 10000, 120);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_WindGust:
	case fffx_WindShear:
	case fffx_Pistol:
		s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 50000, 10000, 200);
			IN_AddRumbleState(s, 0, 0, 10);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_Shotgun:
	case fffx_Laser1:
	case fffx_Laser2:
	case fffx_Laser3:
	case fffx_Laser4:
	case fffx_Laser5:
	case fffx_Laser6:
	case fffx_OutOfAmmo:
	case fffx_LightningGun:
	case fffx_Missile:
	case fffx_GatlingGun:
		s = IN_CreateRumbleScript(IN_GetMainController(), 2, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 39000, 0, 220);
			IN_AddRumbleState(s, 0, 0, 10);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_ShortPlasma:
	case fffx_PlasmaCannon1:
	case fffx_PlasmaCannon2:
	case fffx_Cannon:
	case fffx_FallingShort:
	case fffx_FallingMedium:
		s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 25000,10000, 230);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_FallingFar:
		s = IN_CreateRumbleScript(IN_GetMainController(), 1, true);
		if (s != -1)
		{
			IN_AddRumbleState(s, 32000,10000, 230);
			IN_ExecuteRumbleScript(s);
		}
		break;
	case fffx_StartConst:
		client = IN_GetMainController();
		if(const_rumble[client] == -1)
		{
			const_rumble[client] = IN_CreateRumbleScript(IN_GetMainController(), 9, true);
			if (const_rumble[client] != -1)
			{
				IN_AddEffectFade4(const_rumble[client], 0,0, 50000, 0, 2000);
				IN_AddRumbleState(const_rumble[client], 50000, 0, 300);
				IN_AddEffectFade4(const_rumble[client], 50000,50000, 0, 0, 1000);
				IN_ExecuteRumbleScript(const_rumble[client]);
			}
		}
		break;
	case fffx_StopConst:
		client = IN_GetMainController();
		if (const_rumble[client] == -1)
			return;
		IN_KillRumbleScript(const_rumble[client]);
		const_rumble[client] = -1;
		break;
	default:
		Com_Printf("No rumble script is defined for fffx_id = %i\n",effect);
		break;
	}
}