You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
434 lines
9.8 KiB
434 lines
9.8 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
#include "hlfaceposer.h"
|
|
#include <mxtk/mx.h>
|
|
#include "resource.h"
|
|
#include "PhonemeProperties.h"
|
|
#include "expressions.h"
|
|
#include "expclass.h"
|
|
#include "mdlviewer.h"
|
|
|
|
static CPhonemeParams g_Params;
|
|
|
|
static int g_nPhonemeCount = 0;
|
|
static HWND *g_rgButtons = NULL;
|
|
|
|
#define IDC_PHONEME 2000
|
|
|
|
#define PHONEME_WIDTH 50
|
|
#define PHONEME_HEIGHT 18
|
|
#define PHONEME_GAP 10
|
|
#define PHONEME_VGAP 5
|
|
|
|
typedef long (__stdcall *WINPROCTYPE)( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
|
static WINPROCTYPE lpfnOldButtonProc;
|
|
|
|
static BOOL CALLBACK PhonemeBtnProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
switch ( uMsg )
|
|
{
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
HWND dialog = GetParent( hwnd );
|
|
if ( dialog )
|
|
{
|
|
// Get the hint text item
|
|
HWND helpText = GetDlgItem( dialog, IDC_STATIC_HELPTEXT );
|
|
if ( helpText )
|
|
{
|
|
CExpression *exp = ( CExpression * )GetWindowLong( (HWND)hwnd, GWL_USERDATA );
|
|
if ( exp )
|
|
{
|
|
SendMessage( helpText, WM_SETTEXT, 0, (LPARAM)exp->description );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return CallWindowProc( lpfnOldButtonProc, hwnd, uMsg, wParam, lParam );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : phoneme -
|
|
// Output : static void
|
|
//-----------------------------------------------------------------------------
|
|
static void ClickedPhoneme( HWND hwndDlg, int phoneme )
|
|
{
|
|
HWND ctrl = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME );
|
|
if ( !ctrl )
|
|
return;
|
|
|
|
if ( !g_Params.m_bMultiplePhoneme )
|
|
{
|
|
g_Params.m_szName[ 0 ] = 0;
|
|
}
|
|
else
|
|
{
|
|
SendMessage( ctrl, WM_GETTEXT, (WPARAM)sizeof( g_Params.m_szName ), (LPARAM)g_Params.m_szName );
|
|
}
|
|
if ( phoneme >= g_nPhonemeCount || phoneme < 0 )
|
|
{
|
|
Assert( 0 );
|
|
return;
|
|
}
|
|
|
|
HWND button = g_rgButtons[ phoneme ];
|
|
CExpression *exp = ( CExpression * )GetWindowLong( (HWND)button, GWL_USERDATA );
|
|
if ( exp )
|
|
{
|
|
if ( strlen( g_Params.m_szName ) > 0 )
|
|
{
|
|
strcat( g_Params.m_szName, " " );
|
|
}
|
|
strcat( g_Params.m_szName, exp->name );
|
|
|
|
if ( g_Params.m_bMultiplePhoneme )
|
|
{
|
|
SetFocus( ctrl );
|
|
SendMessage( ctrl, WM_SETTEXT, 0, (LPARAM)g_Params.m_szName );
|
|
SendMessage( ctrl, EM_SETSEL, 0, MAKELONG(0, 0xffff) );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : hwndDlg -
|
|
// Output : static void
|
|
//-----------------------------------------------------------------------------
|
|
static void CreateAndLayoutControls( HWND hwndDlg, CPhonemeParams* params )
|
|
{
|
|
g_nPhonemeCount = 0;
|
|
// Find phomemes
|
|
// Make sure phonemes are loaded
|
|
FacePoser_EnsurePhonemesLoaded();
|
|
|
|
CExpClass *cl = expressions->FindClass( "phonemes", true );
|
|
if ( !cl )
|
|
return;
|
|
|
|
g_nPhonemeCount = cl->GetNumExpressions();
|
|
if ( g_nPhonemeCount == 0 )
|
|
return;
|
|
|
|
g_rgButtons = new HWND[ g_nPhonemeCount ];
|
|
Assert( g_rgButtons );
|
|
|
|
int columns = 7;
|
|
int rows = ( g_nPhonemeCount / columns ) + 1;
|
|
|
|
int dialogW = columns * ( PHONEME_WIDTH + PHONEME_GAP ) + 2 * PHONEME_GAP;
|
|
int dialogH = rows * ( PHONEME_HEIGHT + PHONEME_VGAP ) + 40 + 55 + 30;
|
|
|
|
int startx = PHONEME_GAP;
|
|
int starty = 40;
|
|
|
|
if ( params->m_bPositionDialog )
|
|
{
|
|
int top = params->m_nTop - dialogH - 5;
|
|
int left = params->m_nLeft;
|
|
|
|
MoveWindow( hwndDlg,
|
|
left,
|
|
top,
|
|
dialogW,
|
|
dialogH,
|
|
TRUE );
|
|
}
|
|
else
|
|
{
|
|
MoveWindow( hwndDlg,
|
|
( GetSystemMetrics( SM_CXFULLSCREEN ) - dialogW ) / 2,
|
|
( GetSystemMetrics( SM_CYFULLSCREEN ) - dialogH ) / 2,
|
|
dialogW,
|
|
dialogH,
|
|
TRUE );
|
|
}
|
|
|
|
HWND ctrl = GetDlgItem( hwndDlg, IDOK );
|
|
if ( ctrl )
|
|
{
|
|
MoveWindow( ctrl, dialogW - 220, dialogH - 58, 100, 20, TRUE );
|
|
}
|
|
ctrl = GetDlgItem( hwndDlg, IDCANCEL );
|
|
if ( ctrl )
|
|
{
|
|
MoveWindow( ctrl, dialogW - 110, dialogH - 58, 100, 20, TRUE );
|
|
}
|
|
ctrl = GetDlgItem( hwndDlg, IDC_PHONEMETEXTPROMPT );
|
|
if ( ctrl )
|
|
{
|
|
MoveWindow( ctrl, startx, dialogH - 55, 50, 20, TRUE );
|
|
}
|
|
ctrl = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME );
|
|
if ( ctrl )
|
|
{
|
|
MoveWindow( ctrl, startx + 50, dialogH - 58, 100, 20, TRUE );
|
|
}
|
|
ctrl = GetDlgItem( hwndDlg, IDC_STATIC_HELPTEXT );
|
|
if ( ctrl )
|
|
{
|
|
MoveWindow( ctrl, startx, dialogH - 85, dialogW - startx - 20, 20, TRUE );
|
|
}
|
|
|
|
int r = 0;
|
|
int c = 0;
|
|
for ( int i = 0; i < g_nPhonemeCount; i++ )
|
|
{
|
|
CExpression *exp = cl->GetExpression( i );
|
|
if ( !exp )
|
|
continue;
|
|
|
|
HWND button = CreateWindowEx(
|
|
0,
|
|
"BUTTON",
|
|
va( "%s", exp->name ),
|
|
WS_CHILD | WS_VISIBLE | BS_LEFT,
|
|
startx + c * ( PHONEME_WIDTH + PHONEME_GAP ),
|
|
starty + r * ( PHONEME_HEIGHT + PHONEME_VGAP ),
|
|
PHONEME_WIDTH,
|
|
PHONEME_HEIGHT,
|
|
hwndDlg,
|
|
(HMENU)( IDC_PHONEME + i ),
|
|
(HINSTANCE)GetModuleHandle( 0 ),
|
|
NULL );
|
|
Assert( button );
|
|
SetWindowLong( (HWND)button, GWL_USERDATA, (LONG)exp );
|
|
|
|
// Subclass it
|
|
lpfnOldButtonProc = (WINPROCTYPE)SetWindowLong( (HWND)button, GWL_WNDPROC, (LONG)PhonemeBtnProc );
|
|
|
|
SendMessage ((HWND)button, WM_SETFONT, (WPARAM) (HFONT) GetStockObject (ANSI_VAR_FONT), MAKELPARAM (TRUE, 0));
|
|
|
|
g_rgButtons[ i ] = button;
|
|
|
|
c++;
|
|
if ( c >= columns )
|
|
{
|
|
r++;
|
|
c = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : hwndDlg -
|
|
// Output : static void
|
|
//-----------------------------------------------------------------------------
|
|
static void DestroyControls( HWND hwndDlg )
|
|
{
|
|
for ( int i = 0 ; i < g_nPhonemeCount; i++ )
|
|
{
|
|
if ( g_rgButtons[ i ] )
|
|
{
|
|
DestroyWindow( g_rgButtons[ i ] );
|
|
g_rgButtons[ i ] = NULL;
|
|
}
|
|
}
|
|
|
|
delete[] g_rgButtons;
|
|
g_nPhonemeCount = 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : hwndDlg -
|
|
// Output : static void
|
|
//-----------------------------------------------------------------------------
|
|
static void PhonemePropertiesDialogExit( HWND hwndDlg, int exitCode )
|
|
{
|
|
DestroyControls( hwndDlg );
|
|
|
|
EndDialog( hwndDlg, exitCode );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : allowmultiple -
|
|
// *input -
|
|
// *output -
|
|
// Output : static bool
|
|
//-----------------------------------------------------------------------------
|
|
static bool ValidatePhonemeString( bool allowmultiple, char const *input, char *output )
|
|
{
|
|
// Make sure phonemes are loaded
|
|
FacePoser_EnsurePhonemesLoaded();
|
|
|
|
CExpClass *cl = expressions->FindClass( "phonemes", true );
|
|
if ( !cl )
|
|
return false;
|
|
|
|
if ( !input || !input[ 0 ] )
|
|
return false;
|
|
|
|
// Go one by one
|
|
int count = 1;
|
|
char phoneme[ 128 ];
|
|
char *in, *out;
|
|
|
|
*output = 0;
|
|
|
|
in = (char *)input;
|
|
do
|
|
{
|
|
out = phoneme;
|
|
|
|
while ( *in > 32 )
|
|
{
|
|
*out++ = *in++;
|
|
}
|
|
*out = 0;
|
|
|
|
// Validate phoneme entered
|
|
for ( int i = 0; i < g_nPhonemeCount; i++ )
|
|
{
|
|
CExpression *exp = cl->GetExpression( i );
|
|
if ( !exp )
|
|
continue;
|
|
|
|
if ( !stricmp( exp->name, phoneme ) )
|
|
{
|
|
// Found it
|
|
if ( count != 1 )
|
|
{
|
|
strcat( output, " " );
|
|
}
|
|
strcat( output, phoneme );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !*in )
|
|
break;
|
|
|
|
// Skip whitespace
|
|
in++;
|
|
count++;
|
|
|
|
// Only keep first one
|
|
if ( !allowmultiple )
|
|
break;
|
|
|
|
} while ( 1 );
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : hwndDlg -
|
|
// uMsg -
|
|
// wParam -
|
|
// lParam -
|
|
// Output : static BOOL CALLBACK
|
|
//-----------------------------------------------------------------------------
|
|
static BOOL CALLBACK PhonemePropertiesDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
// Insert code here to put the string (to find and replace with)
|
|
// into the edit controls.
|
|
// ...
|
|
{
|
|
g_Params.PositionSelf( hwndDlg );
|
|
|
|
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
|
|
|
|
CreateAndLayoutControls( hwndDlg, &g_Params );
|
|
|
|
HWND control = GetDlgItem( hwndDlg, IDC_PHONEMENAME );
|
|
if ( control )
|
|
{
|
|
SendMessage( control, WM_SETTEXT , 0,
|
|
( LPARAM )(
|
|
g_Params.m_bMultiplePhoneme ?
|
|
"Click or enter one or more phonemes from list below"
|
|
:
|
|
va( "Phoneme/Viseme: %s", g_Params.m_szName ) ) );
|
|
}
|
|
|
|
control = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME );
|
|
if ( control )
|
|
{
|
|
SetFocus( control );
|
|
SendMessage( control, WM_SETTEXT , 0, ( LPARAM )g_Params.m_szName );
|
|
SendMessage( control, EM_SETSEL, 0, MAKELONG(0, 0xffff) );
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
int cmd = LOWORD( wParam );
|
|
|
|
if ( ( cmd >= IDC_PHONEME ) &&
|
|
( cmd < ( IDC_PHONEME + g_nPhonemeCount ) ) )
|
|
{
|
|
ClickedPhoneme( hwndDlg, cmd - IDC_PHONEME );
|
|
if ( !g_Params.m_bMultiplePhoneme )
|
|
{
|
|
PhonemePropertiesDialogExit( hwndDlg, 1 );
|
|
}
|
|
}
|
|
else if ( cmd != IDC_EDIT_PHONEME )
|
|
{
|
|
switch ( cmd )
|
|
{
|
|
case IDOK:
|
|
{
|
|
// Retrieve text
|
|
char szPhoneme[ 256 ];
|
|
HWND ctrl = GetDlgItem( hwndDlg, IDC_EDIT_PHONEME );
|
|
if ( ctrl )
|
|
{
|
|
SendMessage( ctrl, WM_GETTEXT, (WPARAM)sizeof( szPhoneme ), (LPARAM)szPhoneme );
|
|
|
|
ValidatePhonemeString( g_Params.m_bMultiplePhoneme, szPhoneme, g_Params.m_szName );
|
|
}
|
|
PhonemePropertiesDialogExit( hwndDlg, 1 );
|
|
}
|
|
break;
|
|
case IDCANCEL:
|
|
PhonemePropertiesDialogExit( hwndDlg, 0 );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *view -
|
|
// *actor -
|
|
// Output : int
|
|
//-----------------------------------------------------------------------------
|
|
int PhonemeProperties( CPhonemeParams *params )
|
|
{
|
|
g_Params = *params;
|
|
|
|
int retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ),
|
|
MAKEINTRESOURCE( IDD_PHONEMEPROPERTIES ),
|
|
(HWND)g_MDLViewer->getHandle(),
|
|
(DLGPROC)PhonemePropertiesDialogProc );
|
|
|
|
*params = g_Params;
|
|
|
|
return retval;
|
|
}
|