#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;iwNumberOfElement;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;iucNumberOfChannelAffected;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;ilNumberOfActings;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;iwNumberOfElement;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 (wDistanced_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 (wDistanced_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 (wDistancep_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*/