reman3/Rayman_X/cpa/tempgrp/GAM/LipsSync.c

607 lines
25 KiB
C

#ifdef D_USE_LIPSYNC
#define D_ObjsTbls_Define
/* MR0912*/
#define LSY_MainFile
#include "ToolsCPA.h"
#include "Options/Options.h"
#include "Macros.h"
#include "Actions/AllActs.h"
#include "Structur/MemGame.h"
#include "Structur/ErrGame.h"
#include "Structur/Objects.h"
#include "Structur/GameScpt.h"
#include "Structur/StdObjSt.h"
#include "Structur/EngMode.h"
#include "Basic.h"
#include "GameEng.h"
#include "ObjInit.h"
#include "ZeMem.h"
#include "micros.h"
#include "structur\ObjsTbls.h"
#include "LipsSync.h"
#include "Playanim\Playanim.h"
#include "SND.h"
#include "LSMem.h"
#include "LSErm.h"
/*-----------------------------------------------------------------------------
* Description : Allocate a Lips Synchro table of events
*-----------------------------------------------------------------------------
* Input : Number of events
* Output : Table of lips event
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
tdstLipsSynchroEvent *fn_xAllocateLipsSynchroEvents(long lNbEvents)
{ tdstLipsSynchroEvent *p_stLSEvents;
p_stLSEvents=LSY_fn_p_vAlloc((lNbEvents+1)*sizeof(struct tdstLipsSynchroEvent_));
return p_stLSEvents;
}
/* MR1908*/
struct tdstDialText_ *fn_xAllocateDialTexts(long lNbTexts)
{ struct tdstDialText_ *p_stTexts;
p_stTexts=LSY_fn_p_vAlloc(lNbTexts*sizeof(struct tdstDialText_));
return p_stTexts;
}
struct tdstActing_ *fn_xAllocateActing(long lNbActing)
{ struct tdstActing_ *p_stActing;
p_stActing=LSY_fn_p_vAlloc(lNbActing*sizeof(struct tdstActing_));
return p_stActing;
}
/* MR0912*/
tdstLipsSynchroBinTable *fn_xAllocateLipsSynchroBinTable(long lNbElts)
{ tdstLipsSynchroBinTable *p_stLSBTable;
p_stLSBTable=LSY_fn_p_vAlloc((lNbElts+1)*sizeof(struct tdstLipsSynchroBinTable_));
return p_stLSBTable;
}
/*-----------------------------------------------------------------------------
* Description : Allocate a Lips Synchro table
*-----------------------------------------------------------------------------
* Input : None
* Output : Lips table
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
tdxHandleOfLipsSynchroTable fn_xAllocateLipsSynchroTable()
{ tdxHandleOfLipsSynchroTable hLSTable;
hLSTable=LSY_fn_p_vAlloc(sizeof(struct tdstLipsSynchroTable_));
/* MR1908*/
hLSTable->lNumberOfFrames=0;
hLSTable->lSpeed=0;
hLSTable->p_stTable=NULL;
hLSTable->lSoundHandle=0;
hLSTable->ucNumberOfChannelAffected=0;
hLSTable->lNumberOfTexts=0;
hLSTable->p_stDialTexts=NULL;
hLSTable->lNumberOfActings=0;
hLSTable->p_stActing=NULL;
return hLSTable;
}
/*-----------------------------------------------------------------------------
* Description : Set the speed of the Lips
*-----------------------------------------------------------------------------
* Input : Lips table & speed
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vLSSetSpeed(tdxHandleOfLipsSynchroTable hLSTable,long lSpeed)
{
hLSTable->lSpeed=lSpeed;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/*-----------------------------------------------------------------------------
* Description : Get the speed of the Lips
*-----------------------------------------------------------------------------
* Input : Lips table
* Output : Speed
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
long fn_lLSGetSpeed(tdxHandleOfLipsSynchroTable hLSTable)
{
return hLSTable->lSpeed;
}
/*-----------------------------------------------------------------------------
* Description : Return the number of frame in the lips table
*-----------------------------------------------------------------------------
* Input : Lips table
* Output : Number of frames
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
long fn_lLSGetNumberOfFrame(tdxHandleOfLipsSynchroTable hLSTable)
{
return hLSTable->lNumberOfFrames;
}
/*-----------------------------------------------------------------------------
* Description : Set the phoneme of an element of the lips table
*-----------------------------------------------------------------------------
* Input : Lips table & index & phoneme
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vLSSetPhoneme(tdxHandleOfLipsSynchroTable hLSTable,int iIndex,unsigned char ucPhoneme)
{
hLSTable->p_stTable[iIndex].ucPhoneme=ucPhoneme;
}
/*-----------------------------------------------------------------------------
* Description : Set the intensity of an element of the lips table
*-----------------------------------------------------------------------------
* Input : Lips table & index & intensity
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vLSSetIntensity(tdxHandleOfLipsSynchroTable hLSTable,int iIndex,unsigned char ucIntensity)
{
hLSTable->p_stTable[iIndex].ucIntensity=ucIntensity;
}
/*-----------------------------------------------------------------------------
* Description : Set the expression of an element of the lips table
*-----------------------------------------------------------------------------
* Input : Lips table & index & expression
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vLSSetExpression(tdxHandleOfLipsSynchroTable hLSTable,int iIndex,unsigned char ucExpression)
{
hLSTable->p_stTable[iIndex].ucIntensity=ucExpression;
}
/*-----------------------------------------------------------------------------
* Description : Return the phoneme of an element of the lips table
*-----------------------------------------------------------------------------
* Input : Lips table & index
* Output : phoneme
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
unsigned char fn_ucLSGetPhoneme(tdxHandleOfLipsSynchroTable hLSTable,int iIndex)
{
return hLSTable->p_stTable[iIndex].ucPhoneme;
}
/*-----------------------------------------------------------------------------
* Description : Return the intensity of an element of the lips table
*-----------------------------------------------------------------------------
* Input : Lips table & index
* Output : intensity
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
unsigned char fn_ucLSGetIntensity(tdxHandleOfLipsSynchroTable hLSTable,int iIndex)
{
return hLSTable->p_stTable[iIndex].ucIntensity;
}
/*-----------------------------------------------------------------------------
* Description : Return the expression of an element of the lips table
*-----------------------------------------------------------------------------
* Input : Lips table & index
* Output : expression
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
unsigned char fn_ucLSGetExpression(tdxHandleOfLipsSynchroTable hLSTable,int iIndex)
{
return hLSTable->p_stTable[iIndex].ucExpression;
}
/*-----------------------------------------------------------------------------
* Description : Set the sound to be played with the lips table
*-----------------------------------------------------------------------------
* Input : Lips table & reference to the sound
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
* 08/25/97:Stéphane RONSE:replace SND_tduRefEvt with SND_tdxHandleToSoundEvent
*---------------------------------------------------------------------------*/
void fn_vLSSetSound(tdxHandleOfLipsSynchroTable hLSTable,SND_tdxHandleToSoundEvent p_stSound)
{
hLSTable->p_stSndEvent=p_stSound;
}
/*-----------------------------------------------------------------------------
* Description : Return the sound to be played with the lips table
*-----------------------------------------------------------------------------
* Input : Lips table
* Output : reference to the sound
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
* 08/25/97:Stéphane RONSE:replace SND_tduRefEvt with SND_tdxHandleToSoundEvent
*---------------------------------------------------------------------------*/
SND_tdxHandleToSoundEvent fn_xLSGetSound(tdxHandleOfLipsSynchroTable hLSTable)
{
return hLSTable->p_stSndEvent;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/* MR0708*/
void fn_vSetSoundHandle(tdxHandleOfLipsSynchroTable hLSTable,long handle)
{
hLSTable->lSoundHandle=handle;
}
long fn_lGetSoundHandle(tdxHandleOfLipsSynchroTable hLSTable)
{
return hLSTable->lSoundHandle;
}
/*-----------------------------------------------------------------------------
* Description : Add a channel to be synchronized with the sound
*-----------------------------------------------------------------------------
* Input : Lips table & channel to be added
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vLSAddChannelSync(tdxHandleOfLipsSynchroTable hLSTable,unsigned char ucChannelNumber)
{
hLSTable->ucChannelAffected[hLSTable->ucNumberOfChannelAffected++]=ucChannelNumber;
}
/*-----------------------------------------------------------------------------
* Description : Erase all the channels to be synchronized
*-----------------------------------------------------------------------------
* Input : Lips table
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vLSResetChannelSync(tdxHandleOfLipsSynchroTable hLSTable)
{
hLSTable->ucNumberOfChannelAffected=0;
}
/*-----------------------------------------------------------------------------
* Description : Unused function
*-----------------------------------------------------------------------------
* Input : ...
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vPlayLipsSynch(HIE_tdxHandleToSuperObject hSOM)
{ MS_tdxHandleTo3dData hCurrent3dData=M_GetMSHandle(hSOM,3dData);
tdxHandleOfLipsSynchroTable hLipsTable=fn_x3dDataGetLipsTable(hCurrent3dData);
unsigned char ucAnimSpeed;
unsigned char ucLipsSpeed;
unsigned short uwLipsFrame;
unsigned short uwStartSynchroFrame,uwCurrentSynchroFrame;
tdstObjectsTablesList * hObjTable;
int i/*,j*/;
/*struct tdstState_ *p_stCurrentState;
struct tdstElement3d_ *p_stCurrentElement3d;
HIE_tdxHandleToSuperObject hElement;
struct tdstFrame3d_ *p_stCurrentFrame3d;*/
if (!hLipsTable)
return;
ucAnimSpeed=fn_uc3dDataGetFrameRate(hCurrent3dData);
ucLipsSpeed=(unsigned char)fn_lLSGetSpeed(hLipsTable);
uwStartSynchroFrame=fn_uw3dDataGetStartSynchroFrame(hCurrent3dData);
uwCurrentSynchroFrame=fn_uw3dDataGetCurrentSynchroFrame(hCurrent3dData);
/* MR0708*/
/*uwLipsFrame=(unsigned short)(((uwCurrentSynchroFrame-uwStartSynchroFrame)*ucLipsSpeed)/ucAnimSpeed);*/
uwLipsFrame=(unsigned short)((SND_fn_rGetPosSound(fn_lGetSoundHandle(hLipsTable))-uwStartSynchroFrame)*ucLipsSpeed);
hObjTable=fn_h3dDataGetCurrentObjectsTable(hCurrent3dData);
for (i=0;i<hObjTable->wNumberOfElement;i++)
{
if (hObjTable->d_stObjectsTable[i].ucPhoneme==hLipsTable->p_stTable[uwLipsFrame].ucPhoneme)
break;
}
/* p_stCurrentState = fn_h3dDataGetCurrentState(hCurrent3dData);
p_stCurrentAnim = p_stCurrentState->p_stAnim;
p_stCurrentFrame3d = &p_stCurrentAnim->d_stFrame3d[ucCurrentFrame];
HIE_M_ForEachChildOf(hSOM,hElement,j)
{
if(j==fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim->ucMaxNumberOfElements) break;
p_stCurrentElement3d = p_stCurrentFrame3d->d_p_stElement3d[j];
if(p_stCurrentElement3d!=NULL)
{ if (p_stCurrentElement3d->wElement==0) // Tête (Provisoire)
p_stCurrentElement3d->wElement=i;
}
}*/
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/*-----------------------------------------------------------------------------
* Description : Return the element3D number to be displayed in the given channel
*-----------------------------------------------------------------------------
* Input : SuperObject (character) & channel
* Output : Number of the element3D
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
short fn_vGetLipsSynchObject(HIE_tdxHandleToSuperObject hSOM,short wChannelNumber)
{
MS_tdxHandleTo3dData hCurrent3dData=M_GetMSHandle(hSOM,3dData);
tdxHandleOfLipsSynchroTable hLipsTable=fn_x3dDataGetLipsTable(hCurrent3dData);
unsigned char ucAnimSpeed;
unsigned char ucLipsSpeed;
unsigned short uwLipsFrame;
unsigned short uwStartSynchroFrame,uwCurrentSynchroFrame;
tdstObjectsTablesList * hObjTable;
short i;
short wObject2=0,wObject1=0,wObject=0,wDistance,wDistance1;
BOOL bFound=FALSE;
short a_wObjectSelected[255],wNbOS=0,a_wObjectSelected2[255],wNbOS2=0;
SndReal xSndTime;
double fTimeInSeconds;
if (!hLipsTable) /* No lips table*/
return NO_LIPS;
/* Search if the current channel is synchronized*/
for (i=0;i<hLipsTable->ucNumberOfChannelAffected;i++)
if (hLipsTable->ucChannelAffected[i]==wChannelNumber)
bFound=TRUE;
if (!bFound)
/* The current channel is synchronized*/
return NO_LIPS;
ucAnimSpeed=fn_uc3dDataGetFrameRate(hCurrent3dData); /* Speed of the anim*/
ucLipsSpeed=(unsigned char)fn_lLSGetSpeed(hLipsTable); /* Speed of the lips*/
uwStartSynchroFrame=fn_uw3dDataGetStartSynchroFrame(hCurrent3dData); /* Virtual start frame number of the anim*/
uwCurrentSynchroFrame=fn_uw3dDataGetCurrentSynchroFrame(hCurrent3dData); /* Virtual current frame number of the anim*/
/*uwLipsFrame=(unsigned short)(((uwCurrentSynchroFrame-uwStartSynchroFrame)*ucLipsSpeed)/ucAnimSpeed); // Corresponding frame for the lips*/
xSndTime=SND_fn_rGetPosSound(fn_lGetSoundHandle(hLipsTable));
fTimeInSeconds=M_RealToDoubleSnd(xSndTime);
uwLipsFrame=(unsigned short)((fTimeInSeconds-uwStartSynchroFrame)*ucLipsSpeed);
if ((uwLipsFrame>fn_lLSGetNumberOfFrame(hLipsTable))||(xSndTime==SND_C_POS_ENDED)||(xSndTime==SND_C_POS_UNKNOWN))
{
SND_fn_vKillObjectSound2((long)hSOM,g_lSoundObjectTypeLipsSynchro);
/* The discussion is over*/
hLipsTable->iIndex=-1;
fn_v3dDataSetLipsTable(M_GetMSHandle(hSOM,3dData),NULL);
return NO_LIPS;
}
/* MR2008 : subtitles*/
/* if (hLipsTable->lNumberOfTexts)
for (i=(short)(hLipsTable->lNumberOfTexts-1);i>=0;i--)
if (uwLipsFrame>=hLipsTable->p_stDialTexts[i].lFrameNumber)
{
#if defined(GAM_USE_SCRIPT)
fn_vAddSuperimposedText(
hLipsTable->iIndex,
hLipsTable->p_stDialTexts[i].hText,
FON_fn_xGetFontOfTextHandle(hLipsTable->p_stDialTexts[i].hText),
hLipsTable->p_stDialTexts[i].xPosX,
hLipsTable->p_stDialTexts[i].xPosY,-1);
#endif
break;
}*/
/* MR2108 : Acting*/
if (hLipsTable->lNumberOfActings)
for (i=0;i<hLipsTable->lNumberOfActings;i++)
if (uwLipsFrame==hLipsTable->p_stActing[i].lFrameNumber) /* A voir... Cas où ça rame...*/
{ PLA_fn_bSetNewState(hSOM,hLipsTable->p_stActing[i].hNewState, FALSE,FALSE);
}
/* Recover the object table*/
hObjTable=fn_h3dDataGetCurrentObjectsTable(hCurrent3dData);
if (hLipsTable->p_stTable[uwLipsFrame].ucPhoneme==NO_PHONEME)
return NO_LIPS;
/* Search an object in the OT with the best phoneme*/
wDistance1=(short)LARGE_NUMBER;
for (i=0;i<hObjTable->wNumberOfElement;i++)
{
if (hObjTable->d_stObjectsTable[i].wTypeOfTarget==C_wTdO_Undefined) /* Hole in the OT*/
continue;
wDistance=(short)abs(hObjTable->d_stObjectsTable[i].ucPhoneme-hLipsTable->p_stTable[uwLipsFrame].ucPhoneme);
if (wDistance==wDistance1)
{ a_wObjectSelected[wNbOS++]=i;
}
if (wDistance<wDistance1)
{ wDistance1=wDistance;
wObject=i;
wNbOS=0;
a_wObjectSelected[wNbOS++]=i; /* table which contains the object with the good phoneme*/
}
}
/* Search an object in the OT with the best intensity*/
wDistance1=(short)LARGE_NUMBER;
for (i=0;i<wNbOS;i++)
{
if (hObjTable->d_stObjectsTable[a_wObjectSelected[i]].wTypeOfTarget==C_wTdO_Undefined)
continue;
if (hObjTable->d_stObjectsTable[a_wObjectSelected[i]].ucPhoneme!=hObjTable->d_stObjectsTable[wObject].ucPhoneme)
continue;
wDistance=(short)abs(hObjTable->d_stObjectsTable[a_wObjectSelected[i]].ucIntensity-hLipsTable->p_stTable[uwLipsFrame].ucIntensity);
if (wDistance==wDistance1)
{ a_wObjectSelected2[wNbOS2++]=a_wObjectSelected[i];
}
if (wDistance<wDistance1)
{ wDistance1=wDistance;
wObject1=a_wObjectSelected[i];
wNbOS2=0;
a_wObjectSelected2[wNbOS2++]=a_wObjectSelected[i];
}
}
/* Search an object in the OT with the best expression*/
wDistance1=(short)LARGE_NUMBER;
for (i=0;i<wNbOS2;i++)
{
if (hObjTable->d_stObjectsTable[a_wObjectSelected2[i]].wTypeOfTarget==C_wTdO_Undefined)
continue;
if ((hObjTable->d_stObjectsTable[a_wObjectSelected2[i]].ucPhoneme!=hObjTable->d_stObjectsTable[wObject].ucPhoneme)||
(hObjTable->d_stObjectsTable[a_wObjectSelected2[i]].ucIntensity!=hObjTable->d_stObjectsTable[wObject1].ucIntensity))
continue;
wDistance=(short)abs(hObjTable->d_stObjectsTable[a_wObjectSelected2[i]].ucExpression-hLipsTable->p_stTable[uwLipsFrame].ucExpression);
if (wDistance<wDistance1)
{ wDistance1=wDistance;
wObject2=a_wObjectSelected2[i];
}
}
/*return NO_LIPS;*/
/*fn_v3dDataSetCurrentSynchroFrame(hCurrent3dData,(unsigned char)(uwCurrentSynchroFrame+1));*/
return wObject2;
}
/*-----------------------------------------------------------------------------
* Description : Start synchro lipsing for a character
*-----------------------------------------------------------------------------
* Input : SuperObject (character) & lips table
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 30/06/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
* 08/25/97:Stéphane RONSE:replace SND_tduRefEvt with SND_tdxHandleToSoundEvent
*---------------------------------------------------------------------------*/
void fn_vStartLipsSynchro(HIE_tdxHandleToSuperObject hSOM,tdxHandleOfLipsSynchroTable hLipsTable)
{ long lSoundHandle;
SND_tduRefEvt pEvt;
fn_v3dDataSetLipsTable(M_GetMSHandle(hSOM,3dData),hLipsTable);
fn_v3dDataSetStartSynchroFrame(M_GetMSHandle(hSOM,3dData),0);
fn_v3dDataSetCurrentSynchroFrame(M_GetMSHandle(hSOM,3dData),0);
/* MR2001*/
/*pEvt.pstPtr=hLipsTable->p_stSndEvent;*/
pEvt.pstPtr=SND_fn_pGetBinEvent((unsigned long)hLipsTable->p_stSndEvent)
;
lSoundHandle=SND_fn_lSendRequestSound((long)hSOM,g_lSoundObjectTypeLipsSynchro,pEvt,0,NULL); /* MR0708*/
fn_vSetSoundHandle(hLipsTable,lSoundHandle);
/* MR2008*/
hLipsTable->iIndex=-1;
}
/*-----------------------------------------------------------------------------
* Description : Stop synchro lipsing for a character
*-----------------------------------------------------------------------------
* Input : SuperObject (character)
* Output : None
*-----------------------------------------------------------------------------
* Creation date : 07/07/97 Author : Michaël
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
* 08/25/97:Stéphane RONSE:replace SND_tduRefEvt with SND_tdxHandleToSoundEvent
*---------------------------------------------------------------------------*/
void fn_vStopLipsSynchro(HIE_tdxHandleToSuperObject hSOM)
{ tdxHandleOfLipsSynchroTable hLipsTable;
/*SND_tduRefEvt pEvt;*/
hLipsTable=fn_x3dDataGetLipsTable(M_GetMSHandle(hSOM,3dData));
if (hLipsTable)
{
/* pEvt.pstPtr=hLipsTable->p_stSndEventStop;*/
/* SND_fn_lSendRequestSound((long)hSOM,g_lSoundObjectTypeAnim,pEvt,0,NULL);*/
SND_fn_vKillObjectSound2((long)hSOM,g_lSoundObjectTypeLipsSynchro);
}
fn_v3dDataSetLipsTable(M_GetMSHandle(hSOM,3dData),NULL);
}
BOOL fn_bIsDiscussionOver(HIE_tdxHandleToSuperObject hSOM)
{
return (fn_x3dDataGetLipsTable(M_GetMSHandle(hSOM,3dData))==NULL);
}
#endif /*D_USE_LIPSYNC*/