summaryrefslogtreecommitdiff
path: root/utils/hlfaceposer/eventproperties.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hlfaceposer/eventproperties.cpp')
-rw-r--r--utils/hlfaceposer/eventproperties.cpp657
1 files changed, 657 insertions, 0 deletions
diff --git a/utils/hlfaceposer/eventproperties.cpp b/utils/hlfaceposer/eventproperties.cpp
new file mode 100644
index 0000000..a85b73c
--- /dev/null
+++ b/utils/hlfaceposer/eventproperties.cpp
@@ -0,0 +1,657 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include <mxtk/mx.h>
+#include <stdio.h>
+#include "resource.h"
+#include "EventProperties.h"
+#include "mdlviewer.h"
+#include "choreoevent.h"
+#include "choreoscene.h"
+#include "mathlib/mathlib.h"
+#include "choreochannel.h"
+#include "choreoactor.h"
+#include "filesystem.h"
+#include "scriplib.h"
+
+#include "eventproperties_expression.h"
+#include "eventproperties_face.h"
+#include "eventproperties_firetrigger.h"
+#include "eventproperties_flexanimation.h"
+#include "eventproperties_generic.h"
+#include "eventproperties_gesture.h"
+#include "eventproperties_interrupt.h"
+#include "eventproperties_lookat.h"
+#include "eventproperties_moveto.h"
+#include "eventproperties_permitresponses.h"
+#include "eventproperties_sequence.h"
+#include "eventproperties_speak.h"
+#include "eventproperties_subscene.h"
+
+void CBaseEventPropertiesDialog::PopulateTagList( CEventParams *params )
+{
+ CChoreoScene *scene = params->m_pScene;
+ if ( !scene )
+ return;
+
+ HWND control = GetControl( IDC_TAGS );
+ if ( control )
+ {
+ SendMessage( control, CB_RESETCONTENT, 0, 0 );
+ SendMessage( control, WM_SETTEXT , 0, (LPARAM)va( "\"%s\" \"%s\"", params->m_szTagName, params->m_szTagWav ) );
+
+ for ( int i = 0; i < scene->GetNumActors(); i++ )
+ {
+ CChoreoActor *a = scene->GetActor( i );
+ if ( !a )
+ continue;
+
+ for ( int j = 0; j < a->GetNumChannels(); j++ )
+ {
+ CChoreoChannel *c = a->GetChannel( j );
+ if ( !c )
+ continue;
+
+ for ( int k = 0 ; k < c->GetNumEvents(); k++ )
+ {
+ CChoreoEvent *e = c->GetEvent( k );
+ if ( !e )
+ continue;
+
+ if ( e->GetNumRelativeTags() <= 0 )
+ continue;
+
+ // add each tag to combo box
+ for ( int t = 0; t < e->GetNumRelativeTags(); t++ )
+ {
+ CEventRelativeTag *tag = e->GetRelativeTag( t );
+ if ( !tag )
+ continue;
+
+ SendMessage( control, CB_ADDSTRING, 0, (LPARAM)va( "\"%s\" \"%s\"", tag->GetName(), e->GetParameters() ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+#include "mapentities.h"
+#include "utldict.h"
+
+struct CMapEntityData
+{
+ CMapEntityData()
+ {
+ origin.Init();
+ angles.Init();
+ }
+
+ Vector origin;
+ QAngle angles;
+};
+
+class CMapEntities : public IMapEntities
+{
+public:
+ CMapEntities();
+ ~CMapEntities();
+
+ virtual void CheckUpdateMap( char const *mapname );
+ virtual bool LookupOrigin( char const *name, Vector& origin, QAngle& angles )
+ {
+ int idx = FindNamedEntity( name );
+ if ( idx == -1 )
+ {
+ origin.Init();
+ angles.Init();
+ return false;
+ }
+
+ CMapEntityData *e = &m_Entities[ idx ];
+ Assert( e );
+ origin = e->origin;
+ angles = e->angles;
+ return true;
+ }
+
+ virtual int Count( void );
+ virtual char const *GetName( int number );
+
+ int FindNamedEntity( char const *name );
+
+private:
+ char m_szCurrentMap[ 1024 ];
+
+ CUtlDict< CMapEntityData, int > m_Entities;
+};
+
+static CMapEntities g_MapEntities;
+// Expose to rest of tool
+IMapEntities *mapentities = &g_MapEntities;
+
+CMapEntities::CMapEntities()
+{
+ m_szCurrentMap[ 0 ] = 0;
+}
+
+CMapEntities::~CMapEntities()
+{
+ m_Entities.RemoveAll();
+}
+
+int CMapEntities::FindNamedEntity( char const *name )
+{
+ char lowername[ 128 ];
+ strcpy( lowername, name );
+ _strlwr( lowername );
+
+ int index = m_Entities.Find( lowername );
+ if ( index == m_Entities.InvalidIndex() )
+ return -1;
+
+ return index;
+}
+
+#include "bspfile.h"
+
+void CMapEntities::CheckUpdateMap( char const *mapname )
+{
+ if ( !mapname || !mapname[ 0 ] )
+ return;
+
+ if ( !stricmp( mapname, m_szCurrentMap ) )
+ return;
+
+ // Latch off the name of the map
+ Q_strncpy( m_szCurrentMap, mapname, sizeof( m_szCurrentMap ) );
+
+ // Load names from map
+ m_Entities.RemoveAll();
+
+ FileHandle_t hfile = filesystem->Open( mapname, "rb" );
+ if ( hfile == FILESYSTEM_INVALID_HANDLE )
+ return;
+
+ dheader_t header;
+ filesystem->Read( &header, sizeof( header ), hfile );
+
+ // Check the header
+ if ( header.ident != IDBSPHEADER ||
+ header.version < MINBSPVERSION || header.version > BSPVERSION )
+ {
+ Con_ErrorPrintf( "BSP file %s is wrong version (%i), expected (%i)\n",
+ mapname,
+ header.version,
+ BSPVERSION );
+
+ filesystem->Close( hfile );
+ return;
+ }
+
+ // Find the LUMP_PAKFILE offset
+ lump_t *entlump = &header.lumps[ LUMP_ENTITIES ];
+ if ( entlump->filelen <= 0 )
+ {
+ Con_ErrorPrintf( "BSP file %s is missing entity lump\n", mapname );
+
+ // It's empty or only contains a file header ( so there are no entries ), so don't add to search paths
+ filesystem->Close( hfile );
+ return;
+ }
+
+ // Seek to correct position
+ filesystem->Seek( hfile, entlump->fileofs, FILESYSTEM_SEEK_HEAD );
+
+ char *buffer = new char[ entlump->filelen + 1 ];
+ Assert( buffer );
+
+ filesystem->Read( buffer, entlump->filelen, hfile );
+
+ filesystem->Close( hfile );
+
+ buffer[ entlump->filelen ] = 0;
+
+ // Now we have entity buffer, now parse it
+ ParseFromMemory( buffer, entlump->filelen );
+
+ while ( 1 )
+ {
+ if (!GetToken (true))
+ break;
+
+ if (Q_stricmp (token, "{") )
+ Error ("ParseEntity: { not found");
+
+ char name[ 256 ];
+ char origin[ 256 ];
+ char angles[ 256 ];
+
+ name[ 0 ] = 0;
+ origin[ 0 ] = 0;
+ angles[ 0 ] = 0;
+
+ do
+ {
+ char key[ 256 ];
+ char value[ 256 ];
+
+ if (!GetToken (true))
+ {
+ Error ("ParseEntity: EOF without closing brace");
+ }
+
+ if (!Q_stricmp (token, "}") )
+ break;
+
+ Q_strncpy( key, token, sizeof( key ) );
+
+ GetToken (false);
+
+ Q_strncpy( value, token, sizeof( value ) );
+
+ // Con_Printf( "Parsed %s -- %s\n", key, value );
+
+ if ( !Q_stricmp( key, "name" ) )
+ {
+ Q_strncpy( name, value, sizeof( name ) );
+ }
+ if ( !Q_stricmp( key, "targetname" ) )
+ {
+ Q_strncpy( name, value, sizeof( name ) );
+ }
+ if ( !Q_stricmp( key, "origin" ) )
+ {
+ Q_strncpy( origin, value, sizeof( origin ) );
+ }
+ if ( !Q_stricmp( key, "angles" ) )
+ {
+ Q_strncpy( angles, value, sizeof( angles ) );
+ }
+
+ } while (1);
+
+ if ( name[ 0 ] )
+ {
+ if ( FindNamedEntity( name ) == - 1 )
+ {
+ CMapEntityData ent;
+
+ float org[3];
+ if ( origin[ 0 ] )
+ {
+ if ( 3 == sscanf( origin, "%f %f %f", &org[ 0 ], &org[ 1 ], &org[ 2 ] ) )
+ {
+ ent.origin = Vector( org[ 0 ], org[ 1 ], org[ 2 ] );
+
+ // Con_Printf( "read %f %f %f for entity %s\n", org[0], org[1], org[2], name );
+ }
+ }
+ if ( angles[ 0 ] )
+ {
+ if ( 3 == sscanf( angles, "%f %f %f", &org[ 0 ], &org[ 1 ], &org[ 2 ] ) )
+ {
+ ent.angles = QAngle( org[ 0 ], org[ 1 ], org[ 2 ] );
+
+ // Con_Printf( "read %f %f %f for entity %s\n", org[0], org[1], org[2], name );
+ }
+ }
+
+ m_Entities.Insert( name, ent );
+ }
+ }
+ }
+
+ delete[] buffer;
+}
+
+int CMapEntities::Count( void )
+{
+ return m_Entities.Count();
+}
+
+char const *CMapEntities::GetName( int number )
+{
+ if ( number < 0 || number >= (int)m_Entities.Count() )
+ return NULL;
+
+ return m_Entities.GetElementName( number );
+}
+
+bool NameLessFunc( const char *const& name1, const char *const& name2 )
+{
+ if ( Q_stricmp( name1, name2 ) < 0 )
+ return true;
+ return false;
+}
+
+void CBaseEventPropertiesDialog::SetDialogTitle( CEventParams *params, char const *eventname, char const *desc )
+{
+ char sz[ 256 ];
+ Q_snprintf( sz, sizeof( sz ), " : %s", eventname );
+ Q_strncat( params->m_szDialogTitle, sz, sizeof( params->m_szDialogTitle ), COPY_ALL_CHARACTERS );
+ Q_snprintf( sz, sizeof( sz ), "%s:", desc );
+
+ // Set dialog title
+ SetWindowText( m_hDialog, params->m_szDialogTitle );
+ // Set type name field
+ SetDlgItemText( m_hDialog, IDC_TYPENAME, sz );
+ // Set event name
+ SetDlgItemText( m_hDialog, IDC_EVENTNAME, params->m_szName );
+}
+
+void CBaseEventPropertiesDialog::ShowControlsForEventType( CEventParams *params )
+{
+ // Special processing for various settings
+ if ( !params->m_bHasEndTime )
+ {
+ ShowWindow( GetControl( IDC_ENDTIME ), SW_HIDE );
+ }
+
+ if ( params->m_bFixedLength )
+ {
+ ShowWindow( GetControl( IDC_ENDTIME ), SW_HIDE );
+ ShowWindow( GetControl( IDC_CHECK_ENDTIME ), SW_HIDE );
+ }
+}
+
+void CBaseEventPropertiesDialog::InitControlData( CEventParams *params )
+{
+ SetDlgItemText( m_hDialog, IDC_STARTTIME, va( "%f", params->m_flStartTime ) );
+ SetDlgItemText( m_hDialog, IDC_ENDTIME, va( "%f", params->m_flEndTime ) );
+
+ SendMessage( GetControl( IDC_CHECK_ENDTIME ), BM_SETCHECK,
+ ( WPARAM ) params->m_bHasEndTime ? BST_CHECKED : BST_UNCHECKED,
+ ( LPARAM )0 );
+
+ if ( GetControl( IDC_CHECK_RESUMECONDITION ) != (HWND)0 )
+ {
+ SendMessage( GetControl( IDC_CHECK_RESUMECONDITION ), BM_SETCHECK,
+ ( WPARAM ) params->m_bResumeCondition ? BST_CHECKED : BST_UNCHECKED,
+ ( LPARAM )0 );
+ }
+
+ SendMessage( GetControl( IDC_CHECK_DISABLED ), BM_SETCHECK,
+ ( WPARAM ) params->m_bDisabled ? BST_CHECKED : BST_UNCHECKED,
+ ( LPARAM )0 );
+
+ PopulateTagList( params );
+}
+
+BOOL CBaseEventPropertiesDialog::InternalHandleMessage( CEventParams *params, HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, bool& handled )
+{
+ handled = false;
+ switch(uMsg)
+ {
+ default:
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ default:
+ break;
+ case IDC_CHECK_DISABLED:
+ {
+ params->m_bDisabled = SendMessage( GetControl( IDC_CHECK_DISABLED ), BM_GETCHECK, 0, 0 ) == BST_CHECKED ? true : false;
+ handled = true;
+ return TRUE;
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+void CBaseEventPropertiesDialog::PopulateNamedActorList( HWND wnd, CEventParams *params )
+{
+ int i;
+
+ char const *mapname = NULL;
+ if ( params->m_pScene )
+ {
+ mapname = params->m_pScene->GetMapname();
+ }
+
+ CUtlRBTree< char const *, int > m_SortedNames( 0, 0, NameLessFunc );
+
+ if ( mapname )
+ {
+ g_MapEntities.CheckUpdateMap( mapname );
+
+ for ( i = 0; i < g_MapEntities.Count(); i++ )
+ {
+ char const *name = g_MapEntities.GetName( i );
+ if ( name && name[ 0 ] )
+ {
+ m_SortedNames.Insert( name );
+ }
+ }
+ }
+
+ for ( i = 0 ; i < params->m_pScene->GetNumActors() ; i++ )
+ {
+ CChoreoActor *actor = params->m_pScene->GetActor( i );
+ if ( actor && actor->GetName() && actor->GetName()[0] )
+ {
+ if ( m_SortedNames.Find( actor->GetName() ) == m_SortedNames.InvalidIndex() )
+ {
+ m_SortedNames.Insert( actor->GetName() );
+ }
+ }
+ }
+
+ i = m_SortedNames.FirstInorder();
+ while ( i != m_SortedNames.InvalidIndex() )
+ {
+ char const *name = m_SortedNames[ i ];
+ if ( name && name[ 0 ] )
+ {
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)name );
+ }
+
+ i = m_SortedNames.NextInorder( i );
+ }
+
+ /*
+ // Note have to do this here, after posting data to the control, since we are storing a raw string pointer in m_SortedNames!!!
+ if ( allActors )
+ {
+ allActors->deleteThis();
+ }
+ */
+
+ // These events can also be directed at another player or named target, too
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!player" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!enemy" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!self" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!friend" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!speechtarget" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target1" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target2" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target3" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target4" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target5" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target6" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target7" );
+ SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target8" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : wnd -
+// *params -
+// Output : static void
+//-----------------------------------------------------------------------------
+void CBaseEventPropertiesDialog::ParseTags( CEventParams *params )
+{
+ strcpy( params->m_szTagName, "" );
+ strcpy( params->m_szTagWav, "" );
+
+ if ( params->m_bUsesTag )
+ {
+ // Parse out the two tokens
+ char selectedText[ 512 ];
+ selectedText[ 0 ] = 0;
+ HWND control = GetControl( IDC_TAGS );
+ if ( control )
+ {
+ SendMessage( control, WM_GETTEXT, (WPARAM)sizeof( selectedText ), (LPARAM)selectedText );
+ }
+
+ ParseFromMemory( selectedText, strlen( selectedText ) );
+ if ( TokenAvailable() )
+ {
+ GetToken( false );
+ char tagname[ 256 ];
+ strcpy( tagname, token );
+ if ( TokenAvailable() )
+ {
+ GetToken( false );
+ char wavename[ 256 ];
+ strcpy( wavename, token );
+
+ // Valid
+ strcpy( params->m_szTagName, tagname );
+ strcpy( params->m_szTagWav, wavename );
+
+ }
+ else
+ {
+ params->m_bUsesTag = false;
+ }
+ }
+ else
+ {
+ params->m_bUsesTag = false;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : wnd -
+// *params -
+// Output : static void
+//-----------------------------------------------------------------------------
+void CBaseEventPropertiesDialog::UpdateTagRadioButtons( CEventParams *params )
+{
+ if ( params->m_bUsesTag )
+ {
+ SendMessage( GetControl( IDC_RELATIVESTART ), BM_SETCHECK, ( WPARAM )BST_CHECKED, (LPARAM)0 );
+ SendMessage( GetControl( IDC_ABSOLUTESTART ), BM_SETCHECK, ( WPARAM )BST_UNCHECKED, (LPARAM)0 );
+ }
+ else
+ {
+ SendMessage( GetControl( IDC_ABSOLUTESTART ), BM_SETCHECK, ( WPARAM )BST_CHECKED, (LPARAM)0 );
+ SendMessage( GetControl( IDC_RELATIVESTART ), BM_SETCHECK, ( WPARAM )BST_UNCHECKED, (LPARAM)0 );
+ }
+}
+
+void CBaseEventPropertiesDialog::GetSplineRect( HWND placeholder, RECT& rcOut )
+{
+ GetWindowRect( placeholder, &rcOut );
+ RECT rcDlg;
+ GetWindowRect( m_hDialog, &rcDlg );
+
+ OffsetRect( &rcOut, -rcDlg.left, -rcDlg.top );
+}
+
+void CBaseEventPropertiesDialog::DrawSpline( HDC hdc, HWND placeholder, CChoreoEvent *e )
+{
+ RECT rcOut;
+
+ GetSplineRect( placeholder, rcOut );
+
+ HBRUSH bg = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) );
+ FillRect( hdc, &rcOut, bg );
+ DeleteObject( bg );
+
+ if ( !e )
+ return;
+
+ // Draw spline
+ float range = ( float )( rcOut.right - rcOut.left );
+ if ( range <= 1.0f )
+ return;
+
+ float height = ( float )( rcOut.bottom - rcOut.top );
+
+ HPEN pen = CreatePen( PS_SOLID, 1, GetSysColor( COLOR_BTNTEXT ) );
+ HPEN oldPen = (HPEN)SelectObject( hdc, pen );
+
+ float duration = e->GetDuration();
+ float starttime = e->GetStartTime();
+
+ for ( int i = 0; i < (int)range; i++ )
+ {
+ float frac = ( float )i / ( range - 1 );
+
+ float scale = 1.0f - e->GetIntensity( starttime + frac * duration );
+
+ int h = ( int ) ( scale * ( height - 1 ) );
+
+ if ( i == 0 )
+ {
+ MoveToEx( hdc, rcOut.left + i, rcOut.top + h, NULL );
+ }
+ else
+ {
+ LineTo( hdc, rcOut.left + i, rcOut.top + h );
+ }
+ }
+
+ SelectObject( hdc, oldPen );
+
+ HBRUSH frame = CreateSolidBrush( GetSysColor( COLOR_BTNSHADOW ) );
+ InflateRect( &rcOut, 1, 1 );
+ FrameRect( hdc, &rcOut, frame );
+ DeleteObject( frame );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *view -
+// *actor -
+// Output : int
+//-----------------------------------------------------------------------------
+int EventProperties( CEventParams *params )
+{
+ int iret = 1;
+ switch ( params->m_nType )
+ {
+ default:
+ break;
+ case CChoreoEvent::EXPRESSION:
+ return EventProperties_Expression( params );
+ case CChoreoEvent::LOOKAT:
+ return EventProperties_LookAt( params );
+ case CChoreoEvent::MOVETO:
+ return EventProperties_MoveTo( params );
+ case CChoreoEvent::SPEAK:
+ return EventProperties_Speak( params );
+ case CChoreoEvent::GESTURE:
+ return EventProperties_Gesture( params );
+ case CChoreoEvent::SEQUENCE:
+ return EventProperties_Sequence( params );
+ case CChoreoEvent::FACE:
+ return EventProperties_Face( params );
+ case CChoreoEvent::FIRETRIGGER:
+ return EventProperties_FireTrigger( params );
+ case CChoreoEvent::FLEXANIMATION:
+ return EventProperties_FlexAnimation( params );
+ case CChoreoEvent::SUBSCENE:
+ return EventProperties_SubScene( params );
+ case CChoreoEvent::INTERRUPT:
+ return EventProperties_Interrupt( params );
+ case CChoreoEvent::PERMIT_RESPONSES:
+ return EventProperties_PermitResponses( params );
+ case CChoreoEvent::GENERIC:
+ return EventProperties_Generic( params );
+ }
+
+ return iret;
+}