diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tier3/choreoutils.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'tier3/choreoutils.cpp')
| -rw-r--r-- | tier3/choreoutils.cpp | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/tier3/choreoutils.cpp b/tier3/choreoutils.cpp new file mode 100644 index 0000000..613103e --- /dev/null +++ b/tier3/choreoutils.cpp @@ -0,0 +1,347 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Helper methods + classes for file access +// +//===========================================================================// + +#include "tier3/choreoutils.h" +#include "tier3/tier3.h" +#include "SoundEmitterSystem/isoundemittersystembase.h" +#include "studio.h" +#include "../game/shared/choreoscene.h" +#include "../game/shared/choreoevent.h" +#include "tier1/KeyValues.h" +#include "bone_setup.h" +#include "soundchars.h" + + +//----------------------------------------------------------------------------- +// Find sequence by name +//----------------------------------------------------------------------------- +static int LookupSequence( CStudioHdr *pStudioHdr, const char *pSequenceName ) +{ + for ( int i = 0; i < pStudioHdr->GetNumSeq(); i++ ) + { + if ( !Q_stricmp( pSequenceName, pStudioHdr->pSeqdesc( i ).pszLabel() ) ) + return i; + } + return -1; +} + + +//----------------------------------------------------------------------------- +// Returns sequence flags +//----------------------------------------------------------------------------- +static int GetSequenceFlags( CStudioHdr *pStudioHdr, int nSequence ) +{ + if ( !pStudioHdr || nSequence < 0 || nSequence >= pStudioHdr->GetNumSeq() ) + return 0; + mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( nSequence ); + return seqdesc.flags; +} + + +//----------------------------------------------------------------------------- +// Does a sequence loop? +//----------------------------------------------------------------------------- +static bool DoesSequenceLoop( CStudioHdr *pStudioHdr, int nSequence ) +{ + int nFlags = GetSequenceFlags( pStudioHdr, nSequence ); + bool bLooping = ( nFlags & STUDIO_LOOPING ) ? true : false; + return bLooping; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool AutoAddGestureKeys( CChoreoEvent *e, CStudioHdr *pStudioHdr, float *pPoseParameters, bool bCheckOnly ) +{ + int iSequence = LookupSequence( pStudioHdr, e->GetParameters() ); + if ( iSequence < 0 ) + return false; + + KeyValues *pSeqKeyValues = new KeyValues( "" ); + if ( !pSeqKeyValues->LoadFromBuffer( pStudioHdr->pszName(), Studio_GetKeyValueText( pStudioHdr, iSequence ) ) ) + { + pSeqKeyValues->deleteThis(); + return false; + } + + // Do we have a build point section? + KeyValues *pKVAllFaceposer = pSeqKeyValues->FindKey("faceposer"); + if ( !pKVAllFaceposer ) + { + pSeqKeyValues->deleteThis(); + return false; + } + + int nMaxFrame = Studio_MaxFrame( pStudioHdr, iSequence, pPoseParameters ) - 1; + + // Start grabbing the sounds and slotting them in + KeyValues *pkvFaceposer; + char szStartLoop[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "loop" }; + char szEndLoop[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "end" }; + char szEntry[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "apex" }; + char szExit[CEventAbsoluteTag::MAX_EVENTTAG_LENGTH] = { "end" }; + + for ( pkvFaceposer = pKVAllFaceposer->GetFirstSubKey(); pkvFaceposer; pkvFaceposer = pkvFaceposer->GetNextKey() ) + { + if ( !Q_stricmp( pkvFaceposer->GetName(), "startloop" ) ) + { + Q_strncpy( szStartLoop, pkvFaceposer->GetString(), sizeof(szStartLoop) ); + continue; + } + + if ( !Q_stricmp( pkvFaceposer->GetName(), "endloop" ) ) + { + Q_strncpy( szEndLoop, pkvFaceposer->GetString(), sizeof(szEndLoop) ); + continue; + } + + if ( !Q_stricmp( pkvFaceposer->GetName(), "entrytag" ) ) + { + Q_strncpy( szEntry, pkvFaceposer->GetString(), sizeof(szEntry) ); + continue; + } + + if ( !Q_stricmp( pkvFaceposer->GetName(), "exittag" ) ) + { + Q_strncpy( szExit, pkvFaceposer->GetString(), sizeof(szExit) ); + continue; + } + + if ( !Q_stricmp( pkvFaceposer->GetName(), "tags" ) ) + { + if ( nMaxFrame <= 0 ) + continue; + + KeyValues *pkvTags; + for ( pkvTags = pkvFaceposer->GetFirstSubKey(); pkvTags; pkvTags = pkvTags->GetNextKey() ) + { + float flPercentage = (float)pkvTags->GetInt() / nMaxFrame; + + CEventAbsoluteTag *ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, pkvTags->GetName() ); + if (ptag) + { + // reposition tag + ptag->SetPercentage( flPercentage ); + } + else + { + e->AddAbsoluteTag( CChoreoEvent::ORIGINAL, pkvTags->GetName(), flPercentage ); + e->AddAbsoluteTag( CChoreoEvent::PLAYBACK, pkvTags->GetName(), flPercentage ); + } + // lock the original tags so they can't be edited + ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, pkvTags->GetName() ); + Assert( ptag ); + ptag->SetLocked( true ); + } + e->VerifyTagOrder(); + e->PreventTagOverlap(); + continue; + } + } + + // FIXME: lookup linear tags in sequence data + { + CEventAbsoluteTag *ptag; + ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szStartLoop ); + if (ptag) + { + ptag->SetLinear( true ); + } + ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szStartLoop ); + if (ptag) + { + ptag->SetLinear( true ); + } + ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szEndLoop ); + if (ptag) + { + ptag->SetLinear( true ); + } + ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szEndLoop ); + if (ptag) + { + ptag->SetLinear( true ); + } + + ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szEntry ); + if (ptag) + { + ptag->SetEntry( true ); + } + ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szEntry ); + if (ptag) + { + ptag->SetEntry( true ); + } + ptag = e->FindAbsoluteTag( CChoreoEvent::ORIGINAL, szExit ); + if (ptag) + { + ptag->SetExit( true ); + } + ptag = e->FindAbsoluteTag( CChoreoEvent::PLAYBACK, szExit ); + if (ptag) + { + ptag->SetExit( true ); + } + } + + pSeqKeyValues->deleteThis(); + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool UpdateGestureLength( CChoreoEvent *e, CStudioHdr *pStudioHdr, float *pPoseParameters, bool bCheckOnly ) +{ + Assert( e ); + if ( !e ) + return false; + + if ( e->GetType() != CChoreoEvent::GESTURE ) + return false; + + int iSequence = LookupSequence( pStudioHdr, e->GetParameters() ); + if ( iSequence < 0 ) + return false; + + bool bChanged = false; + float flSeqDuration = Studio_Duration( pStudioHdr, iSequence, pPoseParameters ); + float flCurDuration; + e->GetGestureSequenceDuration( flCurDuration ); + if ( flSeqDuration != 0.0f && flSeqDuration != flCurDuration ) + { + bChanged = true; + if ( !bCheckOnly ) + { + e->SetGestureSequenceDuration( flSeqDuration ); + } + } + + return bChanged; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool UpdateSequenceLength( CChoreoEvent *e, CStudioHdr *pStudioHdr, float *pPoseParameters, bool bCheckOnly, bool bVerbose ) +{ + Assert( e ); + if ( !e ) + return false; + + if ( e->GetType() != CChoreoEvent::SEQUENCE ) + { + if ( bVerbose ) + { + ConMsg( "UpdateSequenceLength: called on non-SEQUENCE event %s\n", e->GetName() ); + } + return false; + } + + int iSequence = LookupSequence( pStudioHdr, e->GetParameters() ); + if ( iSequence < 0 ) + return false; + + bool bChanged = false; + bool bLooping = DoesSequenceLoop( pStudioHdr, iSequence ); + float flSeqDuration = Studio_Duration( pStudioHdr, iSequence, pPoseParameters ); + + if ( bLooping ) + { + if ( e->IsFixedLength() ) + { + if ( bCheckOnly ) + return true; + + if ( bVerbose ) + { + ConMsg( "UpdateSequenceLength: %s is looping, removing fixed length flag\n", e->GetName() ); + } + bChanged = true; + } + e->SetFixedLength( false ); + + if ( !e->HasEndTime() ) + { + if ( bCheckOnly ) + return true; + + if ( bVerbose ) + { + ConMsg( "CheckSequenceLength: %s is looping, setting default end time\n", e->GetName() ); + } + e->SetEndTime( e->GetStartTime() + flSeqDuration ); + bChanged = true; + } + + return bChanged; + } + + if ( !e->IsFixedLength() ) + { + if ( bCheckOnly ) + return true; + + if ( bVerbose ) + { + ConMsg( "CheckSequenceLength: %s is fixed length, removing looping flag\n", e->GetName() ); + } + bChanged = true; + } + e->SetFixedLength( true ); + + if ( e->HasEndTime() ) + { + float dt = e->GetDuration(); + if ( fabs( dt - flSeqDuration ) > 0.01f ) + { + if ( bCheckOnly ) + return true; + if ( bVerbose ) + { + ConMsg( "CheckSequenceLength: %s has wrong duration, changing length from %f to %f seconds\n", + e->GetName(), dt, flSeqDuration ); + } + bChanged = true; + } + } + else + { + if ( bCheckOnly ) + return true; + if ( bVerbose ) + { + ConMsg( "CheckSequenceLength: %s has wrong duration, changing length to %f seconds\n", + e->GetName(), flSeqDuration ); + } + bChanged = true; + } + + if ( !bCheckOnly ) + { + e->SetEndTime( e->GetStartTime() + flSeqDuration ); + } + + return bChanged; +} + + +//----------------------------------------------------------------------------- +// Finds sound files associated with events +//----------------------------------------------------------------------------- +const char *GetSoundForEvent( CChoreoEvent *pEvent, CStudioHdr *pStudioHdr ) +{ + const char *pSoundName = pEvent->GetParameters(); + if ( Q_stristr( pSoundName, ".wav" ) ) + return PSkipSoundChars( pSoundName ); + + const char *pFileName = g_pSoundEmitterSystem->GetWavFileForSound( pSoundName, ( pStudioHdr && pStudioHdr->IsValid() ) ? pStudioHdr->pszName() : NULL ); + return PSkipSoundChars( pFileName ); +} |