464 lines
14 KiB
C++
464 lines
14 KiB
C++
//=============================================================================
|
|
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
|
|
//
|
|
// File: rumbleeffect.cpp
|
|
//
|
|
// Description: Implement RumbleEffect
|
|
//
|
|
// History: 12/19/2002 + Created -- Cary Brisebois
|
|
//
|
|
//=============================================================================
|
|
|
|
//========================================
|
|
// System Includes
|
|
//========================================
|
|
// Foundation Tech
|
|
#include <raddebug.hpp>
|
|
#include <raddebugwatch.hpp>
|
|
|
|
//========================================
|
|
// Project Includes
|
|
//========================================
|
|
#include <input/rumbleeffect.h>
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Global Data, Local Data, Local Classes
|
|
//
|
|
//*****************************************************************************
|
|
#ifdef DEBUGWATCH
|
|
int gRECount = -1;
|
|
#endif
|
|
|
|
extern EffectValue VALUES[];
|
|
|
|
extern EffectValue DYNA_VALUES[];
|
|
|
|
float GAIN_FUDGE = 25.0f;
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Public Member Functions
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::RumbleEffect
|
|
//=============================================================================
|
|
// Description: Constructor.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: N/A.
|
|
//
|
|
//=============================================================================
|
|
RumbleEffect::RumbleEffect() :
|
|
mWheelEffect( NULL )
|
|
{
|
|
unsigned int i;
|
|
for ( i = 0; i < Input::MaxOutputMotor; ++i )
|
|
{
|
|
mMotors[ i ] = NULL;
|
|
mMotorUpdated[ i ] = false;
|
|
}
|
|
|
|
#ifdef DEBUGWATCH
|
|
++gRECount;
|
|
mEffectNum = gRECount;
|
|
char nameSpace[256];
|
|
sprintf( nameSpace, "Controller\\RumbleEffect%d", mEffectNum );
|
|
|
|
char name[256];
|
|
for ( i = 0; i < NUM_EFFECTS; ++i )
|
|
{
|
|
sprintf( name, "%s Effect", VALUES[i].name );
|
|
radDbgWatchAddUnsignedInt( &mCurrentEffects[i].mRumbleTimeLeft, name, nameSpace, NULL, NULL, 0, 100000 );
|
|
}
|
|
|
|
for ( i = 0; i < NUM_DYNA_EFFECTS; ++i )
|
|
{
|
|
sprintf( name, "%s Dyna Effect", DYNA_VALUES[i].name );
|
|
radDbgWatchAddUnsignedInt( &mCurrentDynaEffects[i].mRumbleTimeLeft, name, nameSpace, NULL, NULL, 0, 100000 );
|
|
radDbgWatchAddFloat( &mCurrentDynaEffects[i].mMaxGain, name, nameSpace, NULL, NULL, 0.0f, 1.0f );
|
|
}
|
|
#endif
|
|
|
|
InitEffects();
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::~RumbleEffect
|
|
//=============================================================================
|
|
// Description: Destructor.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: N/A.
|
|
//
|
|
//=============================================================================
|
|
RumbleEffect::~RumbleEffect()
|
|
{
|
|
unsigned int i;
|
|
for ( i = 0; i < Input::MaxOutputMotor; ++i )
|
|
{
|
|
if( mMotors[ i ] )
|
|
{
|
|
mMotors[ i ]->Release();
|
|
mMotors[ i ] = NULL;
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUGWATCH
|
|
gRECount--;
|
|
for ( i = 0; i < NUM_EFFECTS; ++i )
|
|
{
|
|
radDbgWatchDelete( &mCurrentEffects[i].mRumbleTimeLeft );
|
|
}
|
|
|
|
for ( i = 0; i < NUM_DYNA_EFFECTS; ++i )
|
|
{
|
|
radDbgWatchDelete( &mCurrentDynaEffects[i].mRumbleTimeLeft );
|
|
radDbgWatchDelete( &mCurrentDynaEffects[i].mMaxGain );
|
|
}
|
|
#endif
|
|
|
|
ShutDownEffects();
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::SetMotor
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( unsigned int whichMotor, IRadControllerOutputPoint* motor )
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::SetMotor( unsigned int whichMotor, IRadControllerOutputPoint* motor )
|
|
{
|
|
rAssert( whichMotor < Input::MaxOutputMotor );
|
|
|
|
if ( mMotors[ whichMotor ] )
|
|
{
|
|
mMotors[ whichMotor ]->Release();
|
|
}
|
|
|
|
mMotors[ whichMotor ] = motor;
|
|
mMotors[ whichMotor ]->AddRef();
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::SetEffect
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( Effect effect, unsigned int milliseconds )
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::SetEffect( Effect effect, unsigned int milliseconds )
|
|
{
|
|
if ( mCurrentEffects[ effect ].mRumbleTimeLeft < milliseconds )
|
|
{
|
|
mCurrentEffects[ effect ].mRumbleTimeLeft = milliseconds;
|
|
}
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::SetDynaEffect
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( DynaEffect effect, unsigned int milliseconds, float gain )
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::SetDynaEffect( DynaEffect effect, unsigned int milliseconds, float gain )
|
|
{
|
|
if ( mCurrentDynaEffects[ effect ].mRumbleTimeLeft < milliseconds )
|
|
{
|
|
mCurrentDynaEffects[ effect ].mRumbleTimeLeft = milliseconds;
|
|
|
|
if ( gain > 1.0f )
|
|
{
|
|
gain = 1.0f;
|
|
}
|
|
|
|
mCurrentDynaEffects[ effect ].mMaxGain = gain * GAIN_FUDGE;
|
|
|
|
#ifdef RAD_GAMECUBE
|
|
if ( gain * GAIN_FUDGE < 0.3f )
|
|
{
|
|
mCurrentDynaEffects[ effect ].mMaxGain = 0;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::Update
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( unsigned int milliseconds )
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::Update( unsigned int milliseconds )
|
|
{
|
|
//The heaviest effect with time left is the one that runs.
|
|
Effect currentEffect = NUM_EFFECTS;
|
|
|
|
unsigned int i;
|
|
|
|
//Update all the effects.
|
|
for ( i = 0; i < NUM_EFFECTS; ++i )
|
|
{
|
|
if ( mCurrentEffects[ i ].mRumbleTimeLeft <= milliseconds )
|
|
{
|
|
if ( mCurrentEffects[ i ].mRumbleTimeLeft > 0 )
|
|
{
|
|
UpdateEffect( static_cast<Effect>(i), mCurrentEffects[ i ].mRumbleTimeLeft );
|
|
}
|
|
|
|
mCurrentEffects[ i ].mRumbleTimeLeft = 0;
|
|
}
|
|
else
|
|
{
|
|
mCurrentEffects[ i ].mRumbleTimeLeft -= milliseconds;
|
|
|
|
UpdateEffect( static_cast<Effect>(i), milliseconds );
|
|
}
|
|
}
|
|
|
|
for ( i = 0; i < NUM_DYNA_EFFECTS; ++i )
|
|
{
|
|
if ( mCurrentDynaEffects[ i ].mRumbleTimeLeft <= milliseconds )
|
|
{
|
|
if ( mCurrentDynaEffects[ i ].mRumbleTimeLeft > 0 )
|
|
{
|
|
UpdateDynaEffect( static_cast<DynaEffect>(i), mCurrentDynaEffects[ i ].mRumbleTimeLeft, mCurrentDynaEffects[ i ].mMaxGain );
|
|
}
|
|
|
|
mCurrentDynaEffects[ i ].mRumbleTimeLeft = 0;
|
|
}
|
|
else
|
|
{
|
|
mCurrentDynaEffects[ i ].mRumbleTimeLeft -= milliseconds;
|
|
|
|
UpdateDynaEffect( static_cast<DynaEffect>(i), milliseconds, mCurrentDynaEffects[ i ].mMaxGain );
|
|
}
|
|
}
|
|
|
|
for ( i = 0; i < Input::MaxOutputMotor; ++i )
|
|
{
|
|
//You only update a motor when you want to give it a positive value.
|
|
if ( !mMotorUpdated[ i ] )
|
|
{
|
|
if ( mMotors[ i ]&& mMotors[ i ]->GetGain() > 0.0f )
|
|
{
|
|
#ifdef RAD_GAMECUBE
|
|
mMotors[ i ]->SetGain( -1.0f ); //This stops the motor HARD
|
|
#else
|
|
mMotors[ i ]->SetGain( 0.0f );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//Reset them all.
|
|
mMotorUpdated[ i ] = false;
|
|
}
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::ShutDownEffects
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::ShutDownEffects()
|
|
{
|
|
unsigned int i;
|
|
for ( i = 0; i < NUM_EFFECTS; ++i )
|
|
{
|
|
mCurrentEffects[ i ].mRumbleTimeLeft = 0;
|
|
}
|
|
|
|
for ( i = 0; i < Input::MaxOutputMotor; ++i )
|
|
{
|
|
if ( mMotors[ i ] && mMotors[ i ]->GetGain() > 0.0f )
|
|
{
|
|
#ifdef RAD_GAMECUBE
|
|
mMotors[ i ]->SetGain( -1.0f ); //This stops the motor HARD
|
|
#else
|
|
mMotors[ i ]->SetGain( 0.0f );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
OnShutDownEffects();
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Private Member Functions
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::UpdateEffect
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( Effect effect, unsigned int milliseconds )
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::UpdateEffect( Effect effect, unsigned int milliseconds )
|
|
{
|
|
if ( mCurrentEffects[ effect ].mRumbleTimeLeft % VALUES[effect].pulseTime < 32 ) //We use 32 because we hope to only do this once a frame (or twice)
|
|
{
|
|
if ( mMotors[ VALUES[effect].motor ] )
|
|
{
|
|
float currMotorGain = mMotors[ VALUES[effect].motor ]->GetGain();
|
|
float desiredGain = VALUES[effect].gain;
|
|
|
|
if ( currMotorGain < desiredGain )
|
|
{
|
|
mMotors[ VALUES[effect].motor ]->SetGain( VALUES[effect].gain );
|
|
mMotorUpdated[ VALUES[effect].motor ] = true;
|
|
}
|
|
#ifdef RAD_GAMECUBE
|
|
// Michael Riegger - Gamecube is different from other platforms in rumble
|
|
// control in that motor control is basically turn on / turn off commands
|
|
// and that rumble just 'goes' in between those commands. No need to
|
|
// toggle on and off manually
|
|
// so set the updated flag to true always if its where we want. Otherwise
|
|
// gain will be reset to 0 or -1 automatically
|
|
else if ( currMotorGain == desiredGain )
|
|
{
|
|
mMotorUpdated[ VALUES[effect].motor ] = true;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
/* if ( mCurrentEffects[ effect ].mRumbleTimeLeft % VALUES[effect].pulseTime < 32 ) //We use 32 because we hope to only do this once a frame (or twice)
|
|
{
|
|
if ( mMotors[ VALUES[effect].motor ] )
|
|
{
|
|
|
|
|
|
if ( currMotorGain == desiredGain )
|
|
{
|
|
mMotorUpdated[ VALUES[effect].motor ] = true;
|
|
}
|
|
else if ( currMotorGain < desiredGain )
|
|
{
|
|
mMotors[ VALUES[effect].motor ]->SetGain( VALUES[effect].gain );
|
|
mMotorUpdated[ VALUES[effect].motor ] = true;
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::UpdateDynaEffect
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ( DynaEffect effect, unsigned int milliseconds, float gain )
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::UpdateDynaEffect( DynaEffect effect, unsigned int milliseconds, float gain ) //This is a pcnt
|
|
{
|
|
if ( mCurrentDynaEffects[ effect ].mRumbleTimeLeft % DYNA_VALUES[effect].pulseTime < 32 ) //We use 32 because we hope to only do this once a frame (or twice)
|
|
{
|
|
if ( mMotors[ DYNA_VALUES[effect].motor ] &&
|
|
mMotors[ DYNA_VALUES[effect].motor ]->GetGain() < DYNA_VALUES[effect].gain * gain )
|
|
{
|
|
mMotors[ DYNA_VALUES[effect].motor ]->SetGain( DYNA_VALUES[effect].gain * gain );
|
|
mMotorUpdated[ DYNA_VALUES[effect].motor ] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::InitEffects
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::InitEffects()
|
|
{
|
|
#ifdef DEBUGWATCH
|
|
if ( gRECount == 0 )
|
|
{
|
|
char name[256];
|
|
unsigned int i;
|
|
for ( i = 0; i < NUM_EFFECTS; ++i )
|
|
{
|
|
sprintf( name, "Controller\\%s Effect", VALUES[i].name );
|
|
radDbgWatchAddUnsignedInt( &VALUES[i].pulseTime, "PulseTime", name, NULL, NULL, 1, 1000 );
|
|
radDbgWatchAddFloat( &VALUES[i].gain, "Gain", name, NULL, NULL, 0.0f, 1.0f );
|
|
radDbgWatchAddChar( &VALUES[i].motor, "Motor", name, NULL, NULL, 0, 1 );
|
|
}
|
|
|
|
for ( i = 0; i < NUM_DYNA_EFFECTS; ++i )
|
|
{
|
|
sprintf( name, "Controller\\%s Dyna Effect", VALUES[i].name );
|
|
radDbgWatchAddUnsignedInt( &DYNA_VALUES[i].pulseTime, "PulseTime", name, NULL, NULL, 1, 1000 );
|
|
radDbgWatchAddFloat( &DYNA_VALUES[i].gain, "Gain", name, NULL, NULL, 0.0f, 1.0f );
|
|
radDbgWatchAddChar( &DYNA_VALUES[i].motor, "Motor", name, NULL, NULL, 0, 1 );
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//=============================================================================
|
|
// RumbleEffect::OnShutDownEffects
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void RumbleEffect::OnShutDownEffects()
|
|
{
|
|
#ifdef DEBUGWATCH
|
|
if ( gRECount == -1 )
|
|
{
|
|
unsigned int i;
|
|
for ( i = 0; i < NUM_EFFECTS; ++i )
|
|
{
|
|
radDbgWatchDelete( &VALUES[i].pulseTime );
|
|
radDbgWatchDelete( &VALUES[i].gain );
|
|
radDbgWatchDelete( &VALUES[i].motor );
|
|
}
|
|
|
|
for ( i = 0; i < NUM_DYNA_EFFECTS; ++i )
|
|
{
|
|
radDbgWatchDelete( &DYNA_VALUES[i].pulseTime );
|
|
radDbgWatchDelete( &DYNA_VALUES[i].gain );
|
|
radDbgWatchDelete( &DYNA_VALUES[i].motor );
|
|
}
|
|
}
|
|
#endif
|
|
} |