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

2946 lines
121 KiB
C
Raw Blame History

/*##########################################################################################*/
/*## PlayAnim.cpp : ##*/
/*## ##*/
/*## PLAYER d'ANIMATIONS 3D ##*/
/*## -------------------------- ##*/
/*## Version 1.0 ##*/
/*## Creation date 21/10/96 Sebastien DAVID symbol : DVD (Gizmo) ##*/
/*## Revision date 04/11/96 ##*/
/*## ##*/
/*## That file needs to be compatible for all platforms. ##*/
/*## ##*/
/*## (c) Ubi Studios 1996 ##*/
/*##########################################################################################*/
/* ########################### */
/* ##################### ---RUBRIQUES--- ###################### */
/* ############################################################################ */
/* ######################## MANAGMENT of ANIMATIONS FRAMES ####################### */
/* ######################## MANAGMENT of the SUPEROBJECTS HEAP ####################### */
/* ######################## MANAGMENT of Anim's Datas ####################### */
/* ######################## MANAGMENT of SUB-ANIMS ####################### */
/* ######################## MANAGMENT of MATRIX CONTROL ####################### */
/* ######################## MANAGMENT of STATES STATUS ####################### */
/* ############################################################################ */
/* ############################################################ */
/* ########################### */
/* if speed is a discreet function :*/
/* character move only when frame change*/
/*#define DISCREET_SPEED*/
#define D_State_Define /* tmp 05/02/97*/
#define D_ObjsTbls_Define
/*#define D_GIZMO_TEST /* maj DVD (Gizmo) */
#ifdef D_GIZMO_TEST
#endif /* D_GIZMO_TEST */
#include "TOOLSCPA.h"
#include "cpa_std.h"
#include "prf.h"
#include "Actions/AllActs.h"
/* ANNECY AV {*/
#include "Actions/3dData.h"
/* ENDANNECY AV }*/
#include "Structur/ErrGame.h"
#include "Structur/MemGame.h"
#include "STRUCTUR/Objects.h"
#include "STRUCTUR/Anim_s.h"
#include "Structur/StdObjSt.h"
#include "Structur/EngMode.h"
#include "Structur/State.h"
#include "Family.h"
#include "PlayAnim/PlayAnim.h"
#include "PlayAnim/PlayEvts.h"
#include "ZeMem.h"
#include "Physicol.h"
#include "PO.h"
#include "Structur/ObjsTbls.h"
#include "ia_dnm.h"
#include "ZdxStuff.h"
#include "ChanList.h"
#include "LipsSync.h"
#include "Basic.h"
/* Add on for father son links management*/
#include "GameEng.h"
#include "mor.h"
/* For interpolated animations*/
#include "PlayAnim/Interpol/specif/a3x_pref.h"
#include "PlayAnim/Interpol/a3x_intn.h"
#include "PlayAnim/Interpol/a3x_glob.h"
#include "PlayAnim/Interpol/a3x_mem.h"
#include "PlayAnim/Interpol/a3x_cach.h"
/* ******************* */
/* variables globales */
/* ******************* */
#if defined (ACTIVE_EDITOR) || defined (RETAIL)
#define ENGassert(param)
#else
#ifndef U64
#define ENGassert(param) assert(param)
#else
#define ENGassert(param) { assert(param); if((param)==FALSE) ASM_BREAK; }
#endif /*U64*/
#endif
/* Oliv' - Portage v14 - remove warnings*/
/*#ifdef USE_PROFILER*/
/*static long lNbSO = 0;*/
/*static long lNbSOMax = 0;*/
/*#endif*/
/* EndOfOliv'*/
/*static char info[512];*/
/*static char *p_cName = "";*/
/*static char *p_cOldName = "";*/
RND_tdxHandleToRandomIndex g_Randomhandle;
/* for sub-animation object*/
/*tdstSubAnim3d *PLA_g_d_stSubAnimHeap;*/
/*unsigned short PLA_g_a_wStateOfSubAnimHeap[__PLA_NB_MAX_SUBANIM__];*/
/*unsigned long PLA_g_ulCurrentPosInSubAnimHeap; // position in PLA_g_a_ucStateOfSubAnimHeap*/
/*unsigned long PLA_g_ulMaxInSubAnimHeap; // Number of SupAnim allocated in PLA_g_a_ucStateOfSubAnimHeap*/
unsigned long PLA_g_ulMaxOccupationOfSupObjHeap;
unsigned long PLA_g_ulMaxOccupationOfChannels;
/* for hierarchic graphic object*/
HIE_tdxHandleToSuperObject PLA_fn_hFindNextFreeSupObj(void);
static HIE_tdxHandleToSuperObject PLA_g_d_stSupObjHeap;
#ifdef _DEBUG
static unsigned short PLA_g_a_wStateOfSupObjHeap[__PLA_LIM_SUPOBJ_ALLOC__];
#else
static unsigned short PLA_g_a_wStateOfSupObjHeap[__PLA_NB_MAX_SUPOBJ__];
#endif
static unsigned long PLA_g_ulCurrentPosInSupObjHeap; /* position in PLA_g_a_ucStateOfSupObjHeap*/
static unsigned long PLA_g_ulNbAllocInSupObjHeap; /* Number of SupObj allocated in PLA_g_a_ucStateOfSupObjHeap*/
/* for hierarchic graphic object*/
void PLA_fn_vCreateMatrixHeap(void);
/*POS_tdxHandleToPosition PLA_fn_hFindNextFreeMatrix(void);*/
/*void PLA_fn_vReleaseMatrixInHeap(POS_tdxHandleToPosition _hMatrix);*/
void PLA_fn_vReleaseSuperObjectInHeap(HIE_tdxHandleToSuperObject _hSupObj);
static POS_tdxHandleToPosition PLA_g_d_stMatrixHeap;
/*static unsigned short PLA_g_a_wStateOfMatrixHeap[__PLA_NB_MAX_MATRIX__];*/
/*static unsigned long PLA_g_ulCurrentPosInMatrixHeap; // position in PLA_g_a_ucStateOfMatrixHeap*/
/*static unsigned long PLA_g_ulMaxInMatrixHeap; // Number of Matrix allocated in PLA_g_a_ucStateOfMatrixHeap*/
/*unsigned long PLA_g_ulMaxOccupationOfMatrixHeap; // Max of PLA_g_ulMaxInMatrixHeap*/
BOOL g_bAnimConstantSpeed=FALSE;
/*----------------------------------------------------------------------------
-- Description : GAM_fn_ucGetMorphAmount
-- Get the morph amount into the array of morphing data of an animation
------------------------------------------------------------------------------
-- Methods : Nothing to say
------------------------------------------------------------------------------
-- Input : _p_stAnim : Pointer to the morphed animation
-- _ulChannelNumber : Number of the channel
-- _uwFrameNumber : Number of the frame
-- Output : the amount of morphing
------------------------------------------------------------------------------
-- Creation date : Mar 97 Author: Alain Robin
------------------------------------------------------------------------------
-- Modifications :
-- Modification date : Modification author :
----------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
unsigned char GAM_fn_ucGetMorphAmount(tdstAnim3d *_p_stAnim, unsigned long _ulChannelNumber, unsigned short _uwFrameNumber)
{
/* Animation is a interpolated animation*/
tdstA3dGENERAL *p_stCurrentA3dGENERAL;
long i;
#ifndef FORCE_REAL_TIME_LOAD
if(g_bRealTimeAnimationLoad)
#endif
p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL( p_uwLastA3dGENERAL[_p_stAnim->uwNumOfA3dGENERAL], _uwFrameNumber );
#ifndef FORCE_REAL_TIME_LOAD
else
p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL( _p_stAnim->uwNumOfA3dGENERAL, _uwFrameNumber );
#endif
_p_stAnim->d_stMorphDataArray=&p_stMorphData[p_stCurrentA3dGENERAL->uwNumOfFirstMorphData];
for(i=0;i<p_stCurrentA3dGENERAL->uwNumberOfMorphData;++i)
if((_p_stAnim->d_stMorphDataArray[i].uwChannelNumber==_ulChannelNumber)&&(_p_stAnim->d_stMorphDataArray[i].uwFrameNumber==_uwFrameNumber))
return _p_stAnim->d_stMorphDataArray[i].ucMorphingAmount;
return 0;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */
/*----------------------------------------------------------------------------
-- Description : GAM_fn_ucGetMorphTarget
-- Get the morph amount into the array of morphing data of an animation
------------------------------------------------------------------------------
-- Methods : Nothing to say
------------------------------------------------------------------------------
-- Input : _p_stAnim : Pointer to the morphed animation
-- _ulChannelNumber : Number of the channel
-- _uwFrameNumber : Number of the frame
-- Output : the target of morphing
------------------------------------------------------------------------------
-- Creation date : Mar 97 Author: Alain Robin
------------------------------------------------------------------------------
-- Modifications :
-- Modification date : Modification author :
----------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
unsigned char GAM_fn_ucGetMorphTarget(tdstAnim3d *_p_stAnim, unsigned long _ulChannelNumber, unsigned short _uwFrameNumber)
{
/* Animation is a interpolated animation*/
tdstA3dGENERAL *p_stCurrentA3dGENERAL;
long i;
#ifndef FORCE_REAL_TIME_LOAD
if(g_bRealTimeAnimationLoad)
#endif
p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL( p_uwLastA3dGENERAL[_p_stAnim->uwNumOfA3dGENERAL], _uwFrameNumber );
#ifndef FORCE_REAL_TIME_LOAD
else
p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL( _p_stAnim->uwNumOfA3dGENERAL, _uwFrameNumber );
#endif
_p_stAnim->d_stMorphDataArray=&p_stMorphData[p_stCurrentA3dGENERAL->uwNumOfFirstMorphData];
for(i=0;i<p_stCurrentA3dGENERAL->uwNumberOfMorphData;++i)
if((_p_stAnim->d_stMorphDataArray[i].uwChannelNumber==_ulChannelNumber)&&(_p_stAnim->d_stMorphDataArray[i].uwFrameNumber==_uwFrameNumber))
return _p_stAnim->d_stMorphDataArray[i].ucTarget;
return 0;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */
/*----------------------------------------------------------------------------
-- Description : GAM_fn_p_stGetMorphData
-- Get the morph data into the array of morphing data of an animation
------------------------------------------------------------------------------
-- Methods : Nothing to say
------------------------------------------------------------------------------
-- Input : _p_stAnim : Pointer to the morphed animation
-- _ulChannelNumber : Number of the channel
-- _uwFrameNumber : Number of the frame
-- Output : the target of morphing
------------------------------------------------------------------------------
-- Creation date : Jun 98 Author: Alain Robin
------------------------------------------------------------------------------
-- Modifications :
-- Modification date : Modification author :
----------------------------------------------------------------------------*/
tdstMorphData* GAM_fn_p_stGetMorphData(tdstAnim3d *_p_stAnim, unsigned long _ulChannelNumber, unsigned short _uwFrameNumber)
{
/* Animation is a interpolated animation*/
tdstA3dGENERAL *p_stCurrentA3dGENERAL;
long i;
#ifndef FORCE_REAL_TIME_LOAD
if(g_bRealTimeAnimationLoad)
#endif
p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL( p_uwLastA3dGENERAL[_p_stAnim->uwNumOfA3dGENERAL], _uwFrameNumber );
#ifndef FORCE_REAL_TIME_LOAD
else
p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL( _p_stAnim->uwNumOfA3dGENERAL, _uwFrameNumber );
#endif
_p_stAnim->d_stMorphDataArray=&p_stMorphData[p_stCurrentA3dGENERAL->uwNumOfFirstMorphData];
for(i=0;i<p_stCurrentA3dGENERAL->uwNumberOfMorphData;++i)
if((_p_stAnim->d_stMorphDataArray[i].uwChannelNumber==_ulChannelNumber)&&(_p_stAnim->d_stMorphDataArray[i].uwFrameNumber==_uwFrameNumber))
return &(_p_stAnim->d_stMorphDataArray[i]);
return NULL;
}
/* **************************************************************************************/
/* * Description : Stop all morphing task fot the current anim begin at the current frame*/
/* * For the character give in argument*/
/* *===================================================================================**/
/* * Input : SO of the character*/
/* *-----------------------------------------------------------------------------------**/
/* * Creation date : 13/05/98 Author : Carlos Torres*/
/* **************************************************************************************/
void PLA_fn_vStopCurrentMorphAnim(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
tdstAnim3d * p_stCurrentAnim=fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim;
#ifndef U64
unsigned short uwCurrentFrame=fn_uw3dDataGetCurrentFrame(h_Current3dData);
#endif
short i;
/* if is a morphing anim and anim is display (array of element initilize)*/
if (p_stCurrentAnim && p_stCurrentAnim->d_stMorphDataArray && fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d)
{
//AR9904 Because on N64, we are sure that p_stArrayOfElts3d isn't NULL
#ifndef U64
/* for all channel*/
for (i=0;i < p_stCurrentAnim->ucMaxNumberOfElements;i++)
{
/* check if element was morphing*/
if (GAM_fn_ucGetMorphAmount(p_stCurrentAnim,i,uwCurrentFrame) <100 )
MOR_fn_xStopMorph(p_stSuperObject,(fn_p_st3dDataGetCurrentFrame(h_Current3dData))->p_stArrayOfElts3d[i].ucChannelNumber);
}
#else
/* for all channel*/
for (i=0;i<256;++i)
MOR_fn_xStopMorph(p_stSuperObject,(ACP_tdxIndex)i);
#endif
}
}
/* ######################################################################## */
/* ############################################################################ */
/* ########################## MANAGMENT of ANIMATIONS FRAMES #################### */
/* ############################################################################### */
/* ############################################################################### */
/* ######### */
/* ################# */
/* ############# */
/* ######### */
/* ##### */
/* # */
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/* **************************************************************************************/
/* * Description : overwrite super Object Matrix of active channel*/
/* * and update matrix for UCC*/
/* * (use when frame is skip to update control channel)*/
/* *===================================================================================**/
/* *-----------------------------------------------------------------------------------**/
/* * Creation date : 20/04/98 Author : Carlos Torres*/
/* **************************************************************************************/
/* **************************************************************************************/
/* * Description : Do one frame of anim and subanims for one object **/
/* *===================================================================================**/
/* *-----------------------------------------------------------------------------------**/
/* * Creation date : 27/07/97 Author : DVD (Gizmo)*/
/* * Modif : 12/03/98 Morphing Author : Alain Robin(Carlos Torres)*/
/* * Modif : 22/04/98 Stop Morphing when element is no more morph - Carlos Torres*/
/* * Modif : 15/05/98 Reset SO for non-graphic element - Carlos Torres*/
/* * Modif : 20/05/98 Reset Link object for Event and Light - Carlos Torres*/
/* **************************************************************************************/
void PLA_fn_vDoFrame(tdstAnim3d *p_stCurrentAnim, unsigned short uwCurrentFrame
,HIE_tdxHandleToSuperObject p_stSuperObject)
{
/* long i;*/
struct tdstFrame3d_ *p_stCurrentFrame3d;
register struct tdstElement3d_ *p_stElt3d;
struct tdstElement3d_ *p_stElt3dStop;
MS_tdxHandleTo3dData h_Current3dData;
HIE_tdxHandleToSuperObject p_stTargetSO;
tdstAChannel *p_stChannel;
struct tdstObjectsTableElement_ *d_stCurrentObjectsTable, *p_stCurrentObjectsTableElement;
short wElement;
/* Oliv' - Portage v14 - remove warnings*/
/* BOOL bTestActivation=FALSE;*/
/* EndOfOliv'*/
float f_Transparence;
PO_tdxHandleToPhysicalObject hPhysicalObject;
h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
f_Transparence = HIE_fn_fGetSuperObjectTransparenceLevel(p_stSuperObject);
d_stCurrentObjectsTable = fn_h3dDataGetCurrentObjectsTable(h_Current3dData)->d_stObjectsTable;
/* update frame*/
p_stCurrentFrame3d = fn_p_st3dDataGetCurrentFrame(h_Current3dData);
fn_vUpdateFrame(p_stSuperObject,p_stCurrentFrame3d,p_stCurrentAnim,uwCurrentFrame);
p_stElt3d = p_stCurrentFrame3d->p_stArrayOfElts3d;
p_stElt3dStop = p_stElt3d + p_stCurrentAnim->ucMaxNumberOfElements;
/* For each Channel*/
while (p_stElt3d != p_stElt3dStop)
{
if (p_stElt3d->ucChannelNumber == C_ucUnknownChannel )
{
p_stElt3d++;
/* ENGassert(0);*/
continue; /* erreur*/
}
/* get the channel and its target SO*/
p_stChannel = fn_hGetCSOForChannel(fn_h3dDataGetChannelSOList(h_Current3dData),p_stElt3d->ucChannelNumber);
p_stTargetSO = p_stChannel->hSupObject;
#if defined(ANIM_DEBUG) && defined(U64)
if(p_stTargetSO==NULL)
{
osSyncPrintf("Error : Target SO is null\n");
osSyncPrintf("Anim : %d, Frame : %d, Channel : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,uwCurrentFrame,p_stElt3d->ucChannelNumber);
}
#endif
#ifndef RETAIL
ENGassert(p_stTargetSO);
#endif
/* Graphic element in an active channel*/
if (p_stElt3d->eTypeOfElement == TE_GraphicObject && p_stElt3d->bf1ActiveStatus)
{
#ifdef D_USE_LIPSYNC
/* get element checkin lip synchro*/
wElement = fn_vGetLipsSynchObject(p_stSuperObject,p_stElt3d->ucChannelNumber);
if ( wElement == -1000 )
wElement = (short)p_stElt3d->wElement;
#else
wElement = (short)p_stElt3d->wElement;
#endif /*D_USE_LIPSYNC*/
p_stCurrentObjectsTableElement = d_stCurrentObjectsTable + wElement;
/* Element Defined*/
if ( p_stCurrentObjectsTableElement->wTypeOfTarget != C_wTdO_Undefined )
{
if ( p_stCurrentObjectsTableElement->p_stCustomZoom )
{
MTH3D_tdstVector stCustomZoomI,stCustomZoomJ,stCustomZoomK;
MTH_tdxReal f0,f4,f8;
HIE_tdxHandleToSuperObject p_stSO_Child;
/* Element with Custom Zoom ++++++++++++++++++++++++++++++++++++++++*/
/* check if the channel is adapted...*/
if (p_stChannel->hZoomSupObject == NULL)
{
/* we must create the zoom hierarchy*/
/* channel superobject has no asociated object*/
/* zoom superobject has the physical object associated*/
/* zoom superobject is child of channel superobject*/
/* remove associated object from channel SO*/
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,NULL,HIE_C_ulSuperObject);
/* create zoom superobject*/
/* p_cName = p_stCurrentAnim->szAnimName;*/
p_stSO_Child = PLA_fn_hFindNextFreeSupObj();
/* zoom SO is son of channel SO*/
HIE_fn_vSuperObjectAddTail(p_stTargetSO,p_stSO_Child);
/* put a new matrix in zoom superobject*/
#if defined(ANIM_DEBUG) && defined(U64)
if(p_stSO_Child->hLocalMatrix==NULL)
{
osSyncPrintf("Error : Local matrix is null\n");
osSyncPrintf("Anim : %d, Frame : %d, Channel : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,uwCurrentFrame,p_stElt3d->ucChannelNumber);
}
#endif
#ifndef RETAIL
ENGassert(p_stSO_Child->hLocalMatrix != NULL);
#endif
/* HIE_fn_vSetSuperObjectMatrix(p_stSO_Child,PLA_fn_hFindNextFreeMatrix());*/
p_stChannel->hZoomSupObject = p_stSO_Child;
}
else
{
/* ok, hierarchy is good, just signal it*/
p_stSO_Child = p_stChannel->hZoomSupObject;
}
/* NOT a Morphing Anim ------------------------------------------*/
if ( p_stCurrentAnim->d_stMorphDataArray == NULL )
{
/* Physical Object*/
if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_PhysicalObject )
{
/* Look if there is a morphed object in the channel*/
hPhysicalObject = fn_hGetMorphedObjectInChannel (fn_h3dDataGetMorphList (h_Current3dData),p_stElt3d->ucChannelNumber);
/* If not, we take the object of the animation*/
if ( !hPhysicalObject )
hPhysicalObject = p_stCurrentObjectsTableElement->h_Target;
/* put the object in the right superobject*/
HIE_fn_vSetSuperObjectObjectAndType(p_stSO_Child,hPhysicalObject,HIE_C_ulPO);
}
#ifndef U64 /* no mirror on U64*/
/* Mirror*/
else if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_Mirror )
HIE_fn_vSetSuperObjectObjectAndType(p_stSO_Child,p_stCurrentObjectsTableElement->h_Target,HIE_C_ulPO_Mirror);
#endif
}
/* Morphing Anim ------------------------------------------------*/
else
{
/* Physical Object*/
if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_PhysicalObject )
{
ACP_tdxIndex xMorphTaskIndex;
tdstMorphData* p_stMorphData;
p_stMorphData=GAM_fn_p_stGetMorphData(p_stCurrentAnim,p_stElt3d->ucChannelNumber,uwCurrentFrame);
/* element not morphed -- > Stop Morphing*/
if (p_stMorphData == NULL )
{
MOR_fn_xStopMorph(p_stSuperObject,p_stElt3d->ucChannelNumber);
HIE_fn_vSetSuperObjectObjectAndType(p_stSO_Child,p_stCurrentObjectsTableElement->h_Target,HIE_C_ulPO);
}
/* element morphed*/
else
{
/* Morphing*/
if ( p_stMorphData->ucMorphingAmount < 100 )
{
/* Create a new morph task*/
xMorphTaskIndex = MOR_fn_xMorphing( p_stSuperObject, wElement,
p_stMorphData->ucTarget,
p_stMorphData->ucMorphingAmount, p_stElt3d->ucChannelNumber);
if(xMorphTaskIndex!=-1)
{
MOR_fn_vDoMorph(xMorphTaskIndex); /* Execute morphing*/
hPhysicalObject = MOR_fn_hGetMorphedObject (xMorphTaskIndex); /* Get result*/
HIE_fn_vSetSuperObjectObjectAndType ( p_stSO_Child, hPhysicalObject, HIE_C_ulPO ); /* Put the result into the hierarchy*/
}
else
{
#if !defined(RETAIL) && defined(U64)
osSyncPrintf("Problem in anim %d, frame %d, Channel %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,uwCurrentFrame,p_stElt3d->ucChannelNumber);
#endif
HIE_fn_vSetSuperObjectObjectAndType(p_stSO_Child,d_stCurrentObjectsTable[wElement].h_Target,HIE_C_ulPO);
}
}
/* Complete transformation*/
else
{
MOR_fn_xStopMorph( p_stSuperObject, p_stElt3d->ucChannelNumber);
/* target of the morphing*/
hPhysicalObject = d_stCurrentObjectsTable[p_stMorphData->ucTarget].h_Target;
HIE_fn_vSetSuperObjectObjectAndType ( p_stSO_Child, hPhysicalObject, HIE_C_ulPO );
}
}
}
#ifndef U64 /* no mirror on U64*/
else if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_Mirror )
HIE_fn_vSetSuperObjectObjectAndType(p_stSO_Child,p_stCurrentObjectsTableElement->h_Target,HIE_C_ulPO_Mirror);
#endif
}
HIE_fn_vSetSuperObjectBoundingVolume(p_stSO_Child,NULL);
/* build the zoom matrix*/
POS_fn_vSetIdentityMatrix(HIE_fn_hGetSuperObjectMatrix(p_stSO_Child));
MTH3D_M_vGetVectorElements(&f0,&f4,&f8,p_stCurrentObjectsTableElement->p_stCustomZoom);
MTH3D_M_vSetVectorElements(&stCustomZoomI,f0,MTH_C_ZERO,MTH_C_ZERO);
MTH3D_M_vSetVectorElements(&stCustomZoomJ,MTH_C_ZERO,f4,MTH_C_ZERO);
MTH3D_M_vSetVectorElements(&stCustomZoomK,MTH_C_ZERO,MTH_C_ZERO,f8);
POS_fn_vSetScaleMatrix(HIE_fn_hGetSuperObjectMatrix(p_stSO_Child),&stCustomZoomI, &stCustomZoomJ, &stCustomZoomK);
/* Invert faces depending on the number of symmetry*/
if( MTH_M_bLessZero(MTH_M_xMul(f0, MTH_M_xMul(f4, f8))) )
{
HIE_fn_vSetSuperObjectDrawMask(p_stSO_Child, HIE_fn_lGetSuperObjectDrawMask(p_stSO_Child)&(GLI_C_lAllIsEnable-(GLI_C_lNotInvertBackfaces)));
}
/* Module transparency isn't setting in IA*/
if ((HIE_fn_SO_ulGetFlags(p_stSO_Child) & HIE_C_Flag_ModuleTransparency) != HIE_C_Flag_ModuleTransparency )
{
/* NO charcter transparency*/
if ( (HIE_fn_lGetSuperObjectDrawMask(p_stSuperObject)&GLI_C_lIsNotGrided) == GLI_C_lIsNotGrided ) {
/* no anim transparency for that module*/
if (p_stElt3d->ucTransparency == 0xFF) {
HIE_fn_vSetSuperObjectTransparenceLevel(p_stSO_Child,f_Transparence);
HIE_fn_vSetSuperObjectDrawMask(p_stSO_Child, HIE_fn_lGetSuperObjectDrawMask(p_stSO_Child) | GLI_C_lIsNotGrided );
}
/* set anim transparency for the module*/
else {
HIE_fn_vSetSuperObjectTransparenceLevel(p_stSO_Child,(float)p_stElt3d->ucTransparency);
HIE_fn_vSetSuperObjectDrawMask(p_stSO_Child, HIE_fn_lGetSuperObjectDrawMask(p_stSO_Child) & ~GLI_C_lIsNotGrided );
}
}
/* set the charcter transparency to its modules*/
else
HIE_fn_vSetSuperObjectTransparenceLevel(p_stSO_Child,f_Transparence);
}
}
/* NO Custom Zoom +++++++++++++++++++++++++++++++++++++++++++++++++++*/
else
{
/* there is no custom zoom...*/
/* let's see if the hierarchy is good*/
if (p_stChannel->hZoomSupObject != NULL)
{
/* hierarchy not good, we have a zoom in there*/
/* let's remove it !*/
/* isolate zoom superobject*/
LST2_M_DynamicIsolate(p_stChannel->hZoomSupObject);
/* release its matrix*/
/* PLA_fn_vReleaseMatrixInHeap(HIE_fn_hGetSuperObjectMatrix(p_stChannel->hZoomSupObject));*/
/* release zoom superobject*/
PLA_fn_vReleaseSuperObjectInHeap(p_stChannel->hZoomSupObject);
p_stChannel->hZoomSupObject = NULL;
}
/* NOT a Morphing Anim ------------------------------------------*/
if ( p_stCurrentAnim->d_stMorphDataArray == NULL )
{
/* Physical Object*/
if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_PhysicalObject )
{
/* Look if there is a morphed object in the channel*/
hPhysicalObject = fn_hGetMorphedObjectInChannel (fn_h3dDataGetMorphList (h_Current3dData),p_stElt3d->ucChannelNumber);
/* If not, we take the object of the animation*/
if ( !hPhysicalObject )
hPhysicalObject = p_stCurrentObjectsTableElement->h_Target;
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,hPhysicalObject,HIE_C_ulPO);
}
/* Mirror*/
#ifndef U64 /* no mirror on U64*/
else if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_Mirror )
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,p_stCurrentObjectsTableElement->h_Target,HIE_C_ulPO_Mirror);
#endif
}
/* Morphing Anim ------------------------------------------------*/
else
{
/* Physical Object*/
if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_PhysicalObject )
{
ACP_tdxIndex xMorphTaskIndex;
tdstMorphData* p_stMorphData;
p_stMorphData=GAM_fn_p_stGetMorphData(p_stCurrentAnim,p_stElt3d->ucChannelNumber,uwCurrentFrame);
/* element not morphed -- > Stop Morphing*/
if ( p_stMorphData==NULL )
{
MOR_fn_xStopMorph(p_stSuperObject,p_stElt3d->ucChannelNumber);
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,p_stCurrentObjectsTableElement->h_Target,HIE_C_ulPO);
}
/* element morphed*/
else
{
/* Morphing*/
if ( p_stMorphData->ucMorphingAmount < 100 )
{
/* Create a new morph task*/
xMorphTaskIndex = MOR_fn_xMorphing( p_stSuperObject, wElement,
p_stMorphData->ucTarget ,
p_stMorphData->ucMorphingAmount, p_stElt3d->ucChannelNumber); /* Create a new morph task*/
if(xMorphTaskIndex!=-1)
{
MOR_fn_vDoMorph(xMorphTaskIndex); /* Execute morphing*/
hPhysicalObject = MOR_fn_hGetMorphedObject (xMorphTaskIndex); /* Get result*/
HIE_fn_vSetSuperObjectObjectAndType ( p_stTargetSO, hPhysicalObject, HIE_C_ulPO ); /* Put the result into the hierarchy*/
}
else
{
#if !defined(RETAIL) && defined(U64)
osSyncPrintf("Problem in anim %d, frame %d, channel %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,uwCurrentFrame,p_stElt3d->ucChannelNumber);
#endif
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,d_stCurrentObjectsTable[wElement].h_Target,HIE_C_ulPO);
}
}
/* Complete transformation*/
else
{
MOR_fn_xStopMorph( p_stSuperObject, p_stElt3d->ucChannelNumber);
/* target of the morphing*/
hPhysicalObject = d_stCurrentObjectsTable [ p_stMorphData->ucTarget ] . h_Target; /* target of the morphing*/
HIE_fn_vSetSuperObjectObjectAndType ( p_stTargetSO, hPhysicalObject, HIE_C_ulPO );
}
}
}
#ifndef U64 /* no mirror on U64*/
/* Mirror*/
else if ( p_stCurrentObjectsTableElement->wTypeOfTarget == C_wTdO_Mirror ) /* AR980304 little optimisation...*/
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,p_stCurrentObjectsTableElement->h_Target,HIE_C_ulPO_Mirror);
#endif
}
HIE_fn_vSetSuperObjectBoundingVolume(p_stTargetSO,NULL);
}
}
/* Undefined Element*/
else
{
#ifndef RETAIL
#ifdef U64
osSyncPrintf("Undefined element in anim %d, Channel %d, Frame %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,uwCurrentFrame,p_stElt3d->ucChannelNumber);
#endif
ENGassert(0);
#endif
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,NULL,HIE_C_ulSuperObject);
}
}
/* END - Graphic element in an active channel*/
/* Only 3DObject Active have a link object*/
if ((p_stElt3d->eTypeOfElement == TE_EmptyObject) ||
(p_stElt3d->eTypeOfElement == TE_Event) ||
(p_stElt3d->eTypeOfElement == TE_Fake) ||
!p_stElt3d->bf1ActiveStatus)
{
/* warning, it is possible that this channel has a zoom hierarchy...*/
if (p_stChannel->hZoomSupObject)
{
/* there is one !*/
/* let's remove it !*/
/* isolate zoom superobject*/
LST2_M_DynamicIsolate(p_stChannel->hZoomSupObject);
/* release its matrix*/
/* PLA_fn_vReleaseMatrixInHeap(HIE_fn_hGetSuperObjectMatrix(p_stChannel->hZoomSupObject));*/
/* release zoom superobject*/
PLA_fn_vReleaseSuperObjectInHeap(p_stChannel->hZoomSupObject);
p_stChannel->hZoomSupObject = NULL;
}
HIE_fn_vSetSuperObjectObjectAndType(p_stTargetSO,NULL,HIE_C_ulSuperObject);
}
/* Module transparency isn't setting in IA*/
if ((HIE_fn_SO_ulGetFlags(p_stTargetSO) & HIE_C_Flag_ModuleTransparency) != HIE_C_Flag_ModuleTransparency )
{
/* NO charcter transparency*/
if ( (HIE_fn_lGetSuperObjectDrawMask(p_stSuperObject)&GLI_C_lIsNotGrided) == GLI_C_lIsNotGrided ) {
/* no anim transparency for that module*/
if (p_stElt3d->ucTransparency == 0xFF) {
HIE_fn_vSetSuperObjectTransparenceLevel(p_stTargetSO,f_Transparence);
HIE_fn_vSetSuperObjectDrawMask(p_stTargetSO, HIE_fn_lGetSuperObjectDrawMask(p_stTargetSO) | GLI_C_lIsNotGrided );
}
/* set anim transparency for the module*/
else {
HIE_fn_vSetSuperObjectTransparenceLevel(p_stTargetSO,(float)p_stElt3d->ucTransparency);
HIE_fn_vSetSuperObjectDrawMask(p_stTargetSO, HIE_fn_lGetSuperObjectDrawMask(p_stTargetSO) & ~GLI_C_lIsNotGrided );
}
}
/* set the charcter transparency to its modules*/
else
HIE_fn_vSetSuperObjectTransparenceLevel(p_stTargetSO,f_Transparence);
}
fn_vUpdateSPOFlagsOfChannelForActivation (
p_stChannel -> hZoomSupObject ? p_stChannel -> hZoomSupObject : p_stChannel -> hSupObject ,
p_stChannel -> bActiveChannel
) ;
p_stElt3d++;
}
/* now that everything is ready, let's update matrix !*/
fn_vUpdateFrameMatrix(p_stSuperObject,p_stCurrentFrame3d,p_stCurrentAnim,uwCurrentFrame,(unsigned char) fn_b3dDataHasAnimMatrixChanged(h_Current3dData),fn_h3dDataGetChannelSOList(h_Current3dData));
fn_v3dDataResetAnimMatrixHasChanged(h_Current3dData);
/* update global matrix of all child*/
PLA_fn_vRefreshGlobalMatrixUnderCharacter(p_stSuperObject);
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/* Modif : check if char is freezed Carlos Torres 13/03/98*/
/* Modif : del test last frame compute Carlos Torres 13/03/98*/
/* Modif : continuous speed Carlos Torres 21/04/98*/
ACP_tdxBool PLA_fn_bSkipCurrentFrame(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData;
struct tdstState_ *p_stCurrentState;
struct tdstAnim3d_ *p_stCurrentAnim;
unsigned long ulNbFrames;
unsigned short uwNbFrames;
unsigned short NbFramesSLME;
h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
if (p_stCurrentState==NULL)
{
#ifndef RETAIL
ENGassert(0);
#endif
return TRUE; /* not a good object !!! mettre un message d'erreur !!! ...*/
}
p_stCurrentAnim = p_stCurrentState->p_stAnim;
/* for instance : a camera ...*/
if (p_stCurrentAnim==NULL)
return FALSE;
/* skip if char is freezed*/
if(!fn_uc3dDataGetFrameRate(h_Current3dData))
return TRUE;
/* unset all user flags */
fn_v3dDataSetUserEventFlags( h_Current3dData, 0 );
if (fn_l3dDataGetLastComputeEngineFrame(h_Current3dData)==0)
{
/* the frame is at 0 after a reinit or a pause or a change map or at the first time the anim is played...*/
fn_v3dDataSetStartTime(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-g_stEngineStructure.stEngineTimer.ulPauseTime+fn_ul3dDataGetStartTime(h_Current3dData));
fn_v3dDataSetTimePreviousFrame(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount);
}
fn_v3dDataSetLastComputeEngineFrame(h_Current3dData,HIE_fn_lGetGlobalMatrixFrameCounter());
/* update nb frame passed since last MechEvent*/
NbFramesSLME=fn_uw3dDataGetNbEngineFrameSinceLastMechEvent(h_Current3dData);
if (NbFramesSLME!=LME_INVALID)
{
NbFramesSLME++;
fn_v3dDataSetNbEngineFrameSinceLastMechEvent(h_Current3dData,NbFramesSLME);
}
/* The current frame is the same as the previous skip it (anim too fast)*/
if (fn_b3dDataGetSkipCurrentFrame(h_Current3dData))
{
#ifdef D_USE_LIPSYNC
unsigned short uwAddFrame;
#endif
#ifndef DISCREET_SPEED
if(fn_p_stGetLinearSpeedVector(p_stCurrentAnim, fn_uw3dDataGetCurrentFrame(h_Current3dData)))
{
fn_vTransferSpeedInformationPLA_DNM(p_stSuperObject,fn_s3dDataGetLastFrame(h_Current3dData));
}
#endif
/* next frame don't be skipped*/
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,FALSE);
/* compute current frame*/
if (g_bAnimConstantSpeed)
ulNbFrames=fn_uw3dDataGetCurrentFrame(h_Current3dData)+1;
else
ulNbFrames=fn_uc3dDataGetFrameRate(h_Current3dData)*(g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-fn_ul3dDataGetStartTime(h_Current3dData))/1000;
#ifdef D_USE_LIPSYNC
/* update synchro frame for lip synchro*/
uwAddFrame=(short)(ulNbFrames-fn_uw3dDataGetCurrentFrame(h_Current3dData));
fn_v3dDataSetCurrentSynchroFrame(h_Current3dData,(unsigned short)(fn_uw3dDataGetCurrentSynchroFrame(h_Current3dData)+uwAddFrame));
#endif
/* set NbFrame and TimeDelay - depend if frame is over the last*/
if (ulNbFrames>p_stCurrentAnim->uwNumberOfFrames)
{
fn_v3dDataSetTimeDelay(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-1000*p_stCurrentAnim->uwNumberOfFrames/fn_uc3dDataGetFrameRate(h_Current3dData)-fn_ul3dDataGetStartTime(h_Current3dData));
uwNbFrames=p_stCurrentAnim->uwNumberOfFrames;
}
else
{
fn_v3dDataSetTimeDelay(h_Current3dData,0);
uwNbFrames=(unsigned short)ulNbFrames;
}
/* same frame but not over -> skip the next frame*/
if ( (fn_uw3dDataGetCurrentFrame(h_Current3dData) == uwNbFrames) && (uwNbFrames != p_stCurrentAnim->uwNumberOfFrames) )
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,TRUE);
/* if the current anim has only one frame, and if the current state has not been forced, and if the next state is the same*/
/* as the current state, then skip !*/
if (p_stCurrentAnim->uwNumberOfFrames == 1 &&
!fn_b3dDataGetStateJustModified(h_Current3dData) &&
fn_hGetNextStateInState(p_stCurrentState) == p_stCurrentState)
{
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,TRUE);
fn_v3dDataSetCurrentFrame(h_Current3dData,0);
}
else
fn_v3dDataSetCurrentFrame(h_Current3dData,uwNbFrames);
/* if frame over the last --> End Of Anim*/
if (fn_uw3dDataGetCurrentFrame(h_Current3dData) == p_stCurrentAnim->uwNumberOfFrames )
fn_v3dDataSetFlagEndOfAnim(h_Current3dData,TRUE);
/* End of State when End Of Anim & No Repeat & No Next State*/
if (fn_uc3dDataGetRepeatAnimation(h_Current3dData) == 0
&& fn_uw3dDataGetCurrentFrame(h_Current3dData) == p_stCurrentAnim->uwNumberOfFrames
&& fn_hGetNextStateInState(p_stCurrentState) == NULL)
{
fn_v3dDataSetFlagEndState(h_Current3dData,TRUE);
}
return TRUE;
}
/* frame different from the previous*/
else
return FALSE;
}
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/* **************************************************************************************/
/* * Description : Change frame of current anim, and change anim if we have reached **/
/* * end, Make sure that fn_vDoAnim is not called for objects without **/
/* * Anim or State **/
/* *===================================================================================**/
/* *-----------------------------------------------------------------------------------**/
/* * Creation date : 21/10/96 Author : DVD (Gizmo) **/
/* **************************************************************************************/
ACP_tdxBool PLA_fn_bDoAnimPlayerForCharacter(HIE_tdxHandleToSuperObject p_stSuperObject, ACP_tdxBool bNoDisplay, ACP_tdxBool _bHandleSkippedEventsIfRelevant )
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
struct tdstState_ *p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
struct tdstState_ *p_stTmpState;
struct tdstAnim3d_ *p_stCurrentAnim;
unsigned char FlagModifyState;
/* tdstSubAnim3d stTmpSubAnim;*/
ACP_tdxBool bDidChangeState = FALSE;
/* MR2204*/
unsigned long ulAddFrames=0;
POS_tdstCompletePosition *p_stCharMatrix;
MTH3D_tdstVector stCharTransVect/*,stOffsetAnim*/;
#ifdef D_USE_LIPSYNC
/* MR0407*/
unsigned short uwAddFrame;
#endif
unsigned char ucStateSpeed; /* MR2407*/
if (p_stCurrentState==NULL)
{
#ifndef RETAIL
ENGassert(0);
#endif
return FALSE; /* not a good object !!! mettre un message d'erreur !!! ...*/
}
p_stCurrentAnim = p_stCurrentState->p_stAnim;
/* for instance : a camera ...*/
if (p_stCurrentAnim==NULL)
{
PLA_fn_vComputeNextFrame(p_stSuperObject);
return TRUE;
}
/* p_cOldName = p_stCurrentAnim->szAnimName;*/
/* update the stCurrent3dData structure*/
if(fn_uw3dDataGetCurrentFrame(h_Current3dData) == p_stCurrentAnim->uwNumberOfFrames || fn_uc3dDataGetFlagModifState(h_Current3dData) == TRUE)
{
/* the current anim has reached its end... or a new state has been set for this perso*/
if (fn_uc3dDataGetFlagModifState(h_Current3dData) == FALSE)
{
/* the current anim has reached its end.*/
/* it will loop, or carry on another animation. Play remaining events*/
/* if no frame has been skipped since the last one, then this call will set up the next event to play.*/
fn_vPlayLastEventsBeforeRestart( p_stSuperObject );
}
else
{
/* a new state has been set for this perso*/
/* desinit all events. the next anim interrupt the current one, so call with a TRUE to stop events*/
fn_vDesInitAllEvents(p_stSuperObject,fn_h3dDataGetWantedState(h_Current3dData),TRUE);
}
if(fn_uc3dDataGetRepeatAnimation(h_Current3dData) > 0 && fn_uc3dDataGetFlagModifState(h_Current3dData) == FALSE )
{
/* the anim will repeat, and no state change has occured --> normal progression*/
/* look how many frames must be skiped according to the time delay*/
if (g_bAnimConstantSpeed)
ulAddFrames=fn_uw3dDataGetCurrentFrame(h_Current3dData)+1;
else
ulAddFrames=fn_uc3dDataGetFrameRate(h_Current3dData)*fn_ul3dDataGetTimeDelay(h_Current3dData)/1000;
/* this calcul is strange !*/
#ifdef D_USE_LIPSYNC
uwAddFrame=(unsigned short)(ulAddFrames-fn_uw3dDataGetCurrentFrame(h_Current3dData));
fn_v3dDataSetCurrentSynchroFrame(h_Current3dData,(unsigned short)(fn_uw3dDataGetCurrentSynchroFrame(h_Current3dData)+uwAddFrame));
#endif
/* the next frame number must be within the right interval... (from 0 to number of frames -1)*/
ulAddFrames%=p_stCurrentAnim->uwNumberOfFrames;
/* compute start time for this new anim sequence*/
/* this is current time - (number of frames skipped / framerate)*/
fn_v3dDataSetStartTime(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-(1000*ulAddFrames)/fn_uc3dDataGetFrameRate(h_Current3dData));
/* set the current new frame*/
fn_v3dDataSetCurrentFrame(h_Current3dData,(unsigned short)ulAddFrames);
/* ??? last frame == -1 ???*/
fn_v3dDataSetLastFrame(h_Current3dData,-1);
/* BUG state just modified ????*/
/* fn_v3dDataSetStateJustModified(h_Current3dData,TRUE);*/
/* decrease the number of repeat for this anim*/
fn_v3dDataDecRepeatAnimation(h_Current3dData);
}
else
{
/* two cases :*/
/* - a change of state has been asked to interrupt the current one*/
/* or*/
/* - the anim is finished and will not repeat --> carry on next anim*/
if(fn_uc3dDataGetFlagModifState(h_Current3dData) == FALSE)
{
/* anim finished and carry on a new one*/
/* set the nex state*/
fn_v3dDataSetWantedState(h_Current3dData,fn_hGetNextStateInState(fn_h3dDataGetCurrentState(h_Current3dData)));
}
#ifndef RETAIL
if(fn_h3dDataGetWantedState(h_Current3dData)==NULL) M_GameFatalError(E_uwGamePLA_NoWantedState);
#endif
/* get the next state*/
p_stTmpState = fn_h3dDataGetWantedState(h_Current3dData);
if (fn_h3dDataGetCurrentState(h_Current3dData) != p_stTmpState && fn_uc3dDataGetFlagModifState(h_Current3dData) == FALSE )
{
/* anim finished, carry on the next state which is different from the current one*/
/* so desinit all events. the next anim normally follows the current one, so call with a FALSE so that it does not stop events*/
fn_vDesInitAllEvents(p_stSuperObject,NULL,FALSE);
}
/* bDidchangestate is TRUE if the new state is different from the current one, or if the current state has been interrupted*/
bDidChangeState = ( ACP_tdxBool ) ( p_stCurrentState != p_stTmpState || fn_uc3dDataGetFlagModifState ( h_Current3dData ) == TRUE ) ;
if ( bDidChangeState )
{
FlagModifyState = TRUE ;
/* Calcul Offset ici (MR1504)*/
p_stCharMatrix = HIE_fn_hGetSuperObjectMatrix(p_stSuperObject);
MTH3D_M_vSubVector( &stCharTransVect , POS_fn_p_stGetTranslationVector(p_stCharMatrix) , /*POS_fn_p_stGetTranslationVector(*/&p_stTmpState->p_stAnim->stOffsetMatrix/*)*/ ); /*AR9811*/
MTH3D_M_vAddVector( &stCharTransVect , &stCharTransVect , /*POS_fn_p_stGetTranslationVector(*/&p_stCurrentState->p_stAnim->stOffsetMatrix/*)*/ ); /*AR9811*/
POS_fn_vSetTranslationVector(p_stCharMatrix,&stCharTransVect);
POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(p_stSuperObject),HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(p_stSuperObject)),p_stCharMatrix);
/* we change of state, so we change of anim. If new anim has not the same number of elements as the current one*/
/* then we must change the elements array allocation*/
if (p_stCurrentAnim->ucMaxNumberOfElements != p_stTmpState->p_stAnim->ucMaxNumberOfElements || fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d == NULL)
{
/* ANNECY MT - 22/09/98 {*/
/*
if (fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d)
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_Current3dData->h_Family);
TMP_M_Free(fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d);
}
MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_Current3dData->h_Family);
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d = (tdstElement3d*)TMP_M_p_Malloc(sizeof(tdstElement3d) * p_stTmpState->p_stAnim->ucMaxNumberOfElements);
memset(fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d,0,sizeof(tdstElement3d) * p_stTmpState->p_stAnim->ucMaxNumberOfElements);
*/
fn_vAllocArrayOfElts3d (h_Current3dData , p_stTmpState->p_stAnim->ucMaxNumberOfElements);
/* END ANNECY MT }*/
}
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAnim = NULL;
/* current state is the new state*/
fn_v3dDataSetCurrentState(h_Current3dData,p_stTmpState);
fn_vUpdateCurrentActivationForCharacter(p_stSuperObject);
/* get new values*/
p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
p_stCurrentAnim = p_stCurrentState->p_stAnim;
ucStateSpeed=fn_scGetSpeedInState(fn_h3dDataGetCurrentState(h_Current3dData));
/* init events */
if ( _bHandleSkippedEventsIfRelevant )
{
tdstEvent * p_stEvent ;
int i ;
unsigned char ucEventCount ;
/* we force all skipped events to be replayed. */
fn_vInitAllEvents ( p_stSuperObject , 0 ) ;
/* the thing is: we don't want sound events to be played, hence we have to make them not playable this time */
p_stEvent = fn_p_GetEventsAddress( p_stCurrentAnim , 0 ,fn_h3dDataGetCurrentObjectsTable(h_Current3dData) );
if ( p_stEvent )
for
(
i = 0 ;
( i < p_stCurrentAnim -> ucNumberOfEvents )
&& ( p_stEvent -> uwFrameNumber <= fn_uw3dDataGetForcedFrame ( h_Current3dData ) ) ;
i ++ , p_stEvent ++
)
if ( GAM_fn_ucGetTypeOfEvent(p_stEvent) == C_ucSOUND_EVENT )
{
ucEventCount = GAM_fn_ucGetFirstCallOfEvent ( p_stEvent ) ;
fn_v3dDataSetEventActivationByIndex ( h_Current3dData , i , ( unsigned char ) ( ucEventCount ? ucEventCount : ( unsigned char ) 1 ) ) ;
}
}
else
{
fn_vInitAllEvents ( p_stSuperObject , fn_uw3dDataGetForcedFrame ( h_Current3dData ) ) ;
}
/* init frame rate*/
fn_v3dDataSetFrameRate(h_Current3dData,ucStateSpeed); /* MR0306*/
}
else
{
/* here, the current state has not been interrupted, and the next state is the same as the current one*/
ucStateSpeed = fn_uc3dDataGetFrameRate(h_Current3dData);
}
/* look how many frames must be skiped according to the time delay*/
if (g_bAnimConstantSpeed)
ulAddFrames = fn_uw3dDataGetCurrentFrame(h_Current3dData)+1;
else
ulAddFrames = ucStateSpeed * fn_ul3dDataGetTimeDelay(h_Current3dData) / 1000 ;
/* the next frame number must be within the right interval... (from 0 to number of frames -1)*/
ulAddFrames %= p_stCurrentAnim->uwNumberOfFrames;
/* the state has been modified*/
/* set flag if next state is different from current state*/
if (bDidChangeState)
fn_v3dDataSetStateJustModified(h_Current3dData,TRUE);
/* ??? forced frame ??? kesako*/
if(fn_uw3dDataGetForcedFrame(h_Current3dData)!=0)
{
#if defined(ANIM_DEBUG) && defined(U64)
if(fn_uw3dDataGetForcedFrame(h_Current3dData) >= p_stCurrentAnim->uwNumberOfFrames)
{
osSyncPrintf("Error : Forced frame out of range\n");
osSyncPrintf("Anim : %d, Frame : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,fn_uw3dDataGetForcedFrame(h_Current3dData));
}
#endif
#ifndef RETAIL
ENGassert(fn_uw3dDataGetForcedFrame(h_Current3dData) < p_stCurrentAnim->uwNumberOfFrames);
#endif
fn_v3dDataSetCurrentFrame(h_Current3dData,fn_uw3dDataGetForcedFrame(h_Current3dData));
fn_v3dDataSetForcedFrame(h_Current3dData,0);
}
else
{
/* not forced frame... (???)*/
/* ??? strange calcul*/
fn_v3dDataSetStartTime(h_Current3dData,fn_ul3dDataGetTimePreviousFrame(h_Current3dData) - fn_ul3dDataGetTimeDelay(h_Current3dData));
/* the current frame is the new frame number (the one computed up there)*/
fn_v3dDataSetCurrentFrame(h_Current3dData,(unsigned short)ulAddFrames);
/* ??? last frame == -1 ???*/
fn_v3dDataSetLastFrame(h_Current3dData,-1);
}
/* beginning of new (or same) state, so set the new repeat value*/
fn_v3dDataSetRepeatAnimation(h_Current3dData,p_stCurrentState->ucRepeatAnimation);
/* no more end of state now*/
fn_v3dDataSetFlagEndState(h_Current3dData,FALSE);
/* no more modif state now*/
fn_v3dDataSetFlagModifState(h_Current3dData,FALSE);
/* ???*/
fn_v3dDataSetWantedState(h_Current3dData,p_stCurrentState);
}
}
if (!bNoDisplay)
{
PLA_fn_vInitAllChildInHeapNewAnim(p_stSuperObject,p_stCurrentAnim,fn_uw3dDataGetCurrentFrame(h_Current3dData));
PLA_fn_vDoFrame(p_stCurrentAnim,fn_uw3dDataGetCurrentFrame(h_Current3dData),p_stSuperObject);
}
/*
* this flag is true when we are called from the AI by a change action procedure -> if we launch
* the events now, the anim player at the beginning of the next frame will clear them, and the AI
* will miss them as well -> do not launch them now, but next frame, when the flag is false in the
* normal game loop course.
*/
if ( ! _bHandleSkippedEventsIfRelevant )
{
/* last event played is set correctly by*/
/* - previous call to this function*/
/* - init of all events*/
/* - call to fn_vPlayLastEventsBeforeRestart() for previous loop of the same anim*/
fn_vPlayEventsSinceLastOneNoLoop( p_stSuperObject );
}
/* Takes the speed in the anim and transfers it to the mechanics*/
fn_vTransferSpeedInformationPLA_DNM(p_stSuperObject,fn_s3dDataGetLastFrame(h_Current3dData));
PLA_fn_vComputeNextFrame(p_stSuperObject);
return TRUE;
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
void PLA_fn_vComputeNextFrame(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
struct tdstState_ *p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
struct tdstAnim3d_ *p_stCurrentAnim;
unsigned long ulNextFrameNumber;
unsigned short uwNextFrameInAnim;
#ifdef D_USE_LIPSYNC
unsigned short uwFrameDifference;
#endif
if (p_stCurrentState==NULL)
return; /* not a good object !!! mettre un message d'erreur !!! ...*/
p_stCurrentAnim = p_stCurrentState->p_stAnim;
/* for instance : a camera ...*/
if (p_stCurrentAnim==NULL) return;
/* last played frame is the current one*/
fn_v3dDataSetLastFrame(h_Current3dData,fn_uw3dDataGetCurrentFrame(h_Current3dData));
/* compute next frame number*/
if (g_bAnimConstantSpeed)
{
/* constant speed --> next frame is current frame +1*/
ulNextFrameNumber = fn_uw3dDataGetCurrentFrame(h_Current3dData)+1;
}
else
{
/* not constant speed --> next frame is (current time - time of start of anim) * framerate*/
/* == (time since beginning of anim) * framerate*/
ulNextFrameNumber = fn_uc3dDataGetFrameRate(h_Current3dData)*(g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-fn_ul3dDataGetStartTime(h_Current3dData))/1000;
}
#ifdef D_USE_LIPSYNC
/* update synchro frame for lip synchro*/
uwFrameDifference = (short)(ulNextFrameNumber - fn_uw3dDataGetCurrentFrame(h_Current3dData));
fn_v3dDataSetCurrentSynchroFrame(h_Current3dData,(unsigned short)(fn_uw3dDataGetCurrentSynchroFrame(h_Current3dData)+uwFrameDifference));
#endif
/* analyse the next frame number, and compute the real next frame for this anim*/
if (ulNextFrameNumber > p_stCurrentAnim->uwNumberOfFrames)
{
/* the next frame is too big, it exceeds the total number of frames in this anim*/
if (!fn_uc3dDataGetFlagEndOfAnim(h_Current3dData))
{
/* flag end of anim not signaled*/
/* memorize the extra time :*/
/* extra time = (current time - start time) - (total number of frames / frame rate)*/
/* = total time to get to this point - anim total duration*/
fn_v3dDataSetTimeDelay(h_Current3dData, g_stEngineStructure.stEngineTimer.ulCurrentTimerCount - fn_ul3dDataGetStartTime(h_Current3dData) - (1000 * p_stCurrentAnim->uwNumberOfFrames) / fn_uc3dDataGetFrameRate(h_Current3dData));
/* the next frame will be the total number of frame, to signal that we went past the end of the anim*/
uwNextFrameInAnim = p_stCurrentAnim->uwNumberOfFrames;
}
else
{
/* flag end of anim signaled*/
/* so reset*/
uwNextFrameInAnim = 0;
fn_v3dDataSetTimeDelay(h_Current3dData,0);
fn_v3dDataSetStartTime(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount);
}
}
else
{
/* the next frame number didn't exceed the total number of frames in the anim*/
/* so there is no time delay*/
fn_v3dDataSetTimeDelay(h_Current3dData,0);
/* and the real frame number = the next frame number*/
/* Note : it is possible that next frame number == total number of frames in the anim*/
/* this will signal then that we just went past the end of the anim*/
uwNextFrameInAnim = (unsigned short)ulNextFrameNumber;
}
if ((fn_uw3dDataGetCurrentFrame(h_Current3dData) == uwNextFrameInAnim) && !fn_b3dDataGetStateJustModified(h_Current3dData)
&&(uwNextFrameInAnim != p_stCurrentAnim->uwNumberOfFrames))
{
/* if next frame is the current one, and if state was not just modified, and if we did not just pass the end of the anim, then skip next frame*/
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,TRUE);
}
/* the next frame becomes the official current frame*/
/* if the current anim has only one frame, and if the current state has not been forced, and if the next state is the same*/
/* as the current state, then skip !*/
if (p_stCurrentAnim->uwNumberOfFrames == 1 &&
!fn_b3dDataGetStateJustModified(h_Current3dData) &&
fn_hGetNextStateInState(p_stCurrentState) == p_stCurrentState)
{
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,TRUE);
fn_v3dDataSetCurrentFrame(h_Current3dData,0);
}
else
fn_v3dDataSetCurrentFrame(h_Current3dData,uwNextFrameInAnim);
/* update end of anim flag*/
fn_v3dDataSetFlagEndOfAnim(h_Current3dData, (unsigned char)(uwNextFrameInAnim == p_stCurrentAnim->uwNumberOfFrames));
/* End of State when End Of Anim & No Repeat & No Next State*/
if( fn_uc3dDataGetRepeatAnimation(h_Current3dData) == 0 &&
fn_uw3dDataGetCurrentFrame(h_Current3dData) == p_stCurrentAnim->uwNumberOfFrames &&
fn_hGetNextStateInState(p_stCurrentState) == NULL )
{
fn_v3dDataSetFlagEndState(h_Current3dData,TRUE);
}
fn_v3dDataSetStateJustModified(h_Current3dData,FALSE);
/* ????*/
fn_v3dDataSetTimePreviousFrame(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount);
}
/* ######################################################################## */
/* ############################################################################ */
/* ########################## MANAGMENT of the SUPEROBJECTS HEAP ################ */
/* ############################################################################### */
/* ############################################################################### */
/* ######### */
/* ################# */
/* ############# */
/* ######### */
/* ##### */
/* # */
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
void PLA_fn_vInitMatrixHeap(void)
{
unsigned long i;
/* matrix array has the same size as the SO array*/
#ifdef _DEBUG
for(i=0; i<__PLA_LIM_SUPOBJ_ALLOC__ + 1; i++)
{
POS_fn_vSetIdentityMatrix(&PLA_g_d_stMatrixHeap[i]);
}
#else
for(i=0; i<__PLA_NB_MAX_SUPOBJ__ + 1; i++)
{
POS_fn_vSetIdentityMatrix(&PLA_g_d_stMatrixHeap[i]);
}
#endif
}
void PLA_fn_vCreateMatrixHeap(void)
{
/* matrix array has the same size as the SO array*/
MMG_fn_vAddMemoryInfo(MMG_C_lTypeGAM, MMG_C_lSubTypePlayer, 0);
#ifdef _DEBUG
/* the '+1' is for the matrix associated to the emergency SO*/
//XB 08/04/99
//PLA_g_d_stMatrixHeap = ( GEO_tdxHandleToMatrix) TMP_M_p_Malloc(sizeof(POS_tdstCompletePosition) * (__PLA_LIM_SUPOBJ_ALLOC__ + 1));
GEO_M_CPAMalloc(PLA_g_d_stMatrixHeap,GEO_tdxHandleToMatrix,sizeof(POS_tdstCompletePosition)*(__PLA_LIM_SUPOBJ_ALLOC__+1),E_uwGEONotEnoughtMemory);
//End XB 08/04/99
#else
/* the '+1' is for the matrix associated to the emergency SO*/
//XB 08/04/99
//PLA_g_d_stMatrixHeap = ( GEO_tdxHandleToMatrix) TMP_M_p_Malloc(sizeof(POS_tdstCompletePosition) * (__PLA_NB_MAX_SUPOBJ__ + 1));
GEO_M_CPAMalloc(PLA_g_d_stMatrixHeap,GEO_tdxHandleToMatrix,sizeof(POS_tdstCompletePosition)*(__PLA_NB_MAX_SUPOBJ__+1),E_uwGEONotEnoughtMemory);
//End XB 08/04/99
#endif
}
void PLA_fn_vInitSupObjHeap(void)
{
GEO_tdxHandleToMatrix p_stMatrix;
HIE_tdxHandleToSuperObject p_stSO, p_stSOStop;
/*unsigned long i;*/
/* initialise state array for heap, and */
/* make SO local matrix point to the right matrix in the matrix array*/
p_stMatrix = PLA_g_d_stMatrixHeap;
p_stSO = PLA_g_d_stSupObjHeap;
p_stSOStop = p_stSO + __PLA_LIM_SUPOBJ_ALLOC__ +1;
#ifdef _DEBUG
memset(PLA_g_a_wStateOfSupObjHeap, 0, sizeof(short) * __PLA_LIM_SUPOBJ_ALLOC__);
p_stSOStop = p_stSO + __PLA_LIM_SUPOBJ_ALLOC__ +1;
while (p_stSO != p_stSOStop)
{
p_stSO->hLocalMatrix = p_stMatrix;
p_stMatrix++;
p_stSO++;
}
#else
memset(PLA_g_a_wStateOfSupObjHeap, 0, sizeof(short) * __PLA_NB_MAX_SUPOBJ__);
p_stSOStop = p_stSO + __PLA_NB_MAX_SUPOBJ__ +1;
while (p_stSO != p_stSOStop)
{
p_stSO->hLocalMatrix = p_stMatrix;
p_stMatrix++;
p_stSO++;
}
#endif
PLA_g_ulCurrentPosInSupObjHeap = 0L;
PLA_g_ulNbAllocInSupObjHeap = 0L;
}
void PLA_fn_vCreateSupObjHeap(void)
{
#ifdef _DEBUG
PLA_g_d_stSupObjHeap = HIE_fn_p_stCreateSuperObjectTab(__PLA_LIM_SUPOBJ_ALLOC__ + 1); /* + 1 is for the emergency SO*/
#else
PLA_g_d_stSupObjHeap = HIE_fn_p_stCreateSuperObjectTab(__PLA_NB_MAX_SUPOBJ__ + 1); /* + 1 is for the emergency SO*/
#endif
g_Randomhandle = 0;
}
void PLA_fn_vInitHeaps(void)
{
PLA_fn_vInitMatrixHeap();
PLA_fn_vInitSupObjHeap();
}
void PLA_fn_vCreateAndInitHeaps(void)
{
/* always init SO heap after matrix heap*/
PLA_fn_vCreateMatrixHeap();
PLA_fn_vCreateSupObjHeap();
PLA_fn_vInitMatrixHeap();
PLA_fn_vInitSupObjHeap();
PLA_g_ulMaxOccupationOfSupObjHeap = 0L;
PLA_g_ulMaxOccupationOfChannels = 0L;
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
HIE_tdxHandleToSuperObject PLA_fn_hFindNextFreeSupObj(void)
{
HIE_tdxHandleToSuperObject p_stSO_Child;
/* one more SO allocated*/
PLA_g_ulNbAllocInSupObjHeap ++;
/* check if there is some room left*/
/* _______________________ DEBUG CASE _____________________________________ */
#ifdef _DEBUG
if (PLA_g_ulNbAllocInSupObjHeap >= __PLA_LIM_SUPOBJ_ALLOC__)
{
/* not enough memory, so return the emergency SO*/
p_stSO_Child = HIE_fn_hGetElementFromSuperObjectTab(PLA_g_d_stSupObjHeap,__PLA_LIM_SUPOBJ_ALLOC__);
}
else
{
while( PLA_g_a_wStateOfSupObjHeap[PLA_g_ulCurrentPosInSupObjHeap] )
{
PLA_g_ulCurrentPosInSupObjHeap ++;
if (PLA_g_ulCurrentPosInSupObjHeap == __PLA_LIM_SUPOBJ_ALLOC__)
PLA_g_ulCurrentPosInSupObjHeap = 0L;
}
/* _______________________ RELEASE CASE _____________________________________ */
#else
if (PLA_g_ulNbAllocInSupObjHeap >= __PLA_NB_MAX_SUPOBJ__)
{
/* not enough memory, so return the emergency SO*/
p_stSO_Child = HIE_fn_hGetElementFromSuperObjectTab(PLA_g_d_stSupObjHeap,__PLA_NB_MAX_SUPOBJ__);
}
else
{
while( PLA_g_a_wStateOfSupObjHeap[PLA_g_ulCurrentPosInSupObjHeap] )
{
PLA_g_ulCurrentPosInSupObjHeap ++;
if (PLA_g_ulCurrentPosInSupObjHeap == __PLA_NB_MAX_SUPOBJ__)
PLA_g_ulCurrentPosInSupObjHeap = 0L;
}
#endif
/* _______________________ END _____________________________________ */
/* get the new superobject*/
PLA_g_a_wStateOfSupObjHeap[PLA_g_ulCurrentPosInSupObjHeap] = 1;
p_stSO_Child = HIE_fn_hGetElementFromSuperObjectTab(PLA_g_d_stSupObjHeap,PLA_g_ulCurrentPosInSupObjHeap);
}
/*enable all display properties*/
HIE_fn_vSetSuperObjectDrawMask(p_stSO_Child,GLI_C_lAllIsEnable);
HIE_fn_SO_vSetFlags(p_stSO_Child,0);
/* compute new max*/
if (PLA_g_ulMaxOccupationOfSupObjHeap < PLA_g_ulNbAllocInSupObjHeap)
PLA_g_ulMaxOccupationOfSupObjHeap++;
/* update rasters vars*/
PRF_fn_vSetIndependantVariable(PRF_C_ulIdpNbAllocSPO,PLA_g_ulNbAllocInSupObjHeap);
PRF_fn_vSetIndependantVariable(PRF_C_ulIdpNbMaxAllocSPO,PLA_g_ulMaxOccupationOfSupObjHeap);
/* reset Father link & linked object*/
HIE_M_vIsolate(p_stSO_Child);
HIE_fn_vSetSuperObjectObjectAndType(p_stSO_Child,NULL,HIE_C_ulSuperObject);
/* return the handle to the reserved superobject*/
return p_stSO_Child;
}
void PLA_fn_vReleaseSuperObjectInHeap(HIE_tdxHandleToSuperObject _hSupObj)
{
long lPos;
/* _______________________ DEBUG CASE _____________________________________ */
#ifdef _DEBUG
/* check if the given SO is not the emergency SO*/
if (_hSupObj != HIE_fn_hGetElementFromSuperObjectTab(PLA_g_d_stSupObjHeap,__PLA_LIM_SUPOBJ_ALLOC__))
{
lPos = HIE_fn_hGetIndexFromSuperObjectTabAndElement(PLA_g_d_stSupObjHeap, _hSupObj);
assert(lPos >= 0 && lPos < __PLA_LIM_SUPOBJ_ALLOC__ && PLA_g_a_wStateOfSupObjHeap[lPos] != 0) ;
PLA_g_a_wStateOfSupObjHeap[lPos] = 0;
}
/* _______________________ RELEASE CASE _____________________________________ */
#else
/* check if the given SO is not the emergency SO*/
if (_hSupObj != HIE_fn_hGetElementFromSuperObjectTab(PLA_g_d_stSupObjHeap,__PLA_NB_MAX_SUPOBJ__))
{
lPos = HIE_fn_hGetIndexFromSuperObjectTabAndElement(PLA_g_d_stSupObjHeap, _hSupObj);
assert(lPos >= 0 && lPos < __PLA_LIM_SUPOBJ_ALLOC__ && PLA_g_a_wStateOfSupObjHeap[lPos] != 0);
PLA_g_a_wStateOfSupObjHeap[lPos] = 0;
}
#endif
/* _______________________ END _____________________________________ */
PLA_g_ulNbAllocInSupObjHeap--;
/* update rasters vars*/
PRF_fn_vSetIndependantVariable(PRF_C_ulIdpNbAllocSPO,PLA_g_ulNbAllocInSupObjHeap);
}
#ifdef ACTIVE_EDITOR
void PLA_fn_vUpdateFrameCounterForModules(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData;
tdstAChannel *p_stChannel;
h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
p_stChannel = fn_h3dDataGetFirstActiveChannel(h_Current3dData);
while (p_stChannel)
{
/* update only if it was valid before !*/
if (p_stChannel->hSupObject->llastComputeFrameForModule >= HIE_gs_lCurrentFrame-1)
{
p_stChannel->hSupObject->llastComputeFrameForModule = HIE_gs_lCurrentFrame;
}
p_stChannel = p_stChannel->p_stNextActiveChannel;
}
}
#endif
/* called when the actor's transparency changed */
void PLA_fn_vUpdateTransparencyForModules(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData;
tdstAChannel *p_stChannel;
HIE_tdxHandleToSuperObject p_stTargetSO;
float fTransparence = HIE_fn_fGetSuperObjectTransparenceLevel(p_stSuperObject);
register ACP_tdxBool bPersoTransparencyActive = (ACP_tdxBool) ((HIE_fn_lGetSuperObjectDrawMask(p_stSuperObject)&GLI_C_lIsNotGrided) == GLI_C_lIsNotGrided);
h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
p_stChannel = fn_h3dDataGetFirstActiveChannel(h_Current3dData);
while (p_stChannel)
{
/* get the channel and its target SO*/
p_stTargetSO = p_stChannel->hSupObject;
/* Module transparency isn't setting in IA*/
if ((HIE_fn_SO_ulGetFlags(p_stTargetSO) & HIE_C_Flag_ModuleTransparency) != HIE_C_Flag_ModuleTransparency )
{
HIE_fn_vSetSuperObjectTransparenceLevel(p_stTargetSO,fTransparence);
/* NO charcter transparency*/
if ( bPersoTransparencyActive )
{
/* no anim transparency for that module*/
HIE_fn_vSetSuperObjectDrawMask(p_stTargetSO, HIE_fn_lGetSuperObjectDrawMask(p_stTargetSO) | GLI_C_lIsNotGrided );
}
}
p_stChannel = p_stChannel->p_stNextActiveChannel;
}
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
void PLA_fn_vInitAllChildInHeapNewAnim( HIE_tdxHandleToSuperObject p_stSuperObject
, struct tdstAnim3d_ *p_stCurrentAnim,
unsigned short _uwFrameNumber)
{
MS_tdxHandleTo3dData h_Current3dData;
struct tdstFrame3d_ *p_stCurrentFrame3d;
struct tdstElement3d_ *p_stElt3d;
struct tdstElement3d_ *p_stStopElt3d;
register tdstAChannel *p_stNewChannel;
unsigned long ulNextChannelNumber;
tdstCouple *p_stNewCouples, *p_stOldCouples;
CHN_tdxHandleToChannelArray hChannelArray;
register tdstAChannel *p_stLastFrameChannel;
register tdstAChannel *p_stLastFrameChannelForLink;
BOOL bHieChanged;
h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
hChannelArray = fn_h3dDataGetChannelSOList(h_Current3dData);
p_stCurrentFrame3d = fn_p_st3dDataGetCurrentFrame(h_Current3dData);
/* get the old hierarchy couples*/
#ifndef U64
p_stOldCouples = fn_p_st3dDataGetCurrentHieCouples(h_Current3dData);
#else
p_stOldCouples = p_stCurrentFrame3d->stHierarchy.d_stCouples;
#endif
fn_vUpdateFrame(p_stSuperObject,p_stCurrentFrame3d,p_stCurrentAnim,_uwFrameNumber);
p_stElt3d = p_stCurrentFrame3d->p_stArrayOfElts3d;
p_stNewCouples = p_stCurrentFrame3d->stHierarchy.d_stCouples;
if (hChannelArray == NULL)
{
/* create array of channels !!*/
fn_vInitCSOList(&hChannelArray,fn_ul3dDataGetNumberOfChannels(h_Current3dData));
fn_v3dDataSetChannelSOList(h_Current3dData,hChannelArray);
/* set the first active channel to NULL because new activation !*/
fn_v3dDataSetFirstActiveChannel(h_Current3dData, NULL);
}
/* check if hierarhy changed for this frame...*/
/* hie changed if couple array are different*/
if (p_stOldCouples != p_stNewCouples)
{
register unsigned long i;
#ifdef U64
tdstCouple* p_stBackupOldCouples=p_stOldCouples;
/* osSyncPrintf("New hierarchy for anim %d! (%x)\n",p_stCurrentAnim->uwNumOfA3dGENERAL,p_stNewCouples);*/
#endif /*U64*/
/* hierarchy changed !!*/
/* so apply changes on the channels !*/
bHieChanged = TRUE;
/* first, 'isolate' old channels if necessary*/
if (p_stOldCouples)
{
/* ok, there was an old hierarchy*/
i = fn_ul3dDataGetCurrentHieNbCouples(h_Current3dData);
while (i--)
{
/* isolate the channel*/
hChannelArray[p_stOldCouples->wChild].p_stFatherChannel = NULL;
/* next one !*/
p_stOldCouples++;
}
}
/* then, set up the new hierarchy*/
i = p_stCurrentFrame3d->stHierarchy.ulNbOfCouples;
/* register the new hierarchy in the 3ddata*/
fn_v3dDataSetCurrentHieCouples(h_Current3dData,p_stNewCouples);
fn_v3dDataSetCurrentHieNbCouples(h_Current3dData,i);
while (i--)
{
/* set up the channel link*/
hChannelArray[p_stNewCouples->wChild].p_stFatherChannel = hChannelArray + p_stNewCouples->wFather;
/* next one !*/
p_stNewCouples++;
}
#ifdef U64
/*AR9902 Free old hierarchy*/
if (p_stBackupOldCouples)
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeInterpol , MMG_C_lSubTypeHierarchies , 0 );
TMP_M_Free(p_stBackupOldCouples);
}
#endif
}
else
{
bHieChanged = FALSE;
}
/* set the stop adress for elt3d loop*/
p_stStopElt3d = p_stElt3d + p_stCurrentAnim->ucMaxNumberOfElements;
/* get adress of next channel for this new frame*/
if (p_stElt3d == p_stStopElt3d)
{
/* strange, new frame elt3d array is empty...*/
p_stNewChannel = NULL;
}
else
{
ulNextChannelNumber = p_stElt3d->ucChannelNumber;
p_stNewChannel = (ulNextChannelNumber == C_ucUnknownChannel) ? NULL : hChannelArray + ulNextChannelNumber;
}
/* loop init for last frame channel array*/
p_stLastFrameChannel = fn_h3dDataGetFirstActiveChannel(h_Current3dData);
p_stLastFrameChannelForLink = NULL;
/* paralel loop ...*/
/* stop when both pointers reach the end...*/
while (p_stNewChannel || p_stLastFrameChannel)
{
if (p_stNewChannel == p_stLastFrameChannel)
{
/* here, both p_stLastFrameChannel and p_stNewChannel are not NULL*/
/* and we have p_stLastFrameChannel == p_stNewChannel*/
/* so the channel for the next frame was already used for the last frame*/
if (bHieChanged)
{
/* hierarchy changed, so update it !*/
/* isolate old superobject --- not necessary because addtail will do it !*/
/* LST2_M_DynamicIsolate(p_stLastFrameChannel->hSupObject);*/
/* and put it back at its right place*/
if (p_stLastFrameChannel->p_stFatherChannel)
{
/* this channel has another channel for father*/
/* check if this other channel's SO already exists !*/
if (p_stLastFrameChannel->p_stFatherChannel->hSupObject == NULL)
{
/*create it !*/
#if defined(ANIM_DEBUG) && defined(U64)
if(p_stLastFrameChannel->p_stFatherChannel <= p_stLastFrameChannel)
{
osSyncPrintf("Error : p_stLastFrameChannel->p_stFatherChannel > p_stLastFrameChannel\n");
osSyncPrintf("Anim : %d, Frame : %d, Channel : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,_uwFrameNumber,p_stElt3d->ucChannelNumber);
}
#endif
#ifndef RETAIL
ENGassert(p_stLastFrameChannel->p_stFatherChannel > p_stLastFrameChannel);
#endif
p_stLastFrameChannel->p_stFatherChannel->hSupObject = PLA_fn_hFindNextFreeSupObj();
}
HIE_fn_vSuperObjectAddTail(p_stLastFrameChannel->p_stFatherChannel->hSupObject,p_stLastFrameChannel->hSupObject);
}
else
{
HIE_fn_vSuperObjectAddTail(p_stSuperObject,p_stLastFrameChannel->hSupObject);
}
}
/* no need to update link...*/
/* advance to next step, that is advance in both arrays*/
/* link*/
p_stLastFrameChannelForLink = p_stLastFrameChannel;
/* first array*/
/* check if previous frame active channel links are sorted*/
#if defined(ANIM_DEBUG) && defined(U64)
if(!(p_stLastFrameChannel->p_stNextActiveChannel == NULL || p_stLastFrameChannel->p_stNextActiveChannel > p_stLastFrameChannel))
{
osSyncPrintf("Error : sort problem\n");
osSyncPrintf("Anim : %d, Frame : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,_uwFrameNumber);
}
#endif
#ifndef RETAIL
ENGassert(p_stLastFrameChannel->p_stNextActiveChannel == NULL || p_stLastFrameChannel->p_stNextActiveChannel > p_stLastFrameChannel);
#endif
p_stLastFrameChannel = p_stLastFrameChannel->p_stNextActiveChannel;
/* second array*/
p_stElt3d++;
/* get adress of next channel for this new frame*/
if (p_stElt3d == p_stStopElt3d)
{
/* reached the end of second array*/
p_stNewChannel = NULL;
}
else
{
/* check if next frame channels are sorted*/
#if defined(ANIM_DEBUG) && defined(U64)
if(!(p_stElt3d->ucChannelNumber == C_ucUnknownChannel || p_stElt3d->ucChannelNumber > ulNextChannelNumber))
{
osSyncPrintf("Error : sort problem\n");
osSyncPrintf("Anim : %d, Frame : %d, Channel : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,_uwFrameNumber,p_stElt3d->ucChannelNumber);
}
#endif
#ifndef RETAIL
ENGassert(p_stElt3d->ucChannelNumber == C_ucUnknownChannel || p_stElt3d->ucChannelNumber > ulNextChannelNumber);
#endif
ulNextChannelNumber = p_stElt3d->ucChannelNumber;
p_stNewChannel = (ulNextChannelNumber == C_ucUnknownChannel) ? NULL : hChannelArray + ulNextChannelNumber;
}
}
else if (p_stLastFrameChannel == NULL || (p_stNewChannel != NULL && p_stLastFrameChannel > p_stNewChannel))
{
/* there is a new active channel in the new frame...*/
/* allocate a new superObject (if not already done)*/
/* if the new SO already exists, it means that this channel is the father*/
/* of another channel of lower number*/
if (p_stNewChannel->hSupObject == NULL)
{
p_stNewChannel->hSupObject = PLA_fn_hFindNextFreeSupObj();
}
/* put this new supobject at its right place !*/
if (p_stNewChannel->p_stFatherChannel)
{
/* check if the father's SO already exists !*/
if (p_stNewChannel->p_stFatherChannel->hSupObject == NULL)
{
/* it does not exist, so create it !*/
#ifndef RETAIL
ENGassert(p_stNewChannel->p_stFatherChannel > p_stNewChannel);
#endif
p_stNewChannel->p_stFatherChannel->hSupObject = PLA_fn_hFindNextFreeSupObj();
}
HIE_fn_vSuperObjectAddTail(p_stNewChannel->p_stFatherChannel->hSupObject,p_stNewChannel->hSupObject);
}
else
{
HIE_fn_vSuperObjectAddTail(p_stSuperObject,p_stNewChannel->hSupObject);
}
/* set this new SO anim matrix*/
/* HIE_fn_vSetSuperObjectMatrix(p_stNewChannel->hSupObject,&p_stNewChannel->stAnimMatrix);*/
/* update link of previous channel*/
if (p_stLastFrameChannelForLink)
{
/* there was a previous active channel !!*/
/* new channel has been inserted !!*/
/* update link of new channel*/
p_stNewChannel->p_stNextActiveChannel = p_stLastFrameChannelForLink->p_stNextActiveChannel;
/* and update link of previous channel*/
p_stLastFrameChannelForLink->p_stNextActiveChannel = p_stNewChannel;
}
else
{
/* there is no previous active channel, so this new channel is the first one...*/
/* new channel's next active channel is the first active channel*/
p_stNewChannel->p_stNextActiveChannel = fn_h3dDataGetFirstActiveChannel(h_Current3dData);
/* set as the first active in the 3ddata*/
fn_v3dDataSetFirstActiveChannel(h_Current3dData, p_stNewChannel);
}
/* and now, go to next step... that is advance one in the next frame array*/
/* last channel for link is the new one that has been inserted*/
p_stLastFrameChannelForLink = p_stNewChannel;
/* advance in second array*/
p_stElt3d++;
/* get adress of next channel for this new frame*/
if (p_stElt3d == p_stStopElt3d)
{
/* reached the end of second array*/
p_stNewChannel = NULL;
}
else
{
/* check if next frame channels are sorted*/
#if defined(ANIM_DEBUG) && defined(U64)
if(!(p_stElt3d->ucChannelNumber == C_ucUnknownChannel || p_stElt3d->ucChannelNumber > ulNextChannelNumber))
{
if(p_stElt3d->ucChannelNumber == C_ucUnknownChannel)
osSyncPrintf("Unknown channel\n");
else
osSyncPrintf("Error channel bad sorted\n");
osSyncPrintf("Anim : %d, Frame : %d, Channel : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,_uwFrameNumber,p_stElt3d->ucChannelNumber);
}
#endif
#ifndef RETAIL
ENGassert(p_stElt3d->ucChannelNumber == C_ucUnknownChannel || p_stElt3d->ucChannelNumber > ulNextChannelNumber);
#endif
ulNextChannelNumber = p_stElt3d->ucChannelNumber;
p_stNewChannel = (ulNextChannelNumber == C_ucUnknownChannel) ? NULL : hChannelArray + ulNextChannelNumber;
}
}
/* the case p_stLastFrameChannel == NULL will never happen here...*/
/* because it is treated in previous if... so I removed it !*/
else if (p_stNewChannel == NULL || p_stLastFrameChannel < p_stNewChannel)
{
/* there is a channel that is active in previous frame, and that is not*/
/* active any more in next frame...*/
/* so let's disactive it !*/
if (p_stLastFrameChannel->hZoomSupObject)
{
/* it was a zoomed channel, so destroy its zoom matrix*/
/* PLA_fn_vReleaseMatrixInHeap(HIE_fn_hGetSuperObjectMatrix(p_stLastFrameChannel->hZoomSupObject));*/
/* destroy the zoom SO*/
LST2_M_DynamicIsolate(p_stLastFrameChannel->hZoomSupObject);
PLA_fn_vReleaseSuperObjectInHeap(p_stLastFrameChannel->hZoomSupObject);
p_stLastFrameChannel->hZoomSupObject = NULL;
}
/* Add on: kill all father-sons links*/
/* ???*/
/* {
HIE_tdxHandleToSuperObject hChild;
ACP_tdxIndex xChildIndex;
HIE_M_ForEachChildOf(p_stLastFrameChannel->hSupObject,hChild,xChildIndex)
{
if(HIE_fn_ulGetSuperObjectType(hChild) == C_ucCharacter )
{
fn_vReputCharacterSuperObjectAtTheWorld(hChild);
}
}
}
*/ /* then detroy the channel SO*/
LST2_M_DynamicIsolate(p_stLastFrameChannel->hSupObject);
PLA_fn_vReleaseSuperObjectInHeap(p_stLastFrameChannel->hSupObject);
p_stLastFrameChannel->hSupObject = NULL;
/* now update the links*/
if (p_stLastFrameChannelForLink)
{
/* there was a previous active channel !*/
/* so (previous active channel's next active channel) is the (destroyed channel's next active channel) (it is clear !!)*/
p_stLastFrameChannelForLink->p_stNextActiveChannel = p_stLastFrameChannel->p_stNextActiveChannel;
}
else
{
/* there was no previous active channel, so we disactivated the first channel !*/
fn_v3dDataSetFirstActiveChannel(h_Current3dData, p_stLastFrameChannel->p_stNextActiveChannel);
}
/* and now, go to next step... that is advance one in the last frame channel array*/
/* check if previous frame active channel links are sorted*/
#if defined(ANIM_DEBUG) && defined(U64)
if((p_stLastFrameChannel->p_stNextActiveChannel != NULL) && (p_stLastFrameChannel->p_stNextActiveChannel <= p_stLastFrameChannel))
{
osSyncPrintf("Error channel bad sorted\n");
osSyncPrintf("Anim : %d, Frame : %d\n",p_stCurrentAnim->uwNumOfA3dGENERAL,_uwFrameNumber);
}
#endif
#ifndef RETAIL
ENGassert(p_stLastFrameChannel->p_stNextActiveChannel == NULL || p_stLastFrameChannel->p_stNextActiveChannel > p_stLastFrameChannel);
#endif
p_stLastFrameChannel = p_stLastFrameChannel->p_stNextActiveChannel;
}
}
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/* Modif : 22/04/98 Stop morphing before freeing an element - Carlos Torres*/
/* Modif : 15/05/98 Release Matrix for custom zoom channels - Carlos Torres*/
void PLA_fn_vDesInitAllChildOfCharacter(HIE_tdxHandleToSuperObject p_stSuperObject, struct tdstEngineObject_ *p_stObject)
{
MS_tdxHandleTo3dData h_Current3dData;
tdstAChannel *p_stChannel;
tdstAnim3d *p_stCurrentAnim = NULL;
CHN_tdxHandleToChannelArray hArray;
#ifdef U64
tdstCouple *p_stCouples;
struct tdstFrame3d_* p_stCurrentFrame3d;
#endif
if (p_stObject == NULL)
return;
h_Current3dData = p_stObject->h_3dData;
if (fn_h3dDataGetCurrentState(h_Current3dData))
p_stCurrentAnim = fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim;
p_stChannel = fn_h3dDataGetFirstActiveChannel(h_Current3dData);
hArray = fn_h3dDataGetChannelSOList(h_Current3dData);
if (hArray)
{
while (p_stChannel)
{
/* For Morphing Anim and channel morphed --> stop morphing*/
if(p_stSuperObject && p_stCurrentAnim && p_stCurrentAnim->d_stMorphDataArray)
MOR_fn_xStopMorph(p_stSuperObject,(short)(p_stChannel - hArray));
/* release matrix and hierarchy for symetric module*/
if (p_stChannel->hZoomSupObject)
{
/* release zoom matrix*/
/* PLA_fn_vReleaseMatrixInHeap(HIE_fn_hGetSuperObjectMatrix(p_stChannel->hZoomSupObject));*/
/* isolate zoom SO*/
LST2_M_DynamicIsolate(p_stChannel->hZoomSupObject);
/* release zoom SO*/
PLA_fn_vReleaseSuperObjectInHeap(p_stChannel->hZoomSupObject);
p_stChannel->hZoomSupObject = NULL;
}
/* release normal module...*/
if(p_stChannel->hSupObject) /*AR9901*/
{
LST2_M_DynamicIsolate(p_stChannel->hSupObject);
PLA_fn_vReleaseSuperObjectInHeap(p_stChannel->hSupObject);
p_stChannel->hSupObject = NULL;
}
p_stChannel = p_stChannel->p_stNextActiveChannel;
}
}
/* JO 09/01/98*/
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,FALSE);
/* stop playing events and desinit*/
if (p_stSuperObject)
fn_vDesInitAllEvents(p_stSuperObject,NULL,TRUE);
/* delete the channels array !*/
fn_vFreeCSOList(&hArray);
fn_v3dDataSetChannelSOList(h_Current3dData,NULL);
fn_v3dDataSetFirstActiveChannel(h_Current3dData,NULL);
fn_vFreeArrayOfElts3d (h_Current3dData);
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAnim = NULL;
#ifndef U64
if (fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAngularSpeedMatrix)
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeInterpol , MMG_C_lSubTypeSpeedMatrix , 0 );
TMP_M_Free(fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAngularSpeedMatrix);
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAngularSpeedMatrix = NULL;
}
#endif /*U64*/
#ifdef U64
p_stCouples=fn_p_st3dDataGetCurrentHieCouples(h_Current3dData);
if(p_stCouples!=NULL)
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeInterpol , MMG_C_lSubTypeHierarchies , 0 );
TMP_M_Free(p_stCouples);
}
p_stCurrentFrame3d = fn_p_st3dDataGetCurrentFrame(h_Current3dData);
p_stCurrentFrame3d->stHierarchy.d_stCouples=NULL;
#endif /*U64*/
fn_v3dDataSetCurrentHieCouples(h_Current3dData,NULL);
fn_v3dDataSetCurrentHieNbCouples(h_Current3dData,0);
fn_v3dDataSetFlagModifState(h_Current3dData,TRUE);
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,FALSE);
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
void PLA_fn_vRefreshGlobalMatrixUnderCharacter(HIE_tdxHandleToSuperObject _hSprObj)
{
long i;
HIE_tdxHandleToSuperObject hChild;
/* ANNECY MT - 06/10/98 {*/
if(fn_ulStandardGameGetCustomBitsSO(_hSprObj) & GAM_C_CustBitNeedModuleMatrices)
{
HIE_M_ForEachChildOf(_hSprObj, hChild, i)
PLA_fn_vRefreshGlobalMatrixOfAnimsHierarchy(hChild);
}
/* END ANNECY MT }*/
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
void PLA_fn_vRefreshGlobalMatrixOfAnimsHierarchy(HIE_tdxHandleToSuperObject _hSprObj)
{
long i;
register long lType;
HIE_tdxHandleToSuperObject hChild;
lType = HIE_fn_ulGetSuperObjectType(_hSprObj);
if(lType & (HIE_C_ulSuperObject | HIE_C_ulPO | HIE_C_ulPO_Mirror ))
{
POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj),HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(_hSprObj)),HIE_fn_hGetSuperObjectMatrix(_hSprObj));
#ifdef ACTIVE_EDITOR
_hSprObj->llastComputeFrameForModule = HIE_gs_lCurrentFrame;
#endif
}
else return;
HIE_M_ForEachChildOf(_hSprObj, hChild, i)
PLA_fn_vRefreshGlobalMatrixOfAnimsHierarchy(hChild);
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/* ######################################################################## */
/* ############################################################################ */
/* ########################## MANAGMENT of Anim's Datas ######################### */
/* ############################################################################### */
/* ############################################################################### */
/* ######### */
/* ################# */
/* ############# */
/* ######### */
/* ##### */
/* # */
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/* Set New State*/
/*ANNECY CT 11/02/98{*/
/* Modif 26/03/98 CT Reinit flag end of anim*/
/* Modif 15/05/98 CT Stop morphing of the current anim*/
/* Modif 29/09/98 BNT can force the change if required*/
ACP_tdxBool PLA_fn_bSetNewState(HIE_tdxHandleToSuperObject p_stSuperObject,tdxHandleToState h_WantedState, ACP_tdxBool _bForce , ACP_tdxBool _bHandleSkippedEventsIfRelevant )
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
tdxHandleToState h_ResultState;
tdxHandleToTransition h_Transition;
/*fn_v3dDataSetNbEngineFrameSinceLastMechEvent(h_Current3dData,LME_INVALID);*/
if( (h_WantedState == fn_h3dDataGetFirstStateOfAction(h_Current3dData)) && !_bForce )
return(TRUE);
h_Transition = fn_hIfExistTransitionalWithTargetState(fn_h3dDataGetWantedState(h_Current3dData),h_WantedState);
#ifdef _DEBUG
if (h_Transition && !fn_hGetStateToGoInTransition(h_Transition)->p_stAnim) {
ENGassert(0);
h_Transition = NULL;
}
#endif
if(h_Transition==NULL)
{
if(fn_hIfExistProhibitedState(fn_h3dDataGetWantedState(h_Current3dData),h_WantedState)) return(FALSE);
if(fn_h3dDataGetWantedState(h_Current3dData)->ucTransitionStatusFlag == C_ucProhibitedState) return(FALSE);
else h_ResultState = h_WantedState;
}
else h_ResultState = fn_hGetStateToGoInTransition(h_Transition);
/* stop morphing before changing state and animation*/
PLA_fn_vStopCurrentMorphAnim(p_stSuperObject);
if( h_Transition && (fn_ucGetLinkingTypeInTransition(h_Transition) == C_ucProportionalLink))
{
unsigned long ulForcedFrame,ulNewStartTime;
/* compute the proportional frame*/
ulForcedFrame = fn_uw3dDataGetCurrentFrame(h_Current3dData);
ulForcedFrame *= h_ResultState->p_stAnim->uwNumberOfFrames;
ulForcedFrame /= fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim->uwNumberOfFrames;
if(ulForcedFrame>=h_ResultState->p_stAnim->uwNumberOfFrames)
ulForcedFrame=h_ResultState->p_stAnim->uwNumberOfFrames-1;
/* set fictive anim start time*/
ulNewStartTime = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-fn_ul3dDataGetStartTime(h_Current3dData);
ulNewStartTime *= h_ResultState->p_stAnim->uwNumberOfFrames;
ulNewStartTime /= fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim->uwNumberOfFrames;
ulNewStartTime = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount - ulNewStartTime;
fn_v3dDataSetStartTime(h_Current3dData,ulNewStartTime);
/* force the frame*/
fn_v3dDataSetForcedFrame(h_Current3dData,(unsigned short)ulForcedFrame);
fn_v3dDataSetLastFrame(h_Current3dData,(unsigned short)ulForcedFrame);
/* set fictive time for previous frame*/
fn_v3dDataSetTimePreviousFrame(h_Current3dData,
fn_ul3dDataGetStartTime(h_Current3dData)+ulForcedFrame*1000/fn_scGetSpeedInState(h_ResultState));
/* next frame must not be skipped !! */
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,FALSE);
}
else
{
fn_v3dDataSetTimeDelay(h_Current3dData,0);
fn_v3dDataSetCurrentFrame(h_Current3dData,0);
fn_v3dDataSetTimePreviousFrame(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount);
/* next frame must not be skipped !! */
fn_v3dDataSetSkipCurrentFrame(h_Current3dData,FALSE);
}
/* MR1906*/
fn_v3dDataSetNbEngineFrameSinceLastMechEvent(h_Current3dData,LME_INVALID);
fn_v3dDataSetStateInLastFrame(h_Current3dData,fn_h3dDataGetCurrentState(h_Current3dData));
fn_v3dDataSetWantedState(h_Current3dData,h_ResultState);
fn_v3dDataSetFirstStateOfAction(h_Current3dData,h_WantedState);
fn_v3dDataSetFlagModifState(h_Current3dData,TRUE);
/* reinit flag end of anim*/
fn_v3dDataSetFlagEndOfAnim(h_Current3dData,(unsigned char)
(fn_uw3dDataGetForcedFrame(h_Current3dData) == h_ResultState->p_stAnim->uwNumberOfFrames));
PLA_fn_bDoAnimPlayerForCharacter(p_stSuperObject , FALSE , _bHandleSkippedEventsIfRelevant);
return TRUE;
}
/*ENDANNECY CT}*/
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
ACP_tdxBool PLA_fn_bSetNewStateWithRandom(HIE_tdxHandleToSuperObject p_stSuperObject,tdxHandleToState h_WantedState)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
tdxHandleToState h_ResultState = NULL;
struct tdstAnim3d_ *p_stNextAnim;
unsigned short uwFrameNumber;
tdxHandleToTransition h_Transition;
if(h_WantedState==fn_h3dDataGetFirstStateOfAction(h_Current3dData)) return(TRUE);
h_Transition = fn_hIfExistTransitionalWithTargetState(fn_h3dDataGetWantedState(h_Current3dData),h_WantedState);
if(h_ResultState==NULL) {
if(fn_hIfExistProhibitedState(fn_h3dDataGetWantedState(h_Current3dData),h_WantedState)) return(FALSE);
if(fn_h3dDataGetWantedState(h_Current3dData)->ucTransitionStatusFlag == C_ucProhibitedState) return(FALSE);
else h_ResultState = h_WantedState;
}
else h_ResultState = fn_hGetStateToGoInTransition(h_Transition);
/* MR1906*/
fn_v3dDataSetNbEngineFrameSinceLastMechEvent(h_Current3dData,LME_INVALID);
/* MR1709*/
fn_v3dDataSetStartTime(h_Current3dData,0);
fn_v3dDataSetStateInLastFrame(h_Current3dData,fn_h3dDataGetCurrentState(h_Current3dData));
fn_v3dDataSetWantedState(h_Current3dData,h_ResultState);
fn_v3dDataSetFirstStateOfAction(h_Current3dData,h_WantedState);
fn_v3dDataSetFlagModifState(h_Current3dData,TRUE);
p_stNextAnim = fn_h3dDataGetWantedState(h_Current3dData)->p_stAnim;
uwFrameNumber = (unsigned char)RND_fn_ulGetUnsignedLongRandomValue(g_Randomhandle,0,p_stNextAnim->uwNumberOfFrames-1);
fn_v3dDataSetForcedFrame(h_Current3dData,uwFrameNumber);
fn_v3dDataSetLastFrame(h_Current3dData,(short)(uwFrameNumber-1));
fn_v3dDataSetTimeDelay(h_Current3dData,0);
fn_v3dDataSetTimePreviousFrame(h_Current3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount);
PLA_fn_bDoAnimPlayerForCharacter(p_stSuperObject,FALSE,FALSE);
return(TRUE);
}
/*********************************************************************
* Function : PLA_fn_vSetCurrFrame *
* Set the frame specified in the current anim or compute a random *
* frame if frame specified is PLA_C_lRandomFrame *
* Create: 17/02/98 Author : Carlos Torres <20>
**********************************************************************/
void PLA_fn_vSetCurrFrame(HIE_tdxHandleToSuperObject p_stSuperObject, short _wFrame)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
unsigned short uwMaxFrame=(unsigned short)(fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim->uwNumberOfFrames);
unsigned char ucFrameRate = fn_uc3dDataGetFrameRate(h_Current3dData), ucFrameRate2 = ucFrameRate;
/* compute random frame*/
if (_wFrame == PLA_C_wRandomFrame)
{
_wFrame=(short) RND_fn_ulGetUnsignedLongRandomValue(g_Randomhandle,0,uwMaxFrame-1);
}
/* Frame must be < NbFrame*/
else
{
if ( _wFrame < 0 )
{
_wFrame = 0;
}
else if ( _wFrame >= uwMaxFrame )
{
_wFrame = (short) (uwMaxFrame - 1);
}
}
/* change forced frame*/
fn_v3dDataSetForcedFrame(h_Current3dData, _wFrame);
fn_v3dDataSetLastFrame(h_Current3dData, (short)(_wFrame - 1));
/* simulate a changing of state*/
fn_v3dDataSetFlagModifState(h_Current3dData,TRUE);
fn_v3dDataSetWantedState(h_Current3dData,fn_h3dDataGetCurrentState(h_Current3dData));
/* reinit flag in case we have reached the end*/
fn_v3dDataSetFlagEndOfAnim(h_Current3dData,FALSE);
fn_v3dDataSetFlagEndState(h_Current3dData,FALSE);
if ( ! ucFrameRate )
{
/*set a non-null frame rate so that the anim player does something for us*/
ucFrameRate2 = fn_scGetSpeedInState(fn_h3dDataGetCurrentState(h_Current3dData));
fn_v3dDataSetFrameRate(h_Current3dData, ucFrameRate2);
}
/* we can set fictive start time and previous compute frame*/
fn_v3dDataSetStartTime(h_Current3dData,
g_stEngineStructure.stEngineTimer.ulCurrentTimerCount - (1000 * _wFrame) / ucFrameRate2
);
fn_v3dDataSetTimePreviousFrame(h_Current3dData,
g_stEngineStructure.stEngineTimer.ulCurrentTimerCount - 1000 / ucFrameRate2
);
/*change the frame*/
PLA_fn_bDoAnimPlayerForCharacter(p_stSuperObject,FALSE,FALSE);
/*reset the previous frame rate*/
fn_v3dDataSetFrameRate(h_Current3dData, ucFrameRate);
}
/*********************************************************************
* Function : PLA_fn_uwGetNbFrameInCurrAnim *
* Return number of frame in the current anim of the charcter *
* Author : Carlos Torres *
* Date of last modification: 17/02/98 *
**********************************************************************/
unsigned short PLA_fn_uwGetNbFrameInCurrAnim(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
return fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim->uwNumberOfFrames;
}
/*********************************************************************
* Function : PLA_fn_uwGetCurrFrameOfAnim *
* Return the current frame of the anim *
* Author : Carlos Torres *
* Date of last modification: 12/03/98 *
**********************************************************************/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
unsigned short PLA_fn_uwGetCurrFrameOfAnim(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
return fn_uw3dDataGetCurrentFrame(h_Current3dData);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/* Init New State*/
/* Modif : 22/04/98 Reset frame of current anim at init - Carlos Torres*/
BOOL PLA_fn_vInitNewState(HIE_tdxHandleToSuperObject p_stSuperObject,tdxHandleToState h_State)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
/*if(p_stCurrent3dData->p_stFamily->d_stState == NULL ) return; // unknown object*/
if(LST2_M_StaticGetFirstElement(&(fn_h3dDataGetFamily(h_Current3dData)->hForStateArray)) == NULL )
return(FALSE);
fn_v3dDataSetFlagEndState(h_Current3dData,FALSE);
fn_v3dDataSetFlagModifState(h_Current3dData,TRUE);
/*fn_v3dDataSetFlagInitState(h_Current3dData,TRUE);*/
/* Reset frame*/
fn_v3dDataSetCurrentFrame(h_Current3dData,0);
fn_v3dDataSetLastFrame(h_Current3dData,0);
fn_v3dDataSetWantedState(h_Current3dData,h_State);
/*if(fn_h3dDataGetCurrentState(h_Current3dData)==NULL)*/
/* set new state, so init frame array*/
/* ANNECY MT - 22/09/98 {*/
/*
if (fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d != NULL)
{
// normally, this should be NULL, but it may happen when the B-mode is started...
MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_Current3dData->h_Family);
TMP_M_Free(fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d);
}
// and init array
if (h_State->p_stAnim)
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_Current3dData->h_Family);
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d = (tdstElement3d*)TMP_M_p_Malloc(sizeof(tdstElement3d) * h_State->p_stAnim->ucMaxNumberOfElements);
memset(fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d,0,sizeof(tdstElement3d) * h_State->p_stAnim->ucMaxNumberOfElements);
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAnim = NULL;
}
*/
if (h_State->p_stAnim)
{
fn_vAllocArrayOfElts3d (h_Current3dData , h_State->p_stAnim->ucMaxNumberOfElements);
}
else
{
fn_vFreeArrayOfElts3d (h_Current3dData);
}
/* END ANNECY MT }*/
fn_v3dDataSetCurrentState(h_Current3dData,h_State);
fn_vUpdateCurrentActivationForCharacter(p_stSuperObject);
fn_v3dDataSetFirstStateOfAction(h_Current3dData,h_State);
fn_v3dDataSetFrameRate(h_Current3dData,fn_scGetSpeedInState(h_State));
if(h_State->p_stAnim)
fn_vInitAllEvents(p_stSuperObject,0);
return(TRUE);
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
BOOL PLA_fn_bInitNewStateWithRandom(HIE_tdxHandleToSuperObject p_stSuperObject,tdxHandleToState h_WantedState)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
struct tdstAnim3d_ *p_stCurrentAnim;
BOOL test;
test = PLA_fn_vInitNewState(p_stSuperObject,h_WantedState);
if(test)
{
p_stCurrentAnim = fn_h3dDataGetCurrentState(h_Current3dData)->p_stAnim;
fn_v3dDataSetForcedFrame(h_Current3dData,(unsigned char)RND_fn_ulGetUnsignedLongRandomValue(g_Randomhandle,0,p_stCurrentAnim->uwNumberOfFrames-1));
return(TRUE);
}
return(FALSE);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
void PLA_fn_vModifyCurrentState(HIE_tdxHandleToSuperObject p_stSuperObject,tdxHandleToState h_State)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
fn_v3dDataSetFlagEndState(h_Current3dData,FALSE);
fn_v3dDataSetFlagEndOfAnim(h_Current3dData,FALSE);
fn_v3dDataSetFlagModifState(h_Current3dData,TRUE);
/* fn_v3dDataSetFlagInitState(h_Current3dData,TRUE);*/
fn_v3dDataSetWantedState(h_Current3dData,h_State);
fn_v3dDataSetFirstStateOfAction(h_Current3dData,h_State);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/* Test New State*/
BOOL PLA_fn_bTestNewState(HIE_tdxHandleToSuperObject p_stSuperObject,tdxHandleToState h_WantedState)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
/*tdxHandleToState h_ResultState;*/
tdxHandleToTransition h_Transition;
if(h_WantedState==fn_h3dDataGetFirstStateOfAction(h_Current3dData)) return(TRUE);
/*h_ResultState = fn_hIfExistTransitionalWithTargetState(fn_h3dDataGetWantedState(h_Current3dData),h_WantedState);*/
h_Transition = fn_hIfExistTransitionalWithTargetState(fn_h3dDataGetWantedState(h_Current3dData),h_WantedState);
/*if(h_ResultState==NULL)*/
if(h_Transition==NULL)
{
if(fn_hIfExistProhibitedState(fn_h3dDataGetWantedState(h_Current3dData),h_WantedState)) return(FALSE);
if(fn_h3dDataGetWantedState(h_Current3dData)->ucTransitionStatusFlag == C_ucProhibitedState) return(FALSE);
}
return(TRUE);
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/* Test New State*/
BOOL PLA_fn_bTestCurrentAction(HIE_tdxHandleToSuperObject p_stSuperObject,tdxHandleToState h_FirstStateOfAction)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
if(h_FirstStateOfAction==fn_h3dDataGetFirstStateOfAction(h_Current3dData)) return(TRUE);
return(FALSE);
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/* ######################################################################## */
/* ############################################################################ */
/* ########################## MANAGMENT of STATES STATUS ####################### */
/* ############################################################################### */
/* ############################################################################### */
/* ######### */
/* ################# */
/* ############# */
/* ######### */
/* ##### */
/* # */
/* Access Functions for Speed. CGHT 12/02/97*/
/* MR0605: Add speed of skipped frames (warning: if the end of an anim is skipped, only the speeds of the new anim is taking into account*/
/* CGHT 04/06/97 : Add Empty list support.*/
/* Modif : continuous speed Carlos Torres 21/04/98*/
struct MTH3D_tdstVector_ * PLA_fn_stGetLinearSpeedVector(HIE_tdxHandleToSuperObject p_stSuperObject,short sLastFrame)
{
MS_tdxHandleTo3dData h_Current3dData;
struct tdstState_ *p_stCurrentState;
struct tdstAnim3d_ *p_stCurrentAnim;
static struct MTH3D_tdstVector_ stSpeedVector;
/* struct tdstFrame3d_ *p_stCurrentFrame3d;*/
int i;
h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
p_stCurrentAnim = p_stCurrentState->p_stAnim;
if(p_stCurrentAnim!=NULL)
{
MTH3D_tdstVector * p_stVector;
int iFramePassed;
MTH_tdxReal xInvFramePassed;
#ifdef DISCREET_SPEED
MTH3D_M_vFillVector(&stSpeedVector,0);
/* compute covered distance for all frame passed*/
for (i=sLastFrame+1;i<=fn_uw3dDataGetCurrentFrame(h_Current3dData);i++)
{
p_stVector = fn_p_stGetLinearSpeedVector(p_stCurrentAnim,i);
if (p_stVector)
{
MTH3D_M_vAddVector(&stSpeedVector,&stSpeedVector,);
}
}
/* compute speed*/
MTH3D_M_vMulScalarVector(&stSpeedVector,MTH_M_xInv(M_xGetUsefulDeltaTimeInSeconds(g_stEngineStructure.stEngineTimer)),&stSpeedVector);
#else /* DISCREET_SPEED */
iFramePassed=1;
p_stVector = fn_p_stGetLinearSpeedVector(p_stCurrentAnim,fn_uw3dDataGetCurrentFrame(h_Current3dData));
if (p_stVector)
{
MTH3D_M_vCopyVector(&stSpeedVector,p_stVector);
}
else
{
MTH3D_M_vFillVector(&stSpeedVector,0);
}
/* compute covered distance for all frame passed*/
for (i=sLastFrame+1;i<fn_uw3dDataGetCurrentFrame(h_Current3dData);i++,iFramePassed++)
{
/* fn_vUpdateFrame(p_stSuperObject,p_stCurrentFrame3d,p_stCurrentAnim,i);*/
p_stVector = fn_p_stGetLinearSpeedVector(p_stCurrentAnim,(unsigned short)i);
if (p_stVector)
{
MTH3D_M_vAddVector(&stSpeedVector,&stSpeedVector,p_stVector);
}
}
xInvFramePassed = MTH_M_xInv((MTH_tdxReal)iFramePassed);
/* average distance per frame for all frame skipped*/
MTH3D_M_vMulScalarVector(&stSpeedVector,xInvFramePassed,&stSpeedVector);
/* compute speed*/
MTH3D_M_vMulScalarVector(&stSpeedVector,fn_uc3dDataGetFrameRate(h_Current3dData),&stSpeedVector);
#endif /* DISCREET_SPEED */
return &stSpeedVector;
}
else
return NULL;
}
struct MTH3D_tdstMatrix_ * PLA_fn_stGetAngularSpeedMatrix(HIE_tdxHandleToSuperObject p_stSuperObject,short sLastFrame)
{
MS_tdxHandleTo3dData h_Current3dData;
struct tdstState_ *p_stCurrentState;
tdstAnim3d *p_stCurrentAnim;
static struct MTH3D_tdstMatrix_ stSpeedMatrix;
/* struct tdstFrame3d_ *p_stCurrentFrame3d;*/
int i;
ACP_tdxBool bSpeedMatrix = FALSE;
h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
p_stCurrentAnim = p_stCurrentState->p_stAnim;
if(p_stCurrentAnim!=NULL)
{
MTH3D_tdstMatrix stMatrix;
MTH3D_M_vSetIdentityMatrix(&stSpeedMatrix);
for (i=sLastFrame+1 ; i<=fn_uw3dDataGetCurrentFrame(h_Current3dData) ; i++)
{
if (fn_p_stGetAngularSpeedMatrix(p_stCurrentAnim,(unsigned short)i,&stMatrix))
{
MTH3D_M_vMulMatrixMatrix(&stSpeedMatrix,&stSpeedMatrix,&stMatrix);
bSpeedMatrix=TRUE;
}
}
/* return &stSpeedMatrix;*/
}
/* else*/
/* {*/
/* return NULL;*/
/* }*/
return bSpeedMatrix ? &stSpeedMatrix : NULL;
}
BOOL PLA_fn_bTestIfEndOfAction(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
if( fn_uc3dDataGetFlagEndState(h_Current3dData)
&& fn_h3dDataGetCurrentState(h_Current3dData)==fn_h3dDataGetWantedState(h_Current3dData) )
{
return(TRUE);
}
return(FALSE);
}
BOOL PLA_fn_bTestIfEndOfAnim(HIE_tdxHandleToSuperObject p_stSuperObject)
{
if( fn_uc3dDataGetFlagEndOfAnim(M_GetMSHandle(p_stSuperObject,3dData)) ) return(TRUE);
return(FALSE);
}
/*********** TMP *******************/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
void PLA_fn_vInitNewAction(HIE_tdxHandleToSuperObject p_stSuperObject,unsigned short wAction)
{
struct tdstState_ *p_stTmpState;
long i;
LST2_M_StaticGetElementNumber(&(fn_h3dDataGetFamily(M_GetMSHandle(p_stSuperObject,3dData))->hForStateArray)
,p_stTmpState,wAction,i);
PLA_fn_vInitNewState(p_stSuperObject,p_stTmpState);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/* **************************************************************************************/
/* * Description : Change frame of current anim, and change anim if we have reached **/
/* * end, Make sure that fn_vDoAnim is not called for objects without **/
/* * Anim or State **/
/* *===================================================================================**/
/* *-----------------------------------------------------------------------------------**/
/* * Creation date : 27/07/97 Author : DVD (Gizmo) **/
/* **************************************************************************************/
#ifdef ACTIVE_EDITOR
BOOL PLA_fn_bDoFirstInitOfAnimPlayerForCharacter(HIE_tdxHandleToSuperObject p_stSuperObject, tdstAnim3d *p_stNewAnim)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
struct tdstState_ *p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
struct tdstAnim3d_ *p_stCurrentAnim;
/*unsigned char FlagModifyState;*/
/* tdstSubAnim3d stTmpSubAnim;*/
BOOL bDidChangeState = FALSE;
/* MR2204*/
unsigned long ulAddFrames=0;
/* MR0407*/
/*unsigned short uwAddFrame;*/
/*unsigned char ucStateSpeed; // MR2407*/
if (p_stCurrentState==NULL)
return FALSE; /* not a good object !!! mettre un message d'erreur !!! ...*/
p_stCurrentAnim = p_stCurrentState->p_stAnim;
/* for instance : a camera ...*/
if (p_stNewAnim==NULL) return TRUE;
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAnim = NULL;
/* update the stCurrent3dData structure*/
if(fn_uc3dDataGetFlagModifState(h_Current3dData) == TRUE || p_stCurrentAnim != p_stNewAnim)
{
if (p_stCurrentAnim->ucMaxNumberOfElements != p_stNewAnim->ucMaxNumberOfElements || fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d == NULL)
{
/* ANNECY MT - 22/09/98 {*/
/*
if (fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d)
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_Current3dData->h_Family);
TMP_M_Free(fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d);
}
MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_Current3dData->h_Family);
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d = (tdstElement3d*)TMP_M_p_Malloc(sizeof(tdstElement3d) * p_stNewAnim->ucMaxNumberOfElements);
memset(fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stArrayOfElts3d,0,sizeof(tdstElement3d) * p_stNewAnim->ucMaxNumberOfElements);
*/
fn_vAllocArrayOfElts3d (h_Current3dData , p_stNewAnim->ucMaxNumberOfElements);
/* END ANNECY MT }*/
fn_p_st3dDataGetCurrentFrame(h_Current3dData)->p_stAnim = NULL;
}
fn_v3dDataSetFlagModifState(h_Current3dData,FALSE);
/* fn_v3dDataSetCurrentHieCouples(h_Current3dData,NULL);*/
/* fn_v3dDataSetCurrentHieNbCouples(h_Current3dData,0);*/
/* fn_v3dDataSetFirstActiveChannel(h_Current3dData,NULL);*/
}
p_stCurrentState->p_stAnim = p_stNewAnim;
PLA_fn_vInitAllChildInHeapNewAnim(p_stSuperObject,p_stNewAnim,fn_uw3dDataGetCurrentFrame(h_Current3dData));
PLA_fn_vDoFrame(p_stNewAnim,fn_uw3dDataGetCurrentFrame(h_Current3dData),p_stSuperObject);
/* last event played is set correctly by*/
/* - previous call to this function*/
/* - init of all events*/
/* - call to fn_vPlayLastEventsBeforeRestart() for previous loop of the same anim*/
/* fn_vPlayEventsSinceLastOneNoLoop( p_stSuperObject );*/
/* Takes the speed in the anim and transfers it to the mechanics*/
/*fn_vTransferSpeedInformationPLA_DNM(p_stSuperObject,ucLastFrame);*/
/* fn_vTransferSpeedInformationPLA_DNM(p_stSuperObject,fn_s3dDataGetLastFrame(h_Current3dData));*/
/*fn_v3dDataSetLastFrame(h_Current3dData,fn_uc3dDataGetCurrentFrame(h_Current3dData));*/
return TRUE;
}
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
void PLA_fn_bDoOffsetFirstInitForCharacter(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
struct tdstState_ *p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
MTH3D_tdstVector stCharTransVect/*,stOffsetAnim*/;
POS_tdstCompletePosition *p_stCharMatrix;
/* Calcul Offset ici (MR1504)*/
p_stCharMatrix=HIE_fn_hGetSuperObjectMatrix(p_stSuperObject);
/*POS_fn_vGetTranslationVector(&p_stTmpState->p_stAnim->stOffsetMatrix,&stOffsetAnim);*/
POS_fn_vGetTranslationVector(p_stCharMatrix,&stCharTransVect);
/*MTH3D_M_vSubVector(&stCharTransVect,&stCharTransVect,&stOffsetAnim);*/
/* POS_fn_vGetTranslationVector(&p_stCurrentState->p_stAnim->stOffsetMatrix,&stOffsetAnim);
MTH3D_M_vAddVector(&stCharTransVect,&stCharTransVect,&stOffsetAnim); */
MTH3D_M_vAddVector(&stCharTransVect,&stCharTransVect,&p_stCurrentState->p_stAnim->stOffsetMatrix); /*AR9811*/
POS_fn_vSetTranslationVector(p_stCharMatrix,&stCharTransVect);
POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(p_stSuperObject),HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(p_stSuperObject)),p_stCharMatrix);
}
#endif
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/*POS_tdxHandleToPosition PLA_fn_hFindNextFreeMatrix(void)
{
PLA_g_ulMaxInMatrixHeap ++;
if ( PLA_g_ulMaxInMatrixHeap >= __PLA_NB_MAX_MATRIX__ )
M_GameFatalError(E_uwGameNoMorePLAObj);
if(PLA_g_ulMaxInMatrixHeap > PLA_g_ulMaxOccupationOfMatrixHeap) PLA_g_ulMaxOccupationOfMatrixHeap++;
while ( PLA_g_a_wStateOfMatrixHeap[PLA_g_ulCurrentPosInMatrixHeap] )
{ // stop when PLA_g_a_wStateOfMatrixHeap[CurrentPos]
// attention !!! __PLA_NB_MAX_MATRIX__ est une puissance de 2 !!!
PLA_g_ulCurrentPosInMatrixHeap ++;
if(PLA_g_ulCurrentPosInMatrixHeap == __PLA_NB_MAX_MATRIX__) PLA_g_ulCurrentPosInMatrixHeap = 0L;
}
PLA_g_a_wStateOfMatrixHeap[PLA_g_ulCurrentPosInMatrixHeap] = 1;
return &PLA_g_d_stMatrixHeap[PLA_g_ulCurrentPosInMatrixHeap];
}
*/
/*void PLA_fn_vReleaseMatrixInHeap(POS_tdxHandleToPosition _hMatrix)
{
long lPos = _hMatrix - PLA_g_d_stMatrixHeap;
if ( (lPos < 0) || (lPos > __PLA_NB_MAX_MATRIX__) || (PLA_g_a_wStateOfMatrixHeap[lPos] == 0) )
M_GameFatalError(E_uwGameNoMorePLAObj);
PLA_g_a_wStateOfMatrixHeap[lPos] = 0;
PLA_g_ulMaxInMatrixHeap --;
}
*/
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
/*.............############################################################.............*/
/*.....############################################################################.....*/
/*.####################################################################################.*/
/*void PLA_fn_vForceRegenerationWhenBlockInNoState_EndOfAction(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
struct tdstState_ *p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
if(p_stCurrentState == NULL) return;
if(p_stCurrentState->p_stAnim == NULL) return;
/* Write the last frame until animation is changed*/
/*PLA_fn_vInitAllChildInHeapNewAnim(p_stSuperObject,p_stCurrentState->p_stAnim,(unsigned char)(p_stCurrentState->p_stAnim->uwNumberOfFrames-1));
PLA_fn_vDoFrame(p_stCurrentState->p_stAnim,(unsigned char)(p_stCurrentState->p_stAnim->uwNumberOfFrames-1),p_stSuperObject);
}
void PLA_fn_vForceRegenerationWhenSkip(HIE_tdxHandleToSuperObject p_stSuperObject)
{
MS_tdxHandleTo3dData h_Current3dData = M_GetMSHandle(p_stSuperObject,3dData);
struct tdstState_ *p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
unsigned short uwCurrentFrame;
if(p_stCurrentState == NULL) return;
if(p_stCurrentState->p_stAnim == NULL) return;
uwCurrentFrame=fn_uw3dDataGetCurrentFrame(h_Current3dData);
if(uwCurrentFrame == p_stCurrentState->p_stAnim->uwNumberOfFrames) uwCurrentFrame--;
PLA_fn_vInitAllChildInHeapNewAnim(p_stSuperObject,p_stCurrentState->p_stAnim,uwCurrentFrame);
PLA_fn_vDoFrame(p_stCurrentState->p_stAnim,uwCurrentFrame,p_stSuperObject);
}*/
/*.####################################################################################.*/
/*.....############################################################################.....*/
/*.............############################################################.............*/
#ifdef ACTIVE_EDITOR
extern unsigned char g_ucIsEdInGhostMode;
void fn_vCheckModuleAccessGam(HIE_tdxHandleToSuperObject hPerso, unsigned char cChannel)
{
HIE_tdxHandleToSuperObject hModule;
hModule = fn_hGetSuperObjectInChannel(fn_h3dDataGetChannelSOList(M_GetMSHandle(hPerso, 3dData)),(short) cChannel);
/* if B mode, no check is done*/
if (g_ucIsEdInGhostMode)
{
if (hModule)
hModule->llastComputeFrameForModule = HIE_gs_lCurrentFrame;
return;
}
/* if hModule is NULL, then there is an error : access to a valid channel number, but nothing in the channel !*/
if (hModule == NULL)
{
/* error !*/
char cText[512];
if (M_GetMSHandle(hPerso,Brain) && M_pstGetMindOfBrain(M_GetMSHandle(hPerso,Brain)))
{
sprintf(cText,"You try to access a module that does not exist at this moment !!!\n"
"this module belongs to : %s\nThe number of the channel you try to access is : %i\n",(M_pstGetMindOfBrain(M_GetMSHandle(hPerso,Brain)))->szPersoName,cChannel);
}
else
{
sprintf(cText,"You try to access a module that does not exist at this moment !!!\n"
"this module belongs to <actor with no brain (current state is %s)>\nThe number of the channel you try to access is : %i\n",cChannel, fn_p_szGetStateName(fn_h3dDataGetCurrentState(M_GetMSHandle(hPerso,3dData))));
}
MessageBox(NULL,cText,"Module Access error",MB_OK|MB_ICONWARNING);
fn_vForceEditor();
}
else if (hModule->llastComputeFrameForModule < HIE_gs_lCurrentFrame-1)
{
/* error !*/
char cText[512];
if (M_GetMSHandle(hPerso,Brain) && M_pstGetMindOfBrain(M_GetMSHandle(hPerso,Brain)))
{
sprintf(cText,"You try to get a module position that is not up to date !!!\n"
"this module belongs to : %s\n",(M_pstGetMindOfBrain(M_GetMSHandle(hPerso,Brain)))->szPersoName);
}
else
{
sprintf(cText,"You try to get a module position that is not up to date !!!\n"
"this module belongs to <actor with no brain (current state is %s>\n", fn_p_szGetStateName(fn_h3dDataGetCurrentState(M_GetMSHandle(hPerso,3dData))));
}
if (fn_ulStandardGameGetCustomBitsSO(hPerso) & GAM_C_CustBitNeedModuleMatrices)
{
strcat(cText,"This Perso already has the custombit 2 set, but it seems that the anim player has not\n"
"been played this time..., so check anim player related flags\n");
}
else
{
strcat(cText,"This perso does not have the custom bit 2 set, correct this and try again\n");
}
sprintf (cText + strlen(cText),"There is a difference of %i frames\n",HIE_gs_lCurrentFrame-hModule->llastComputeFrameForModule);
MessageBox(NULL,cText,"Module Access error",MB_OK|MB_ICONWARNING);
fn_vForceEditor();
}
}
#endif