#define PO_FRIEND #define HieFriend #define ENV_FRIEND #define D_State_Define #include "ToolsCPA.h" #include "Mor.h" /* AR980213*/ #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 "structur/anim_s.h" #include "Structur/State.h" #include "Basic.h" #include "GameEng.h" #include "ObjInit.h" #include "ZeMem.h" #include "ToolMatr.h" /* anim interpolated*/ #include "ChanList.h" #include "PlayAnim/Interpol/a3x_intn.h" #include "playanim\playanim.h" #include "prf.h" #if defined (ACTIVE_EDITOR) || defined (RETAIL) #define ENGassert(param) #else #define ENGassert(param) assert(param) #endif /*----------------------------------------------------------------------------- * Description : Return the channel which contains a SO *----------------------------------------------------------------------------- * Input : Handle to the list Handle to the SO * Output : None *----------------------------------------------------------------------------- * Creation date : 25/03/97 Author : Michaël *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ unsigned short fn_uwGetChannelOfSuperObject(CHN_tdxHandleToChannelArray hChannelArray, HIE_tdxHandleToSuperObject hSO, unsigned long ulNumberOfChannels) { unsigned short i; for (i=0; i < ulNumberOfChannels; i++) { if (hChannelArray[i].hSupObject == hSO) return i; } /* The SO isn't found*/ return C_ucUnknownChannel; } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /*----------------------------------------------------------------------------- * Description : Init a CHN_tdxHandleToCSOList list. *----------------------------------------------------------------------------- * Input : Pointer on the handle to the list * Output : None *----------------------------------------------------------------------------- * Creation date : 25/03/97 Author : Michaël *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ void fn_vInitCSOList(CHN_tdxHandleToChannelArray *p_hChannelArray, unsigned long ulNumberOfChannels) { unsigned long ulI; MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeCSO , 0 ); *p_hChannelArray = (CHN_tdxHandleToChannelArray)TMP_M_p_Malloc(sizeof(tdstAChannel) * ulNumberOfChannels); /* memset(*p_hChannelArray,0,sizeof(tdstAChannel) * ulNumberOfChannels); AR9904 Already done in the alloc function */ for ( ulI = 0 ; ulI < ulNumberOfChannels ; ulI ++ ) ( * p_hChannelArray ) [ ulI ] . bActiveChannel = TRUE ; #if defined(USE_PROFILER) && !defined(PRESS_DEMO) if (PRF_fn_lIncIndependantVariable(PRF_C_ulIdpNbAllocCHA,ulNumberOfChannels) > PRF_fn_lGetIndependantVariable(PRF_C_ulIdpNbMaxAllocCHA)) { PRF_fn_vSetIndependantVariable(PRF_C_ulIdpNbMaxAllocCHA,PRF_fn_lGetIndependantVariable(PRF_C_ulIdpNbAllocCHA)); } #endif } /*----------------------------------------------------------------------------- * Description : Free a CHN_tdxHandleToCSOList list. *----------------------------------------------------------------------------- * Input : Pointer on the handle to the list * Output : None *----------------------------------------------------------------------------- * Creation date : 16/08/97 Author : Sebastien DAVID (Gizmo) *---------------------------------------------------------------------------*/ void fn_vFreeCSOList(CHN_tdxHandleToChannelArray *p_hChannelArray/*, unsigned long ulNumberOfChannels*/) { /* unsigned long i;*/ CHN_tdxHandleToChannelArray hArray; #ifndef RETAIL long lSize; #endif hArray = *p_hChannelArray; if (hArray == NULL) return; #ifndef RETAIL lSize = *(((long*)hArray)-1); lSize *= 4; lSize /= sizeof(tdstAChannel); #endif RETAIL /* if(hArray == NULL) return; AR9903 Already done ! */ /* for (i=0; ih_3dData; CHN_tdxHandleToChannelArray hChannelArray = fn_h3dDataGetChannelSOList(hCurrent3dData); if (hChannelArray == NULL) { return; } ulNbChannels = fn_ul3dDataGetNumberOfChannels(hCurrent3dData) ; if (_uwChannel != 0xffff) { ENGassert(_uwChannel >= 0 && _uwChannel < ulNbChannels ); /* loose control of one channel*/ hChannelArray[_uwChannel].bControlledChannel = _bControlled; } else { /* loose control of all channels*/ tdstAChannel *p_stChannel ; unsigned long ulI ; for ( ulI = 0 , p_stChannel = hChannelArray ; ulI < ulNbChannels ; ulI ++ , p_stChannel ++ ) { p_stChannel->bControlledChannel = _bControlled; } } } /*----------------------------------------------------------------------------- * Description : activate a channel *----------------------------------------------------------------------------- * Input : The SO of the character * The channel number * Output : None *---------------------------------------------------------------------------*/ void fn_vUpdateSPOFlagsOfChannelForActivation(HIE_tdxHandleToSuperObject _hSOChannel, ACP_tdxBool _bActivate) { unsigned long ulSpoFlags ; if ( _hSOChannel ) { ulSpoFlags = HIE_M_xGetSuperObjectMember(_hSOChannel , ulFlags); if ( _bActivate ) { /* it becomes pickable, visible and shadowable */ HIE_M_vSetSuperObjectMember(_hSOChannel , ulFlags, ulSpoFlags & ~ ( HIE_C_Flag_ulNotPickable | HIE_C_Flag_ulHidden | HIE_C_Flag_ulNoShadowOnMe ) ) ; } else { /* it becomes not pickable, visible or shadowable */ HIE_M_vSetSuperObjectMember(_hSOChannel , ulFlags, ulSpoFlags | HIE_C_Flag_ulNotPickable | HIE_C_Flag_ulHidden | HIE_C_Flag_ulNoShadowOnMe ) ; } } } void fn_vActivateChannel(HIE_tdxHandleToSuperObject _hPerso , unsigned short _uwChannel , ACP_tdxBool _bActivate ) { MS_tdxHandleTo3dData h_3dData = M_GetMSHandle(_hPerso,3dData); tdstAChannel *p_stChannel ; HIE_tdxHandleToSuperObject hModule ; /* Recover the CSO list of the character*/ unsigned long ulNbChannels ; CHN_tdxHandleToChannelArray hChannelArray = fn_h3dDataGetChannelSOList(h_3dData); if (hChannelArray == NULL) { return; } ulNbChannels = fn_ul3dDataGetNumberOfChannels(h_3dData) ; if (_uwChannel != 0xffff) { ENGassert(_uwChannel >= 0 && _uwChannel < ulNbChannels ); /* loose control of one channel*/ p_stChannel = & hChannelArray [ _uwChannel ] ; p_stChannel -> bActiveChannel = _bActivate ; hModule = p_stChannel -> hZoomSupObject ? p_stChannel -> hZoomSupObject : p_stChannel -> hSupObject ; fn_vUpdateSPOFlagsOfChannelForActivation ( hModule , _bActivate ) ; #ifndef U64 #ifndef RETAIL DEMO_fn_vSaveCanalActivationDesactivation ( _hPerso , ( unsigned char ) _uwChannel , _bActivate ) ; #endif /* RETAIL */ #endif } else { /* loose control of all channels*/ unsigned long ulI ; for ( ulI = 0 , p_stChannel = hChannelArray ; ulI < ulNbChannels ; ulI ++ , p_stChannel ++ ) { p_stChannel = & hChannelArray [ ulI ] ; p_stChannel -> bActiveChannel = _bActivate ; hModule = p_stChannel -> hZoomSupObject ? p_stChannel -> hZoomSupObject : p_stChannel -> hSupObject ; fn_vUpdateSPOFlagsOfChannelForActivation ( hModule , _bActivate ) ; #ifndef U64 #ifndef RETAIL DEMO_fn_vSaveCanalActivationDesactivation ( _hPerso , ( unsigned char ) _uwChannel , _bActivate ) ; #endif /* RETAIL */ #endif } } } /*----------------------------------------------------------------------------- * Description : deactivate a channel *----------------------------------------------------------------------------- * Input : The SO of the character * The channel number * Output : None *----------------------------------------------------------------------------- * Creation date : 27/03/97 Author : Michaël *----------------------------------------------------------------------------- * Modification date : 02 Apr 98 Modification Author : B. Germain ANNECY BBB * Modifications : - the UCC list no longer exists, it is replaced by a handle to the control matrix in the CSO element - if uwChannel == 0xFFF, all controlled channels are released *---------------------------------------------------------------------------*/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */ void fn_vDeactivateChannel(struct tdstEngineObject_ *_hActor, unsigned short _uwChannel) { /* Recover the CSO list of the character*/ unsigned long ulNbChannels ; MS_tdxHandleTo3dData hCurrent3dData = _hActor->h_3dData; CHN_tdxHandleToChannelArray hChannelArray = fn_h3dDataGetChannelSOList(hCurrent3dData); if (hChannelArray == NULL) { return; } ulNbChannels = fn_ul3dDataGetNumberOfChannels(hCurrent3dData) ; if (_uwChannel != 0xffff) { ENGassert(_uwChannel >= 0 && _uwChannel < ulNbChannels ); /* loose control of one channel*/ hChannelArray[_uwChannel].bActiveChannel = FALSE; } else { /* loose control of all channels*/ tdstAChannel *p_stChannel ; unsigned long ulI ; for ( ulI = 0 , p_stChannel = hChannelArray ; ulI < ulNbChannels ; ulI ++ , p_stChannel ++ ) { p_stChannel->bActiveChannel = FALSE; } } } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */ /* if (_uwChannel != 0xffff && hChannelArray[_uwChannel].hControlMatrix) { // only one channel is requested // and it is controled, so loose control if (hChannelArray[_uwChannel].hSupObject) { // update the matrix if we release an active channel !! // if the channel is not active, its matrix is NULL anyway... // find and give back the animation element matrix to the superobject // (that would otherwise reference a nonexistent matrix, ARGH!!! tdstState *p_stCurrentState = fn_h3dDataGetCurrentState(hCurrent3dData); if ( p_stCurrentState ) { struct tdstAnim3d_ *p_stCurrentAnim = p_stCurrentState->p_stAnim; if ( p_stCurrentAnim ) { struct tdstFrame3d_ *p_stCurrentFrame3d = fn_p_GetFramesAddress(p_stCurrentAnim,fn_uw3dDataGetCurrentFrame(hCurrent3dData),g_stEngineStructure.stEngineTimer.ulTrameNumber,(void*)fn_h_StandardGameGetSuperObject(_hActor->h_StandardGame)); if ( p_stCurrentFrame3d ) { struct tdstElement3d_ *p_stCurrentElement3d, *p_stStopElt3d; p_stCurrentElement3d = p_stCurrentFrame3d->p_stArrayOfElts3d; p_stStopElt3d = p_stCurrentElement3d + p_stCurrentAnim->ucMaxNumberOfElements; // look for the 3d element that correspond to the channel that must be released while (p_stCurrentElement3d != p_stStopElt3d) { if (p_stCurrentElement3d->ucChannelNumber == _uwChannel) { HIE_fn_vSetSuperObjectMatrix(hChannelArray[_uwChannel].hSupObject, p_stCurrentElement3d->stMatrix); break; } p_stCurrentElement3d++; } } } } } //destroy the control matrix TMP_M_Free(hChannelArray[_uwChannel].hControlMatrix); //clear the handle in the CSO element hChannelArray[_uwChannel].hControlMatrix = NULL; } else if (_uwChannel == 0xffff) { // loose control of all channels tdstState *p_stCurrentState = fn_h3dDataGetCurrentState(hCurrent3dData); //and give back the animation element matrix to the superobject (that would otherwise reference a nonexistent matrix, ARGH!!! if ( p_stCurrentState ) { struct tdstAnim3d_ *p_stCurrentAnim = p_stCurrentState->p_stAnim; if ( p_stCurrentAnim ) { struct tdstFrame3d_ *p_stCurrentFrame3d = fn_p_GetFramesAddress(p_stCurrentAnim,fn_uw3dDataGetCurrentFrame(hCurrent3dData),g_stEngineStructure.stEngineTimer.ulTrameNumber,(void*)fn_h_StandardGameGetSuperObject(_hActor->h_StandardGame)); if ( p_stCurrentFrame3d ) { struct tdstElement3d_ *p_stCurrentElement3d, *p_stStopElt3d; p_stCurrentElement3d = p_stCurrentFrame3d->p_stArrayOfElts3d; p_stStopElt3d = p_stCurrentElement3d + p_stCurrentAnim->ucMaxNumberOfElements; // look for the 3d element that correspond to the channel that must be released while (p_stCurrentElement3d != p_stStopElt3d) { if (p_stCurrentElement3d->ucChannelNumber != C_ucUnknownChannel) { if (hChannelArray[p_stCurrentElement3d->ucChannelNumber].hControlMatrix) { if (hChannelArray[p_stCurrentElement3d->ucChannelNumber].hSupObject ) { HIE_fn_vSetSuperObjectMatrix(hChannelArray[p_stCurrentElement3d->ucChannelNumber].hSupObject, p_stCurrentElement3d->stMatrix); } //destroy the control matrix TMP_M_Free(hChannelArray[p_stCurrentElement3d->ucChannelNumber].hControlMatrix); //clear the handle in the CSO element hChannelArray[p_stCurrentElement3d->ucChannelNumber].hControlMatrix = NULL; } } p_stCurrentElement3d++; } } } } } } */ #include "ChanLis1.cxx" /*----------------------------------------------------------------------------- * Description : Update the matrix of the controled channels of a character *----------------------------------------------------------------------------- * Input : The SO of the character * Output : None *----------------------------------------------------------------------------- * Creation date : 27/03/97 Author : Michaël *----------------------------------------------------------------------------- * Modification date : 08/07/97 Modification Author : CGHT * Modifications : Bug correction for absolute mode. *---------------------------------------------------------------------------*/ /*void fn_vUpdateMatrixOfControledChannels(struct tdstEngineObject_ *_hActor) { // tdstAChannel *p_stChannel; // this function is not of any use now, because matrix, controlled or not, are automatically updated... // Recover the CSO list of the character MS_tdxHandleTo3dData hCurrent3dData; CHN_tdxHandleToChannelArray hChannelArray; // some variables to scan the CSO list unsigned long i; POS_tdstCompletePosition *hSource, *hDest; MS_tdxHandleToAnimEffect hAnimEffect; hCurrent3dData = _hActor->h_3dData; hChannelArray = fn_h3dDataGetChannelSOList(hCurrent3dData); if (!hChannelArray) return; hAnimEffect = _hActor->h_AnimEffect; p_stChannel = fn_h3dDataGetFirstActiveChannel(hCurrent3dData); i=0; while (p_stChannel) { if (p_stChannel->hControlMatrix) { hDest = p_stChannel->hControlMatrix; hSource = HIE_fn_hGetSuperObjectMatrix(p_stChannel->hSupObject); if ( hSource != hDest ) //if we did not already do it { //copy the current matrix in the control matrix POS_fn_vCopyMatrix(hDest, hSource); // and give the control matrix to the superobject HIE_fn_vSetSuperObjectMatrix(p_stChannel->hSupObject, hDest); } // if there is an animeffect structure if ( hAnimEffect ) { //perform the effects on the controlled channel fn_vDoAnimEffect(hAnimEffect, M_GetSuperObject(_hActor), i, p_stChannel->hSupObject); } } i++; p_stChannel = p_stChannel->p_stNextActiveChannel; } }*/ /*----------------------------------------------------------------------------- * Description : Create a Morph element *----------------------------------------------------------------------------- * Input : None * Output : None *----------------------------------------------------------------------------- * Creation date : 12/2/97 Author : alexander *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ tdstMorphChannelList* fn_p_stCreateMorphListElement() { tdstMorphChannelList * p_stMorphList; MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeMorphChannelList , 0 ); p_stMorphList= (tdstMorphChannelList *) TMP_M_p_Malloc (sizeof (tdstMorphChannelList)); LST2_M_DynamicInitElement (p_stMorphList); return p_stMorphList; } /*----------------------------------------------------------------------------- * Description : Free a Morph Channel element *----------------------------------------------------------------------------- * Input : None * Output : None *----------------------------------------------------------------------------- * Creation date : 12/1/97 Author : alexander *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ void fn_vFreeMorphListElement(tdstMorphChannelList * p_stMorphList) { MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeMorphChannelList , 0 ); TMP_M_Free(p_stMorphList); } /*----------------------------------------------------------------------------- * Description : Init a CHN_tdxHandleToMorphList list. *----------------------------------------------------------------------------- * Input : Pointer on the handle to the list * Output : None *----------------------------------------------------------------------------- * Creation date : 12/2/97 Author : alexander *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ void fn_vInitMorphList(CHN_tdxHandleToMorphList *p_hMorphList) { if( *p_hMorphList != NULL ) return; MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeMorphList , 0 ); * p_hMorphList = (CHN_tdxHandleToMorphList) TMP_M_p_Malloc (sizeof (LST2_M_DynamicAnchorDeclaration(CHN_tdxHandleToMorphElement))); LST2_M_DynamicInitAnchor(*p_hMorphList); } /*----------------------------------------------------------------------------- * Description : Free a CHN_tdxHandleToMorphList list. *----------------------------------------------------------------------------- * Input : Pointer on the handle to the list * Output : None *----------------------------------------------------------------------------- * Creation date : 12/1/97 Author : alexander *---------------------------------------------------------------------------*/ void fn_vFreeMorphList(CHN_tdxHandleToMorphList *p_hMorphList) { if( *p_hMorphList == NULL ) return; while( LST2_M_DynamicGetNumberOfElements(*p_hMorphList) > 0 ) { /* get head*/ tdstMorphChannelList *p_hMorphElt = LST2_M_DynamicGetFirstElement(*p_hMorphList); /* isolate*/ LST2_M_DynamicIsolate(p_hMorphElt); /* free*/ fn_vFreeMorphListElement(p_hMorphElt); } MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeMorphList , 0 ); TMP_M_Free(*p_hMorphList); *p_hMorphList = NULL; } /*----------------------------------------------------------------------------- * Description : Add/change the Morphelement to/of a channel *----------------------------------------------------------------------------- * Input : Handle to the list Channel number Handle to the physical object * Output : None *----------------------------------------------------------------------------- * Creation date : 12/1/97 Author : Alexander *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ void fn_vPutMorphElementInChannel(CHN_tdxHandleToMorphList hMorphList,unsigned short uwChannel,ACP_tdxIndex IndexOfMorphList) { tdstMorphChannelList *p_stMorph,*p_stMorph2; unsigned short uwIndex,uwNumOfElts; /*FB190898 */ if (!hMorphList) return; /*ENDFB*/ uwNumOfElts=(unsigned short)LST2_M_DynamicGetNumberOfElements(hMorphList); LST2_M_DynamicForEachElementOf(hMorphList,p_stMorph2,uwIndex) { if (p_stMorph2->uwChannelNumber==uwChannel) /* If the channel is already active*/ { p_stMorph2->MorphListIndex=IndexOfMorphList; break; } if (p_stMorph2->uwChannelNumber>uwChannel) /* The channel will be included before the current channel*/ { break; } } if (!p_stMorph2) /* If the channel doesn't already active (and end of the list reached)*/ { p_stMorph=fn_p_stCreateMorphListElement(); p_stMorph->uwChannelNumber=uwChannel; p_stMorph->MorphListIndex=IndexOfMorphList; LST2_M_DynamicAddTail(hMorphList,p_stMorph); } else { if (p_stMorph2->uwChannelNumber!=uwChannel) /* If the channel doesn't already active*/ { p_stMorph=fn_p_stCreateMorphListElement(); p_stMorph->uwChannelNumber=uwChannel; p_stMorph->MorphListIndex=IndexOfMorphList; LST2_M_DynamicInsertBetween(p_stMorph,LST2_M_DynamicGetPrevElement(p_stMorph2),p_stMorph2); } } } /*----------------------------------------------------------------------------- * Description : Remove a channel from the list *----------------------------------------------------------------------------- * Input : Handle to the list Channel number * Output : None *----------------------------------------------------------------------------- * Creation date : 12/2/97 Author : Alexander *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ void fn_vRemoveChannelFromMorphList(CHN_tdxHandleToMorphList hMorphList,unsigned short uwChannel) { tdstMorphChannelList *p_stMorph,*p_stMorph_Next; unsigned short uwIndex; /*FB190898 */ if (!hMorphList) return; /*ENDFB*/ LST2_M_DynamicForEachMovingElementOf(hMorphList,p_stMorph,p_stMorph_Next,uwIndex) { if (p_stMorph->uwChannelNumber==uwChannel) { if (!LST2_M_DynamicGetNumberOfElements(hMorphList)) break; LST2_M_DynamicIsolate(p_stMorph); fn_vFreeMorphListElement(p_stMorph); break; } } } /*----------------------------------------------------------------------------- * Description : Return the MorphListIndex corresponding to a channel *----------------------------------------------------------------------------- * Input : Handle to the list Channel number * Output : None *----------------------------------------------------------------------------- * Creation date : 03/25/97 Author : Alexander *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ ACP_tdxIndex fn_hMorphListIndex(CHN_tdxHandleToMorphList hMorphList,unsigned short uwChannel) { tdstMorphChannelList *p_stMorph; unsigned short uwIndex; /*FB190898 */ if (!hMorphList) return -1; /*ENDFB*/ LST2_M_DynamicForEachElementOf(hMorphList,p_stMorph,uwIndex) { if (p_stMorph->uwChannelNumber==uwChannel) /* If the channel is found*/ { return p_stMorph->MorphListIndex; } if (p_stMorph->uwChannelNumber>uwChannel) /* The channel doesn't exist*/ { return -1; } } /* The channel doesn't exist*/ return -1; } /*----------------------------------------------------------------------------- * Description : Return the PO currently morphed in a specific channel, NULL if none *----------------------------------------------------------------------------- * Input : Handle to the list Channel number * Output : PO *----------------------------------------------------------------------------- * Creation date : 01/27/98 Author : Alexis Vaisse *----------------------------------------------------------------------------- * Modification date : Modification Author : * Modifications : *---------------------------------------------------------------------------*/ PO_tdxHandleToPhysicalObject fn_hGetMorphedObjectInChannel (CHN_tdxHandleToMorphList hMorphList,unsigned short uwChannel) { ACP_tdxIndex xIndex = fn_hMorphListIndex(hMorphList, uwChannel); return xIndex != -1 ? MOR_fn_hGetMorphedObject (xIndex) : NULL; }