/******************************************************************************
 * CFast_3.cpp : passage de l'ia en C, 3eme passe
 * autheur : Jean-Marc Drouaud
 ******************************************************************************/

#include "stdafx.h"

#define D_Brain_StructureDefine

#include "ai.h"
#include "AI/AIBase/CFast.h"
#include "CFast_3.hpp"
#include "CFast_2.hpp"
#include "EdIRBELs.hpp" 
#include "EdIRBeEn.hpp"
#include "x:/cpa/TempGrp/AI/AIBase/DsgMemC.h"

FILE *g_fdCxx = NULL ;
FILE *g_fdH = NULL ;
FILE *g_fdNode = NULL ;
char g_szModelName[256] ;
char g_szFamilyName[256] ;
char g_szEngineSectionName[256] ;


typedef enum eProcessWhat_
{
	E_pw_Invalid ,
	E_pw_Comport ,
	E_pw_Reflex ,
	E_pw_Macro ,
	E_pw_Subroutine

} tdeProcessWhat ;
tdeProcessWhat g_eProcessWhat = E_pw_Invalid ;

unsigned long g_ulTreeIndex ;
unsigned long g_ulLabelNumber = 0 ;
unsigned long g_ulNumberFor = 0 ;
unsigned long g_ulBreak = 0 ;
unsigned long g_ulGotRfx = 0 ;
unsigned long g_ulGotCmp = 0 ;
unsigned long g_ulGotDsgVar = 0 ;
unsigned long g_ulPseudoTreeIndex = 0;
unsigned long g_ulPseudoTreePrev = 0;
long g_lCompteurPourLesSi = 0 ;
unsigned long g_ulSiDebug = 0 ;
long g_lIndexForCondition = 1 ;

long g_lOpenedBraceByIf[128] ;
unsigned long g_ulCondStringSet = 0 ;
char g_szConditionString1[2048] ;
char g_szConditionString2[2048] ;
unsigned long g_ulSiTreeDepth = 0 ;
unsigned long g_ulMakeElse = 0 ;
unsigned long g_ulProcessIf = 0 ;
unsigned long g_ulBloquantMoteur = 0 ;

long gRemoveNextModelRef = 0 ;

#define CFast_fprintf(sz) CFast_ThirdPassIndent () ; fprintf sz ;

#define DEBUG_CFAST
#ifdef DEBUG_CFAST
long g_lDebugLevel = 3 ;
#define CFast_fprintf_d(l, sz) if ( l<g_lDebugLevel ) fprintf sz ;
#else
#define CFast_fprintf_d(sz) 
#endif /* DEBUG_CFAST */

CFast_tdstNode *gapst_Params[10];
#define CLEAR_Params() memset(gapst_Params, 0, sizeof(gapst_Params))

extern struct AI_tdstMind_ *gp_stCurrentMind;

tdstNodeInterpret       *g_d_stMemoTree ;
unsigned long           ulSizeMemoTree;
unsigned long           ulLastMemoTree;
char                    cEvaluateMemo;

tdeVariableType   g_eParamType[CFast_lMaxTreeDepth] ;
tdstNodeInterpret g_a_stPseudoTree[7][CFast_lMaxTreeDepth] ;
tdeTypeInterpret  g_eCurrentType = E_ti_Unknown ;
tdeTypeInterpret  g_eTypeOfParam = E_ti_Unknown ;


/*
 * stack of pseudonode
 */
#define CFAST_ThirdPassStackSize 64
CFast_tdstNode *g_stStack[CFAST_ThirdPassStackSize] ;
unsigned long g_ulNbNodeInStack = 0 ;

CFast_tdstNode *g_stParamStack[CFAST_ThirdPassStackSize] ;
unsigned long g_ulNbParamInStack = 0 ;

CFast_tdstNode *g_p_stLastNode = NULL ;



bool CFast_fn_vThirdPassField ( CFast_tdstNode *p_stPerso, CFast_tdstNode *p_stNode)  ;

/*******************************************************************************
 *******************************************************************************
 * manage the file indentation
 *******************************************************************************
 *******************************************************************************/
long g_ulIndentation = 0 ;
void CFast_ThirdPassAddIndentLevel (void) {
  g_ulIndentation += 2 ;
}
void CFast_ThirdPassRmIndentLevel (void) {
  g_ulIndentation -= 2 ;
  if ( g_ulIndentation < 0 ) 
    g_ulIndentation = 0 ;
}
void CFast_ThirdPassIndent (void) {
  long i ;

  for (i=0 ; i<g_ulIndentation ; i++)
    fputc ( ' ', g_fdCxx) ;
}
/*******************************************************************************
 *******************************************************************************
 * process conditions
 *******************************************************************************
 *******************************************************************************/
typedef struct _the_tree_ tdstTree ;
struct _the_tree_ {
  CFast_tdstNode *p_stFirstNode ;
  CFast_tdstNode *p_stLastNode ;
  tdstTree *p_stLeft ;
  tdstTree *p_stRight ;
} ;
tdstTree *d_stCondStack[CFAST_ThirdPassStackSize] ;
unsigned long g_ulNbElemInCondStack = 0 ;

long CFast_ThirdPassIsLogicalOperator (CFast_tdstNode *p_stNode) {
  if ( M_GetTypeInterpret((&p_stNode->stNode)) != E_ti_Condition )
    return FALSE ;
  if ( M_eCondIdInterpret((&p_stNode->stNode)) == eCond_Et  ||
       M_eCondIdInterpret((&p_stNode->stNode)) == eCond_Ou  ||
       M_eCondIdInterpret((&p_stNode->stNode)) == eCond_Not || 
       M_eCondIdInterpret((&p_stNode->stNode)) == eCond_XOr )
    return TRUE ;
  return FALSE ;
}
long CFast_ThirdPassIsIfKeyword ( CFast_tdstNode *p_stNode ) {
  if ( M_GetTypeInterpret((&p_stNode->stNode)) != E_ti_KeyWord )
    return FALSE ;
  if ( (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_If)  ||
       (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_If2) ||
       (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_If4) ||
       (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_If8) ||
       (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_If16)||
       (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_IfNot))
    return TRUE;
  return FALSE;
}
CFast_tdstNode *SkipNextCond (CFast_tdstNode *p_stNode) {
  CFast_tdstNode *p_stCurrentNode ;

  p_stCurrentNode = p_stNode ;
  while ( M_GetTypeInterpret((&p_stCurrentNode->stNode)) != E_ti_Condition &&
	  !CFast_ThirdPassIsIfKeyword (p_stCurrentNode) && !p_stCurrentNode->bIsABooleanDsgVarRef ) {
    p_stCurrentNode++ ;    
  }
  return (p_stCurrentNode) ;
}

tdstTree *CreateLeaf (CFast_tdstNode *p_stNode, CFast_tdstNode **p_stNextNode) {
  tdstTree *p_stLeaf ;

  p_stLeaf = (tdstTree *) malloc ( sizeof (tdstTree) ) ;
  p_stLeaf->p_stFirstNode = p_stNode ;
  p_stLeaf->p_stLastNode  = SkipNextCond (p_stNode) ;
  p_stLeaf->p_stLeft      = NULL ;
  p_stLeaf->p_stRight     = NULL ;

  if ( p_stLeaf->p_stLastNode < p_stNode )
    p_stLeaf->p_stLastNode = p_stNode ;

  *p_stNextNode = p_stLeaf->p_stLastNode + 1 ;

  return (p_stLeaf) ;
}

void FreeTree (tdstTree *p_stTree) {
  if ( p_stTree->p_stLeft != NULL )
    FreeTree (p_stTree->p_stLeft) ;
  if ( p_stTree->p_stRight != NULL )
    FreeTree (p_stTree->p_stRight) ;
  free ( p_stTree ) ;
}

tdstTree *PopCond (void) {
  if ( g_ulNbElemInCondStack > 0)
    return (d_stCondStack[--g_ulNbElemInCondStack]) ;
  assert (NULL) ;
  return (NULL) ;
}

CFast_tdstNode *PushCond (CFast_tdstNode *p_stNode, long lNbPop) {
  tdstTree *p_stLeaf ;
  CFast_tdstNode *p_stNextNode; 

  p_stLeaf = CreateLeaf ( p_stNode, &p_stNextNode ) ;
  if ( lNbPop == 2 ) {
    p_stLeaf->p_stRight = PopCond () ;
    p_stLeaf->p_stLeft = PopCond () ;
  }
  else if ( lNbPop == 1 )
    p_stLeaf->p_stLeft = PopCond () ;

  d_stCondStack[g_ulNbElemInCondStack++] = p_stLeaf ;
  return ( p_stNextNode ) ;
}
bool process_and (long *plNbStatement){
  bool bCloseBracket = 0 ;

  CFast_ThirdPassIndent () ;
  if ( g_ulCondStringSet ) {
    fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ;
    g_ulCondStringSet = 0 ;
    fprintf ( g_fdCxx, "if ( long%d ) {\n", g_lIndexForCondition ) ;
    bCloseBracket = 1 ;
//     fprintf ( g_fdCxx, "if ( %s ) {\n", g_szConditionString2 ) ;
//     g_ulCondStringSet = 0 ;
//     g_ulMakeElse ++ ;
//     (*plNbStatement)++ ;
  }
  else {
    fprintf ( g_fdCxx, "if ( long%d ) {\n", g_lIndexForCondition ) ;
    bCloseBracket = 1 ;
  }
  g_lOpenedBraceByIf[g_lCompteurPourLesSi]++ ;
  CFast_ThirdPassAddIndentLevel () ;
  return (bCloseBracket) ;
}
void close_and_statement (long *plNbStatement) {
  while ( g_ulMakeElse ) {
    CFast_ThirdPassRmIndentLevel () ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n" ) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "else {\n" ) ;
    CFast_ThirdPassAddIndentLevel () ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "long%d = 0;\n", g_lIndexForCondition ) ;
    CFast_ThirdPassRmIndentLevel () ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n" ) ;
    g_ulMakeElse-- ;
    (*plNbStatement)-- ;
    g_lOpenedBraceByIf[g_lCompteurPourLesSi] -- ;
  }
}
bool process_or(long *plNbStatement) {
  bool bCloseBracket = 0 ;

  if ( g_ulCondStringSet ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ;
    if ( *plNbStatement /*g_ulMakeElse*/ ) {
      close_and_statement (plNbStatement) ;
    }
    g_ulCondStringSet = 0 ;
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "if ( !long%d ) {\n", g_lIndexForCondition ) ;
  CFast_ThirdPassAddIndentLevel () ;
  g_lOpenedBraceByIf[g_lCompteurPourLesSi]++ ;  
  bCloseBracket = 1 ;
  return (bCloseBracket) ;
}
bool process_not(long *plNbStatement) {
  char *sztmp ;
  char szTemp[2048] ;

  if ( g_ulCondStringSet ) {
    sprintf ( szTemp, "!( %s )", g_szConditionString2 ) ;
    strcpy ( g_szConditionString2, szTemp ) ;
    sztmp = strstr ( g_szConditionString1, "==" ) ;
    if ( sztmp )
      *(sztmp) = '!' ;
    else {
      sztmp = strstr ( g_szConditionString1, "=" ) ;
      *(sztmp+1) = '!' ;
    }
  }
  else {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "long%d = long%d ? 0 : 1 ;\n", g_lIndexForCondition, g_lIndexForCondition) ;
  }
  return (FALSE) ;
}

bool process_xor (long *plNbStatement) {
  if ( g_ulCondStringSet ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ;
    g_ulCondStringSet = 0 ;
      }
  g_ulCondStringSet = 0 ;
  g_lIndexForCondition++ ;
  return (FALSE) ;
}

void CFast_ThirdPassMakeIf ( tdstTree *p_stTree, long *plNbAndStatement ) {
  CFast_tdstNode *p_stCurrentNode ;
  long bCloseBracket = 0 ;
  long lNbAndInLeftTree = 0 ;  
  long lNbAndInRightTree = 0 ;


  
  g_ulSiTreeDepth++ ;

  if ( p_stTree->p_stLeft )
    CFast_ThirdPassMakeIf (p_stTree->p_stLeft, &lNbAndInLeftTree) ;

  
  if ( CFast_ThirdPassIsLogicalOperator(p_stTree->p_stFirstNode) ) {
    switch ( M_eCondIdInterpret((&p_stTree->p_stFirstNode->stNode))) {
    case eCond_Et :
      CFast_fprintf_d(3, ( g_fdCxx, "\n/* [Condition : Et] ********** [%d, %d]*/\n", g_lCompteurPourLesSi, g_lOpenedBraceByIf[g_lCompteurPourLesSi])) ;
      bCloseBracket = process_and (&lNbAndInLeftTree) ;
      break ;
    case eCond_Ou :
      CFast_fprintf_d(3, ( g_fdCxx, "\n/* [Condition : Ou] ********** [%d, %d]*/\n", g_lCompteurPourLesSi, g_lOpenedBraceByIf[g_lCompteurPourLesSi])) ;
      bCloseBracket = process_or (&lNbAndInLeftTree) ;
      break ;
    case eCond_Not :
      CFast_fprintf_d(3, ( g_fdCxx, "\n/* [Condition : Not] ********** [%d, %d]*/\n", g_lCompteurPourLesSi, g_lOpenedBraceByIf[g_lCompteurPourLesSi])) ;
      process_not (&lNbAndInLeftTree) ;
      break ;
    case eCond_XOr :
      CFast_fprintf_d(3, ( g_fdCxx, "\n/* [Condition : xor] ********** [%d, %d]*/\n", g_lCompteurPourLesSi, g_lOpenedBraceByIf[g_lCompteurPourLesSi])) ;
      process_xor(&lNbAndInLeftTree) ;
      break ;
    }
  }
  else {
    p_stCurrentNode = p_stTree->p_stFirstNode ;
    while ( p_stCurrentNode <= p_stTree->p_stLastNode ) {
      if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
	      p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
      }
      else if ( p_stCurrentNode->d_cOptimisedNode ) {
	      CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
	      p_stCurrentNode++ ;
      }
      else {
	      p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
      }
    }
  }

  if ( p_stTree->p_stRight )
    CFast_ThirdPassMakeIf (p_stTree->p_stRight, &lNbAndInRightTree) ;

  if ( bCloseBracket ) {
    if (g_ulCondStringSet) {
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ; 
      if ( lNbAndInRightTree /*g_ulMakeElse*/ ) {
	      close_and_statement (&lNbAndInRightTree) ;
      }
      g_ulCondStringSet = 0 ;
    }
    CFast_ThirdPassRmIndentLevel () ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n" ) ;
    g_lOpenedBraceByIf[g_lCompteurPourLesSi] -- ;
  }

  if ( CFast_ThirdPassIsLogicalOperator(p_stTree->p_stFirstNode) &&
       M_eCondIdInterpret((&p_stTree->p_stFirstNode->stNode)) == eCond_XOr ) {
    if ( g_ulCondStringSet ) {
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ;
      g_ulCondStringSet = 0 ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "long%d ^= long%d\n", g_lIndexForCondition-1, g_lIndexForCondition ) ;
    g_lIndexForCondition-- ;
  }
  (*plNbAndStatement) += lNbAndInLeftTree + lNbAndInRightTree ; 
  g_ulSiTreeDepth-- ;
}

CFast_tdstNode *CFast_ThirdPassProcessIf ( CFast_tdstNode *p_stNode) {
  CFast_tdstNode *d_stIfTree ;
  tdstTree *p_stTree ;
  CFast_tdstNode *p_stCurrentNode, *p_stLastNode ;
  long lNbNode, i ;
  long lNbAndStatement = 0 ;

  g_ulProcessIf = 1 ;
  g_lIndexForCondition = 1 ;

  p_stCurrentNode = p_stNode ;
  lNbNode = 0 ;
  while ( !CFast_ThirdPassIsIfKeyword (p_stCurrentNode) ) {
    p_stCurrentNode ++ ;
    lNbNode++ ;
  }
  lNbNode ++ ;

  d_stIfTree = (CFast_tdstNode *) malloc ( lNbNode*sizeof (CFast_tdstNode) ) ;
  for ( i=0, p_stCurrentNode=p_stNode ; i<lNbNode ; i++, p_stCurrentNode++ ) {
    memcpy ( &d_stIfTree[i], p_stCurrentNode, sizeof(CFast_tdstNode) ) ;
    M_SetTypeInterpret((&d_stIfTree[i].stMiscellaneousNode), E_ti_Unknown ) ;
  }
  
  p_stLastNode = d_stIfTree + lNbNode ;
  p_stCurrentNode = d_stIfTree ;
  while ( p_stCurrentNode < p_stLastNode ) {
    if ( CFast_ThirdPassIsLogicalOperator(p_stCurrentNode) )
      p_stCurrentNode = PushCond ( p_stCurrentNode, p_stCurrentNode->ucNumberOfParamNeeded ) ;
    else if ( CFast_ThirdPassIsIfKeyword(p_stCurrentNode) ) 
      p_stCurrentNode = PushCond ( p_stCurrentNode, 1 ) ;
    else
      p_stCurrentNode = PushCond ( p_stCurrentNode, 0 ) ;
  }
  p_stTree = PopCond () ;
  if ( CFast_ThirdPassIsIfKeyword(p_stTree->p_stFirstNode) ) {
    i=0 ;
    switch ( M_eKeyWordIdInterpret((&p_stTree->p_stFirstNode->stNode)) ) {
    case eKeyWord_If2 :
      i = 0x1 ;
      break ;
    case eKeyWord_If4 :
      i = 0x3 ;
      break ;
    case eKeyWord_If8 :
      i = 0x7 ;
      break ;
    case eKeyWord_If16 :
      i = 0xF ;
      break ;
    }
    if ( i )
	{
      CFast_ThirdPassIndent () ;	
      fprintf ( g_fdCxx, "if ( ! ( gcGlobAleat & %#x ) )\n", i) ;
      CFast_ThirdPassIndent () ;	
      fprintf ( g_fdCxx, "{\n", i) ;
      g_lOpenedBraceByIf[g_lCompteurPourLesSi]++ ;
      CFast_ThirdPassAddIndentLevel () ;
    }
  }
  g_ulSiTreeDepth = 0 ;
  g_ulMakeElse = 0 ;
  CFast_ThirdPassMakeIf (p_stTree->p_stLeft, &lNbAndStatement) ;
  if ( CFast_ThirdPassIsIfKeyword(p_stTree->p_stFirstNode) ) {
    CFast_ThirdPassIndent () ;
    if ( M_eKeyWordIdInterpret((&p_stTree->p_stFirstNode->stNode)) == eKeyWord_IfNot )
	{
      if ( g_ulCondStringSet )
	  {
 	      fprintf ( g_fdCxx, "if ( !( %s ) ) {\n", g_szConditionString2 ) ;
 	      g_ulCondStringSet = 0 ;
      }
      else
//       if ( g_ulCondStringSet ) {
// 	fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ;
// 	g_ulCondStringSet = 0 ;
// 	CFast_ThirdPassIndent () ;
//       }
      fprintf ( g_fdCxx, "if ( !long1 ) {\n", g_lIndexForCondition ) ;
    }
    else
	{
      if ( g_ulCondStringSet )
	  {
  	    fprintf ( g_fdCxx, "if ( %s ) {\n", g_szConditionString2 ) ;
  	    g_ulCondStringSet = 0 ;
      }
      else
//       if ( g_ulCondStringSet ) {
// 	fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ;
// 	g_ulCondStringSet = 0 ;
// 	CFast_ThirdPassIndent () ;
//       }      
      fprintf ( g_fdCxx, "if ( long1 ) {\n", g_lIndexForCondition ) ;
    }
    CFast_ThirdPassAddIndentLevel () ;
    g_lOpenedBraceByIf[g_lCompteurPourLesSi]++ ;
    g_lCompteurPourLesSi ++ ;
  }
  FreeTree(p_stTree) ;
  free ( d_stIfTree ) ;
  g_ulProcessIf = 0 ;
  return (p_stNode+lNbNode) ;
}

/*******************************************************************************
 *******************************************************************************
 * gestion DES operateurs ternaires 
 *******************************************************************************
 *******************************************************************************/
CFast_tdstNode *get_father(CFast_tdstNode *p_stNode) {
  long depth ;
  CFast_tdstNode *p_stFather ;

  depth = M_DepthInterpret(&p_stNode->stNode) - 1;
  if ( depth < 1 ) 
    return (NULL) ;

  p_stFather = p_stNode ;
  while ( depth != M_DepthInterpret(&p_stFather->stNode) )
    p_stFather ++ ;
  return (p_stFather) ;
}

bool is_a_ternary_operator (tdstNodeInterpret* p_stNode) {
  if ( (M_GetTypeInterpret(p_stNode) == E_ti_Function)        && 
       ( (M_eFuncIdInterpret(p_stNode) == eFunc_TernOp)    ||
         (M_eFuncIdInterpret(p_stNode) == eFunc_TernSup)   ||
         (M_eFuncIdInterpret(p_stNode) == eFunc_TernEq)    ||
         (M_eFuncIdInterpret(p_stNode) == eFunc_TernInfEq) ||
         (M_eFuncIdInterpret(p_stNode) == eFunc_TernSupEq) ) )
    return TRUE;
  return FALSE;
}

bool special_node_for_ternop ( CFast_tdstNode *p_stNode ) {
  CFast_tdstNode *p_stFather ;
  
  if ( M_GetTypeInterpret(&p_stNode->stNode) == E_ti_Constant  ||
       M_GetTypeInterpret(&p_stNode->stNode) == E_ti_Real      ||
       M_GetTypeInterpret(&p_stNode->stNode) == E_ti_DsgVarRef ||
       M_GetTypeInterpret(&p_stNode->stNode) == E_ti_DsgVar    ||
       ( M_GetTypeInterpret(&p_stNode->stNode) == E_ti_Operator && 
         M_eOperatorIdInterpret(&p_stNode->stNode) == eOperator_Dot )) {
    p_stFather = get_father(p_stNode) ;
    if ( p_stFather == NULL )
      return (FALSE) ;
    return (is_a_ternary_operator(&p_stFather->stNode) ) ;
  }
  return (FALSE) ;
}
CFast_tdstNode *process_special_node_for_ternop (CFast_tdstNode *p_stNode, long lIndex ) {
  CFast_tdstNode *p_stCurrentNode ;
  char cFloat=0, cVector=0, szTemp[1024] ;

  p_stCurrentNode = p_stNode ;
  if ( CFast_Get1Param (szTemp, p_stNode, &cFloat, &cVector, 1 ) ) {
    if ( cVector ) {
      assert (NULL) ;
      return ( p_stNode+1 ) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", lIndex ) ;
    if ( cFloat ) {
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = %s ;\n", lIndex, szTemp ) ;
    }
    else {
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xLongToReal(%s) ;\n", 
		lIndex, szTemp ) ;
    }
  }
  else {
    assert (NULL) ;
    return (p_stNode+1) ;
  }

  return ( p_stNode+1 ) ;
}


CFast_tdstNode *process_special_node_for_ternary (CFast_tdstNode *p_stNode, char *szParam ) {
  CFast_tdstNode *p_stCurrentNode ;
  char cFloat=0, cVector=0, szTemp[1024] ;

  p_stCurrentNode = p_stNode ;
  if ( CFast_Get1Param (szTemp, p_stNode, &cFloat, &cVector, 1 ) ) {
    if ( cVector ) {
      assert (NULL) ;
      return ( p_stNode+1 ) ;
    }
    if ( cFloat ) {
      strcpy ( szParam, szTemp ) ;
    }
    else {
      sprintf ( szParam, "MTH_M_xLongToReal(%s)", szTemp ) ;
    }
  }
  else {
    assert (NULL) ;
    return (p_stNode+1) ;
  }

  return ( p_stNode+1 ) ;
}


CFast_tdstNode *get_param_before( CFast_tdstNode *p_stNode, long lParam ) {
  long nb ;

  p_stNode -- ;
  while ( lParam ) {
    nb = p_stNode->ucNumberOfParamNeeded ;
    p_stNode = get_param_before ( p_stNode, nb ) ; 
    lParam -- ;
  }

  return ( p_stNode ) ;
}
CFast_tdstNode *process_tern_block ( CFast_tdstNode *p_stNode, CFast_tdstNode *p_stLastNode, 
                                     char ucIndexOfEvalParam ) {
  CFast_tdstNode *p_stCurrentNode, *p_stTmp ;
  bool bSetParam ;
  long lDepth ;

  if ( is_a_ternary_operator(&p_stLastNode->stNode) ) {
    p_stTmp = p_stNode ;
    while ( p_stTmp <= p_stLastNode ) {
      p_stTmp->bIsATernOpParam = 1 ;
      p_stTmp ++ ;
    }
    p_stCurrentNode = CFast_ThirdPassProcessTernOperators ( p_stNode ) ;
  }
  else {
    p_stCurrentNode = p_stLastNode ;
    while ( p_stCurrentNode > p_stNode) {
      if ( is_a_ternary_operator(&p_stCurrentNode->stNode) ) {
        lDepth = M_DepthInterpret(&p_stCurrentNode->stNode) ;
        do {
          p_stCurrentNode->bIsATernOpParam = 1 ;
          p_stCurrentNode -- ;
        } while ( p_stCurrentNode > p_stNode && lDepth < M_DepthInterpret(&p_stCurrentNode->stNode) );
      }
      else {
        p_stCurrentNode-- ;
      }
    }
    p_stCurrentNode = p_stNode ;
    bSetParam = TRUE ;
    while ( p_stCurrentNode <= p_stLastNode ) {
      if ( p_stCurrentNode->bIsATernOpParam) {
        p_stCurrentNode = CFast_ThirdPassProcessTernOperators ( p_stCurrentNode ) ;
      }
      else if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
        p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
      }
      else if ( p_stCurrentNode->d_cOptimisedNode ) {
        CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
        p_stCurrentNode++ ;
      }
      else if ( special_node_for_ternop (p_stCurrentNode) ){
        p_stCurrentNode =  process_special_node_for_ternop(p_stCurrentNode, ucIndexOfEvalParam) ;
        bSetParam = FALSE ;
      }
      else {
        p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
      }
    }
  }

  if ( bSetParam ) {
    CFast_ThirdPassPop () ;
    CFast_ThirdPassIndent () ;
    if ( g_eParamType[p_stLastNode->ucIndexOfEvalParam] == E_vt_Integer ) {
      fprintf ( g_fdCxx, "M_xValueInterpret(&CFast_g_a_stParam[%d]) = MTH_M_xLongToReal(M_lValueInterpret(&CFast_g_a_stParam[%d]));\n", 
                ucIndexOfEvalParam, p_stLastNode->ucIndexOfEvalParam ) ;     
    }
    else if ( g_eParamType[p_stLastNode->ucIndexOfEvalParam] == E_vt_Float ) {
      fprintf ( g_fdCxx, "M_xValueInterpret(&CFast_g_a_stParam[%d]) = M_xValueInterpret(&CFast_g_a_stParam[%d]);\n", 
                ucIndexOfEvalParam, p_stLastNode->ucIndexOfEvalParam ) ;
    }
    else {
      assert (NULL) ;
    }
  }
  return (p_stCurrentNode) ;
}

void process_tern ( CFast_tdstNode *p_stNode, 
                    CFast_tdstNode *p_stTernOpNode, 
                    CFast_tdstNode *p_stParam1, 
                    CFast_tdstNode *p_stParam2, 
                    CFast_tdstNode *p_stParam3, 
                    CFast_tdstNode *p_stParam4 ) {
  CFast_tdstNode *p_stCurrentNode, *p_stNodeFromStack1, *p_stNodeFromStack2;
  char szParam1[1024], szParam2[1024] ;
  bool bPopStack ;
  char cOp ;
  char *d_szOperators[6] = { "==", "<", ">", "==", "<=", ">=" } ;

  p_stCurrentNode = p_stNode ;
  /*
   * eval param 1
   */
  bPopStack = TRUE ;
  while ( p_stCurrentNode <= p_stParam1 ) {
    if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
      p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
    }
    else if ( p_stCurrentNode->d_cOptimisedNode ) {
      CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
      p_stCurrentNode++ ;
    }
    else if ( special_node_for_ternop (p_stCurrentNode) ){
	    p_stCurrentNode =  process_special_node_for_ternary(p_stCurrentNode, szParam1) ;
	    bPopStack = FALSE ;
    }
    else {
      p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
    }
  }
    
  if ( bPopStack) {
    p_stNodeFromStack1 = CFast_ThirdPassPop () ;
    sprintf ( szParam1, "M_xValueInterpret(&CFast_g_a_stParam[%d])", p_stNodeFromStack1->ucIndexOfEvalParam ) ;
  }

  /*
   * eval param 2
   */
  bPopStack = TRUE ;
  while ( p_stCurrentNode <= p_stParam2 ) {
    if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
      p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
    }
    else if ( p_stCurrentNode->d_cOptimisedNode ) {
      CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
      p_stCurrentNode++ ;
    }
    else if ( special_node_for_ternop (p_stCurrentNode) ){
	    p_stCurrentNode =  process_special_node_for_ternary(p_stCurrentNode, szParam2) ;
	    bPopStack = FALSE ;
    }
    else {
      p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
    }
  }

  if ( bPopStack) {
    p_stNodeFromStack2 = CFast_ThirdPassPop () ;
    sprintf ( szParam2, "M_xValueInterpret(&CFast_g_a_stParam[%d])", p_stNodeFromStack2->ucIndexOfEvalParam ) ;
  }

  /*
   * make the test
   */
  CFast_ThirdPassIndent () ;
  switch ( M_eFuncIdInterpret(&p_stTernOpNode->stNode) ) {
  case eFunc_TernInf :
    cOp = 1 ;
    break ;
  case eFunc_TernSup :
    cOp = 2 ;
    break ;
  case eFunc_TernEq :
    cOp = 3 ;
    break ;
  case eFunc_TernInfEq :
    cOp = 4 ;
    break ;
  case eFunc_TernSupEq :
    cOp = 5 ;
    break ;
  default :
    cOp = 0 ;
    fprintf ( g_fdCxx, "/* bad test !! unknown operator */\n") ;
    CFast_ThirdPassIndent () ;
    MessageBox ( NULL, "traitement des operateurs Math_Tern???", "ERROR !", MB_ICONSTOP ) ;
    break ;
  }
  fprintf ( g_fdCxx, "if ( %s %s %s ) {\n", szParam1, d_szOperators[cOp], szParam2 ) ;
  CFast_ThirdPassAddIndentLevel () ;

  /*
   * eval param 3
   */
  p_stCurrentNode = process_tern_block ( p_stCurrentNode, p_stParam3,  
                                         p_stTernOpNode->ucIndexOfEvalParam) ;

  CFast_ThirdPassRmIndentLevel () ;
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "} else {\n" ) ;
  CFast_ThirdPassAddIndentLevel () ;

  /*
   * eval param 4
   */
  p_stCurrentNode = process_tern_block ( p_stCurrentNode, p_stParam4, 
                                         p_stTernOpNode->ucIndexOfEvalParam) ;

  g_eParamType[p_stTernOpNode->ucIndexOfEvalParam] = E_vt_Float ;
  CFast_ThirdPassRmIndentLevel () ;
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "}\n" ) ;
}
void CFast_ThirdPassProcessTernOp ( CFast_tdstNode *p_stNode, 
                                    CFast_tdstNode *p_stTernOpNode, 
                                    CFast_tdstNode *p_stParam1, 
                                    CFast_tdstNode *p_stParam2,
                                    CFast_tdstNode *p_stParam3 ) {
  CFast_tdstNode *p_stCurrentNode;
  bool bSetParam ;

  p_stCurrentNode = p_stNode ;
  /*
   * eval condition
   */
  while ( p_stCurrentNode <= p_stParam1 ) {
    if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
      p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
    }
    else if ( p_stCurrentNode->d_cOptimisedNode ) {
      CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
      p_stCurrentNode++ ;
    }
    else {
      if ( special_node_for_ternop (p_stCurrentNode) ) {
        p_stCurrentNode->bIsABooleanDsgVarRef = 1 ;
      }
      p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
    }
  }

  CFast_ThirdPassIndent () ;
  if ( g_ulCondStringSet ) {
  	fprintf ( g_fdCxx, "if ( %s ) {\n", g_szConditionString2 ) ;
  	g_ulCondStringSet = 0 ;
  }
  else if ( p_stParam1->ucIndexOfEvalParam ) {
    CFast_ThirdPassPop () ;
    fprintf ( g_fdCxx, "if (M_lValueInterpret(&CFast_g_a_stParam[%d])) {\n", p_stParam1->ucIndexOfEvalParam ) ;
  }
  else {
    fprintf ( g_fdCxx, "if ( long%d ) {\n", g_lIndexForCondition ) ;    
  }
  CFast_ThirdPassAddIndentLevel () ;
  /*
   * eval param 2
   */
  bSetParam = TRUE ;

  p_stCurrentNode = process_tern_block ( p_stCurrentNode, p_stParam2,  
                                         p_stTernOpNode->ucIndexOfEvalParam) ;

  CFast_ThirdPassRmIndentLevel () ;
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "} else {\n" ) ;
  CFast_ThirdPassAddIndentLevel () ;

  /*
   * eval param 3
   */
  p_stCurrentNode = process_tern_block ( p_stCurrentNode, p_stParam3,  
                                         p_stTernOpNode->ucIndexOfEvalParam) ;
  g_eParamType[p_stTernOpNode->ucIndexOfEvalParam] = E_vt_Float ;
  CFast_ThirdPassRmIndentLevel () ;
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "}\n" ) ;
}

CFast_tdstNode *CFast_ThirdPassProcessTernOperators ( CFast_tdstNode *p_stNode ) {
  CFast_tdstNode *p_stCurrentNode, *p_stTernOpNode, *p_stParam1, *p_stParam2, *p_stParam3, *p_stParam4 ;
  CFast_tdstNode *p_stLastNode, *p_stFather ;
  bool bTernOp = FALSE, soon_of_ternop ;

  /*
   * unmark all the ternary operator's parameters
   * be careful of nested ternary operator
   */
  p_stLastNode = p_stNode ;
  do {
    p_stLastNode->bIsATernOpParam = 0 ;
    p_stLastNode ++ ;

    /* look for nested operators */
    if ( is_a_ternary_operator (&p_stLastNode->stNode) ) {
      soon_of_ternop = FALSE ;
      p_stFather = p_stLastNode ;
      while ( (p_stFather = get_father(p_stFather)) && !soon_of_ternop ) {
        if ( is_a_ternary_operator (&p_stFather->stNode) && p_stFather->bIsATernOpParam >= 0)
          soon_of_ternop = TRUE ; /* if the father is a ternary operator and if it has not 
                                     been processed yet, this is not the top of the tree
                                     look for the next operator */
      }
      if ( !soon_of_ternop ) {
        p_stLastNode->bIsATernOpParam = 0 ;
        p_stLastNode ++ ;
        break ;
      }
    }

  } while ( p_stLastNode->bIsATernOpParam ) ;

  p_stCurrentNode = p_stNode ;
  p_stTernOpNode = p_stLastNode - 1;
  p_stTernOpNode->bIsATernOpParam = -1 ; /* operator processed */
  if ( M_eFuncIdInterpret(&p_stTernOpNode->stNode) == eFunc_TernOp ) {
    bTernOp = TRUE ;
    p_stParam1 = get_param_before ( p_stTernOpNode, 2 ) ;  
    p_stParam2 = get_param_before ( p_stTernOpNode, 1 ) ;  
    p_stParam3 = get_param_before ( p_stTernOpNode, 0 ) ;
    CFast_ThirdPassProcessTernOp (p_stCurrentNode,p_stTernOpNode, p_stParam1,
                                  p_stParam2, p_stParam3) ;
  }
  else {
    p_stParam1 = get_param_before ( p_stTernOpNode, 3 ) ;  
    p_stParam2 = get_param_before ( p_stTernOpNode, 2 ) ;  
    p_stParam3 = get_param_before ( p_stTernOpNode, 1 ) ;
    p_stParam4 = get_param_before ( p_stTernOpNode, 0 ) ;
    process_tern ( p_stCurrentNode, p_stTernOpNode, p_stParam1, p_stParam2, p_stParam3, p_stParam4) ;
  }

  
  p_stTernOpNode->ucNumberOfParamNeeded = 0 ;
  CFast_ThirdPassPush (p_stTernOpNode) ;
  return (p_stLastNode) ;
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassInitPseudoTree
 * DESCRIPTION : init pseudo-tree for optimisation
 *******************************************************************************/
void CFast_ThirdPassInitPseudoTree (long lIndex) {
  int i, j ;

  if ( lIndex < 0 ) {
    for ( j=0 ; j<7 ; j++ )
      for (i=1 ; i<CFast_lMaxTreeDepth ; i++ ) 
	M_SetTypeInterpret(&g_a_stPseudoTree[j][i], E_ti_Unknown) ;

    M_SetTypeInterpret(&g_a_stPseudoTree[E_ti_KeyWord][0]   , E_ti_KeyWord);
    M_SetTypeInterpret(&g_a_stPseudoTree[E_ti_Condition][0] , E_ti_Condition);
    M_SetTypeInterpret(&g_a_stPseudoTree[E_ti_Operator][0]  , E_ti_Operator);
    M_SetTypeInterpret(&g_a_stPseudoTree[E_ti_Function][0]  , E_ti_Function);
    M_SetTypeInterpret(&g_a_stPseudoTree[E_ti_Procedure][0] , E_ti_Procedure);
    M_SetTypeInterpret(&g_a_stPseudoTree[E_ti_MetaAction][0], E_ti_MetaAction);
    M_SetTypeInterpret(&g_a_stPseudoTree[6][0]    , E_ti_Vector);
  }
  else if ( lIndex > 0 ) {
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][lIndex], E_ti_Unknown) ;
  }
}



/*******************************************************************************
 * FUNCTION    : procedure_can_stop_engine
 * DESCRIPTION : return TRUE if the procedure can stop the AI engine
 *               eProc_ChangeMyComport, eProc_ChangeMyComportReflex and
 *               eProc_ChangeMyComportAndMyReflex are process separately
 *               so don 't put them here !
 *******************************************************************************/
bool procedure_can_stop_engine (tdeProcedureId eProcedure) {
	bool res = FALSE ;
	switch (eProcedure)
	{
	case eProc_BreakAI :
	case eProc_KillPerso :
	case eProc_KillPersoAndClearVariable :
	case eProc_ChangeAction :
	case eProc_ChangeActionForce :
	case eProc_ChangeActionRandom :
	case eProc_ChangeActionWithEvents :
		res = TRUE ;
		break ;
	}
	return (res) ;
}



/*******************************************************************************
 *******************************************************************************
 * gestion des macros
 *******************************************************************************
 *******************************************************************************/
typedef struct CFast_tdstSubr_ {
  void *p_vPtr ;
  long lGotMeta ;
  long lCreated ; 
  long lGotRfxOrCmp ;
} CFast_tdstSubr ;

CFast_tdstSubr *g_d_stSubr = NULL ;
unsigned long g_ulNbOfSubr = 0 ;

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddSubr
 * DESCRIPTION : add a subroutine in the list of the subroutine
 *               called before the 1st pass
 *******************************************************************************/
void test_node_for_subr ( tdstNodeInterpret *p_stNode )
{
	if ( M_GetTypeInterpret(p_stNode) == E_ti_MetaAction )
	{
		g_d_stSubr[g_ulNbOfSubr-1].lGotMeta ++ ;
	}
	else if ( M_GetTypeInterpret(p_stNode) == E_ti_Procedure )
	{
		if ( M_eProcedureIdInterpret(p_stNode) == eProc_SetActionReturn )
		{
			g_d_stSubr[g_ulNbOfSubr-1].lGotMeta ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_ChangeMyComport )
		{
			g_d_stSubr[g_ulNbOfSubr-1].lGotRfxOrCmp ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_ChangeMyComportReflex )
		{
			g_d_stSubr[g_ulNbOfSubr-1].lGotRfxOrCmp ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) ==  eProc_ChangeMyComportAndMyReflex)
		{
			g_d_stSubr[g_ulNbOfSubr-1].lGotRfxOrCmp += 2 ; 
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_KillPerso )
		{
			g_d_stSubr[g_ulNbOfSubr-1].lGotRfxOrCmp ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_KillPersoAndClearVariable )
		{
			g_d_stSubr[g_ulNbOfSubr-1].lGotRfxOrCmp ++ ;
		}
		else if ( procedure_can_stop_engine ( M_eProcedureIdInterpret(p_stNode) ) )
		{
			g_d_stSubr[g_ulNbOfSubr-1].lGotRfxOrCmp ++ ;
		}
	}
}

tdstMacro * fn_p_stGetMacroRefFromEditorPointer ( CPA_EdIR_MainBehaviour * _p_stEditorSubroutine ) ;

long CFast_ThirdPassAddSubr ( void * vSubrId )
{
	tdstMacro * p_stMacro = fn_p_stGetMacroRefFromEditorPointer ( ( CPA_EdIR_MainBehaviour * ) vSubrId ) ;
	if ( g_d_stSubr == NULL )
	{
		g_d_stSubr = ( CFast_tdstSubr * ) malloc ( sizeof ( CFast_tdstSubr ) ) ;
		g_ulNbOfSubr = 1 ;
		g_d_stSubr -> p_vPtr = p_stMacro ;
		g_d_stSubr -> lGotMeta = 0 ;
		g_d_stSubr -> lCreated = 0 ;
		g_d_stSubr -> lGotRfxOrCmp = 0 ;
	}
	else
	{
		if ( CFast_ThirdPassIsSubrExist ( p_stMacro ) >= 0 )
		{
			return (-1) ;
		}
		g_ulNbOfSubr++ ;
		g_d_stSubr = ( CFast_tdstSubr * ) realloc ( g_d_stSubr , g_ulNbOfSubr * sizeof ( CFast_tdstSubr ) ) ; 
		g_d_stSubr [ g_ulNbOfSubr - 1 ] . p_vPtr = p_stMacro ;
		g_d_stSubr [ g_ulNbOfSubr - 1 ] . lGotMeta = 0 ;
		g_d_stSubr [ g_ulNbOfSubr - 1 ] . lCreated = 0 ;
		g_d_stSubr [ g_ulNbOfSubr - 1 ] . lGotRfxOrCmp = 0 ;
	}
	/* here a subroutine was added */
	{
		tdstTreeInterpret * p_stCurrentRule = p_stMacro -> p_stInitTree ;
		tdstNodeInterpret * p_stTmpNode = p_stCurrentRule -> p_stNodeInterpret ;

		while ( M_GetTypeInterpret(p_stTmpNode) != E_ti_EndTree )
		{
			test_node_for_subr ( p_stTmpNode ) ;
			p_stTmpNode ++ ;
		}
	}
	return ( g_ulNbOfSubr - 1 ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassIsSubrExist
 * DESCRIPTION : check if a subroutine exist
 *******************************************************************************/
long CFast_ThirdPassIsSubrExist ( void * vSubrId )
{
	long i ;

	for ( i = 0 ; i < ( long ) g_ulNbOfSubr ; i ++ )
	{
		if ( g_d_stSubr [ i ] . p_vPtr == vSubrId )
			return i ;
	}
	return (-1) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassInitSubr
 * DESCRIPTION : init the subroutine table
 *               must be called before the 3rd pass initialisation
 *******************************************************************************/
void CFast_ThirdPassInitSubr ( AI_tdstMind * p_stMind )
{
	unsigned long ulComport, ulNbComport;
	unsigned long ulRules ;
	unsigned long ulNodesCount;
	tdstListOfMacro *p_stListOfMacro ;
	tdstMacro *p_stMacro;
	tdstComport *p_stComport ;
	tdstTreeInterpret *p_stCurrentRule;
	tdstNodeInterpret *p_stCurrentNode;
	long lSubr , lNbSubr ;

	/*
	 * subroutine
	 */
	p_stListOfMacro = AI_M_p_stGetListOfMacroAIModel(AI_M_p_stGetAIModel(p_stMind));
	if ( p_stListOfMacro )
	{
		for ( lNbSubr = 0 ; lNbSubr < M_GetNbMacro(p_stListOfMacro) ; lNbSubr ++ )
		{
			p_stMacro = M_GetMacroN ( p_stListOfMacro , lNbSubr ) ;
			p_stCurrentRule = p_stMacro->p_stInitTree ;
			for
			(
				ulNodesCount=0, p_stCurrentNode = p_stCurrentRule->p_stNodeInterpret ; 
				ulNodesCount < p_stCurrentRule->uwNbNode ; 
				ulNodesCount ++ , p_stCurrentNode ++
			)
			{
				if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_MacroRef )
				{
					lSubr = CFast_ThirdPassAddSubr ( (void *)M_p_stMacroInterpret(p_stCurrentNode) ) ;
				}
			}
		}
	}


	/*
	* reflex
	*/
	if ( AI_M_p_stGetReflex(p_stMind) == NULL )
		goto Intelligence ; /* pour yann :-) */
	ulNbComport = M_GetNbComport(AI_M_p_stGetReflex(p_stMind)) ;
	for ( ulComport=0 ; ulComport<ulNbComport ; ulComport++ )
	{
		p_stComport = M_GetComportN(AI_M_p_stGetReflex(p_stMind), ulComport );
		if (p_stComport->p_stSchedule != NULL)
		{
			p_stCurrentRule = p_stComport->p_stSchedule;
			for
			(
				ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
				ulNodesCount<p_stCurrentRule->uwNbNode ; 
				ulNodesCount++, p_stCurrentNode++
			)
			{
				if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_MacroRef )
				{
					lSubr = CFast_ThirdPassAddSubr ( (void *)M_p_stMacroInterpret(p_stCurrentNode) ) ;
				}
			}
		}
		else
		{
			for
			(
				ulRules=0, p_stCurrentRule=p_stComport->p_stRules ;
				ulRules<p_stComport->ucNbRules ; 
				ulRules++, p_stCurrentRule++
			)
			{
				for
				(
					ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
					ulNodesCount<p_stCurrentRule->uwNbNode ; 
					ulNodesCount++, p_stCurrentNode++
				)
				{
					if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_MacroRef )
					{
						lSubr = CFast_ThirdPassAddSubr ( (void *)M_p_stMacroInterpret(p_stCurrentNode) ) ;
					}
				}
			}
		}
	}
	/*
	* intelligence
	*/
Intelligence:
	if ( AI_M_p_stGetIntelligence(p_stMind) == NULL ) 
		return ;
	ulNbComport = M_GetNbComport(AI_M_p_stGetIntelligence(p_stMind)) ;
	for ( ulComport=0 ; ulComport<ulNbComport ; ulComport++ )
	{
		p_stComport = M_GetComportN(AI_M_p_stGetIntelligence(p_stMind), ulComport );
		if (p_stComport->p_stSchedule != NULL)
		{
			p_stCurrentRule = p_stComport->p_stSchedule;
			for
			(
				ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
				ulNodesCount<p_stCurrentRule->uwNbNode ; 
				ulNodesCount++, p_stCurrentNode++
			)
			{
				if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_MacroRef )
				{
					lSubr = CFast_ThirdPassAddSubr ( (void *)M_p_stMacroInterpret(p_stCurrentNode) ) ;
				}
			}
		}
		else
		{
			for
			(
				ulRules=0, p_stCurrentRule=p_stComport->p_stRules ;
				ulRules<p_stComport->ucNbRules ; 
				ulRules++, p_stCurrentRule++
			)
			{
				for
				(
					ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
					ulNodesCount<p_stCurrentRule->uwNbNode ; 
					ulNodesCount++, p_stCurrentNode++
				)
				{
					if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_MacroRef )
					{
						lSubr = CFast_ThirdPassAddSubr ( (void *)M_p_stMacroInterpret(p_stCurrentNode) ) ;
					}
				}
			}
		}
	}
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassCreateSubr
 * DESCRIPTION : write down the code for a subroutine
 *******************************************************************************/
void CFast_ThirdPassCreateSubr (CFast_tdstNode *p_stNode) {
  CFast_tdstNode *p_stCurrentNode ;

  p_stCurrentNode = p_stNode ;
  while ( M_GetTypeInterpret((&p_stCurrentNode->stNode)) != E_ti_EndTree && p_stCurrentNode<g_p_stLastNode) {
    if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
      p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
    }
    else if ( p_stCurrentNode->d_cOptimisedNode ) {
      CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
      p_stCurrentNode++ ;
    }
    else {
      p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
    }
  }  
}



/*******************************************************************************
 *******************************************************************************
 * gestion des macros
 *******************************************************************************
 *******************************************************************************/
typedef struct CFast_tdstMacro_ {
  void *p_vPtr ;
  long lGotMeta ;
  long lCreated ; 
  long lGotRfxOrCmp ;
} CFast_tdstMacro ;

CFast_tdstMacro *g_d_stMacro = NULL ;
unsigned long g_ulNbOfMacro = 0 ;
unsigned long g_ulNbMacroInCurrentComport = 0 ;

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddMacro
 * DESCRIPTION : add a macro in the list of the macro 
 *               called before the 1st pass
 *******************************************************************************/
long CFast_ThirdPassAddMacro ( void *vMacroId ) {
  if ( g_d_stMacro == NULL ) {
    g_d_stMacro = (CFast_tdstMacro *) malloc ( sizeof (CFast_tdstMacro) ) ;
    g_ulNbOfMacro = 1 ;
    g_d_stMacro->p_vPtr = vMacroId ;
    g_d_stMacro->lGotMeta = 0 ;
    g_d_stMacro->lCreated = 0 ;
    g_d_stMacro->lGotRfxOrCmp = 0 ;
  }
  else {
    if ( CFast_ThirdPassIsMacroExist(vMacroId) >= 0 ) {
      return (-1) ;
    }
    g_ulNbOfMacro++ ;
    g_d_stMacro = (CFast_tdstMacro *) realloc ( g_d_stMacro, g_ulNbOfMacro*sizeof (CFast_tdstMacro) ) ; 
    g_d_stMacro[g_ulNbOfMacro-1].p_vPtr = vMacroId ;
    g_d_stMacro[g_ulNbOfMacro-1].lGotMeta = 0 ;
    g_d_stMacro[g_ulNbOfMacro-1].lCreated = 0 ;
    g_d_stMacro[g_ulNbOfMacro-1].lGotRfxOrCmp = 0 ;
  }
  return (g_ulNbOfMacro-1) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassIsMacroCreate
 * DESCRIPTION : check if a macro has already been writen
 *******************************************************************************/
long CFast_ThirdPassIsMacroCreate(void *vMacroId) {
  long i ;

  for (i=0; i<(long)g_ulNbOfMacro ; i++ ) {
    if ( g_d_stMacro[i].p_vPtr == vMacroId )
      if ( g_d_stMacro[i].lCreated )
	return (i) ;
    else 
      return (-1) ;
  }
  return (-1) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassIsMacroExist
 * DESCRIPTION : check if a macro exist
 *******************************************************************************/
long CFast_ThirdPassIsMacroExist(void *vMacroId) {
  long i ;

  for (i=0; i<(long)g_ulNbOfMacro ; i++ ) {
    if ( g_d_stMacro[i].p_vPtr == vMacroId )
      return (i) ;
  }
  return (-1) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassInitMacro
 * DESCRIPTION : init the macro table
 *               must be called before the 3rd pass initialisation
 *******************************************************************************/
void test_node_for_macro ( tdstNodeInterpret *p_stNode )
{
	if ( M_GetTypeInterpret(p_stNode) == E_ti_MetaAction )
	{
		g_d_stMacro[g_ulNbOfMacro-1].lGotMeta ++ ;
	}
	else if ( M_GetTypeInterpret(p_stNode) == E_ti_Procedure )
	{
		if ( M_eProcedureIdInterpret(p_stNode) == eProc_SetActionReturn )
		{
			g_d_stMacro[g_ulNbOfMacro-1].lGotMeta ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_ChangeMyComport )
		{
			g_d_stMacro[g_ulNbOfMacro-1].lGotRfxOrCmp ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_ChangeMyComportReflex )
		{
			g_d_stMacro[g_ulNbOfMacro-1].lGotRfxOrCmp ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) ==  eProc_ChangeMyComportAndMyReflex)
		{
			g_d_stMacro[g_ulNbOfMacro-1].lGotRfxOrCmp += 2 ; 
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_KillPerso )
		{
			g_d_stMacro[g_ulNbOfMacro-1].lGotRfxOrCmp ++ ;
		}
		else if ( M_eProcedureIdInterpret(p_stNode) == eProc_KillPersoAndClearVariable )
		{
			g_d_stMacro[g_ulNbOfMacro-1].lGotRfxOrCmp ++ ;
		}
		else if ( procedure_can_stop_engine ( M_eProcedureIdInterpret(p_stNode) ) )
		{
			g_d_stMacro[g_ulNbOfMacro-1].lGotRfxOrCmp ++ ;
		}
	}
}

void CFast_ThirdPassInitMacro ( AI_tdstMind *p_stMind )
{
	unsigned long ulComport, ulNbComport, lDone ;
	unsigned long ulRules, ulTmpRulesCount  ;
	unsigned long ulNodesCount, ulNodesCount2;
	tdstComport *p_stComport ;
	tdstListOfMacro *p_stListOfMacro ;
	tdstMacro *p_stMacro;
	tdstTreeInterpret *p_stCurrentRule, *p_stTmpRule;
	tdstNodeInterpret *p_stCurrentNode, *p_stTmpNode;
	long lMacro , lNbSubr ;

	/*
	 * subroutine
	 */
	p_stListOfMacro = AI_M_p_stGetListOfMacroAIModel(AI_M_p_stGetAIModel(p_stMind));
	if ( p_stListOfMacro )
	{
		for ( lNbSubr = 0 ; lNbSubr < M_GetNbMacro(p_stListOfMacro) ; lNbSubr ++ )
		{
			p_stMacro = M_GetMacroN ( p_stListOfMacro , lNbSubr ) ;
			p_stCurrentRule = p_stMacro->p_stInitTree ;
			for
			(
				ulNodesCount=0, p_stCurrentNode = p_stCurrentRule->p_stNodeInterpret ; 
				ulNodesCount < p_stCurrentRule->uwNbNode ; 
				ulNodesCount ++ , p_stCurrentNode ++
			)
			{
				if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_BeginMacro )
				{
					lMacro = CFast_ThirdPassAddMacro ( (void *) M_lValueInterpret(p_stCurrentNode) ) ;
					if ( lMacro >= 0 )
					{
						p_stTmpNode = p_stCurrentNode + 1 ;
						ulNodesCount2 = ulNodesCount ;
						while ( M_GetTypeInterpret(p_stTmpNode) != E_ti_EndMacro && ulNodesCount2 < p_stCurrentRule->uwNbNode )
						{
							test_node_for_macro ( p_stTmpNode ) ;
							p_stTmpNode ++ ;
							ulNodesCount2 ++ ;
						}
					}
				}
			}
		}
	}



	/*
	 * reflex
	 */
	if ( AI_M_p_stGetReflex(p_stMind) == NULL )
		goto Intelligence ; /* pour yann :-) */

	ulNbComport = M_GetNbComport(AI_M_p_stGetReflex(p_stMind)) ;
	for ( ulComport=0 ; ulComport<ulNbComport ; ulComport++ )
	{
		p_stComport = M_GetComportN(AI_M_p_stGetReflex(p_stMind), ulComport );
		if (p_stComport->p_stSchedule != NULL)
		{
			p_stCurrentRule = p_stComport->p_stSchedule;
			for
			(
				ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
				ulNodesCount<p_stCurrentRule->uwNbNode ; 
				ulNodesCount++, p_stCurrentNode++
			)
			{
				if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_BeginMacro )
				{
					lMacro = CFast_ThirdPassAddMacro ( (void *)M_lValueInterpret(p_stCurrentNode) ) ;
					if ( lMacro >= 0 )
					{
						p_stTmpNode = p_stCurrentNode + 1 ;
						ulNodesCount2 = ulNodesCount ;
						while ( M_GetTypeInterpret(p_stTmpNode) != E_ti_EndMacro && ulNodesCount2<p_stCurrentRule->uwNbNode )
						{
							test_node_for_macro ( p_stTmpNode ) ;
							p_stTmpNode++ ;
							ulNodesCount2++ ;
						}
					}
				}
			}
		}
		else
		{
			for
			(
				ulRules=0, p_stCurrentRule=p_stComport->p_stRules ;
				ulRules<p_stComport->ucNbRules ; 
				ulRules++, p_stCurrentRule++
			)
			{
				for
				(
					ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
					ulNodesCount<p_stCurrentRule->uwNbNode ; 
					ulNodesCount++, p_stCurrentNode++
				)
				{
					if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_BeginMacro )
					{
						lMacro = CFast_ThirdPassAddMacro ( (void *)M_lValueInterpret(p_stCurrentNode) ) ;
						if ( lMacro >= 0 )
						{
							p_stTmpNode = p_stCurrentNode + 1 ;
							p_stTmpRule = p_stCurrentRule ;
							ulTmpRulesCount = ulRules ;
							ulNodesCount2 = ulNodesCount ;
							lDone = 0 ;
							while ( M_GetTypeInterpret(p_stTmpNode) != E_ti_EndMacro && !lDone )
							{
								test_node_for_macro ( p_stTmpNode ) ;
								p_stTmpNode++ ;
								ulNodesCount2++ ;
								if ( ulNodesCount2>p_stTmpRule->uwNbNode )
								{ 
									/* next rule */
									ulTmpRulesCount++ ;
									if ( ulTmpRulesCount<p_stComport->ucNbRules )
									{
										ulNodesCount2 = 0 ;
										p_stTmpRule++ ;
										p_stTmpNode = p_stTmpRule->p_stNodeInterpret ;
									}
									else
									{
										lDone = 1 ;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	/*
	 * intelligence
	 */
Intelligence:
	if ( AI_M_p_stGetIntelligence(p_stMind) == NULL ) 
		return ;
	ulNbComport = M_GetNbComport(AI_M_p_stGetIntelligence(p_stMind)) ;
	for ( ulComport=0 ; ulComport<ulNbComport ; ulComport++ )
	{
		p_stComport = M_GetComportN(AI_M_p_stGetIntelligence(p_stMind), ulComport );
		if (p_stComport->p_stSchedule != NULL)
		{
			p_stCurrentRule = p_stComport->p_stSchedule;
			for
			(
				ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
				ulNodesCount<p_stCurrentRule->uwNbNode ; 
				ulNodesCount++, p_stCurrentNode++
			)
			{
				if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_BeginMacro )
				{
					lMacro = CFast_ThirdPassAddMacro ( (void *)M_lValueInterpret(p_stCurrentNode) ) ;
					if ( lMacro >= 0 )
					{
						p_stTmpNode = p_stCurrentNode + 1 ;
						ulNodesCount2 = ulNodesCount ;
						while ( M_GetTypeInterpret(p_stTmpNode) != E_ti_EndMacro && ulNodesCount2<p_stCurrentRule->uwNbNode )
						{
							test_node_for_macro ( p_stTmpNode ) ;
							p_stTmpNode++ ;
							ulNodesCount2++ ;
						}
					}
				}
			}
		}
		else
		{
			for
			(
				ulRules=0, p_stCurrentRule=p_stComport->p_stRules ;
				ulRules<p_stComport->ucNbRules ; 
				ulRules++, p_stCurrentRule++
			)
			{
				for
				(
					ulNodesCount=0, p_stCurrentNode=p_stCurrentRule->p_stNodeInterpret ; 
					ulNodesCount<p_stCurrentRule->uwNbNode ; 
					ulNodesCount++, p_stCurrentNode++
				)
				{
					if ( M_GetTypeInterpret(p_stCurrentNode) == E_ti_BeginMacro )
					{
						lMacro = CFast_ThirdPassAddMacro ( (void *)M_lValueInterpret(p_stCurrentNode) ) ;
						if ( lMacro >= 0 )
						{
							p_stTmpNode = p_stCurrentNode + 1 ;
							p_stTmpRule = p_stCurrentRule ;
							ulTmpRulesCount = ulRules ;
							ulNodesCount2 = ulNodesCount ;
							lDone = 0 ;
							while ( M_GetTypeInterpret(p_stTmpNode) != E_ti_EndMacro && !lDone )
							{
								test_node_for_macro ( p_stTmpNode ) ;
								p_stTmpNode++ ;
								ulNodesCount2++ ;
								if ( ulNodesCount2>p_stTmpRule->uwNbNode )
								{ 
									/* next rule */
									ulTmpRulesCount++ ;
									if ( ulTmpRulesCount<p_stComport->ucNbRules )
									{
										ulNodesCount2 = 0 ;
										p_stTmpRule++ ;	
										p_stTmpNode = p_stTmpRule->p_stNodeInterpret ;
									}
									else
									{
										lDone = 1 ;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassCreateMacro
 * DESCRIPTION : write down the code for a macro
 *******************************************************************************/
void CFast_ThirdPassCreateMacro (CFast_tdstNode *p_stNode) {
  CFast_tdstNode *p_stCurrentNode ;

  p_stCurrentNode = p_stNode ;
  while ( M_GetTypeInterpret((&p_stCurrentNode->stNode)) != E_ti_EndMacro && p_stCurrentNode<g_p_stLastNode) {
    if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
      p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
    }
    else if ( p_stCurrentNode->d_cOptimisedNode ) {
      CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
      p_stCurrentNode++ ;
    }
    else {
      p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
    }
  }  
}
/*******************************************************************************
 *******************************************************************************
 * initialisation 
 *******************************************************************************
 *******************************************************************************/


/*******************************************************************************
 * FUNCTION    : init_thirdpass
 * DESCRIPTION : made some init before parse a tree
 *******************************************************************************/
unsigned long g_ulNbOfChangeRfx ;
unsigned long g_ulNbOfChangeCmp ;
unsigned long g_ulNbOfReference ;
unsigned long g_ulNbOfDsgVar ;

void init_decleration (CFast_tdstNode *p_stNode, unsigned long ulNbNode, char cMacro)
{
	CFast_tdstNode * p_stCurrentNode , * p_stLastNode ;
	char cDone = 0 ;
	tdeTypeInterpret eNodeType ;

	g_ulNbOfChangeRfx = 0 ;
	g_ulNbOfChangeCmp = 0 ;
	g_ulNbOfReference = 0 ;
	g_ulNbOfDsgVar    = 0 ;
	p_stCurrentNode   = p_stNode ;
	p_stLastNode      = p_stNode + ulNbNode ;

	while ( p_stCurrentNode < p_stLastNode && !cDone)
	{
		eNodeType = M_GetTypeInterpret((&p_stCurrentNode->stNode)) ;

		if ( cMacro && eNodeType == E_ti_EndMacro ) 
			break ;
		if ( p_stCurrentNode->lIndexOfRef >= 0 )
		{
			g_ulNbOfReference ++ ;
			p_stCurrentNode ++ ;
			continue ;
		}
		switch ( eNodeType )
		{
		case E_ti_DsgVarRef :
			g_ulNbOfDsgVar ++ ;
			break ;

		case E_ti_Procedure :
			if ( M_eProcedureIdInterpret((&p_stCurrentNode->stNode)) == eProc_ChangeMyComport )
			{
				g_ulNbOfChangeCmp++ ;
			}
			else if ( M_eProcedureIdInterpret((&p_stCurrentNode->stNode)) == eProc_ChangeMyComportReflex )
			{
				g_ulNbOfChangeRfx++ ;
			}	
			else if ( M_eProcedureIdInterpret((&p_stCurrentNode->stNode)) == eProc_ChangeMyComportAndMyReflex )
			{
				g_ulNbOfChangeRfx ++ ;
				g_ulNbOfChangeCmp ++ ;
			}
			break ;
		}
		if ( eNodeType == E_ti_BeginMacro )
		{
			while ( p_stCurrentNode < p_stLastNode && M_GetTypeInterpret((&p_stCurrentNode->stNode)) != E_ti_EndMacro )
				p_stCurrentNode++ ;
		}
		p_stCurrentNode++ ;
	}
}
/*******************************************************************************
 Common local variable declatation.
 *******************************************************************************/
void CFast_ThirdPassLocalDeclaration ( void )
{
	fprintf ( g_fdCxx, "  register  AI_tdstMind * p_stLocalMind0 = p_stGlobalMind ;\n");

	if ( g_ulNbOfReference ) 
		fprintf ( g_fdCxx, "  register struct tdstNodeInterpret_   *p_stRefTree = gp_stRefTree;\n");

	fprintf ( g_fdCxx, "  register struct tdstNodeInterpret_ * p_stPseudoTree = gp_stPseudoTree ;\n");

	if ( g_ulNbOfChangeCmp && ( g_eProcessWhat != E_pw_Reflex ) ) 
		fprintf ( g_fdCxx, "  register tdstIntelligence * p_stIntelligence = p_stLocalMind0 -> p_stIntelligence ;\n") ;

	if ( g_ulNbOfChangeRfx && ( g_eProcessWhat != E_pw_Comport ) ) 
		fprintf ( g_fdCxx, "  register tdstIntelligence * p_stReflex = p_stLocalMind0->p_stReflex ;\n") ;

	if ( g_ulGotDsgVar && g_ulNbOfDsgVar )
	{
		fprintf ( g_fdCxx, "  register char * p_cLocalDsgMemBuffer = p_cGlobalDsgMemBuffer ;\n");
		fprintf ( g_fdCxx, "  register tdstDsgVarInfo * p_stLocalDsgVarInfo = p_stGlobalDsgVarInfo ;\n");
	}

	fprintf ( g_fdCxx, "\n");

	fprintf ( g_fdCxx, "  register long long1 , long2 ;\n");
	fprintf ( g_fdCxx, "  long long3 , long4 , long5 , long6 , long7 , long8 ;\n");
	fprintf ( g_fdCxx, "  register AI_tdstMind * p_stLocalMind1 , * p_stLocalMind2 , * p_stLocalMind4 , * p_stLocalMind8 ;\n");

	fprintf ( g_fdCxx, "\n");
}

void init_global_vars (void)
{
  g_ulLabelNumber = 0 ;
  g_lCompteurPourLesSi = 0 ;
  g_ulNumberFor = 0 ;
  g_ulBreak = 0 ;
  g_ulProcessIf = 0 ;
  g_ulNbMacroInCurrentComport = 0 ;
  g_lIndexForCondition = 1 ;
  g_ulBloquantMoteur = 0 ;
  CFast_ThirdPassInitPseudoTree (-1) ;
  memset (g_lOpenedBraceByIf, 0, 128*sizeof(long)) ;
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassCreateAllMacro
 * DESCRIPTION : parse the tree for new macro to write 
 *******************************************************************************/
void CFast_ThirdPassCreateAllMacro (CFast_tdstNode *p_stNode, unsigned long ulNbNode, char *szDecl)
{
	unsigned long i = 0 , j ;
	long lMacro ;
	CFast_tdstNode *p_stCurrentNode, *p_stLastNode ;
	tdeTypeInterpret eNodeType ;

	p_stCurrentNode = p_stNode ;
	g_p_stLastNode = p_stLastNode = p_stNode + ulNbNode ;

	while ( i < g_ulNbOfMacro && p_stCurrentNode < p_stLastNode )
	{
		eNodeType = M_GetTypeInterpret((&p_stCurrentNode->stNode)) ;
		if ( eNodeType == E_ti_BeginMacro )
		{
			g_eProcessWhat = E_pw_Macro ;

			lMacro = CFast_ThirdPassIsMacroCreate( (void *)M_lValueInterpret(&p_stCurrentNode->stNode) ) ;
			if ( lMacro < 0 )
			{
				init_decleration(p_stCurrentNode+1, p_stLastNode-p_stCurrentNode-1, 1) ;
				lMacro = CFast_ThirdPassIsMacroExist( (void *)M_lValueInterpret(&p_stCurrentNode->stNode) ) ;
				fprintf ( g_fdCxx, "long CFast_%s_Macro_%d (void)\n{\n", g_szModelName, lMacro ) ;
				CFast_ThirdPassAddIndentLevel () ;
				/*
				* declaration des varaibles locales
				*/
				if ( szDecl != NULL )
					fprintf ( g_fdCxx, "%s\n\n", szDecl ) ;

				CFast_ThirdPassLocalDeclaration();

				/*
				* MetaAction et Bloquant Moteur
				*/
				if ( g_d_stMacro[lMacro].lGotMeta )
				{
					CFast_ThirdPassIndent () ;
					fprintf ( g_fdCxx, "long lMetaAction ;\n\n" ) ; /* <------------ declaration de variable !!*/
					CFast_ThirdPassIndent () ;
					fprintf ( g_fdCxx, "lMetaAction = CFast_g_bProcessReflex ? p_stLocalMind0->CFast_lRfxMetaActionForMacro : p_stLocalMind0->CFast_lCmpMetaActionForMacro ;\n" ) ;
					CFast_ThirdPassIndent () ;
					fprintf ( g_fdCxx, "switch(lMetaAction)\n");
					CFast_ThirdPassIndent () ;
					fprintf ( g_fdCxx, "{\n");
					for ( j=1 ; j<=(unsigned long)g_d_stMacro[lMacro].lGotMeta ; j++ )
					{
						CFast_ThirdPassIndent () ;
						fprintf ( g_fdCxx, "  case %d : goto label%d ;\n", j, j ) ;
					}
					CFast_ThirdPassIndent () ;
					fprintf ( g_fdCxx, "}\n" ) ;
				}	
				init_global_vars () ;
				CFast_ThirdPassCreateMacro ( p_stCurrentNode+1 ) ;
				i++ ;
				g_d_stMacro[lMacro].lCreated = 1 ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "return 0 ;\n" ) ;

				CFast_ThirdPassRmIndentLevel () ;
				fprintf ( g_fdCxx, "}\n" ) ;
			}
		}
		p_stCurrentNode ++ ;
	}
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassMakeMain
 * DESCRIPTION : create main function for a model
 *******************************************************************************/
void CFast_ThirdPassMakeMain (void) {
  /*
   * la fonction main du model 
   */
#ifdef DEBUG_CFAST
  fprintf ( g_fdCxx, "void CFast_Dummy_%s(void) ;\n", g_szModelName) ;
#endif /* DEBUG_CFAST */
  fprintf ( g_fdCxx, "char g_%s_StaticTreeInit = 0 ;\n\n\n", g_szModelName );

  fprintf ( g_fdCxx, "void CFast_%s_Main ( HIE_tdxHandleToSuperObject hSuperObjPerso )\n{\n", g_szModelName ) ;
  fprintf ( g_fdCxx, "  register long                lIndex ;\n " ) ;
  fprintf ( g_fdCxx, "  register AI_tdstMind         *p_stMind = M_pstGetMindOfBrain(M_GetMSHandle(hSuperObjPerso, Brain)) ;\n" ) ;
  fprintf ( g_fdCxx, "\n" );
  fprintf ( g_fdCxx, "  p_stGlobalMind = p_stMind;\n" );
  fprintf ( g_fdCxx, "  gp_stRefTree = &M_CFast_GetReferenceNodeN(hSuperObjPerso, 0);\n" );
  fprintf ( g_fdCxx, "  g_hSuperObjectPerso = hSuperObjPerso;\n" );

  fprintf ( g_fdCxx, "\n#ifndef U64\n" );
//   fprintf ( g_fdCxx, "  gp_stPseudoTree = gast_%s_PseudoTree;\n", g_szModelName ) ;
  fprintf ( g_fdCxx, "  gp_stPseudoTree = p_stMind->p_stAIModel->CFast_dst_ParamArray;\n" );
  fprintf ( g_fdCxx, "#else\n" );
  fprintf ( g_fdCxx, "  gp_stPseudoTree = CFast_gast_ArrayFunctions[p_stMind->p_stAIModel->CFast_lFunction].mp_stPseudoTree;\n");
  fprintf ( g_fdCxx, "#endif\n\n" );

#ifdef DEBUG_CFAST
  fprintf ( g_fdCxx, "#ifdef DEBUG_CFAST\n" ) ;
  fprintf ( g_fdCxx, "  if ( !g_%s_StaticTreeInit )\n  {\n", g_szModelName ) ;
  fprintf ( g_fdCxx, "    g_%s_StaticTreeInit = 1 ;\n", g_szModelName ) ;
  fprintf ( g_fdCxx, "    CFast_Dummy_%s();\n", g_szModelName) ;
  fprintf ( g_fdCxx, "  }\n" ) ;
  fprintf ( g_fdCxx, "#endif /* DEBUG_CFAST */\n" ) ;
#endif /* DEBUG_CFAST */

  if(g_ulGotDsgVar)
  {
    fprintf ( g_fdCxx, "  p_cGlobalDsgMemBuffer = p_stMind->p_stDsgMem->p_cDsgMemBuffer;\n");
    fprintf ( g_fdCxx, "  p_stGlobalDsgVarInfo = (*(p_stMind->p_stDsgMem->p_p_stDsgVar))->p_stDsgVarInfo;\n");
  }
  
  if ( g_ulGotRfx )
  {
    if ( g_ulGotCmp ) 
      fprintf ( g_fdCxx, "  %s = 0 ;\n", CFast_szBoolMetaRflxName );
    fprintf ( g_fdCxx, "  AI_M_SetDoingIntel(p_stMind, 0) ;\n" ) ;
    fprintf ( g_fdCxx, "  CFast_g_bProcessReflex = 1 ;\n" ) ;
    fprintf ( g_fdCxx, "  lIndex = M_GetCurrentComport(AI_M_p_stGetReflex(p_stMind))->CFast_lMyIndex ;\n");
    fprintf ( g_fdCxx, "  CFast_%s_ArrayReflex[lIndex]();\n", g_szModelName ) ; 
    fprintf ( g_fdCxx, "\n" ) ;
  }
  if ( g_ulGotCmp )
  {
    if ( g_ulGotRfx )
	{
      fprintf ( g_fdCxx, "  if ( !%s  )\n  {\n", CFast_szBoolMetaRflxName, g_szModelName ) ;
      CFast_ThirdPassAddIndentLevel () ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "  AI_M_SetDoingIntel(p_stMind, 1) ;\n" ) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "  CFast_g_bProcessReflex = 0 ;\n" ) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "  lIndex = M_GetCurrentComport(AI_M_p_stGetIntelligence(p_stMind))->CFast_lMyIndex ;\n");
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "  CFast_%s_ArrayComport[lIndex]();\n", g_szModelName ) ; 
    if ( g_ulGotRfx )
	{
      fprintf ( g_fdCxx, "  }\n" ) ;
      CFast_ThirdPassRmIndentLevel () ;
    }
  }
  fprintf ( g_fdCxx, "}\n" ) ;
  fflush ( g_fdCxx ) ;  
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassInit
 * DESCRIPTION : 3rd pass initialisation. create .cxx file, create reflex and
 *               intelligence functions array and main function for a model
 *******************************************************************************/
BOOL CFast_ThirdPassInit ( CPA_EdIR_Brain *p_oBrain, char *szEngineSectionName, char *szModelName, char *szFamilyName )
{
  char *szTemp ;
  char szfilename[256], szpath[256] ;
  int i ;

  /* For references in optim */
  CLEAR_Params();
  /*
   * re-init the stack 
   */
  g_ulNbNodeInStack = 0 ; 

  if ( szEngineSectionName == NULL || szFamilyName == NULL || szModelName == NULL )
    return (FALSE) ;

  strcpy ( g_szFamilyName, szFamilyName );
  strcpy ( g_szModelName, szModelName) ;
  strcpy ( g_szEngineSectionName, szEngineSectionName);

  
//  sprintf(szpath, "x:/cpa/exe/main/gamedata/world/levels/_common/families/%s/%s/%s.nod", szFamilyName, szModelName, szModelName);  
  sprintf(szpath, "gamedata/world/levels/_common/families/%s/%s/%s.nod", szFamilyName, szModelName, szModelName);  
  if ( (g_fdNode = fopen ( szpath, "w" )) == NULL ) {
    return (FALSE) ;
  }

  CFast_vMakeFileNameFromModel ( szfilename, g_szModelName ) ;
  sprintf ( szpath, "%s%s.h", CFast_szCFastPath, szfilename ) ;

  if ( (g_fdH = fopen ( szpath, "w" )) == NULL ) {
    return (FALSE) ;
  }

  szTemp = strrchr(szpath, '.');
  strcpy(szTemp, ".cxx");
  if ( (g_fdCxx = fopen ( szpath, "w" )) == NULL ) {
    return (FALSE) ;
  }

  fprintf ( g_fdCxx, "/******************************************************************************\n" ) ;
  fprintf ( g_fdCxx, " * %s.cxx : file automaticly generated\n", szfilename) ;
  fprintf ( g_fdCxx, " ******************************************************************************/\n") ;

  fprintf ( g_fdNode, "{CreatePseudoTree:(XXXX)\n" );

  szTemp = strrchr(szpath, '.');
  strcpy(szTemp, ".h");

  fprintf ( g_fdCxx, "\n" ) ;
//CB  fprintf ( g_fdCxx, "#ifndef U64\n" ) ;
  fprintf ( g_fdCxx, "#include \"%s\"\n", szpath) ;
//CB  fprintf ( g_fdCxx, "#endif\n" ) ;

//CB  fprintf ( g_fdH, "/*tdstNodeInterpret gast_%s_PseudoTree[] = {\n", g_szModelName ) ;
  fprintf ( g_fdH, "tdstNodeInterpret gast_%s_PseudoTree[] =\n{\n", g_szModelName ) ;

  CPA_EdIR_MainBehaviourList *p_oReflex, *p_oComport,*p_oSubroutines ;
  CPA_EdIR_MainBehaviour *p_oBehaviour;
  p_oReflex = &(p_oBrain->m_clListOfReflexBehaviours) ;
  p_oComport = &(p_oBrain->m_clListOfIntelligenceBehaviours) ;
  p_oSubroutines = &(p_oBrain->m_clListOfSubrs) ;
  POSITION pos ;

  g_ulPseudoTreeIndex = 0;
  g_ulPseudoTreePrev = 0;

  g_d_stMemoTree = (tdstNodeInterpret *) malloc(1000 * sizeof(tdstNodeInterpret));
  ulSizeMemoTree = 1000;
  ulLastMemoTree = 0;
  cEvaluateMemo = 0;

  /*
   * declaration des fonctions
   */
  pos = p_oReflex->GetHeadPosition () ;
  while (pos)
  {
    p_oBehaviour = p_oReflex->GetNext (pos) ;
    fprintf ( g_fdCxx, "void CFast_%s_Rfx_%s ( void ) ;\n", g_szModelName, 
	      p_oBehaviour->GetName () ) ;
  }
  fprintf ( g_fdCxx, "\n" ) ;

  pos = p_oComport->GetHeadPosition () ;
  while (pos)
  {
    p_oBehaviour = p_oComport->GetNext (pos) ;
    fprintf ( g_fdCxx, "void CFast_%s_Cmp_%s ( void ) ;\n", g_szModelName, 
	      p_oBehaviour->GetName () ) ;
  }
  fprintf ( g_fdCxx, "\n" ) ;

  pos = p_oSubroutines->GetHeadPosition () ;
  i = 0 ;
  while (pos)
  {
    p_oBehaviour = p_oSubroutines->GetNext (pos) ;
    fprintf ( g_fdCxx, "long CFast_%s_Sbr_%d  (void ) ; /* %s */\n", g_szModelName, i,
	      p_oBehaviour->GetName () ) ;
	i ++ ;
  }
  fprintf ( g_fdCxx, "\n" ) ;

  for ( i=0 ; i<(long)g_ulNbOfMacro ; i++ ) {
    fprintf ( g_fdCxx, "long CFast_%s_Macro_%d ( void ) ;\n", 
	      g_szModelName, i ) ;
  }

  /*
   * creation du tableau de fonctions des reflexes
   */
  pos = p_oReflex->GetHeadPosition () ;
  if ( pos == NULL )
  {
    g_ulGotRfx = 0 ;
  }
  else
  {
    g_ulGotRfx = 1 ;
    p_oBehaviour = p_oReflex->GetNext (pos) ;
    fprintf ( g_fdCxx, "CFast_EvalFunc CFast_%s_ArrayReflex[] = {\n", g_szModelName ) ;
    fprintf ( g_fdCxx, "  CFast_%s_Rfx_%s", g_szModelName, p_oBehaviour->GetName () ) ;
    while ( pos )
	{
      fprintf ( g_fdCxx, ",\n" ) ;
      p_oBehaviour = p_oReflex->GetNext (pos) ;
      fprintf ( g_fdCxx, "  CFast_%s_Rfx_%s", g_szModelName, p_oBehaviour->GetName () ) ;    
    }
    fprintf ( g_fdCxx, "\n};\n" ) ; 
  }
  /*
   * creation du tableau de fonctions des reflexes
   */
  pos = p_oComport->GetHeadPosition () ;
  if ( pos == NULL )
  {
    g_ulGotCmp = 0 ;
  }
  else
  {
    g_ulGotCmp = 1 ;
    p_oBehaviour = p_oComport->GetNext (pos) ;
    fprintf ( g_fdCxx, "CFast_EvalFunc CFast_%s_ArrayComport[] = { \n", g_szModelName ) ;
    fprintf ( g_fdCxx, "  CFast_%s_Cmp_%s", g_szModelName, p_oBehaviour->GetName () ) ;
    while ( pos )
	{
      fprintf ( g_fdCxx, ",\n" ) ;
      p_oBehaviour = p_oComport->GetNext (pos) ;
      fprintf ( g_fdCxx, "  CFast_%s_Cmp_%s", g_szModelName, p_oBehaviour->GetName () ) ;    
    }
    fprintf ( g_fdCxx, "\n};\n" ) ; 
  }  

  /*
   * tableau pour recevoir les adresses des vars designers
   */
  if(gp_stCurrentMind->p_stDsgMem && gp_stCurrentMind->p_stDsgMem->p_p_stDsgVar)
  {
    g_ulGotDsgVar = 1 ;
  }
  else
    g_ulGotDsgVar = 0 ;
  fprintf ( g_fdCxx, "\n" ) ;
  fflush (g_fdCxx) ;

  CFast_ThirdPassMakeMain() ;

  return (TRUE) ;
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddSubroutine
 * DESCRIPTION : parse a subroutine
 *******************************************************************************/
BOOL CFast_ThirdPassAddSubroutine ( CPA_EdIR_Brain *p_oBrain, CFast_tdstComportTree *p_stTree, tdstMacro *_p_stMacro,  unsigned long ulSubr )
{
	unsigned long i;
	BOOL bResult ;
	CPA_EdIR_MainBehaviourList *p_oSubroutines ;
	CPA_EdIR_MainBehaviour *p_oBehaviour;
	p_oSubroutines = &(p_oBrain->m_clListOfSubrs) ;			

	POSITION pos = p_oSubroutines->GetHeadPosition () ;

	g_ulNbNodeInStack = 0 ;

	if ( ulSubr > (unsigned long)p_oSubroutines->GetCount() )
	{
		return (FALSE) ;
	}

	for ( i = 0 ; i < ulSubr ; i ++ )
	{
		p_oSubroutines -> GetNext (pos) ;
	}

	p_oBehaviour = p_oSubroutines->GetAt (pos) ;

	/* we got the subroutine in sequential order: get the id in the CFast array */
	ulSubr = CFast_ThirdPassIsSubrExist ( ( void * ) _p_stMacro ) ;
	

	fprintf ( g_fdCxx, "/*\n * Model : %s Subroutine %s\n */\n", g_szModelName, p_oBehaviour->GetName () ) ;
	fprintf ( g_fdCxx, "long CFast_%s_Sbr_%d (void) /* %s */\n{\n", g_szModelName, ulSubr, 
	p_oBehaviour->GetName () ) ;
	if ( p_stTree->uwNbNode > 0 )
	{ 
		g_eProcessWhat = E_pw_Subroutine ;

		init_decleration( p_stTree->p_stCFastNode, p_stTree->uwNbNode, 0 ) ;

		CFast_ThirdPassAddIndentLevel () ;

		if ( p_stTree->d_cDeclarations != NULL )
			fprintf ( g_fdCxx, "%s\n\n", p_stTree->d_cDeclarations ) ;

		CFast_ThirdPassLocalDeclaration();

        /*
         * MetaAction et Bloquant Moteur
         */
        if ( g_d_stSubr[ulSubr].lGotMeta )
		{
			fprintf ( g_fdCxx, "  long lMetaAction ;\n\n" ) ; /* <------------ declaration de variable !!*/
			fprintf ( g_fdCxx, "  lMetaAction = CFast_g_bProcessReflex ? p_stLocalMind0->CFast_lRfxMetaActionForMacro : p_stLocalMind0->CFast_lCmpMetaActionForMacro ;\n" ) ;
			fprintf ( g_fdCxx, "  switch(lMetaAction)\n  {\n");
			for ( i = 1 ; i <= (unsigned long) g_d_stSubr[ulSubr].lGotMeta ; i ++ )
			{
				fprintf ( g_fdCxx, "  case %d : goto label%d ;\n", i, i ) ;
			}
			fprintf ( g_fdCxx, "  }\n" ) ;
        }	

		init_global_vars () ;
		bResult = CFast_ThirdPassParseTree ( p_stTree->p_stCFastNode, p_stTree->uwNbNode ) ;
		//     fprintf ( g_fdCxx, "  return ;\n" ) ;  
		CFast_ThirdPassRmIndentLevel () ;
	}
    fprintf ( g_fdCxx, "  return (0) ;\n" ) ;
	fprintf ( g_fdCxx, "}\n\n") ;
	fflush ( g_fdCxx ) ;
	/*
	* creer les macros du comportement courant
	*/
	if ( g_ulNbMacroInCurrentComport )
	{
		CFast_ThirdPassCreateAllMacro (p_stTree->p_stCFastNode, p_stTree->uwNbNode, p_stTree->d_cDeclarations) ;
	}
	fflush ( g_fdCxx ) ;

	return (bResult) ;
}


/*******************************************************************************
 * FUNCTION    : fn_lGetNbBlockingSubrForComport
 * DESCRIPTION : scan a reflex, comport or subr and tells how many blocking
 *               subrs are called within
 *******************************************************************************/
long fn_lGetNbBlockingSubrForComport ( CFast_tdstComportTree * p_stTree )
{
	long lTotal = 0 , lI ;
	CFast_tdstNode * p_stCurrentNode ;

	for
	(
		lI = 0 , p_stCurrentNode = p_stTree->p_stCFastNode ;
		lI < p_stTree->uwNbNode ;
		lI ++ , p_stCurrentNode ++
	)
	{
		if ( M_GetTypeInterpret( & p_stCurrentNode -> stNode ) == E_ti_MacroRef )
		{
			long lSubr = CFast_ThirdPassIsSubrExist ( ( void * ) fn_p_stGetMacroRefFromEditorPointer ( ( CPA_EdIR_MainBehaviour * ) M_p_stMacroInterpret ( & p_stCurrentNode -> stNode ) ) ) ;
			if ( lSubr >= 0 && ( g_d_stSubr[lSubr].lGotMeta /*|| g_d_stSubr[lSubr].lGotRfxOrCmp*/ ) )
			{
				lTotal ++ ;
			}
		}
	}

	return lTotal ;
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddRfx
 * DESCRIPTION : parse a reflex
 *******************************************************************************/
BOOL CFast_ThirdPassAddRfx ( CPA_EdIR_Brain *p_oBrain, CFast_tdstComportTree *p_stTree, unsigned long ulReflex )
{
	unsigned long i, ulNbSwitch ;
	BOOL bResult ;
	CPA_EdIR_MainBehaviourList *p_oReflex ;
	CPA_EdIR_MainBehaviour *p_oBehaviour;
	p_oReflex = &(p_oBrain->m_clListOfReflexBehaviours) ;
	POSITION pos = p_oReflex->GetHeadPosition () ;

	g_ulNbNodeInStack = 0 ;
	if ( ulReflex > (unsigned long)p_oReflex->GetCount() )
	{
		return (FALSE) ;
	}
	for ( i=0 ; i<ulReflex ; i++ )
	{
		p_oReflex->GetNext (pos) ;
	}
	p_oBehaviour = p_oReflex->GetAt (pos) ;
	fprintf ( g_fdCxx, "/*\n * Model : %s Reflexe %s\n */\n", g_szModelName, p_oBehaviour->GetName () ) ;
	fprintf ( g_fdCxx, "void CFast_%s_Rfx_%s (void)\n{\n", g_szModelName, p_oBehaviour->GetName () ) ;
	if ( p_stTree->uwNbNode > 0 )
	{ 
		g_eProcessWhat = E_pw_Reflex ;

		init_decleration( p_stTree->p_stCFastNode, p_stTree->uwNbNode, 0 ) ;

		CFast_ThirdPassAddIndentLevel () ;

		if ( p_stTree->d_cDeclarations != NULL )
			fprintf ( g_fdCxx, "%s\n\n", p_stTree->d_cDeclarations ) ;

		CFast_ThirdPassLocalDeclaration();
		/*
		* MetaAction et Bloquant Moteur
		*/
		ulNbSwitch = p_stTree->uwNbMetaAction + p_stTree->uwNbStopEngine ;
		/* also count subroutines that contain metaaction and stopengine */
		ulNbSwitch += fn_lGetNbBlockingSubrForComport ( p_stTree ) ;
		if ( ulNbSwitch )
		{
			if ( ulNbSwitch == 1 )
			{
				fprintf ( g_fdCxx, "  if ( p_stLocalMind0 -> CFast_lRfxMetaAction )\n" ) ;
				fprintf ( g_fdCxx, "    goto label1 ;\n" ) ;
			}
			else
			{
				fprintf ( g_fdCxx, "  switch(p_stLocalMind0->CFast_lRfxMetaAction)\n  {\n");
				for ( i = 1 ; i <= ulNbSwitch ; i ++ )
				{
					fprintf ( g_fdCxx, "  case %d : goto label%d ;\n", i, i ) ;
				}
				fprintf ( g_fdCxx, "  }\n" ) ;
			}
		}
		init_global_vars () ;
		bResult = CFast_ThirdPassParseTree ( p_stTree->p_stCFastNode, p_stTree->uwNbNode ) ;
		//     fprintf ( g_fdCxx, "  return ;\n" ) ;  
		CFast_ThirdPassRmIndentLevel () ;
	}
	fprintf ( g_fdCxx, "}\n\n") ;
	fflush ( g_fdCxx ) ;
	/*
	* creer les macros du comportement courant
	*/
	if ( g_ulNbMacroInCurrentComport )
	{
		CFast_ThirdPassCreateAllMacro (p_stTree->p_stCFastNode, p_stTree->uwNbNode, p_stTree->d_cDeclarations) ;
	}
	fflush ( g_fdCxx ) ;

  return (bResult) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddCmp
 * DESCRIPTION : parse a comport
 *******************************************************************************/
BOOL CFast_ThirdPassAddCmp ( CPA_EdIR_Brain *p_oBrain, CFast_tdstComportTree *p_stTree, unsigned long ulComport )
{
	unsigned long i, ulNbSwitch ;
	BOOL bResult ;
	CPA_EdIR_MainBehaviourList *p_oComport ;
	CPA_EdIR_MainBehaviour *p_oBehaviour;
	p_oComport = &(p_oBrain->m_clListOfIntelligenceBehaviours) ;
	POSITION pos = p_oComport->GetHeadPosition () ;

	g_ulNbNodeInStack = 0 ;

	if ( ulComport > (unsigned long)p_oComport->GetCount() )
	{
		return (FALSE) ;
	}
	for ( i = 0 ; i < ulComport ; i ++ )
	{
		p_oComport->GetNext (pos) ;
	}

	p_oBehaviour = p_oComport->GetAt (pos) ;
	fprintf ( g_fdCxx, "/*\n * Model : %s Comportement %s\n */\n", g_szModelName, p_oBehaviour->GetName () ) ;
	fprintf ( g_fdCxx, "void CFast_%s_Cmp_%s (void)\n{\n", g_szModelName, 
	p_oBehaviour->GetName () ) ;
	if ( p_stTree->uwNbNode > 0 )
	{
		g_eProcessWhat = E_pw_Comport ;

		init_decleration( p_stTree->p_stCFastNode, p_stTree->uwNbNode, 0 ) ;

		if ( p_stTree->d_cDeclarations != NULL )
			fprintf ( g_fdCxx, "%s\n\n", p_stTree->d_cDeclarations ) ;

		CFast_ThirdPassLocalDeclaration();

		CFast_ThirdPassAddIndentLevel () ;
		/*
		* MetaAction et Bloquant Moteur
		*/
		ulNbSwitch = p_stTree->uwNbMetaAction + p_stTree->uwNbStopEngine ;
		/* also count subroutines that contain metaaction and stopengine */
		ulNbSwitch += fn_lGetNbBlockingSubrForComport(p_stTree) ;
		if ( ulNbSwitch )
		{
			if ( ulNbSwitch == 1 )
			{
				fprintf ( g_fdCxx, "  if ( p_stLocalMind0 -> CFast_lCmpMetaAction ) \n" ) ;
				fprintf ( g_fdCxx, "    goto label1 ;\n" ) ;
			}
			else
			{
				fprintf ( g_fdCxx, "  switch(p_stLocalMind0->CFast_lCmpMetaAction) {\n");
				for ( i=1 ; i<=ulNbSwitch ; i++ )
				{
					fprintf ( g_fdCxx, "  case %d : goto label%d ;\n", i, i ) ;
				}
				fprintf ( g_fdCxx, "  }\n" ) ;
			}
		}
		init_global_vars () ;
		bResult = CFast_ThirdPassParseTree ( p_stTree->p_stCFastNode, p_stTree->uwNbNode) ;
		CFast_ThirdPassRmIndentLevel () ;
		//     fprintf ( g_fdCxx, "  return ;\n" ) ;
	}
	fprintf ( g_fdCxx, "}\n\n") ;
	fflush ( g_fdCxx ) ;
	/*
	* creer les macros du comportement courant
	*/
	if ( g_ulNbMacroInCurrentComport )
	{
		CFast_ThirdPassCreateAllMacro (p_stTree->p_stCFastNode, p_stTree->uwNbNode, p_stTree->d_cDeclarations) ;
	}

	fflush ( g_fdCxx ) ;

	return (bResult) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassFinish
 * DESCRIPTION : end 3rd pass process
 *******************************************************************************/
extern long g_lNbTotalDeNoeud;
BOOL CFast_ThirdPassFinish ( CPA_EdIR_Brain *p_oBrain )
{
	if ( g_d_stMacro != NULL )
		free (g_d_stMacro) ;
	g_ulNbOfMacro = 0 ;
	g_d_stMacro = NULL ;

	if ( g_d_stSubr != NULL )
		free (g_d_stSubr) ;
	g_d_stSubr = NULL ;
	g_ulNbOfSubr = 0 ;

  if ( g_fdCxx == NULL )
    return (FALSE) ;
#ifdef DEBUG_CFAST
  fprintf ( g_fdCxx, "void CFast_Dummy_%s(void) {\n", g_szModelName) ;
  fprintf ( g_fdCxx, "#ifdef DEBUG_CFAST\n" ) ;
  fprintf ( g_fdCxx, "  long lSize ;\n" ) ;
  fprintf ( g_fdCxx, "  FILE *fd = fopen ( \"CfastAISize.log\", \"a\") ;\n" ) ;
  fprintf ( g_fdCxx, "\n" );
  fprintf ( g_fdCxx, "  lSize = (long)CFast_Dummy_%s - (long)CFast_%s_Main ;\n", g_szModelName, g_szModelName ) ;
  if ( g_ulGotRfx )
    fprintf ( g_fdCxx, "  lSize += sizeof ( CFast_%s_ArrayReflex ) ;\n", g_szModelName ) ;
  if ( g_ulGotCmp ) 
    fprintf ( g_fdCxx, "  lSize += sizeof ( CFast_%s_ArrayComport ) ;\n", g_szModelName ) ;
  fprintf ( g_fdCxx, "  lSize += %d;\n", ulLastMemoTree*8 ) ;
  fprintf ( g_fdCxx, "  fprintf ( fd, \"%s : \tAI = %d\\tC = %%d\\tDiff = %%+d\\n\", lSize, %d-lSize ) ;\n", 
	    g_szModelName, g_lNbTotalDeNoeud*8, g_lNbTotalDeNoeud*8 ) ;
  fprintf ( g_fdCxx, "  fclose (fd) ;\n" ) ;
  fprintf ( g_fdCxx, "#endif /* DEBUG_CFAST */\n" ) ;
  fprintf ( g_fdCxx, "}\n" ) ;
#else
  fprintf ( g_fdCxx, "void CFast_Dummy_%s(void) {}\n", g_szModelName) ;
#endif /* DEBUG_CFAST */
  fclose ( g_fdCxx ) ;

  if(g_ulPseudoTreeIndex == 0)
    fprintf ( g_fdH, "  CFast_M_MakeNode( 0, 0, 0, 0, 0),\n");

//CB  fprintf ( g_fdH, "};*/\n" ) ;
  fprintf ( g_fdH, "};\n" ) ;

  fprintf ( g_fdH, "#define CFast_M_%s_StaticTreeSize %d\n", g_szModelName, ulLastMemoTree ) ;
  fprintf ( g_fdH, "#define CFast_%s_AISize %d\n", g_szModelName, g_lNbTotalDeNoeud*8) ;

  fprintf ( g_fdNode, "}\n");
  fseek ( g_fdNode, 0, SEEK_SET ) ;
  fprintf ( g_fdNode, "{CreatePseudoTree:(%4d)\n", ulLastMemoTree ) ;

  fclose ( g_fdH ) ;
  fclose ( g_fdNode ) ;

  free(g_d_stMemoTree);

  return (TRUE) ;
}
/*******************************************************************************
 *******************************************************************************
 * gestion de la pile
 *******************************************************************************
 *******************************************************************************/
CFast_tdstNode *CFast_ThirdPassPop ( void ) {
  if ( g_ulNbNodeInStack > 0 ) {
    return ( g_stStack[--g_ulNbNodeInStack] ) ;
  }
  CFast_fprintf_d(0, ( g_fdCxx, "/*STACK CORRUPT !!!!!!!!!!\n*/" ) );
  fflush ( g_fdCxx ) ;
  return (NULL) ;
}
void CFast_ThirdPassPush ( CFast_tdstNode *p_stNode ) {
  if(!p_stNode) 
    return;
  if ( g_ulNbNodeInStack < CFAST_ThirdPassStackSize ) {
    g_stStack[g_ulNbNodeInStack++] = p_stNode ;
  }
}

long CFast_ThirdPassPopAllParam ( unsigned long ulNbParam, BOOL bRecursiveCall ) {
  int i, nb ;
  CFast_tdstNode *p_stNode ;
  tdeVariableType eDsgVarType ;

  if ( !bRecursiveCall )
    g_eTypeOfParam = E_ti_Constant ;

  for ( i=0, nb=0 ; i<(long)ulNbParam ; i++, nb++ ) {
    p_stNode = CFast_ThirdPassPop () ;
    if ( p_stNode->ucNumberOfParamNeeded ) {
      nb += CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 1 ) ;
    }
    CFast_ThirdPassPushParam ( p_stNode ) ;
    if ( !bRecursiveCall ) {
      switch (p_stNode->stNode.eType) {
      case E_ti_Real :
	g_eTypeOfParam = E_ti_Real ; 
	break ;
      case E_ti_Constant :
	break ;
      case E_ti_DsgVarRef :
	eDsgVarType = fn_GetDsgVarType ( M_GetDsgVarType(gp_stCurrentMind, M_lValueInterpret((&p_stNode->stNode))) ) ;
	if (eDsgVarType == E_vt_Float )
	  g_eTypeOfParam = E_ti_Real ;
	break ;
      case E_ti_Operator :
	switch ( M_eOperatorIdInterpret((&p_stNode->stNode)) ) {
	case eOperator_GetVectorX :
	case eOperator_GetVectorY :
	case eOperator_GetVectorZ :
	  g_eTypeOfParam = E_ti_Real ;
	  break ;
	default :
	  if ( g_eParamType[p_stNode->ucIndexOfEvalParam] == E_vt_Float )
	    g_eTypeOfParam = E_ti_Real ;
	  else if (g_eParamType[p_stNode->ucIndexOfEvalParam] == E_vt_Integer) 
	    g_eTypeOfParam = (g_eTypeOfParam == E_ti_Real) 
	      ? E_ti_Real 
	      : (g_eTypeOfParam == E_ti_Constant) ? E_ti_Constant : E_ti_Unknown ;
	  else
	    g_eTypeOfParam = g_eTypeOfParam == E_ti_Real ? E_ti_Real : E_ti_Unknown ;
	}
	break ;
      case E_ti_Function :
	eDsgVarType = CFast_fn_eGetFunctionTypeOutParam (p_stNode, M_eFuncIdInterpret(&p_stNode->stNode)) ;
	if ( eDsgVarType == E_vt_Float ) 
	  g_eTypeOfParam = E_ti_Real ;
	break ;
      default :
	g_eTypeOfParam = g_eTypeOfParam == E_ti_Real ? E_ti_Real : E_ti_Unknown ;
	break ;
      }
    }
  }
  return (nb) ;
}

CFast_tdstNode *CFast_ThirdPassPopParam ( void ) {
  if ( g_ulNbParamInStack > 0 ) {
    return ( g_stParamStack[--g_ulNbParamInStack] ) ;
  }
  return (NULL) ;
}
void CFast_ThirdPassPushParam ( CFast_tdstNode *p_stNode ) {
  if ( g_ulNbParamInStack < CFAST_ThirdPassStackSize ) {
    g_stParamStack[g_ulNbParamInStack++] = p_stNode ;
  }
}


/*******************************************************************************
 *******************************************************************************
 * gestion des noeuds static
 *******************************************************************************
 *******************************************************************************/


long CFast_ThirdPassCheckParamStackForOptimisation (unsigned long ulNbParam) {
  unsigned long i ;
  long          nb ;
  long          lModelCast = 0 ;

  CFast_tdstNode *p_stNode ;

  for (i=1, nb=0 ; i<=ulNbParam ; i++, nb ++ ) {
    p_stNode = g_stParamStack[g_ulNbParamInStack-i] ;
    if ( i == ulNbParam && 
	 p_stNode->stNode.eType == E_ti_Operator && 
	 p_stNode->stNode.uId.eOperatorId == eOperator_Ultra ){
      nb -- ;
      continue ;
    }
    else if ( p_stNode->stNode.eType == E_ti_Operator && 
	      p_stNode->stNode.uId.eOperatorId == eOperator_ModelCast ){
      nb -- ;
      lModelCast = 1 ;
      continue ;
    }
    else if ( lModelCast && p_stNode->stNode.eType == E_ti_ModelRef ) {
      nb-- ;
      lModelCast = 0 ;
    }
    else if ( p_stNode->lIndexOfRef>=0 ) {
      continue ;
//       return (-1) ;
    }
    else if ( p_stNode->ucNumberOfParamNeeded || p_stNode->stNode.eType == E_ti_String ) {
      return (-1) ;
    }
  }

  return (nb) ;  
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddStaticNode
 * DESCRIPTION : Add a Static node 
 *******************************************************************************/
void CFast_ThirdPassAddStaticNode ( CFast_tdstNode *p_stNode) {
  long lRes[10], i, j, k, l;
  unsigned char lIndex , cFound = 0 ;
  CFast_tdstNode *a_stStackNode[50] ;
  CFast_tdstNode *p_stStackNode ;
  long lMemo;
  unsigned long ulNbParam ;

  g_ulPseudoTreePrev = g_ulPseudoTreeIndex;

  /* Evaluate all nodes */
  lMemo = ulLastMemoTree;
  cEvaluateMemo = 1;

  ulNbParam = p_stNode->ucNumberOfParamNeeded ;
  lIndex = p_stNode->ucIndexOfEvalParam ;
  p_stNode->ucIndexOfEvalParam = 0 ;
  CFast_ThirdPassMakeStaticTree (p_stNode) ;
  p_stNode->ucIndexOfEvalParam = lIndex ;
  i=1; 
  while ( (a_stStackNode[i] = CFast_ThirdPassPopParam ()) != NULL ) {
    lRes[i] = CFast_ThirdPassMakeStaticTree(a_stStackNode[i])  ; 
    if ( lRes[i] != -3 ) {
      i++ ;
    }
    else {
      ulNbParam -- ;
    }
  }
  k = i;

  /* Search matching in previous nodes */
  for(i = 0; i < lMemo; i++) {
    j = lMemo;
    l = i;
    while(!memcmp(&g_d_stMemoTree[l], &g_d_stMemoTree[j], sizeof(tdstNodeInterpret))) {
      l++; j++;
      if((unsigned long) j == ulLastMemoTree) {
	/* YES ! */
	ulLastMemoTree = lMemo;
	g_ulPseudoTreePrev = i;
	cFound = 1;
	goto Found;
      }
    }
  }

  for(i = k - 1; i >= 1; i--)
    CFast_ThirdPassPushParam (a_stStackNode[i]);

  /* Generate files */
  cEvaluateMemo = 0;

  lIndex = p_stNode->ucIndexOfEvalParam ;
  p_stNode->ucIndexOfEvalParam = 0 ;
  CFast_ThirdPassMakeStaticTree (p_stNode) ;
  p_stNode->ucIndexOfEvalParam = lIndex ;
  i=1; 
  while ( (a_stStackNode[i] = CFast_ThirdPassPopParam ()) != NULL ) {
    lRes[i] =CFast_ThirdPassMakeStaticTree(a_stStackNode[i])  ; 
    i++ ;
  }

Found:
  for ( i=1 ; i<=(long)ulNbParam ; i++ ) {
    if ( lRes[i]>-1 ) { 
      CFast_ThirdPassIndent () ;
//       p_stStackNode = g_stParamStack[ulNbParam-i] ;
      p_stStackNode = a_stStackNode[i] ;
      if ( M_GetTypeInterpret((&p_stStackNode->stNode)) == E_ti_KeyWord ) {
	if (M_eKeyWordIdInterpret((&p_stStackNode->stNode)) == eKeyWord_Me) { /* mode cle Moi */
	  fprintf (g_fdCxx, "M_p_stPersoRefInterpret(p_stPseudoTree+%d) = M_GetEngineObject(g_hSuperObjectPerso);\n", 
		 g_ulPseudoTreePrev+i ) ;
	}
	else if (M_eKeyWordIdInterpret((&p_stStackNode->stNode)) == eKeyWord_MainActor) {
	  fprintf (g_fdCxx, "M_p_stPersoRefInterpret(p_stPseudoTree+%d) = M_GetEngineObject( MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()) ) ;\n", g_ulPseudoTreePrev+i ) ;	  
	}
      }
      else {
	switch (g_eParamType[lRes[i]]) {
	case E_vt_Vector :
	  fprintf (g_fdCxx, "  M_p_stVectorInterpret(p_stPseudoTree+%d) = &M_GetSetParam_stVectorValue(%s+%d);\n", 
		   g_ulPseudoTreePrev+i, CFast_szParamVarName, lRes[i] ) ;
	  break ;
	default :
	  fprintf (g_fdCxx, "  M_lValueInterpret(p_stPseudoTree+%d) = M_GetSetParam_lValue(%s+%d);\n", 
		 g_ulPseudoTreePrev+i, CFast_szParamVarName, lRes[i]) ;
	  break ;
	}
      }
    }
  }

  if(!cFound) {
    g_ulPseudoTreeIndex += ulNbParam + 1 ;
  }
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassMakeStaticTree
 * DESCRIPTION : build static PseudoTree
 * RETURN VALUE: >= 0 : ok, node is the result of a previous evaluation
 *               -1   : ok
 *               -2   : error, should never append... except while debugging !
 *               -3   : ok, but node must be skip
 *******************************************************************************/
long CFast_ThirdPassMakeStaticTree ( CFast_tdstNode *p_stNode) {
  static long lSkipNextNode = 0 ;
  char szTmp[128] ;
  tdeTypeInterpret eNodeType ;
  long lRes; 

  if ( lSkipNextNode ) {
    lSkipNextNode = 0 ;
    return (-3) ;
  }
  eNodeType = M_GetTypeInterpret((&p_stNode->stNode)) ;
  if ( eNodeType == E_ti_KeyWord &&
       ( (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_Me) ||
	 (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_MainActor) /*|| 
	 (M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_World)*/ ) ) {
     p_stNode->ucIndexOfEvalParam = 0 ;
  }
  if ( p_stNode->ucIndexOfEvalParam ) {
    eNodeType = CFast_g_aEvt2Eti[g_eParamType[p_stNode->ucIndexOfEvalParam]] ;
    strcpy ( szTmp, "0" ) ;
    lRes = p_stNode->ucIndexOfEvalParam ;
  }
  else if ( p_stNode->lIndexOfRef >= 0 ) {
    eNodeType = E_ti_Unknown ;
    sprintf ( szTmp, "%d", p_stNode->lIndexOfRef ) ;
    lRes = -1 ;
  }
  else {
    lRes = -1 ;
    switch ( eNodeType ) {
    case E_ti_KeyWord :
      sprintf ( szTmp, "%d", M_eKeyWordIdInterpret((&p_stNode->stNode)) ) ;
      break ;
    case E_ti_Condition :
      sprintf ( szTmp, "%d", M_eCondIdInterpret((&p_stNode->stNode)) ) ;
      break ;
    case E_ti_Operator :
      if ( M_eOperatorIdInterpret((&p_stNode->stNode)) == eOperator_Ultra ) {
	CFast_ThirdPassAddUltraNode () ;
	return (-3) ;
      }
      else if ( M_eOperatorIdInterpret((&p_stNode->stNode)) == eOperator_ModelCast ) {
	lSkipNextNode = 1 ;
	return (-3) ;
      }
      sprintf ( szTmp, "%d", M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
      break ;
    case E_ti_Function :
      sprintf ( szTmp, "%d", M_eFuncIdInterpret((&p_stNode->stNode)) ) ;
      break ;
    case E_ti_Procedure :
      sprintf ( szTmp, "%d", M_eProcedureIdInterpret((&p_stNode->stNode)) ) ;
      break ;
    case E_ti_MetaAction :
      sprintf ( szTmp, "%d", M_eMetaActionIdInterpret((&p_stNode->stNode)) ) ;
      break ;
    case E_ti_BeginMacro :
    case E_ti_EndMacro :
    case E_ti_EndTree :
    case E_ti_Button :
    case E_ti_ConstantVector :   
    case E_ti_Module :
    case E_ti_DsgVarId :
    case E_ti_String :    
    case E_ti_LipsSynchroRef :
    case E_ti_FamilyRef :
    case E_ti_PersoRef :
    case E_ti_ActionRef :
    case E_ti_SuperObjectRef :
    case E_ti_WayPointRef :

    case E_ti_ComportRef :
    case E_ti_ModuleRef :
    case E_ti_SoundEventRef :
    case E_ti_ObjectTableRef :
    case E_ti_GameMaterialRef :
    case E_ti_ParticleGenerator :
    case E_ti_ModelRef :
    case E_ti_Light :
    case E_ti_Graph :
    case E_ti_MacroRef :
    case E_ti_Unknown :
      CFast_fprintf_d(1, ( g_fdCxx, "/****** bad param type [%d] ******/\n", eNodeType ) );
      return (-2);
      break ;

    case E_ti_Field :
    case E_ti_DsgVar :
    case E_ti_DsgVarRef :
    case E_ti_Constant :
    case E_ti_Mask :
    case E_ti_Caps :
    case E_ti_Vector:
      sprintf ( szTmp, "%d", M_lValueInterpret((&p_stNode->stNode)) ) ;
      break ;
    case E_ti_Real :      
      sprintf ( szTmp, "%d", *(long *)&M_xValueInterpret((&p_stNode->stNode)) ) ;
      break ;
      break ;
    case E_ti_Color :
    sprintf ( szTmp, "%d", M_ColorValueInterpret((&p_stNode->stNode)) ) ; 
    break ;
    }
  }
  
  if(cEvaluateMemo == 0) {
    fprintf ( g_fdH, "  CFast_M_MakeNode( %s, %d, 0, 0, 0),\n", szTmp, eNodeType) ;
    fprintf ( g_fdNode, "\tMakeNode (%s, %d, 0, 0, 0)\n", szTmp, eNodeType ) ;
//     fwrite( &p_stNode->stNode, 1, sizeof(tdstNodeInterpret), g_fdNode);
  }
  else {
    if(ulLastMemoTree == ulSizeMemoTree) {
      ulSizeMemoTree += 100;
      g_d_stMemoTree = (tdstNodeInterpret *) realloc(g_d_stMemoTree, ulSizeMemoTree * sizeof(tdstNodeInterpret));
    }
    memcpy(&g_d_stMemoTree[ulLastMemoTree], &p_stNode->stNode, sizeof(tdstNodeInterpret));
    if ( p_stNode->lIndexOfRef >= 0 ) {
      M_lValueInterpret(&g_d_stMemoTree[ulLastMemoTree]) = p_stNode->lIndexOfRef ;
    }
    g_d_stMemoTree[ulLastMemoTree].eType = eNodeType ;
    g_d_stMemoTree[ulLastMemoTree].ucDepth = 0;
    g_d_stMemoTree[ulLastMemoTree].uwNodeToSkip = 0;
    ulLastMemoTree++;
  }

  return (lRes) ;
}
/*******************************************************************************
 *******************************************************************************
 * transformation des noeuds
 *******************************************************************************
 *******************************************************************************/
/*
 * change = 1, change mon cmp
 * change = 2, change mon rfx
 * change = 3, change cmp et rfx
 * change = 0, autres fonctions
 */
void add_bloquant_moteur (long change)
{
	CFast_fprintf_d(2, ( g_fdCxx, "\n/* [bloquant moteur] *********************/\n") );

	g_ulBloquantMoteur = 0 ;

	CFast_ThirdPassIndent ( ) ;
	g_ulLabelNumber ++ ;
	if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
	{ /* macro */
		CFast_ThirdPassIndent () ;
		if ( g_ulGotRfx && g_ulGotCmp )
		{
			switch (change)
			{
			case 0 :
				fprintf ( g_fdCxx, "if ( CFast_g_bProcessReflex )\n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lRfxMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "else\n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lCmpMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
				break ;

			case 1 :
				fprintf ( g_fdCxx, "if ( CFast_g_bProcessReflex )\n{\n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lRfxMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "}\n" ) ;
				break ;

			case 2 :
				fprintf ( g_fdCxx, "if ( !CFast_g_bProcessReflex )\n{\n" ) ;
				CFast_ThirdPassIndent () ;	
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lCmpMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "}\n" ) ;
				break ;
			}	
		}
		else if ( g_ulGotCmp )
		{
			if ( change & 1 )
			{
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
			}
		}
		else
		{
			if ( change > 1 )
			{
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
			}
		}
		CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "return (1);\n" ) ;
	}
	else if ( g_eProcessWhat == E_pw_Comport )
	{ /* comportement */
		fprintf ( g_fdCxx, "p_stLocalMind0 -> CFast_lCmpMetaAction = %d ;\n", g_ulLabelNumber ) ;
		CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "return ;\n" ) ;
	}
	else
	{ /* reflexe */
		fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaAction = %d;\n", g_ulLabelNumber ) ;
		CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "return ;\n" ) ;
	}
	fprintf ( g_fdCxx, "label%d :\n", g_ulLabelNumber ) ;
	CFast_ThirdPassIndent ( ) ;
	if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
	{
		if ( g_ulGotRfx && g_ulGotCmp )
		{
			switch ( change )
			{
			case 0 :
				fprintf ( g_fdCxx, "if ( CFast_g_bProcessReflex ) \n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lRfxMetaActionForMacro = 0;\n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "else\n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lCmpMetaActionForMacro = 0;\n" ) ;
				break ;

			case 1 :
				fprintf ( g_fdCxx, "if ( CFast_g_bProcessReflex ) \n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lRfxMetaActionForMacro = 0;\n" ) ;
				break ;

			case 2 :
				fprintf ( g_fdCxx, "if ( !CFast_g_bProcessReflex ) \n" ) ;
				CFast_ThirdPassIndent () ;
				fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lCmpMetaActionForMacro = 0;\n" ) ;
				break ;
			}
		}
		else if ( g_ulGotCmp )
		{
			if ( change & 1 )
			{
				fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaActionForMacro = 0;\n" ) ;
			}
		}
		else
		{
			if ( change > 1 )
			{
				fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaActionForMacro = 0;\n" ) ;
			}
		}
	}
	else if ( g_eProcessWhat == E_pw_Comport )
	{ /* comportement */
		fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaAction = 0;\n" ) ;
	}
	else
	{ /* reflexe */
		fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaAction = 0;\n" ) ;
	}
	CFast_ThirdPassInitPseudoTree(-1) ; /* ??? */
	CFast_fprintf_d(4, ( g_fdCxx, "/*******************************/\n" ) );
	fflush ( g_fdCxx ) ;
}


/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddKeyWord
 * DESCRIPTION : add a keyword node
 *******************************************************************************/
void CFast_ThirdPassAddKeyWord (CFast_tdstNode *p_stNode, BOOL bAddVar ) {
  CFast_tdstNode *p_stStackNode ;
  tdeKeyWordId eKeyword ;

  eKeyword = M_eKeyWordIdInterpret((&p_stNode->stNode)) ;
  switch ( eKeyword ) {
  case eKeyWord_If :
  case eKeyWord_If2 : 
  case eKeyWord_If4 : 
  case eKeyWord_If8 : 
  case eKeyWord_If16 :
  case eKeyWord_IfNot :
    CFast_fprintf_d(0, ( g_fdCxx, "/****** eKeyWord_If* ******/\n" ) );
    assert (NULL) ;
    return ;
    break ;
  case eKeyWord_IfDebug :
    g_lOpenedBraceByIf[g_lCompteurPourLesSi] = -1 ;
    fprintf ( g_fdCxx, "#ifdef __DEBUG_AI__\n" ) ;
    g_lCompteurPourLesSi++ ;
    return ;
    break ;
  case eKeyWord_IfNotU64 :
    g_lOpenedBraceByIf[g_lCompteurPourLesSi] = -1 ;
    fprintf ( g_fdCxx, "#ifndef U64\n" ) ;
    g_lCompteurPourLesSi++ ;
    return ;
    break ;
  case eKeyWord_Then : 
    g_lCompteurPourLesSi-- ;
    CFast_ThirdPassRmIndentLevel () ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n") ;
    g_lOpenedBraceByIf[g_lCompteurPourLesSi]-- ;
    return ;
    break ;   
  case eKeyWord_Else : 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "else {\n") ;
    CFast_ThirdPassInitPseudoTree (-1) ;
    CFast_ThirdPassAddIndentLevel () ;
    g_lOpenedBraceByIf[g_lCompteurPourLesSi]++ ;
    g_lCompteurPourLesSi++ ;
    return ;
    break ;  
  case eKeyWord_EngineGoto :  
    break ;
  case eKeyWord_Me : 
  case eKeyWord_MainActor :   
  //case eKeyWord_World :     
    CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Keyword : %s] ********** [%d, %d, %d]*/\n", 
			 szFindKeyWordEditorNameFromId(M_eKeyWordIdInterpret((&p_stNode->stNode))), 
			 g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, p_stNode->ucIndexOfEvalParam ) );
    if ( bAddVar ) {      
      if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_KeyWord ) {
      	CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_KeyWord);\n", 
                  CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
	      M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_KeyWord);
      }
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_eKeyWordIdInterpret(&%s[%d][%d]) = (tdeKeyWordId)%d ;\n", 
		            CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex, 
		            M_eKeyWordIdInterpret((&p_stNode->stNode)) ) ;
    }
    else {
      CFast_ThirdPassPush (p_stNode) ;
      g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Perso ;
    }
    CFast_fprintf_d(4, ( g_fdCxx, "/************[%d]*/\n", g_ulNbNodeInStack ) );
    return ;
    break ;      
  case eKeyWord_Nobody :      
  case eKeyWord_Nowhere :     
  case eKeyWord_CapsNull :    
  case eKeyWord_NoGraph :
#if defined(ACTIVE_EDITOR)    
  case eKeyWord_NoComport :   
  case eKeyWord_NoAction :    
  case eKeyWord_Schedule :    
  case eKeyWord_InterruptRule :
  case eKeyWord_Vector :      
  case eKeyWord_ConstVector : 
    break ;
  case eKeyWord_Endif :   
    CFast_fprintf_d(3, ( g_fdCxx, "/* [ENDIF]***********[%d, %d]*/\n",g_lCompteurPourLesSi, g_lOpenedBraceByIf[g_lCompteurPourLesSi] ) );
    CFast_ThirdPassInitPseudoTree (-1) ;
    g_lCompteurPourLesSi -- ;
    if ( g_lOpenedBraceByIf[g_lCompteurPourLesSi] < 0 ) {
      fprintf ( g_fdCxx, "#endif\n") ;
      g_lOpenedBraceByIf[g_lCompteurPourLesSi] = 0 ;
    }
    else {
      while ( g_lOpenedBraceByIf[g_lCompteurPourLesSi] ) {
	      CFast_ThirdPassRmIndentLevel () ;
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "}\n") ;
	      g_lOpenedBraceByIf[g_lCompteurPourLesSi]-- ;
      }
    }
    return ;
    break ;    
  case eKeyWord_Macro :       
  case eKeyWord_True :        
  case eKeyWord_False :       
  case eKeyWord_StopEngine :  
  case eKeyWord_StopRule :    
  case eKeyWord_NonStop :
    break ;
#endif
  }
  CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Keyword : %s] ********** [%d, %d, %d]*/\n", 
		                   szFindKeyWordEditorNameFromId(M_eKeyWordIdInterpret((&p_stNode->stNode))), 
		                   g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, p_stNode->ucIndexOfEvalParam ) );
  g_eCurrentType = E_ti_KeyWord ;
  CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
  if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
    CFast_ThirdPassAddStaticNode (p_stNode) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallKeyword_Static(%d, %d) ;\n",
	            g_ulPseudoTreePrev, p_stNode->ucIndexOfEvalParam) ;
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_KeyWord][0], E_ti_KeyWord) ] **********/\n", 
			                   CFast_szPseudoTreeVarName ) );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_eKeyWordIdInterpret(&%s[E_ti_KeyWord][0]) = (tdeKeyWordId)%d ;\n", 
	            CFast_szPseudoTreeVarName, 
	            M_eKeyWordIdInterpret((&p_stNode->stNode)) ) ;

    g_ulTreeIndex = 0 ;
    while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex ) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallKeyword_NoStatic(%d) ;\n",
	            p_stNode->ucIndexOfEvalParam) ;
  }
  p_stNode->ucNumberOfParamNeeded = 0 ;
  g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ;
  CFast_ThirdPassPush (p_stNode) ;
  CFast_fprintf_d(4, ( g_fdCxx, "/************[%d]*/\n", g_ulNbNodeInStack ) );

  if ( g_ulBloquantMoteur )
    add_bloquant_moteur (0) ;

  fflush ( g_fdCxx ) ;
  
} 

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddCondition
 * DESCRIPTION : add a condition node
 *******************************************************************************/
char CFast_ThirdPassAddIPT(CFast_tdstNode *p_stNode);
void CFast_ThirdPassAddCondition (CFast_tdstNode *p_stNode )
{
  CFast_tdstNode *p_stStackNode ;
  tdeCondId eCondition ;
  char cRes ;
  
  eCondition = M_eCondIdInterpret((&p_stNode->stNode)) ;

  if ( g_ulCondStringSet && !g_ulProcessIf )
  {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "long%d = %s; /* oups */\n", ++g_lIndexForCondition, g_szConditionString2 ) ;
    g_ulCondStringSet = 0 ;
  }

  CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Cond : %s] ********** [%d, %d, %d]*/\n", 
		                  szFindConditionEditorNameFromId(M_eCondIdInterpret((&p_stNode->stNode))), 
		                  g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, 
                      p_stNode->ucIndexOfEvalParam ) );

  cRes = CFast_ThirdPassAddComp(p_stNode);
  if ( cRes ) { 
    goto EndCond ;
  }
  cRes = CFast_ThirdPassAddIPT(p_stNode);
  if ( cRes ) { 
    goto EndCond ;
  }
  if ( !g_ulProcessIf )
  {
    switch ( eCondition )
	{
    case eCond_Et :
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "long%d &= long%d;\n", g_lIndexForCondition-1,  g_lIndexForCondition) ;
      g_lIndexForCondition-- ;
      goto EndCond ;
      break ;
    case eCond_Ou :
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "long%d |= long%d;\n", g_lIndexForCondition-1,  g_lIndexForCondition) ;
      g_lIndexForCondition-- ;
      goto EndCond ;
      break ;
    case eCond_Not :
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "long%d = !long%d;\n", g_lIndexForCondition,  g_lIndexForCondition) ;
      goto EndCond ;
      break ;
    case eCond_XOr :
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "long%d ^= long%d;\n", g_lIndexForCondition-1,  g_lIndexForCondition) ;
      g_lIndexForCondition-- ;
      goto EndCond ;
      break ;
    }
  }
  else {
    if ( eCondition == eCond_Et  || eCondition == eCond_Ou || 
	 eCondition == eCond_Not || eCondition == eCond_XOr ) {
      assert (NULL) ;
      return ;
    }    
  }
  g_eCurrentType = E_ti_Condition ;
  CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
  if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
    CFast_ThirdPassAddStaticNode (p_stNode) ;
    if ( g_ulProcessIf )
	{
      sprintf ( g_szConditionString2, "CFast_CallCondition_Static(%d)", g_ulPseudoTreePrev ) ;
      sprintf ( g_szConditionString1, "long%d = CFast_CallCondition_Static(%d) ;", 
                g_lIndexForCondition, g_ulPseudoTreePrev) ;
      g_ulCondStringSet = 1 ;
    }
    else {
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "long%d = CFast_CallCondition_Static(%d) ;\n",
		            ++g_lIndexForCondition, g_ulPseudoTreePrev) ;
      g_ulCondStringSet = 0 ;
    }
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Condition][0], E_ti_Condition)] *********/\n", 
			                   CFast_szPseudoTreeVarName ) );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_eCondIdInterpret(&%s[E_ti_Condition][0]) = (tdeCondId)%d ;\n", CFast_szPseudoTreeVarName, 
	            M_eCondIdInterpret((&p_stNode->stNode)) ) ;    
    g_ulTreeIndex = 0 ;
    while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
    }  
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "long%d = CFast_CallCondition_NoStatic( ) ;\n",g_lIndexForCondition) ;
  }
EndCond :
  if ( p_stNode->bIsACondition ) {
    if ( g_ulCondStringSet ) {
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "%s\n", g_szConditionString1 ) ;
      g_ulCondStringSet = 0 ;
    }
    fprintf ( g_fdCxx, "M_Full_GetSetParam_Integer(&CFast_g_a_stParam[%d], long%d) ;\n", 
	            p_stNode->ucIndexOfEvalParam, g_lIndexForCondition-- ) ;
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ;
    p_stNode->ucNumberOfParamNeeded = 0 ;
    CFast_ThirdPassPush (p_stNode) ;
  }
  CFast_fprintf_d(4, ( g_fdCxx, "/************[%d]*/\n", g_ulNbNodeInStack ) );
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddOperator
 * DESCRIPTION : add an operator node
 *******************************************************************************/
void CFast_ThirdPassAddOperator (CFast_tdstNode *p_stNode, BOOL bAddVar ) {
  CFast_tdstNode *p_stStackNode ;
  int nb ;

  CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Op : %s] ********** [%d, %d, %d]*/\n", 
		                  szFindOperatorEditorNameFromId(M_eOperatorIdInterpret((&p_stNode->stNode))), 
		                  g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, p_stNode->ucIndexOfEvalParam ) );
  switch ( M_eOperatorIdInterpret((&p_stNode->stNode))) {
  case eOperator_ScalarPlusScalar :
  case eOperator_ScalarMinusScalar :
  case eOperator_ScalarMulScalar : 
  case eOperator_ScalarDivScalar : 
  case eOperator_ScalarUnaryMinus :
    g_eCurrentType = E_ti_Operator ;      
    nb = CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
    if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
      CFast_ThirdPassAddStaticNode (p_stNode) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_Static(%d) ;\n", p_stNode->ucIndexOfEvalParam,g_ulPseudoTreePrev) ;
    }
    else {
      CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Operator][0], E_ti_Operator)] ********/\n", 
			                CFast_szPseudoTreeVarName ) );
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[E_ti_Operator][0]) = (tdeOperatorId)%d ;\n", 
		            CFast_szPseudoTreeVarName, M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
      g_ulTreeIndex = 0 ;
      while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
	      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
      }
      
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_NoStatic() ;\n", p_stNode->ucIndexOfEvalParam) ;
    }
    p_stNode->ucNumberOfParamNeeded = 0 ;
    if ( g_eTypeOfParam == E_ti_Unknown ) {
      MessageBox(NULL,  "oups !! Scalar operator", "CFAST 3", MB_ICONSTOP);
      CFast_fprintf_d(1,  ( g_fdCxx, "/* Scalar operator : %s */\n", szFindOperatorEditorNameFromId(M_eOperatorIdInterpret((&p_stNode->stNode))) ) ) ;
      g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ; // or E_vt_Float depending on the scalar type
    }
    else if ( g_eTypeOfParam == E_ti_Real ){
      g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    } 
    else {
      g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ;
    }
    CFast_ThirdPassPush (p_stNode) ;
    break ;
  case eOperator_PlusAffect :  
  case eOperator_MinusAffect : 
  case eOperator_MulAffect :  
  case eOperator_DivAffect :   
  case eOperator_PlusPlusAffect :  
  case eOperator_MinusMinusAffect :
  case eOperator_Affect :  
    g_eCurrentType = E_ti_Operator ;  
    CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
    if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
      CFast_ThirdPassAddStaticNode (p_stNode) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_Static ( %d ) ;\n",
		p_stNode->ucIndexOfEvalParam,g_ulPseudoTreePrev) ;
    }
    else {
      CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Operator][0], E_ti_Operator)] ********/\n", 
			                CFast_szPseudoTreeVarName ) );
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[E_ti_Operator][0]) = (tdeOperatorId)%d ;\n", 
		            CFast_szPseudoTreeVarName, M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
      g_ulTreeIndex=0 ;
      while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
	      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
      }
      
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_NoStatic( ) ;\n", p_stNode->ucIndexOfEvalParam) ;
    }
    break ;
  case eOperator_ModelCast :
    if ( bAddVar ) {
      gRemoveNextModelRef = 1 ;
      g_ulTreeIndex -- ;
    }
    else
      CFast_ThirdPassPush (p_stNode) ;
    break ;
  case eOperator_Dot : 
  case eOperator_Array :
    if ( p_stNode->bIsABooleanDsgVarRef ) {
      char szTmp[1000], cForFloat=0, cForVector=0 ;
      unsigned char c ;

      c = p_stNode->ucIndexOfEvalParam ;
      p_stNode->ucIndexOfEvalParam = 0 ;
      if ( CFast_Get1Param( szTmp, p_stNode, &cForFloat, &cForVector, 1) ) {
	      p_stNode->ucIndexOfEvalParam = c ;
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "long%d = %s;\n", g_lIndexForCondition, szTmp );
      }
      else if ( M_eOperatorIdInterpret((&p_stNode->stNode)) == eOperator_Dot ) {
	      CFast_tdstNode *p_stNodeDsgVar, *p_stNodePerso ;

        p_stNodeDsgVar = CFast_ThirdPassPop () ; /* field */
        p_stNodePerso  = CFast_ThirdPassPop () ; /* perso */


        /* for condition processing */
        if ( CFast_fn_vThirdPassField ( p_stNodePerso, p_stNodeDsgVar) ) {
	        sprintf ( g_szConditionString2, "long%d", g_lIndexForCondition+1 ) ;
	        sprintf ( g_szConditionString1, "long%d = %s ;", g_lIndexForCondition, g_szConditionString2 ) ;
          g_ulCondStringSet = 1 ;
        }
      }
      else {
      	CFast_fprintf_d(1, ( g_fdCxx, "/****** ERROR : find array as a boolean expression ******/\n") );
        fflush (g_fdCxx) ;
	      assert (NULL) ;
      }
    }
    else if ( bAddVar ) {
      if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Operator ) {
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Operator);\n", 
		              CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
	                M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Operator);
      }
      else {
	      CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Operator)] ********/\n", 
			                       CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
      }
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[%d][%d]) = (tdeOperatorId)%d ;\n", 
		            CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex, 
		            M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
    }
    else 
      CFast_ThirdPassPush (p_stNode) ;
    break ;
  case eOperator_GetVectorX : 
  case eOperator_GetVectorY : 
  case eOperator_GetVectorZ : 
    if ( p_stNode->bAffectWithGetVector ) {
      if ( bAddVar ) {
	      if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Operator ) {
	        CFast_ThirdPassIndent () ;
	        fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Operator);\n", 
		                CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
	        M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Operator);
	      }
	      else {
	        CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d], E_ti_Operator)] ********/\n", 
			                         CFast_szPseudoTreeVarName, g_ulTreeIndex ) );
	      }
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[%d][%d]) = (tdeOperatorId)%d ;\n", 
		              CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex, 
		              M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
      }
      else {
	      CFast_ThirdPassPush (p_stNode) ;
      }
    }
    else {
      g_eCurrentType = E_ti_Operator;	
      CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
      if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
	      CFast_ThirdPassAddStaticNode (p_stNode) ;
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "CFast_CallOperator%d_Static( %d ) ;\n",
		              p_stNode->ucIndexOfEvalParam, g_ulPseudoTreePrev) ;
      }
      else {
	      CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Operator][0], E_ti_Operator)] ********/\n", 
			                  CFast_szPseudoTreeVarName ) );
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[E_ti_Operator][0]) = (tdeOperatorId)%d ;\n", 
		              CFast_szPseudoTreeVarName, M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
	      g_ulTreeIndex=0 ;
	      while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
	        CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
	      }
	
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "CFast_CallOperator%d_NoStatic( ) ;\n", p_stNode->ucIndexOfEvalParam) ;
      }
      p_stNode->ucNumberOfParamNeeded = 0 ;
      g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
      CFast_ThirdPassPush (p_stNode) ;
    }
    break ;
  case eOperator_VectorPlusVector :
  case eOperator_VectorMinusVector :
  case eOperator_VectorMulScalar :
  case eOperator_VectorDivScalar :
  case eOperator_VectorUnaryMinus :
    g_eCurrentType = E_ti_Operator ;	
    CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
    if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
      CFast_ThirdPassAddStaticNode (p_stNode) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_Static( %d ) ;\n", p_stNode->ucIndexOfEvalParam, g_ulPseudoTreePrev) ;
    }
    else {
      CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Operator][0], E_ti_Operator)] ********/\n", 
			   CFast_szPseudoTreeVarName ) );
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[E_ti_Operator][0]) = (tdeOperatorId)%d ;\n", 
		            CFast_szPseudoTreeVarName, M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;     
      g_ulTreeIndex=0 ;
      while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
	      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
      }
    
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_NoStatic( ) ;\n", p_stNode->ucIndexOfEvalParam) ;
    }
    p_stNode->ucNumberOfParamNeeded = 0 ;
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Vector ;
    CFast_ThirdPassPush (p_stNode) ;
    break ;
  case eOperator_SetVectorX : 
  case eOperator_SetVectorY :
  case eOperator_SetVectorZ :
    g_eCurrentType = E_ti_Operator ;
    CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
    if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
      CFast_ThirdPassAddStaticNode (p_stNode) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_Static( %d ) ;\n", p_stNode->ucIndexOfEvalParam, g_ulPseudoTreePrev) ;
    }
    else {
      CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Operator][0], E_ti_Operator)] ********/\n", 
			                CFast_szPseudoTreeVarName ) );
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[E_ti_Operator][0]) = (tdeOperatorId)%d ;\n", 
		            CFast_szPseudoTreeVarName, M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
      g_ulTreeIndex=0 ;
      while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
	      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
      }
      
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "CFast_CallOperator%d_NoStatic( ) ;\n", p_stNode->ucIndexOfEvalParam) ;
    }
    break ;
  case eOperator_Ultra :           
    if ( bAddVar ) {
      CFast_ThirdPassAddUltraNode () ;
    }
    else
      CFast_ThirdPassPush (p_stNode) ;
    break ;
  case eOperator_AffectArray : // not tested
    g_eCurrentType = E_ti_Operator ;
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Operator][%d], E_ti_Operator)] ********/\n", 
			                   CFast_szPseudoTreeVarName, g_ulTreeIndex ) );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_eOperatorIdInterpret(&%s[E_ti_Operator][%d]) = (tdeOperatorId)%d ;\n", 
	            CFast_szPseudoTreeVarName, g_ulTreeIndex, M_eOperatorIdInterpret((&p_stNode->stNode)) ) ;
    
    CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
    g_ulTreeIndex=0 ;
    while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
    }
    
    break ;
  }
  CFast_fprintf_d(4, ( g_fdCxx, "/************[%d]*/\n", g_ulNbNodeInStack ) );

  if ( g_ulBloquantMoteur )
    add_bloquant_moteur (0) ;

  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddFunction
 * DESCRIPTION : add a function node
 *******************************************************************************/
void CFast_ThirdPassAddFunction (CFast_tdstNode *p_stNode ) {
  CFast_tdstNode *p_stStackNode ;

  CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Func : %s] ********** [%d, %d, %d]*/\n", 
		       szFindFunctionEditorNameFromId(M_eFuncIdInterpret((&p_stNode->stNode))),
		       g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, p_stNode->ucIndexOfEvalParam ) );
  g_eCurrentType = E_ti_Function ;
  CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
  if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
    CFast_ThirdPassAddStaticNode (p_stNode) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallFunction%d_Static( %d ) ;\n", 
	      p_stNode->ucIndexOfEvalParam,g_ulPseudoTreePrev) ;
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Function][0], E_ti_Function)] ********/\n", 
			 CFast_szPseudoTreeVarName ) );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_eFuncIdInterpret(&%s[E_ti_Function][0]) = (tdeFuncId)%d ;\n", CFast_szPseudoTreeVarName, 
	      M_eFuncIdInterpret((&p_stNode->stNode)) ) ;
    g_ulTreeIndex=0 ;
    while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallFunction%d_NoStatic( ) ;\n",
	      p_stNode->ucIndexOfEvalParam) ;
  }
  /*
   * special case for the fucking function VEC_ProduitScalaire that should return integer
   * but that returns float !
   *
  if ( M_eFuncIdInterpret((&p_stNode->stNode)) == eFunc_DotProduct ) {
    CFast_fprintf_d(4, ( g_fdCxx, "/*\n") );
    CFast_fprintf_d(4, ( g_fdCxx, " * special treatment for this function\n") );
    CFast_fprintf_d(4, ( g_fdCxx, " * convert the returned result to the expected format\n") );
    CFast_fprintf_d(4, ( g_fdCxx, " * /\n") );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_lValue(CFast_g_a_stParam+%d) = M_GetSetParam_xValue(CFast_g_a_stParam+%d) ; \n", p_stNode->ucIndexOfEvalParam) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Integer ; \n", p_stNode->ucIndexOfEvalParam) ;
  }
  */
  CFast_fprintf_d(4, ( g_fdCxx, "/************[%d]*/\n", g_ulNbNodeInStack ) );
  g_eParamType[p_stNode->ucIndexOfEvalParam] = CFast_fn_eGetFunctionTypeOutParam (p_stNode, M_eFuncIdInterpret(&p_stNode->stNode)) ;
  p_stNode->ucNumberOfParamNeeded = 0 ;
  CFast_ThirdPassPush (p_stNode) ;

  if ( g_ulBloquantMoteur )
    add_bloquant_moteur (0) ;

  fflush ( g_fdCxx ) ;
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddProcedure
 * DESCRIPTION : add a procedure node
 *******************************************************************************/
void CFast_ThirdPassAddProcedure (CFast_tdstNode *p_stNode ) {
  CFast_tdstNode *p_stStackNode ;
  tdeProcedureId eProcedure ;

  eProcedure = M_eProcedureIdInterpret((&p_stNode->stNode)) ;

  switch ( eProcedure ) {
  case eProc_None :
    CFast_fprintf_d(2, ( g_fdCxx, "\n/* [nerienfaire()] *********** [%d, %d, %d]*/\n", 
			 g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, p_stNode->ucIndexOfEvalParam ) );
    fflush(g_fdCxx) ;
    return ;
    break ;
  case eProc_SetActionReturn : 
    p_stStackNode = CFast_ThirdPassPop() ;
    g_ulBloquantMoteur = 1 ;
    return ;
    break ;
  case eKeyWord_Boucle : 
    {
      char szTemp[512], cFloat = 0, cVector = 0 ;
      
      
      CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Proc : %s] *********** [%d, %d, %d]*/\n", 
			                     szFindProcedureEditorNameFromId(eProcedure),
			                     g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, 
                           p_stNode->ucIndexOfEvalParam ) );
      p_stStackNode = CFast_ThirdPassPop() ;
      if ( !CFast_Get1Param (szTemp, p_stStackNode, &cFloat, &cVector, 1 ) )
	  {
	      assert (NULL) ;
      }
      else
	  {
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "{\n" ) ;
        CFast_ThirdPassAddIndentLevel () ;
        CFast_ThirdPassIndent () ;
        fprintf ( g_fdCxx, "int i%d;\n", g_ulNumberFor ) ;
        if ( cFloat )
		{
          fprintf ( g_fdCxx, "for ( i%d=MTH_M_xLongToReal(%s) ; i%d>0 ; i%d-- ) { /* Boucle %d */\n", 
                    g_ulNumberFor, szTemp, g_ulNumberFor, g_ulNumberFor, g_ulNumberFor++) ;
        }
        else if ( !cVector )
		{
          fprintf ( g_fdCxx, "for ( i%d=%s ; i%d>0 ; i%d-- ) { /* Boucle %d */\n", 
                    g_ulNumberFor, szTemp, g_ulNumberFor, g_ulNumberFor, g_ulNumberFor++) ;
        }
        else
		{
          assert (NULL) ;
        }
        CFast_fprintf_d(4, ( g_fdCxx, "/*************[%d]*/\n", g_ulNbNodeInStack ) );
        CFast_ThirdPassInitPseudoTree(-1) ;
      }
      return ;
    }
    break ;
  case eKeyWord_FinBoucle :
    CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Proc : %s] ********** [%d, %d, %d]*/\n", 
			                   szFindProcedureEditorNameFromId(eProcedure),
			                   g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, 
                         p_stNode->ucIndexOfEvalParam ) );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n" ) ;
    CFast_ThirdPassRmIndentLevel () ;
    fprintf ( g_fdCxx, "}\n" ) ;
    if ( g_ulBreak ) 
      fprintf ( g_fdCxx, "EndLoop%d :\n ", --g_ulNumberFor ) ;
    if ( !g_ulNumberFor )
      g_ulBreak = 0 ;
    CFast_fprintf_d(4, ( g_fdCxx, "/*************[%d]*/\n", g_ulNbNodeInStack ) );
    CFast_ThirdPassInitPseudoTree(-1) ;
    return ;
    break ;
  case eKeyWord_Break : 
    CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Proc : %s] *********** [%d, %d, %d]*/\n", 
			                   szFindProcedureEditorNameFromId(eProcedure),
			                   g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, 
                         p_stNode->ucIndexOfEvalParam ) );    
    p_stStackNode = CFast_ThirdPassPop() ;
    if ( p_stStackNode->ucIndexOfEvalParam )
	{
      CFast_fprintf_d(1, ( g_fdCxx, "\n/* [Proc : Break] **** Aaaaaaaaaaaaaaaarghhhhh ***********/\n" ) );
    }
    else
	{
      if ( M_lValueInterpret(&p_stStackNode->stNode) == -1 )
	  {
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "return ;\n" ) ;
      }
      else if ( M_lValueInterpret(&p_stStackNode->stNode) == 0 )
	  {
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "break ;\n" ) ;	
      }
      else
	  {
        long lGotoLabel ;
        CFast_ThirdPassIndent () ;
        lGotoLabel = ((g_ulNumberFor-1) - M_lValueInterpret(&p_stStackNode->stNode)) >= 0 ? (g_ulNumberFor-1) - M_lValueInterpret(&p_stStackNode->stNode) : 0 ;        
        fprintf ( g_fdCxx, "goto EndLoop%d ;\n", lGotoLabel ) ;
        g_ulBreak ++ ;
      }
    }
    CFast_fprintf_d(4, ( g_fdCxx, "/*************[%d]*/\n", g_ulNbNodeInStack ) );
    return ;
    break ;
  }
  CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Proc : %s] *********** [%d, %d, %d]*/\n", 
		                   szFindProcedureEditorNameFromId(eProcedure),
		                   g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, 
                       p_stNode->ucIndexOfEvalParam ) );
  g_eCurrentType = E_ti_Procedure ;
  CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
  if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1)
  {
    CFast_ThirdPassAddStaticNode (p_stNode) ;
    if ( procedure_can_stop_engine(eProcedure) )
	{
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "fn_vSetProcedureActionReturn(C_ACTION_ENGINE_CONTINUE);\n" ) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallProcedure_Static( %d ) ;\n", g_ulPseudoTreePrev) ;
  }
  else
  {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_Procedure][0], E_ti_Procedure)] ********/\n", CFast_szPseudoTreeVarName ) ); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_eProcedureIdInterpret(&%s[E_ti_Procedure][0]) = (tdeProcedureId)%d ;\n", 
	      CFast_szPseudoTreeVarName, eProcedure ) ;
    g_ulTreeIndex=0 ;
    while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
    }  
    if ( procedure_can_stop_engine(eProcedure) )
	{
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "fn_vSetProcedureActionReturn(C_ACTION_ENGINE_CONTINUE);\n" ) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallProcedure_NoStatic( ) ;\n") ;
  }
  CFast_fprintf_d(4, ( g_fdCxx, "/*************[%d]*/\n", g_ulNbNodeInStack ) );

  if ( procedure_can_stop_engine(eProcedure) )
  {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "if (fn_ucGetProcedureActionReturn() != (C_ACTION_ENGINE_CONTINUE))\n{\n" ) ;
    if ( g_eProcessWhat != E_pw_Comport )
	{
	  CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "  %s = 1 ;\n" , CFast_szBoolMetaRflxName ) ;
    }
	if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
	{
		CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx , "  if ( CFast_g_bProcessReflex )\n" ) ;
		CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx , "    p_stLocalMind0->CFast_lRfxMetaAction = 0 ;\n" ) ;
		CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx , "  else\n" ) ;
		CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx , "    p_stLocalMind0->CFast_lCmpMetaAction = 0 ;\n" ) ;
	}
    CFast_ThirdPassIndent () ;
	if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
	{
      fprintf ( g_fdCxx, "  return (1) ;\n" ) ;
    }
    else {
      fprintf ( g_fdCxx, "  return ;\n" ) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n" ) ;
  }
  else if ( eProcedure == eProc_ChangeMyComport )
  {
    if ( g_ulBloquantMoteur )
	{
      if ( g_eProcessWhat == E_pw_Comport )
	  {
        g_ulLabelNumber ++ ;
        fprintf ( g_fdCxx, "label%d :\n", g_ulLabelNumber ) ;
        CFast_fprintf( ( g_fdCxx, "return ;\n" ) ) ;
        g_ulBloquantMoteur = 0 ;
        return ;
      }
      else
        add_bloquant_moteur (1) ;
    }
    change_mon_cmp (0) ;
  }
  else if ( eProcedure == eProc_ChangeMyComportReflex )
  {
    if ( g_ulBloquantMoteur )
	{
      if ( g_eProcessWhat == E_pw_Reflex )
	  {
        g_ulLabelNumber++ ;
        fprintf ( g_fdCxx, "label%d :\n", g_ulLabelNumber ) ;
        CFast_fprintf( ( g_fdCxx, "return ;\n" ) ) ;
        g_ulBloquantMoteur = 0 ;
        return ;
      }
      else
	add_bloquant_moteur (2) ;
    }    
    change_mon_rfx (0) ;
  }
  else if ( eProcedure == eProc_ChangeMyComportAndMyReflex )
  {
    if ( g_ulBloquantMoteur )
	{
      if ( ( g_eProcessWhat == E_pw_Comport ) || ( g_eProcessWhat == E_pw_Reflex ) )
	  {
        g_ulLabelNumber++ ;
        fprintf ( g_fdCxx, "label%d :\n", g_ulLabelNumber ) ;
        CFast_fprintf( ( g_fdCxx, "return ;\n" ) ) ;
        g_ulBloquantMoteur = 0 ;
        return ;
      }
      else
        add_bloquant_moteur (3) ;
    }

    change_mon_rfx(1) ;
    change_mon_cmp(1) ;
  }

  if ( g_ulBloquantMoteur )
    add_bloquant_moteur (0) ;

  fflush ( g_fdCxx ) ;
}
void change_mon_rfx (int change_both)
{
  if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
  {
    CFast_fprintf( ( g_fdCxx, "if ( CFast_g_bProcessReflex ) {\n" ) ) ;
    CFast_fprintf( ( g_fdCxx, "  CFast_%s_ArrayReflex[p_stReflex->p_stCurrentComport->CFast_lMyIndex]();\n", 
		     g_szModelName ) ) ;
    if ( !change_both )
	{
      CFast_fprintf( ( g_fdCxx, "  return (1) ;\n" ) ) ;
      CFast_fprintf( ( g_fdCxx, "}\n" ) ) ;
    }
  }
  else
  {
    if ( g_eProcessWhat == E_pw_Reflex )
	{
      CFast_fprintf( ( g_fdCxx, "CFast_%s_ArrayReflex[p_stReflex->p_stCurrentComport->CFast_lMyIndex]();\n", g_szModelName ) ) ;
      CFast_fprintf( ( g_fdCxx, "return ;\n" ) ) ;
    }
  }
}

void change_mon_cmp (int change_both)
{
  if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
  {
    if ( ! change_both )
	{
      CFast_fprintf( ( g_fdCxx, "if ( !CFast_g_bProcessReflex )\n{\n" ) ) ;
    }
    else
	{
      CFast_fprintf( ( g_fdCxx, "}\nelse\n{\n" ) ) ;
    }
    CFast_fprintf( ( g_fdCxx, "  CFast_%s_ArrayComport[p_stIntelligence->p_stCurrentComport->CFast_lMyIndex]();\n", g_szModelName ) ) ;
    if ( ! change_both )
	{
      CFast_fprintf( ( g_fdCxx, "  return (1) ;\n" ) ) ;
      CFast_fprintf( ( g_fdCxx, "}\n" ) ) ;
    }
    else
	{
      CFast_fprintf( ( g_fdCxx, "}\n" ) ) ;
      CFast_fprintf( ( g_fdCxx, "return (1) ;\n" ) ) ;
    }
  }
  else
  {
    if ( g_eProcessWhat == E_pw_Comport )
	{
      CFast_fprintf( ( g_fdCxx, "CFast_%s_ArrayComport[p_stIntelligence->p_stCurrentComport->CFast_lMyIndex]();\n", g_szModelName ) ) ;
      CFast_fprintf( ( g_fdCxx, "return ;\n" ) ) ;
    }
  }
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddMetaAction
 * DESCRIPTION : add a meta-action node
 *******************************************************************************/
void CFast_ThirdPassAddMetaAction (CFast_tdstNode *p_stNode ) {
  CFast_tdstNode *p_stStackNode ;
  
  CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Meta : %s] ********** [%d, %d, %d]*/\n", 
		       szFindMetaActionEditorNameFromId(M_eMetaActionIdInterpret((&p_stNode->stNode))),
		       g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, p_stNode->ucIndexOfEvalParam ) );
  g_eCurrentType = E_ti_MetaAction ;
    
  CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
  if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
    CFast_ThirdPassAddStaticNode (p_stNode) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallMetaActionInit_Static( %d ) ;\n", g_ulPseudoTreePrev
	      ) ;
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[E_ti_MetaAction][0], E_ti_MetaAction)] ********/\n", 
			 CFast_szPseudoTreeVarName ) );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_eMetaActionIdInterpret(&%s[E_ti_MetaAction][0]) = (tdeMetaActionId)%d ;\n", 
	      CFast_szPseudoTreeVarName, M_eMetaActionIdInterpret((&p_stNode->stNode)) ) ;
    g_ulTreeIndex=0 ;
    while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
    }  
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallMetaActionInit_NoStatic( ) ;\n") ;
  }
  CFast_ThirdPassIndent () ;
  g_ulLabelNumber++ ;
  if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
  {
    if ( g_ulGotRfx && g_ulGotCmp ) {
      fprintf ( g_fdCxx, "if ( !CFast_g_bProcessReflex ) \n" ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lCmpMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "else\n" ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lRfxMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
    }
    else if ( g_ulGotCmp ) {
      fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
    }
    else {
      fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaActionForMacro = %d;\n", g_ulLabelNumber ) ;
    }
  }
  else if ( g_eProcessWhat == E_pw_Comport )
  {
    fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaAction = %d;\n", g_ulLabelNumber ) ;
  }
  else
  {
    fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaAction = %d;\n", g_ulLabelNumber ) ;
  }
  fprintf ( g_fdCxx, "label%d :\n",g_ulLabelNumber ) ;
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "if ( CFast_CallMetaAction(%d) & (C_DefaultMetaActionNotFinished)) {\n", M_eMetaActionIdInterpret((&p_stNode->stNode)), CFast_szPseudoTreeVarName) ;
  CFast_ThirdPassIndent () ;

  if ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) )
  {
    if ( g_ulGotCmp && g_ulGotRfx ) {
      fprintf ( g_fdCxx, "  if ( CFast_g_bProcessReflex ) \n" ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "    %s = 1 ;\n", CFast_szBoolMetaRflxName ) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "  return (1) ;\n" );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n" ) ;
    CFast_ThirdPassIndent () ;
    if ( !g_ulGotRfx ) {
      fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaActionForMacro = 0;\n" ) ;      
    }
    else if ( !g_ulGotCmp ) {
      fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaActionForMacro = 0;\n" ) ;
    }
    else {
      fprintf ( g_fdCxx, "if ( CFast_g_bProcessReflex ) \n" ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lRfxMetaActionForMacro = 0;\n" ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "else\n" ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "  p_stLocalMind0->CFast_lCmpMetaActionForMacro = 0;\n" ) ;
    }
  }
  else
  {
    if ( ( g_eProcessWhat == E_pw_Reflex ) && g_ulGotCmp )
	{
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "  %s = 1 ;\n", CFast_szBoolMetaRflxName ) ;
    }
    fprintf ( g_fdCxx, "  return ;\n" );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "}\n" ) ;
    CFast_ThirdPassIndent () ;
    if ( g_eProcessWhat == E_pw_Comport ) 
      fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaAction = 0;\n" ) ;
    else
      fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaAction = 0;\n" ) ;
  }
  CFast_fprintf_d(4, ( g_fdCxx, "/*************[%d]*/\n", g_ulNbNodeInStack ) );

  if ( g_ulBloquantMoteur )
    add_bloquant_moteur (0) ;

  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddVector
 * DESCRIPTION : add a vector node
 *******************************************************************************/
void CFast_ThirdPassAddVector(CFast_tdstNode *p_stNode ) {
  CFast_tdstNode *p_stStackNode ;

  CFast_fprintf_d(2, ( g_fdCxx, "\n/* [Vector] *********** [%d, %d, %d]*/\n", 
		       g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, 
		       p_stNode->ucIndexOfEvalParam ) );
  g_eCurrentType = (tdeTypeInterpret)6  ;
  
  CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
  if ( CFast_ThirdPassCheckParamStackForOptimisation (p_stNode->ucNumberOfParamNeeded) > -1 ) {
    CFast_ThirdPassAddStaticNode (p_stNode) ;
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallVector%d_Static (%d) ;\n", p_stNode->ucIndexOfEvalParam, g_ulPseudoTreePrev ) ;
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[6][0], E_ti_Vector)] ********/\n", 
			 CFast_szPseudoTreeVarName ) );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_p_stVectorInterpret(&%s[6][0]) = %d ;\n", CFast_szPseudoTreeVarName, 
	      M_p_stVectorInterpret((&p_stNode->stNode)) ) ; /* ??? */
    g_ulTreeIndex=0 ;
    while ( (p_stStackNode = CFast_ThirdPassPopParam ()) != NULL ) {
      CFast_ThirdPassAddStackNode(p_stStackNode, ++g_ulTreeIndex) ;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "CFast_CallVector%d_NoStatic () ; \n", p_stNode->ucIndexOfEvalParam ) ;
  }
  CFast_fprintf_d(4, ( g_fdCxx, "/*************[%d]*/\n", g_ulNbNodeInStack ) );
  g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Vector ;
  p_stNode->ucNumberOfParamNeeded = 0 ;
  CFast_ThirdPassPush (p_stNode) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddField
 * DESCRIPTION : add a field node
 *******************************************************************************/
void CFast_ThirdPassAddField (CFast_tdstNode *p_stNode)
{
  if ( p_stNode->bIsABooleanDsgVarRef ) {
	g_lIndexForCondition -- ;
    CFast_fn_vThirdPassField ( NULL, p_stNode ) ;
  }
  else {
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Field ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Field);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Field);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Field)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_eFieldIdInterpret(&%s[%d][%d]) = (tdeFieldId)%d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_eFieldIdInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
  }
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddReal
 * DESCRIPTION : add a real node
 *******************************************************************************/
void CFast_ThirdPassAddReal (CFast_tdstNode *p_stNode ) {
  if ( p_stNode->bIsABooleanDsgVarRef ) {
    char szTmp[1000], cForFloat=0, cForVector=0 ;
    unsigned char c ;

    c = p_stNode->ucIndexOfEvalParam ;
    p_stNode->ucIndexOfEvalParam = 0 ;
    CFast_Get1Param( szTmp, p_stNode, &cForFloat, &cForVector, 1) ;
    p_stNode->ucIndexOfEvalParam = c ;

    strcpy (g_szConditionString2, szTmp) ;
    sprintf ( g_szConditionString1, "long%d = MTH_M_xRealToLong(%s);", g_lIndexForCondition, szTmp ) ;
    g_ulCondStringSet = 1 ;

    return ;
  }
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Real ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Real);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Real);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Real)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }  
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_xValueInterpret(&%s[%d][%d]) = MTH_M_xFloatToReal(%ff) ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_xValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddConstant
 * DESCRIPTION : add a constant node
 *******************************************************************************/
void CFast_ThirdPassAddConstant (CFast_tdstNode *p_stNode ) {
  if ( p_stNode->bIsABooleanDsgVarRef ) {
    char szTmp[1000], cForFloat=0, cForVector=0 ;
    unsigned char c ;

    c = p_stNode->ucIndexOfEvalParam ;
    p_stNode->ucIndexOfEvalParam = 0 ;
    CFast_Get1Param( szTmp, p_stNode, &cForFloat, &cForVector, 1) ;
    p_stNode->ucIndexOfEvalParam = c ;

    strcpy (g_szConditionString2, szTmp) ;
    sprintf ( g_szConditionString1, "long%d = %s;", g_lIndexForCondition, szTmp ) ;
    g_ulCondStringSet = 1 ;

    return ;
  }
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Constant ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Constant);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Constant);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Constant)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  } 
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddButton
 * DESCRIPTION : add a button node
 *******************************************************************************/
void CFast_ThirdPassAddButton (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Button ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Button);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Button);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Button)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddMask
 * DESCRIPTION : add a mask node
 *******************************************************************************/
void CFast_ThirdPassAddMask (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Mask ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Mask);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Mask);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Mask)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_xMaskInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_xMaskInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddString
 * DESCRIPTION : add a String node
 *******************************************************************************/
void CFast_ThirdPassAddString (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_String ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_String);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_String);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_String)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_szStringInterpret(&%s[%d][%d]) = \"%s\" ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_szStringInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddLipsSynchro
 * DESCRIPTION : add a LipsSynchro  node
 *******************************************************************************/
void CFast_ThirdPassAddLipsSynchro (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_LipsSynchroRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_LipsSynchroRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_LipsSynchroRef);
  }
  else {
     CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_LipsSynchroRef)] ********/\n", 
			  CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddFamily
 * DESCRIPTION : add a Family  node
 *******************************************************************************/
void CFast_ThirdPassAddFamily (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_FamilyRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_FamilyRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_FamilyRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_FamilyRef)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddPerso
 * DESCRIPTION : add a Perso  node
 *******************************************************************************/
void CFast_ThirdPassAddPerso (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_PersoRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_PersoRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_PersoRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_PersoRef)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddAction
 * DESCRIPTION : add a Action node
 *******************************************************************************/
void CFast_ThirdPassAddAction (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_ActionRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ActionRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_ActionRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_ActionRef)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddObject
 * DESCRIPTION : add a Object node
 *******************************************************************************/
void CFast_ThirdPassAddObject (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_SuperObjectRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_SuperObjectRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_SuperObjectRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_SuperObjectRef)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddWP
 * DESCRIPTION : add a WP node
 *******************************************************************************/
void CFast_ThirdPassAddWP (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_WayPointRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_WayPointRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_WayPointRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_WayPointRef)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddComport
 * DESCRIPTION : add a ComportRef node
 *******************************************************************************/
void CFast_ThirdPassAddComport (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_ComportRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ComportRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_ComportRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_WayPointRef)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddModule
 * DESCRIPTION : add a ModuleRef node
 *******************************************************************************/
void CFast_ThirdPassAddModule (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_ModuleRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ModuleRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_ModuleRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_ModuleRef)] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddSoundEvent
 * DESCRIPTION : add a SoundEvent node
 *******************************************************************************/
void CFast_ThirdPassAddSoundEvent (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_SoundEventRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_SoundEventRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_SoundEventRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_SoundEventRef] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddObjectTable
 * DESCRIPTION : add a ObjectTable node
 *******************************************************************************/
void CFast_ThirdPassAddObjectTable (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_ObjectTableRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ObjectTableRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_ObjectTableRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_ObjectTableRef] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddParticleGenerator
 * DESCRIPTION : add a ParticleGenerator node
 *******************************************************************************/
void CFast_ThirdPassAddParticleGenerator (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_ParticleGenerator ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ParticleGenerator);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_ParticleGenerator);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_ParticleGenerator] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddColor
 * DESCRIPTION : add a Color node
 *******************************************************************************/
void CFast_ThirdPassAddColor (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Color ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Color);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Color);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Color] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_ColorValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_ColorValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddModel
 * DESCRIPTION : add a ModelRef node
 *******************************************************************************/
void CFast_ThirdPassAddModel (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_ModelRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ModelRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_ModelRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_ModelRef] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddLight
 * DESCRIPTION : add a Light node
 *******************************************************************************/
void CFast_ThirdPassAddLight (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Light ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Light);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Light);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Light] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddCaps
 * DESCRIPTION : add a Caps node
 *******************************************************************************/
void CFast_ThirdPassAddCaps (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Caps ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Caps);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Caps);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Caps] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_ulCapsInterpret(&%s[%d][%d]) = %lu ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_ulCapsInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddGraph
 * DESCRIPTION : add a Graph node
 *******************************************************************************/
void CFast_ThirdPassAddGraph (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_Graph ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Graph);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Graph);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_Graph] ********/\n", 
			  CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddDsgVar
 * DESCRIPTION : add a DsgVarRef node
 *******************************************************************************/
void CFast_ThirdPassAddDsgVar (CFast_tdstNode *p_stNode){
  if ( p_stNode->bIsABooleanDsgVarRef ) {
    char szTmp[1000], cForFloat=0, cForVector=0 ;
    unsigned char c ;

    c = p_stNode->ucIndexOfEvalParam ;
    p_stNode->ucIndexOfEvalParam = 0 ;
    CFast_Get1Param( szTmp, p_stNode, &cForFloat, &cForVector, 1) ;
    p_stNode->ucIndexOfEvalParam = c ;

    strcpy (g_szConditionString2, szTmp) ;
    if ( cForFloat )
      sprintf ( g_szConditionString1, "long%d = MTH_M_xRealToLong(%s);", g_lIndexForCondition, szTmp ) ;
    else
      sprintf ( g_szConditionString1, "long%d = %s;", g_lIndexForCondition, szTmp ) ;
    g_ulCondStringSet = 1 ;

//     CFast_ThirdPassIndent () ;
//     fprintf ( g_fdCxx, "long%d = %s;\n", g_lIndexForCondition, szTmp );
    return ;
  }
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_DsgVarRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_DsgVarRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_DsgVarRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_DsgVarRef] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddGameMaterial
 * DESCRIPTION : add a GameMaterial node
 *******************************************************************************/
void CFast_ThirdPassAddGameMaterial (CFast_tdstNode *p_stNode){
  if ( M_GetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex]) != E_ti_GameMaterialRef ) {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_GameMaterialRef);\n", 
	      CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) ;
    M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_GameMaterialRef);
  }
  else {
    CFast_fprintf_d(3, ( g_fdCxx, "/* [M_SetTypeInterpret(&%s[%d][%d], E_ti_GameMaterialRef] ********/\n", 
			 CFast_szPseudoTreeVarName, g_eCurrentType, g_ulTreeIndex ) );
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = %d ;\n", CFast_szPseudoTreeVarName, 
	    g_eCurrentType, g_ulTreeIndex, M_lValueInterpret((&p_stNode->stNode)) ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddOptimisedNode
 * DESCRIPTION : add an optimised node got from the 2d pass 
 *               pop the param stack then write down the string
 *******************************************************************************/
void CFast_ThirdPassAddOptimisedNode (CFast_tdstNode *p_stNode ) {
    
  CFast_ThirdPassPopAllParam ( p_stNode->ucNumberOfParamNeeded, 0 ) ;
  g_ulNbParamInStack = 0 ;  
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "%s ;\n", p_stNode->d_cOptimisedNode ) ;
  fflush ( g_fdCxx ) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddUltraNode
 * DESCRIPTION : add an ultra operator, PersoRef is gotten from the ParamStack
 *******************************************************************************/
void CFast_ThirdPassAddUltraNode (void) {
  CFast_tdstNode *p_stStackNode ;

  p_stStackNode = CFast_ThirdPassPopParam () ;
  CFast_ThirdPassIndent () ;
  if ( M_GetTypeInterpret((&p_stStackNode->stNode)) == E_ti_KeyWord ) {
    if ( M_eKeyWordIdInterpret((&p_stStackNode->stNode)) == eKeyWord_Me ) {
      CFast_fprintf_d(3, ( g_fdCxx, "/* skip ultra operator : Me !! */\n" ) );
    }
    else if ( M_eKeyWordIdInterpret((&p_stStackNode->stNode)) == eKeyWord_MainActor ) {
      fprintf ( g_fdCxx, "CFast_fn_vSetUltraOperatorMainActor();\n" ) ;
    }
    /*else if ( M_eKeyWordIdInterpret((&p_stStackNode->stNode)) == eKeyWord_World ) {
      fprintf ( g_fdCxx, "CFast_fn_vSetUltraOperatorWorld();\n" ) ;
    }*/
  }
  else if ( p_stStackNode->lIndexOfRef<0 ){
    fprintf ( g_fdCxx, "CFast_fn_vSetUltraOperatorPersoVar(%d);\n", M_lValueInterpret(&p_stStackNode->stNode)) ;
  }
  else {
    fprintf ( g_fdCxx, "CFast_fn_vSetUltraOperatorPersoRef(%d);\n", p_stStackNode->lIndexOfRef) ;
  }  
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddStackNode
 * DESCRIPTION : add a node that has been stacked
 *******************************************************************************/
void CFast_ThirdPassAddStackNode (CFast_tdstNode *p_stNode, unsigned long ulDepth ) {
  /*
   * function or operator return
   */
  if ( p_stNode->ucIndexOfEvalParam ) {
    /*
     * cas particulier pour les operateurs moi, acteur principal et world
     */
    if ( M_GetTypeInterpret((&p_stNode->stNode)) == E_ti_KeyWord ) {
      if ( M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_Me ) {
	CFast_ThirdPassIndent () ;
	fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_PersoRef);\n", 
		  CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
	CFast_ThirdPassIndent () ;
	fprintf ( g_fdCxx, "M_p_stPersoRefInterpret(&%s[%d][%d]) = M_GetEngineObject(g_hSuperObjectPerso) ; \n",
		  CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
	CFast_ThirdPassInitPseudoTree (ulDepth) ;
	fflush ( g_fdCxx ) ;
	return ;
      }
      else if ( M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_MainActor ) {
	CFast_ThirdPassIndent () ;
	fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_PersoRef);\n", 
		  CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
	CFast_ThirdPassIndent () ;
	fprintf ( g_fdCxx, "M_p_stPersoRefInterpret(&%s[%d][%d]) = M_GetEngineObject(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode())) ; \n", CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
	CFast_ThirdPassInitPseudoTree (ulDepth) ;
	fflush ( g_fdCxx ) ;
	return ;
      }
      /*else if ( M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_World ) {
	CFast_ThirdPassIndent () ;
	fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_PersoRef);\n", 
		  CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
	CFast_ThirdPassIndent () ;
	fprintf ( g_fdCxx, "M_p_stPersoRefInterpret(&%s[%d][%d]) = M_GetEngineObject(g_stEngineStructure.h_WorldCaracter) ; \n", CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
	CFast_ThirdPassInitPseudoTree (ulDepth) ;
	fflush ( g_fdCxx ) ;
	return ;
      }*/
    }
    /*
     * variables temporaires
     */
    CFast_ThirdPassIndent () ;
    CFast_ThirdPassInitPseudoTree (ulDepth) ;
    switch ( g_eParamType[p_stNode->ucIndexOfEvalParam] ) {
    case E_vt_Integer :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Constant);\n", 
             		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		            CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		            p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_PositiveInteger :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Constant);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_ulValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_String :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_String);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_WayPoint :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_WayPointRef);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_DsgVarId :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_DsgVarRef);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Action :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ActionRef);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Button :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Button);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_LipsSynchro :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_LipsSynchroRef);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_ObjectTable :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ObjectTableRef);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_SuperObject :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_SuperObjectRef);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Family :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_FamilyRef);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_SoundEvent :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_SoundEventRef);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Comport :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ComportRef);\n", 
		 CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_ParticleGenerator :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ParticleGenerator);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Color :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Color);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Model :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ModelRef);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Light :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Light);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Caps :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_CapsRef);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Graph :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Graph);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;

    case E_vt_Vector :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_ConstantVector);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_p_stVectorInterpret(&%s[%d][%d]) = &M_GetSetParam_stVectorValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Float :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Real);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_xValueInterpret(&%s[%d][%d]) = M_GetSetParam_xValue(&%s[%d]) ;\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Perso :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_PersoRef);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_p_stPersoRefInterpret(&%s[%d][%d]) = M_GetSetParam_p_stEngineObjValue(&%s[%d]);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Mask :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Mask);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_xMaskInterpret(&%s[%d][%d]) = M_GetSetParam_xMaskValue(&%s[%d]);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;
    case E_vt_Module :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Module);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lModuleInterpret(&%s[%d][%d]) = M_GetSetParam_lModuleValue(&%s[%d]);\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam ) ;
      break ;     
    default :
      fprintf ( g_fdCxx, "M_SetTypeInterpret(&%s[%d][%d], E_ti_Constant);\n", 
 		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
 		p_stNode->ucIndexOfEvalParam ) ;
      CFast_ThirdPassIndent () ;
      fprintf ( g_fdCxx, "M_lValueInterpret(&%s[%d][%d]) = M_GetSetParam_lValue(&%s[%d]) ; /* Default [%d] */\n", 
		CFast_szPseudoTreeVarName, g_eCurrentType, ulDepth, CFast_szParamVarName, 
		p_stNode->ucIndexOfEvalParam, g_eParamType[p_stNode->ucIndexOfEvalParam]) ;     
      break ;
    }
    fflush ( g_fdCxx ) ;
  }
  else {
    /*
     * other node 
     */
    CFast_ThirdPassParseNode ( p_stNode, TRUE ) ;
  }
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddRef
 * DESCRIPTION : add a reference
 *******************************************************************************/
void CFast_ThirdPassAddRef ( CFast_tdstNode *p_stNode ) {
  if ( gRemoveNextModelRef && M_GetTypeInterpret(&p_stNode->stNode) == E_ti_ModelRef ) {
    g_ulTreeIndex--;
    return ;
  }
  CFast_ThirdPassIndent () ;
  fprintf ( g_fdCxx, "CFast_memcpy ( %d, %d, %d) ;\n",
	          g_eCurrentType, g_ulTreeIndex, p_stNode->lIndexOfRef ) ;
  M_SetTypeInterpret(&g_a_stPseudoTree[g_eCurrentType][g_ulTreeIndex], E_ti_Unknown) ;
}



//#####################################################################################################################
//#####################################################################################################################
//													OPTIMISATIONS
//#####################################################################################################################
//#####################################################################################################################

/*********************************************************************************************************************/
/*********************************************************************************************************************/

#define _CFast_ThirdPassPush_(a, node)\
{\
	if(gapst_Params[a*2])\
	{\
		CFast_ThirdPassPush(gapst_Params[(a*2)+1]);\
		gapst_Params[(a*2)+1] = NULL;\
		CFast_ThirdPassPush(gapst_Params[a*2]);\
		gapst_Params[a*2] = NULL;\
	}\
	CFast_ThirdPassPush (node);\
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/

int CFast_GetTypeReturnFunc(CFast_tdstNode *p_stParam)
{
	if(M_GetTypeInterpret(&p_stParam->stNode) == E_ti_Function)
	{
		switch(M_eOperatorIdInterpret(&p_stParam->stNode))
		{
		case eFunc_GetTime:				return 4;
		case eFunc_GetElapsedTime:		return 4;
		case eFunc_GetHitPointsMax :
		  return 4 ;
		case eFunc_GetPersoAbsolutePosition :
		  return 4 ;
		default:
			return 0;
		}
	}
	return 0;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/

char CFast_Get1Param(char *psz_Temp, CFast_tdstNode *p_stParam, char *cForFloat, char *cForVector, int iIndex) {
  struct AI_tdstMind_       *p_stCurrentMind = gp_stCurrentMind;
  struct tdstNodeInterpret_ *p_stRefTree = gp_stCurrentMind->p_stAIModel->CFast_dst_RefTreeArray;
  int                       iTmpIndex = 0;
  CFast_tdstNode            *p_stParamX = p_stParam;
  char                      *p_szMacro = "M_LocalGetDsgVarAddr";
  unsigned long             ulCastOperator = 0 ;
  tdeDsgVarTypeId           eDsgVarType ;
  CFast_tdstNode            *p_stModelNode = NULL ;
  /*
   * Not a result of function.
   */
  if(p_stParam->ucIndexOfEvalParam <= 0) {
    /* One normal real node */
    switch(M_GetTypeInterpret(&p_stParam->stNode)) {
    case E_ti_Real:
      sprintf(psz_Temp, "MTH_M_xFloatToReal(%ff)", M_xValueInterpret(&p_stParam->stNode));
      *cForFloat += iIndex;
      return 1;
      break;

    case E_ti_Constant:
      sprintf(psz_Temp, "%d", M_lValueInterpret(&p_stParam->stNode));
      return 1;
      break;

      /* Reference */
    case E_ti_Operator:

      if(M_eOperatorIdInterpret(&p_stParam->stNode) == eOperator_Dot){
	      gapst_Params[iIndex*2] = CFast_ThirdPassPop();       /* DsgVarRef */
	      if(M_GetTypeInterpret(&gapst_Params[iIndex*2]->stNode) != E_ti_DsgVarRef) {
	        CFast_ThirdPassPush(gapst_Params[iIndex*2]);
	        gapst_Params[iIndex*2] = NULL;
	        return 0;
	      }
	      gapst_Params[(iIndex*2)+1] = CFast_ThirdPassPop();   /* PersoRef or ModelCast */
   	    if ( p_stRefTree != NULL && 
  	         M_GetTypeInterpret(&gapst_Params[(iIndex*2)+1]->stNode) == E_ti_Operator &&
   	         M_eOperatorIdInterpret(&gapst_Params[(iIndex*2)+1]->stNode) == eOperator_ModelCast ) {
   	      gapst_Params[(iIndex*2)+1] = CFast_ThirdPassPop(); /* DsgVarRef */
   	      p_stModelNode = CFast_ThirdPassPop();              /* ModelRef */
   	      ulCastOperator = 1 ;
   	    }
   	    else 
	        if(gapst_Params[(iIndex*2)+1]->lIndexOfRef == -1) {
	          CFast_ThirdPassPush(gapst_Params[(iIndex*2)+1]);
	          CFast_ThirdPassPush(gapst_Params[iIndex*2]);
	          gapst_Params[iIndex*2] = NULL;
	          gapst_Params[(iIndex*2)+1] = NULL;
	          return 0;
	        }

          iTmpIndex = iIndex;
          p_stParamX = gapst_Params[iIndex*2];
          p_szMacro = "M_GetDsgVarAddr";
          
          if ( ulCastOperator ) {
            tdstNodeInterpret * p_stIntNode ;
            
            /*
             * get dsgvar type
             */
            p_stIntNode = p_stRefTree + p_stModelNode->lIndexOfRef ;
            if ( gapst_Params[(iIndex*2)]->lIndexOfRef > -1 ) {
              eDsgVarType = M_p_stModelInterpret(p_stIntNode)->p_stDsgVar->p_stDsgVarInfo[M_CFast_ucGetRealIndice(gapst_Params[(iIndex*2)]->lIndexOfRef)].eDsgVarTypeId ;    
            }
            else {
              eDsgVarType = M_p_stModelInterpret(p_stIntNode)->p_stDsgVar->p_stDsgVarInfo[M_lDsgVarIdInterpret(&gapst_Params[(iIndex*2)]->stNode)].eDsgVarTypeId ;
            }
            /*
            * write the initialisation of the perso mind
            */
            CFast_ThirdPassIndent () ;
            if ( gapst_Params[(iIndex*2)+1]->lIndexOfRef > -1 ) {
              fprintf ( g_fdCxx, "p_stLocalMind%d = (M_GetMSHandle( (*((HIE_tdxHandleToSuperObject *)M_GetDsgVarAddr(p_stLocalMind0, M_CFast_ucGetRealIndice(%d)))), Brain))->p_stMind ;\n", iIndex, gapst_Params[(iIndex*2)+1]->lIndexOfRef ) ;
            }
            else {
              fprintf ( g_fdCxx, "p_stLocalMind%d = (M_GetMSHandle( (*((HIE_tdxHandleToSuperObject *)M_GetDsgVarAddr(p_stLocalMind0, %d))), Brain))->p_stMind ;\n", iIndex, M_lDsgVarIdInterpret(&gapst_Params[(iIndex*2)+1]->stNode) ) ;
            }
            p_stCurrentMind = NULL ;
          }
          else {
            /* This is a reference on a dsgvar */
            CFast_ThirdPassIndent () ;
            fprintf(g_fdCxx, "p_stLocalMind%d = M_pstGetMindOfBrain(M_GetMSHandle(M_CFast_hGetPersoRef(%d) ,Brain));\n", iIndex, gapst_Params[(iIndex*2)+1]->lIndexOfRef);
            p_stCurrentMind = M_pstGetMindOfBrain(M_GetMSHandle(M_GetSuperObject(M_p_stPersoRefInterpret(&gapst_Params[(iIndex*2)+1]->stNode)), Brain));
          }

      }
      else 
	return 0;


    case E_ti_DsgVarRef:
      if ( !ulCastOperator ) 
	      eDsgVarType = M_GetDsgVarType(p_stCurrentMind, M_lValueInterpret(&p_stParamX->stNode)) ;

        switch(eDsgVarType)
	      {
	      case eDsgVarType_Float:
	        sprintf(psz_Temp, "(*((MTH_tdxReal *)(%s(p_stLocalMind%d, %d))))", p_szMacro, iTmpIndex, M_lValueInterpret(&p_stParamX->stNode));
	        *cForFloat += iIndex;
	        return 1;
	        break;
	      case eDsgVarType_Vector:
	        sprintf(psz_Temp, "((MTH3D_tdstVector *)(%s(p_stLocalMind%d, %d)))", p_szMacro, iTmpIndex, M_lValueInterpret(&p_stParamX->stNode));
	        *cForVector += iIndex;
	        return 1;
	      case eDsgVarType_Boolean:			
	      case eDsgVarType__128To127:
	      case eDsgVarType_0To255:
	        sprintf(psz_Temp, "(*((char *)(%s(p_stLocalMind%d, %d))))",  p_szMacro, iTmpIndex, M_lValueInterpret(&p_stParamX->stNode));
	        return 1;
	        break;
	      case eDsgVarType__32768To32767:
	      case eDsgVarType_0To65535:			
	        sprintf(psz_Temp, "(*((short *)(%s(p_stLocalMind%d, %d))))",  p_szMacro, iTmpIndex, M_lValueInterpret(&p_stParamX->stNode));
	        return 1;
	        break;
	      case eDsgVarType_Integer:
	      case eDsgVarType_PositiveInteger:	
	        sprintf(psz_Temp, "(*((int *)(%s(p_stLocalMind%d, %d))))",  p_szMacro, iTmpIndex, M_lValueInterpret(&p_stParamX->stNode));
	        return 1;
	        break;
	      default:
	        return 0;
	    }
      return 0;
      break;

    default:
      return 0;
    }
  }
  /*
   * Result of a previous function call.
   */
  else
    {
      switch(g_eParamType[p_stParam->ucIndexOfEvalParam])
	{
	case E_vt_Float:
	  *cForFloat += iIndex;
	  sprintf(psz_Temp, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d])", p_stParam->ucIndexOfEvalParam);
	  return 1;
	  break;
	case E_vt_Vector:
	  *cForVector += iIndex;
	  sprintf(psz_Temp, "&M_GetSetParam_stVectorValue(&CFast_g_a_stParam[%d])", p_stParam->ucIndexOfEvalParam);
	  return 1;
	  break;
	case E_vt_Integer:
	  if ( M_GetTypeInterpret(&p_stParam->stNode) == E_ti_Operator ) {
	    /*
	     * scalar operators always return signed values ... I hope !
	     */
	    sprintf(psz_Temp, "M_GetSetParam_lValue(&CFast_g_a_stParam[%d])", p_stParam->ucIndexOfEvalParam);
	    return 1;
	  }
	  switch(CFast_GetTypeReturnFunc(p_stParam))
	    {
	    case 4:
	      sprintf(psz_Temp, "M_GetSetParam_ulValue(&CFast_g_a_stParam[%d])", p_stParam->ucIndexOfEvalParam);
	      return 1;
	    case -4:
	      sprintf(psz_Temp, "M_GetSetParam_lValue(&CFast_g_a_stParam[%d])", p_stParam->ucIndexOfEvalParam);
	      return 1;
	      break;
	    default:
	      return 0;
	    }
	  break;
	default:
	  return 0;
	}
    }
}


char CFast_Get2Params
(
	CFast_tdstNode	**p_stParam1, 
	CFast_tdstNode	**p_stParam2, 
	char			*cForFloat, 
	char			*cForVector, 
	char			*psz_Temp1,
	char			*psz_Temp2
)
{
	CLEAR_Params();
	*cForFloat = *cForVector = 0;

	*p_stParam2 = CFast_ThirdPassPop();
	if(*p_stParam2 == NULL)
	{
		return 0;
	}

	if(CFast_Get1Param(psz_Temp2, *p_stParam2, cForFloat, cForVector, 2) == 0)
	{
		_CFast_ThirdPassPush_(2, *p_stParam2);
		return 0;
	}

	*p_stParam1 = CFast_ThirdPassPop();
	if(*p_stParam1 == NULL)
	{
		_CFast_ThirdPassPush_(2, *p_stParam2);
		return 0;
	}

	if(CFast_Get1Param(psz_Temp1, *p_stParam1, cForFloat, cForVector, 1) == 0)
	{
		_CFast_ThirdPassPush_(1, *p_stParam1);
		_CFast_ThirdPassPush_(2, *p_stParam2);
		return 0;
	}

	return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassAddComp(CFast_tdstNode *p_stNode) {
  char			cForFloat, cForVector;
  char			szTemp[1000];
  char			szTemp1[1000];
  char			szTemp2[1000];
  char			szTemp3[1000];
  CFast_tdstNode	*p_stParam1, *p_stParam2;

  /* Check for a good operator */
  switch ( M_eCondIdInterpret((&p_stNode->stNode)) ) {
  case eCond_Lesser:
  case eCond_Greater:
  case eCond_LesserOrEqual:
  case eCond_GreaterOrEqual:
  case eCond_Equal:
  case eCond_Different:
    break;
  default:
    return 0;
  }

  /* Get the 2 params */
  if(!CFast_Get2Params(&p_stParam1, &p_stParam2, &cForFloat, &cForVector, szTemp1, szTemp2))
    return 0;

  if(cForVector) {
    _CFast_ThirdPassPush_(1, p_stParam1);
    _CFast_ThirdPassPush_(2, p_stParam2);
    return 0;
  }

  if((cForFloat) && (!(cForFloat & 1))) {
    sprintf(szTemp3, "MTH_M_xLongToReal(%s)", szTemp1);
    strcpy(szTemp1, szTemp3);
  }

  if((cForFloat) && (!(cForFloat & 2))) {
    sprintf(szTemp3, "MTH_M_xLongToReal(%s)", szTemp2);
    strcpy(szTemp2, szTemp3);
  }

  /* Write the operation */
  switch ( M_eCondIdInterpret((&p_stNode->stNode)) )  {
  case eCond_Lesser:
    if(cForFloat)   sprintf ( szTemp, "MTH_M_bLess(%s, %s)",szTemp1,szTemp2 ); 
    else            sprintf ( szTemp, "%s < %s",szTemp1,szTemp2 ); 
    break;
  case eCond_Greater:
    if(cForFloat)   sprintf ( szTemp, "MTH_M_bGreater(%s, %s)",szTemp1,szTemp2 ); 
    else            sprintf ( szTemp, "%s > %s",szTemp1,szTemp2 ); 
    break;
  case eCond_LesserOrEqual:
    if(cForFloat)   sprintf ( szTemp, "MTH_M_bLessEqual(%s, %s)",szTemp1,szTemp2 ); 
    else            sprintf ( szTemp, "%s <= %s",szTemp1,szTemp2 ); 
    break;
  case eCond_GreaterOrEqual:
    if(cForFloat)   sprintf ( szTemp, "MTH_M_bGreaterEqual(%s, %s)",szTemp1,szTemp2 ); 
    else            sprintf ( szTemp, "%s >= %s",szTemp1,szTemp2 ); 
    break;
  case eCond_Equal:
    if(cForFloat)   sprintf ( szTemp, "MTH_M_bEqual(%s, %s)",szTemp1,szTemp2 ); 
    else            sprintf ( szTemp, "%s == %s",szTemp1,szTemp2 ); 
    break;
  case eCond_Different:
    if(cForFloat)   sprintf ( szTemp, "MTH_M_bDifferent(%s, %s)",szTemp1,szTemp2 ); 
    else            sprintf ( szTemp, "%s != %s",szTemp1,szTemp2 ); 
    break;
  }

  if ( g_ulProcessIf )
  {
    strcpy ( g_szConditionString2, szTemp ) ;
    sprintf ( g_szConditionString1, "long%d = %s ? 1 : 0;", g_lIndexForCondition, szTemp) ;
    g_ulCondStringSet = 1 ;
  }
  else {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "long%d = %s ? 1 : 0;\n", ++g_lIndexForCondition,szTemp) ;    
  }

//   CFast_ThirdPassIndent () ;
//   fprintf ( g_fdCxx, "long%d = %s ? 1 : 0;\n", g_lIndexForCondition,szTemp) ;
  return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassAddOper(CFast_tdstNode *p_stNode) {
  char             cForFloat, cForVector;
  char             szTemp0[1000];
  char             szTemp1[1000];
  char             szTemp2[1000];
  char             szTemp3[1000];
  long             lNbParam ;
  CFast_tdstNode   *p_stParam1, *p_stParam2;

  /* Check for a good operator */
  switch ( M_eCondIdInterpret((&p_stNode->stNode)) )  {
  case eOperator_ScalarPlusScalar:
  case eOperator_ScalarMinusScalar:
  case eOperator_ScalarMulScalar:
  case eOperator_ScalarDivScalar:
    lNbParam = 2 ;
    break ;
  case eOperator_ScalarUnaryMinus:
    lNbParam = 1 ;
    return 0 ;
    break;
  case eOperator_VectorMulScalar:
  case eOperator_VectorDivScalar:
  case eOperator_VectorPlusVector:
  case eOperator_VectorMinusVector:
    lNbParam = 2 ;
    break;
  default:
    return 0;
  }

  if ( lNbParam == 2 ) {
    /* Get the 2 params */
    if(!CFast_Get2Params(&p_stParam1, &p_stParam2, &cForFloat, &cForVector, szTemp1, szTemp2))
      return 0;
  }
  else {
    /* Get the params */
    p_stParam1 = CFast_ThirdPassPop(); 
    if ( p_stParam1 == NULL ) {
      return 0;
    }
    cForFloat = cForVector = 0;
    if ( !CFast_Get1Param (szTemp1, p_stParam1, &cForFloat, &cForVector, 1) )
      return 0;
  }

  /* Get string for result */
  if(cForVector) {
    sprintf(szTemp0, "&M_GetSetParam_stVertexValue(&CFast_g_a_stParam[%d])", p_stNode->ucIndexOfEvalParam);
  }
  else if(cForFloat) {
    sprintf(szTemp0, "M_Full_GetSetParam_Float(&CFast_g_a_stParam[%d],", p_stNode->ucIndexOfEvalParam);
  }
  else {
    sprintf(szTemp0, "M_Full_GetSetParam_Integer(&CFast_g_a_stParam[%d],", p_stNode->ucIndexOfEvalParam);
  }
  
  if((cForFloat) && (!(cForFloat & 1) && (!(cForVector & 1)))) {
    sprintf(szTemp3, "MTH_M_xLongToReal(%s)", szTemp1);
    strcpy(szTemp1, szTemp3);
  }
  
  if ( lNbParam == 2 ) {
    if((cForFloat) && (!(cForFloat & 2) && (!(cForVector & 2)))) {
      sprintf(szTemp3, "MTH_M_xLongToReal(%s)", szTemp2);
      strcpy(szTemp2, szTemp3);
    }
  }

  /* Write the operation */
  CFast_ThirdPassIndent () ;
  switch ( M_eCondIdInterpret((&p_stNode->stNode)) )  {
  case eOperator_ScalarPlusScalar:
    if(cForFloat)
      fprintf ( g_fdCxx, "%s MTH_M_xAdd(%s,%s));\n",szTemp0,szTemp1,szTemp2 ); 
    else
      fprintf ( g_fdCxx, "%s %s + %s);\n",szTemp0,szTemp1,szTemp2 ); 
    break;
  case eOperator_ScalarMinusScalar:
    if(cForFloat)
      fprintf ( g_fdCxx, "%s MTH_M_xSub(%s,%s));\n",szTemp0,szTemp1,szTemp2 ); 
    else
      fprintf ( g_fdCxx, "%s %s - %s);\n",szTemp0,szTemp1,szTemp2 ); 
    break;
  case eOperator_ScalarMulScalar:
    if(cForFloat)
      fprintf ( g_fdCxx, "%s MTH_M_xMul(%s,%s));\n",szTemp0,szTemp1,szTemp2 ); 
    else
      fprintf ( g_fdCxx, "%s %s * %s);\n",szTemp0,szTemp1,szTemp2 ); 
    break;
  case eOperator_ScalarDivScalar:
    if(cForFloat)
      fprintf ( g_fdCxx, "%s MTH_M_xDiv(%s,%s));\n",szTemp0,szTemp1,szTemp2 ); 
    else
      fprintf ( g_fdCxx, "%s %s / %s);\n",szTemp0,szTemp1,szTemp2 ); 
    break;

  case eOperator_ScalarUnaryMinus:
    if(cForFloat)
      fprintf ( g_fdCxx, "%s -%s);\n", szTemp0, szTemp1); 
    else
      fprintf ( g_fdCxx, "%s -%s);\n", szTemp0, szTemp1);     
    break ;

  case eOperator_VectorPlusVector:
    fprintf ( g_fdCxx, "MTH3D_M_vAddVector(%s, %s, %s);\n",szTemp0,szTemp1,szTemp2 ); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Vector;\n", p_stNode->ucIndexOfEvalParam);
    cForVector = 1;
    break;
  case eOperator_VectorMinusVector:
    fprintf ( g_fdCxx, "MTH3D_M_vSubVector(%s, %s, %s);\n",szTemp0,szTemp1,szTemp2 ); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Vector;\n", p_stNode->ucIndexOfEvalParam);
    cForVector = 1;
    break;
  case eOperator_VectorMulScalar:
    if(cForVector & 2)
      fprintf ( g_fdCxx, "MTH3D_M_vMulScalarVector(%s, %s, %s);\n",szTemp0,szTemp1,szTemp2 ); 
    else
      fprintf ( g_fdCxx, "MTH3D_M_vMulScalarVector(%s, %s, %s);\n",szTemp0,szTemp2,szTemp1 ); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Vector;\n", p_stNode->ucIndexOfEvalParam);
    cForVector = 1;
    break;
  case eOperator_VectorDivScalar:
    if(cForVector & 1)
      fprintf ( g_fdCxx, "MTH3D_M_vDivScalarVector(%s, %s, %s);\n",szTemp0,szTemp1,szTemp2 ); 
    else
      fprintf ( g_fdCxx, "MTH3D_M_vDivScalarVector(%s, %s, %s);\n",szTemp0,szTemp2,szTemp1 ); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Vector;\n", p_stNode->ucIndexOfEvalParam);
    cForVector = 1;
    break;
  }

  p_stNode->ucNumberOfParamNeeded = 0 ;
  if(cForFloat && !cForVector)
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
  else if(cForVector)
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Vector;
  else
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ;
  CFast_ThirdPassPush (p_stNode) ;

  return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassGetRealParam(char *psz_Temp, CFast_tdstNode *p_stParam, int iIndex)
{
	char	szTemp[1000], cForFloat = 0, cForVector = 0;

	if(CFast_Get1Param(psz_Temp, p_stParam, &cForFloat, &cForVector, 1 << (iIndex-1)) == 0)
		return 0;
	if(!cForFloat)
	{
		sprintf(szTemp, "MTH_M_xLongToReal(%s)", psz_Temp);
		strcpy(psz_Temp, szTemp);
	}
	if(cForVector)
		return 0;
	return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassGetConstParam(char *psz_Temp, CFast_tdstNode *p_stParam, int iIndex)
{
	char	szTemp[1000], cForFloat = 0, cForVector = 0;

	if(CFast_Get1Param(psz_Temp, p_stParam, &cForFloat, &cForVector, 1 << (iIndex-1)) == 0)
		return 0;
	if(cForFloat == 2)
	{
		sprintf(szTemp, "MTH_M_xRealToLong(%s)", psz_Temp);
		strcpy(psz_Temp, szTemp);
	}
	if(cForVector)
		return 0;
	return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassGetVectorParam(char *psz_Temp, CFast_tdstNode *p_stParam, int iIndex)
{
	char	cForFloat = 0, cForVector = 0;

	if(CFast_Get1Param(psz_Temp, p_stParam, &cForFloat, &cForVector, 1 << (iIndex-1)) == 0)
		return 0;
	if(!cForVector)
		return 0;

	return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassAddVecFunc(CFast_tdstNode *p_stNode)
{
	CFast_tdstNode	*p_stParam1, *p_stParam2;
	char			szTemp1[1000];
	char			szTemp2[1000];

	switch ( M_eCondIdInterpret((&p_stNode->stNode)) ) 
	{
	case eFunc_GetVectorNorm:
		p_stParam1 = CFast_ThirdPassPop();
		if(CFast_ThirdPassGetVectorParam(szTemp1, p_stParam1, 1) == 0)
		{
			_CFast_ThirdPassPush_(1, p_stParam1);
			return 0;
		}

	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH3D_M_xNormVector(%s);\n", p_stNode->ucIndexOfEvalParam, szTemp1); 
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);

		g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
		break;

	case eFunc_Normalize:
		p_stParam1 = CFast_ThirdPassPop();
		if(CFast_ThirdPassGetVectorParam(szTemp1, p_stParam1, 1) == 0)
		{
			_CFast_ThirdPassPush_(1, p_stParam1);
			return 0;
		}
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "if (MTH3D_M_bIsNullVector(%s)) {\n" , szTemp1); 
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "  MTH3D_M_vCopyVector(&M_GetSetParam_stVectorValue(&CFast_g_a_stParam[%d]), %s);\n", p_stNode->ucIndexOfEvalParam, szTemp1); 
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "} else {\n");         
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "  MTH3D_M_vNormalizeVector(&M_GetSetParam_stVectorValue(&CFast_g_a_stParam[%d]), %s);\n", p_stNode->ucIndexOfEvalParam, szTemp1); 
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "}\n");         
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Vector;\n", p_stNode->ucIndexOfEvalParam);

		g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Vector;
		break;

	case eFunc_ScaledVector:
		p_stParam2 = CFast_ThirdPassPop();
		if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0)
		{
			_CFast_ThirdPassPush_(2, p_stParam2);
			return 0;
		}
		p_stParam1 = CFast_ThirdPassPop();
		if(CFast_ThirdPassGetVectorParam(szTemp1, p_stParam1, 1) == 0)
		{
			_CFast_ThirdPassPush_(1, p_stParam1);
			_CFast_ThirdPassPush_(2, p_stParam2);
			return 0;
		}

	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "MTH3D_M_vMulScalarVector(&M_GetSetParam_stVectorValue(&CFast_g_a_stParam[%d]), %s, %s);\n", p_stNode->ucIndexOfEvalParam, szTemp2, szTemp1); 
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Vector;\n", p_stNode->ucIndexOfEvalParam);

		g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Vector;
		break;

	case eFunc_CrossProduct:
		p_stParam2 = CFast_ThirdPassPop();
		if(CFast_ThirdPassGetVectorParam(szTemp2, p_stParam2, 2) == 0)
		{
			_CFast_ThirdPassPush_(2, p_stParam2);
			return 0;
		}
		p_stParam1 = CFast_ThirdPassPop();
		if(CFast_ThirdPassGetVectorParam(szTemp1, p_stParam1, 1) == 0)
		{
			_CFast_ThirdPassPush_(1, p_stParam1);
			_CFast_ThirdPassPush_(2, p_stParam2);
			return 0;
		}

	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "MTH3D_M_vCrossProductVectorWithoutBuffer(&M_GetSetParam_stVectorValue(&CFast_g_a_stParam[%d]), %s, %s);\n", p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2); 
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Vector;\n", p_stNode->ucIndexOfEvalParam);

		g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Vector;
		break;

	default:
		return 0;
	}

    p_stNode->ucNumberOfParamNeeded = 0 ;
    CFast_ThirdPassPush (p_stNode) ;
	return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassAddIPT(CFast_tdstNode *p_stNode) {
  CFast_tdstNode *p_stParam1;

  switch ( M_eCondIdInterpret((&p_stNode->stNode)) ) {
  case eCond_PressedBut:
    p_stParam1 = CFast_ThirdPassPop();
    if((p_stParam1->lIndexOfRef == -1) || (p_stParam1->ucIndexOfEvalParam)) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    sprintf ( g_szConditionString2, "(long)IPT_fn_bIsValidated((IPT_tdxHandleToEntryElement) M_lValueInterpret(p_stRefTree+%d))", p_stParam1->lIndexOfRef ) ;
    sprintf ( g_szConditionString1, "long%d = %s ? 1 : 0;", g_lIndexForCondition, g_szConditionString2 );
    g_ulCondStringSet = 1 ;
    break;

  case eCond_JustPressedBut:
    p_stParam1 = CFast_ThirdPassPop();
    if((p_stParam1->lIndexOfRef == -1)||(p_stParam1->ucIndexOfEvalParam)) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    sprintf ( g_szConditionString2, "(long)IPT_fn_bIsJustValidated((IPT_tdxHandleToEntryElement) M_lValueInterpret(p_stRefTree+%d))", p_stParam1->lIndexOfRef ) ;
    sprintf ( g_szConditionString1, "long%d = %s ? 1 : 0;", g_lIndexForCondition, g_szConditionString2 );
    g_ulCondStringSet = 1 ;
    break;

  case eCond_ReleasedBut:
    p_stParam1 = CFast_ThirdPassPop();
    if((p_stParam1->lIndexOfRef == -1)||(p_stParam1->ucIndexOfEvalParam)) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    sprintf ( g_szConditionString2, "(long)IPT_fn_bIsInvalidated((IPT_tdxHandleToEntryElement) M_lValueInterpret(p_stRefTree+%d))", p_stParam1->lIndexOfRef ) ;
    sprintf ( g_szConditionString1, "long%d = %s ? 1 : 0;", g_lIndexForCondition, g_szConditionString2 );
    g_ulCondStringSet = 1 ;
    break;

  case eCond_JustReleasedBut:
    p_stParam1 = CFast_ThirdPassPop();
    if((p_stParam1->lIndexOfRef == -1)||(p_stParam1->ucIndexOfEvalParam)) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    sprintf ( g_szConditionString2, "(long)IPT_fn_bIsJustInvalidated((IPT_tdxHandleToEntryElement) M_lValueInterpret(p_stRefTree+%d))", p_stParam1->lIndexOfRef ) ;
    sprintf ( g_szConditionString1, "long%d = %s ? 1 : 0;", g_lIndexForCondition, g_szConditionString2 );
    g_ulCondStringSet = 1 ;
    break;

  default:
    return 0;
  }

  if ( !g_ulProcessIf )
  {
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "long%d = %s;\n", ++g_lIndexForCondition, g_szConditionString2 ) ;
    g_ulCondStringSet = 0 ;
  }
  
  return 1;
}

/*********************************************************************************************************************/
/*********************************************************************************************************************/
char CFast_ThirdPassAddIPTCamProc(CFast_tdstNode *p_stNode)
{
	CFast_tdstNode	*p_stParam1;

	switch ( M_eProcedureIdInterpret((&p_stNode->stNode)) ) 
	{
	case eProc_DeactivateBut:
		p_stParam1 = CFast_ThirdPassPop();
		if((p_stParam1->lIndexOfRef == -1)||(p_stParam1->ucIndexOfEvalParam))
		{
			_CFast_ThirdPassPush_(1, p_stParam1);
			return 0;
		}
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "IPT_fn_vDesactivateEntryElement((IPT_tdxHandleToEntryElement) M_lValueInterpret(p_stRefTree+%d));\n",p_stParam1->lIndexOfRef);
		break;

	case eProc_ActivateBut:
		p_stParam1 = CFast_ThirdPassPop();
		if((p_stParam1->lIndexOfRef == -1)||(p_stParam1->ucIndexOfEvalParam))
		{
			_CFast_ThirdPassPush_(1, p_stParam1);
			return 0;
		}
	    CFast_ThirdPassIndent () ;
		fprintf ( g_fdCxx, "IPT_fn_vActivateEntryElement((IPT_tdxHandleToEntryElement) M_lValueInterpret(p_stRefTree+%d));\n",p_stParam1->lIndexOfRef);
		break;
	default:
		return 0;
	}
	return 1;
}

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassAddMthFunc
 * DESCRIPTION : replace Math functions by MTH_ functions 
 *******************************************************************************/
char CFast_ThirdPassAddMthFunc(CFast_tdstNode *p_stNode) {
  CFast_tdstNode	*p_stParam1, *p_stParam2, *p_stParam3, *p_stParam4 ;
  char			szTemp1[1000];
  char			szTemp2[1000];
  char			szTemp3[1000];
  char			szTemp4[1000];


  switch ( M_eCondIdInterpret((&p_stNode->stNode)) ) {
  case eFunc_Int :
    p_stParam1 = CFast_ThirdPassPop();
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      CFast_ThirdPassPush (p_stParam1) ;
      return 0;
    }

    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_lValue(&CFast_g_a_stParam[%d]) = MTH_M_xRealToLong(%s) ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Integer;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ;
    break;
  case eFunc_RandomInt :
    p_stParam2 = CFast_ThirdPassPop();  // Max value
    if(CFast_ThirdPassGetConstParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  // First value
    if(CFast_ThirdPassGetConstParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_lValue(&CFast_g_a_stParam[%d]) = RND_fn_lGetLongRandomValue(0,%s,%s);\n",
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2 );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Integer;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ;
    break ;
  case eFunc_Real :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetConstParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xLongToReal(%s) ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;    
    break ;
  case eFunc_Sinus : 
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xSin( MTH_M_xDegToRad(%s) );\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_Cosinus :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xCos( MTH_M_xDegToRad(%s) );\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ; 
  case eFunc_Square :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xSqr( %s );\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_SquareRoot :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xSqrt( %s );\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_RandomReal :
    p_stParam2 = CFast_ThirdPassPop();  // Max value
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  // First value
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = RND_fn_xGetRealRandomValue(0,%s,%s);\n",
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2 );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_MinimumReal :
    p_stParam2 = CFast_ThirdPassPop();  // Max value
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  // First value
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
/*
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_lValue(&CFast_g_a_stParam[%d]) = MTH_M_xRealToLong (MTH_M_xMin(%s,%s));\n",
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2 );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Integer;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Integer ;
*/
    /* this function really returns float even deffunc.h say no !! */
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xMin(%s,%s);\n",
	            p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2 );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_MaximumReal :
    p_stParam2 = CFast_ThirdPassPop();  // Max value
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  // First value
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xMax(%s,%s);\n",
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2 );
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_DegreeToRadian :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xDegToRad(%s) ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_RadianToDegree :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xRadToDeg(%s) ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_AbsoluteValue :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xAbs(%s) ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_LimitRealInRange :
    p_stParam3 = CFast_ThirdPassPop();  // Max value
    if(CFast_ThirdPassGetRealParam(szTemp3, p_stParam3, 3) == 0) {
      _CFast_ThirdPassPush_(3, p_stParam3);
      return 0;
    }
    p_stParam2 = CFast_ThirdPassPop();  // Min value
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  // first value
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_bLess(%s, %s) ?  %s : (MTH_M_bGreater(%s, %s) ? %s : %s) ;\n", p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2, szTemp2, szTemp1, szTemp3, szTemp3, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_Sign :
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_bLess(%s, MTH_C_ZERO) ? MTH_M_xFloatToReal(-1.0f) : MTH_M_xFloatToReal(1.0f);\n", p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ; 
    break ;
  case eFunc_Cube :	
    p_stParam1 = CFast_ThirdPassPop();
    if ( CFast_ThirdPassGetRealParam ( szTemp1, p_stParam1, 1) == 0 ) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_xMul(MTH_M_xSqr(%s), %s) ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_Modulo :
    return 0 ;
    break ;
  case eFunc_TernInf :
    p_stParam4 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp4, p_stParam4, 4) == 0) {
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam3 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp3, p_stParam3, 3) == 0) {
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam2 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_bLess(%s, %s) ? %s : %s ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2, szTemp3, szTemp4); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_TernSup :
    p_stParam4 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp4, p_stParam4, 4) == 0) {
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam3 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp3, p_stParam3, 3) == 0) {
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam2 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_bGreater(%s, %s) ? %s : %s ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2, szTemp3, szTemp4); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_TernEq :
    p_stParam4 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp4, p_stParam4, 4) == 0) {
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam3 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp3, p_stParam3, 3) == 0) {
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam2 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_bEqual(%s, %s) ? %s : %s ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2, szTemp3, szTemp4); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_TernInfEq :
    p_stParam4 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp4, p_stParam4, 4) == 0) {
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam3 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp3, p_stParam3, 3) == 0) {
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam2 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_bLessEqual(%s, %s) ? %s : %s ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2, szTemp3, szTemp4); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;
  case eFunc_TernSupEq :
    p_stParam4 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp4, p_stParam4, 4) == 0) {
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam3 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp3, p_stParam3, 3) == 0) {
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam2 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp2, p_stParam2, 2) == 0) {
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    p_stParam1 = CFast_ThirdPassPop();  
    if(CFast_ThirdPassGetRealParam(szTemp1, p_stParam1, 1) == 0) {
      _CFast_ThirdPassPush_(1, p_stParam1);
      _CFast_ThirdPassPush_(2, p_stParam2);
      _CFast_ThirdPassPush_(3, p_stParam3);
      _CFast_ThirdPassPush_(4, p_stParam4);
      return 0;
    }
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_xValue(&CFast_g_a_stParam[%d]) = MTH_M_bGreaterEqual(%s, %s) ? %s : %s ;\n", 
	      p_stNode->ucIndexOfEvalParam, szTemp1, szTemp2, szTemp3, szTemp4); 
    CFast_ThirdPassIndent () ;
    fprintf ( g_fdCxx, "M_GetSetParam_Type(&CFast_g_a_stParam[%d]) = E_vt_Float;\n", p_stNode->ucIndexOfEvalParam);
    
    g_eParamType[p_stNode->ucIndexOfEvalParam] = E_vt_Float ;
    break ;    
  default :
    return 0 ;
    break ;
  }
  CFast_fprintf_d( 2, ( g_fdCxx, "\n/* [Math_ : %s] ********** [%d, %d, %d]*/\n", 
			szFindFunctionEditorNameFromId(M_eFuncIdInterpret((&p_stNode->stNode))),
			g_ulNbNodeInStack, p_stNode->ucNumberOfParamNeeded, p_stNode->ucIndexOfEvalParam )) ;
  p_stNode->ucNumberOfParamNeeded = 0 ;
  CFast_ThirdPassPush (p_stNode) ;
  return 1;
}

//#####################################################################################################################
//#####################################################################################################################

/*******************************************************************************
 *******************************************************************************
 * parse tree
 *******************************************************************************
 *******************************************************************************/

/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassParseNode
 * DESCRIPTION : parse a node 
 *******************************************************************************/
CFast_tdstNode *CFast_ThirdPassParseNode ( CFast_tdstNode *p_stNode, BOOL bAddVar ) {
  CFast_tdstNode *p_stCurrentNode;
  long lMacro, lSubr, i ;
  char cRes;
  tdeTypeInterpret eNodeType ;
  eNodeType = M_GetTypeInterpret((&p_stNode->stNode)) ;
  
  p_stCurrentNode = p_stNode ;
  /*
   * special node stMiscellaneousNode != E_ti_Unknown
   * ( if2, if4 ... )
   */
	if (M_GetTypeInterpret(&(p_stNode->stMiscellaneousNode)) != E_ti_Unknown && !bAddVar)
	{
		if
		(
			M_GetTypeInterpret(&(p_stNode->stMiscellaneousNode)) == E_ti_KeyWord && 
			((M_eKeyWordIdInterpret((&p_stNode->stMiscellaneousNode)) == eKeyWord_If) ||
			(M_eKeyWordIdInterpret((&p_stNode->stMiscellaneousNode)) == eKeyWord_If2) ||
			(M_eKeyWordIdInterpret((&p_stNode->stMiscellaneousNode)) == eKeyWord_If4) ||
			(M_eKeyWordIdInterpret((&p_stNode->stMiscellaneousNode)) == eKeyWord_If8) ||
			(M_eKeyWordIdInterpret((&p_stNode->stMiscellaneousNode)) == eKeyWord_If16)||
			(M_eKeyWordIdInterpret((&p_stNode->stMiscellaneousNode)) == eKeyWord_IfNot))
		)
		{
			if ( !(M_GetTypeInterpret(&(p_stNode->stNode)) == E_ti_KeyWord &&
			M_eKeyWordIdInterpret((&p_stNode->stNode)) == eKeyWord_Endif) )
			{
				p_stCurrentNode = CFast_ThirdPassProcessIf(p_stNode) ;
				return (p_stCurrentNode) ;
			}
		}
	}
  /*
   * check for ternop function params 
   * don't know that it may do if ternop is in a if statement :(
   */
  if ( p_stNode->bIsATernOpParam )
  {
    p_stCurrentNode = CFast_ThirdPassProcessTernOperators (p_stCurrentNode) ; 
    return (p_stCurrentNode) ;
  }

  /*
   * references
   */
  if ( p_stCurrentNode->lIndexOfRef > -1 )
  {
    if ( bAddVar ) 
      CFast_ThirdPassAddRef ( p_stCurrentNode ) ;
    else 
      CFast_ThirdPassPush (p_stCurrentNode) ;
  }
  else
  {
    /*
     * normal node
     */
    switch ( eNodeType ) {
    case E_ti_KeyWord :
      CFast_ThirdPassAddKeyWord (p_stCurrentNode, bAddVar) ;
      break ;
    case E_ti_Condition :      
      CFast_ThirdPassAddCondition (p_stCurrentNode) ;
      break ;
    case E_ti_Operator :
      cRes = CFast_ThirdPassAddOper(p_stCurrentNode);
      if(!cRes) 
	      CFast_ThirdPassAddOperator (p_stCurrentNode, bAddVar) ;
      break ;
    case E_ti_Function :
      cRes = CFast_ThirdPassAddVecFunc(p_stCurrentNode);
      if ( !cRes )
 	      cRes = CFast_ThirdPassAddMthFunc(p_stCurrentNode) ;
      if(!cRes) 
	      CFast_ThirdPassAddFunction (p_stCurrentNode) ;
      if ( p_stCurrentNode->bIsABooleanDsgVarRef ) {
	      CFast_ThirdPassIndent () ;
	      fprintf ( g_fdCxx, "long%d = M_GetSetParam_lValue(&%s[%d]);\n", 
		    g_lIndexForCondition, CFast_szParamVarName, p_stNode->ucIndexOfEvalParam ) ;
      }
     
      break ;
    case E_ti_Procedure :
      cRes = CFast_ThirdPassAddIPTCamProc(p_stCurrentNode);
      if(!cRes) 
	      CFast_ThirdPassAddProcedure (p_stCurrentNode) ;
      break ;
    case E_ti_MetaAction :
      CFast_ThirdPassAddMetaAction (p_stCurrentNode) ;
      CFast_ThirdPassInitPseudoTree(-1) ;
      break ;

	case E_ti_MacroRef :
      lSubr = CFast_ThirdPassIsSubrExist( ( void * ) fn_p_stGetMacroRefFromEditorPointer ( ( CPA_EdIR_MainBehaviour * ) M_p_stMacroInterpret ( & p_stCurrentNode -> stNode ) ) ) ;
      if ( lSubr >= 0 )
	  {
        if ( g_d_stSubr [ lSubr ] . lGotMeta )
		{
          CFast_ThirdPassIndent ( ) ;
          if ( g_eProcessWhat == E_pw_Comport )
            fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaAction = %d;\n", ++ g_ulLabelNumber ) ;
          else 
            fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaAction = %d;\n", ++ g_ulLabelNumber ) ;
          for ( i = 0 ; i < g_d_stSubr [ lSubr ] . lGotMeta ; i ++ )
            if ( i == 0 )
              fprintf ( g_fdCxx , "label%d :\n" , g_ulLabelNumber ) ;  
            else
              fprintf ( g_fdCxx , "label%d :\n", ++ g_ulLabelNumber ) ;  /* !!!!!!! */
            
            CFast_ThirdPassIndent ( ) ;
            
            fprintf ( g_fdCxx, "if ( CFast_%s_Sbr_%d ( ) )\n", g_szModelName, lSubr ) ;
            CFast_ThirdPassIndent ( ) ;
			fprintf ( g_fdCxx , "  return %s;\n" , ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) ) ? "1 " : "" ) ;
            
            CFast_ThirdPassIndent () ;
            if ( g_eProcessWhat == E_pw_Comport )
              fprintf ( g_fdCxx, "p_stLocalMind0 -> CFast_lCmpMetaAction = 0 ;\n" ) ;
            else 
              fprintf ( g_fdCxx, "p_stLocalMind0 -> CFast_lRfxMetaAction = 0 ;\n" ) ;
        }
        else
		{
          if ( g_d_stSubr[lSubr].lGotRfxOrCmp )
		  {
            CFast_ThirdPassIndent () ;
            fprintf ( g_fdCxx, "if ( CFast_%s_Sbr_%d ( ) )\n", g_szModelName, lSubr ) ;
            CFast_ThirdPassIndent () ;
			fprintf ( g_fdCxx , "  return %s;\n" , ( ( g_eProcessWhat == E_pw_Macro ) || ( g_eProcessWhat == E_pw_Subroutine ) ) ? "1 " : "" ) ;
          }
          else
		  {
            CFast_ThirdPassIndent () ;
            fprintf ( g_fdCxx, "CFast_%s_Sbr_%d ( ) ;\n", g_szModelName, lSubr ) ;
          }
        }
      }
      else
	  {
	      CFast_fprintf_d( 1, ( g_fdCxx, "/* [MacroRef : erreur unreferenced subroutine] *************/\n" )) ;
      }
      CFast_fprintf_d( 2, ( g_fdCxx, "/* [MacroRef : %d] ********** [%d]*/\n", 
			                      (p_stCurrentNode-p_stNode)/sizeof(CFast_tdstNode *), 
                            g_ulNbNodeInStack )) ;
      CFast_ThirdPassInitPseudoTree(-1) ;
      fflush (g_fdCxx) ;
      break ;

    case E_ti_BeginMacro :
      g_ulNbMacroInCurrentComport++ ;
      lMacro = CFast_ThirdPassIsMacroExist((void *)M_lValueInterpret(&p_stCurrentNode->stNode)) ;
      if ( lMacro >= 0 )
	  {
        if ( g_d_stMacro[lMacro].lGotMeta )
		{
          CFast_ThirdPassIndent () ;
          if ( g_eProcessWhat == E_pw_Comport )
            fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaAction = %d;\n",
            ++g_ulLabelNumber ) ;
          else 
            fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaAction = %d;\n",
            ++g_ulLabelNumber ) ;
          for ( i=0 ; i<g_d_stMacro[lMacro].lGotMeta ; i++ )
            if ( i==0 )
              fprintf ( g_fdCxx, "label%d :\n",g_ulLabelNumber ) ;  
            else
              fprintf ( g_fdCxx, "label%d :\n", ++g_ulLabelNumber ) ;  /* !!!!!!! */
            
            CFast_ThirdPassIndent () ;
            
            fprintf ( g_fdCxx, "if (CFast_%s_Macro_%d ())\n", g_szModelName, lMacro ) ;
            CFast_ThirdPassIndent () ;
            fprintf ( g_fdCxx, "  return ;\n" ) ;
            
            CFast_ThirdPassIndent () ;
            if ( g_eProcessWhat == E_pw_Comport )
              fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lCmpMetaAction = 0;\n" ) ;
            else 
              fprintf ( g_fdCxx, "p_stLocalMind0->CFast_lRfxMetaAction = 0;\n" ) ;
        }
        else {
          if ( g_d_stMacro[lMacro].lGotRfxOrCmp ) {
            CFast_ThirdPassIndent () ;
            fprintf ( g_fdCxx, "if (CFast_%s_Macro_%d ())\n", g_szModelName, lMacro ) ;
            CFast_ThirdPassIndent () ;
            fprintf ( g_fdCxx, "  return ;\n" ) ;
          }
          else {
            CFast_ThirdPassIndent () ;
            fprintf ( g_fdCxx, "CFast_%s_Macro_%d () ;\n", g_szModelName, lMacro ) ;
          }
        }
      }
      else {
	      CFast_fprintf_d( 1, ( g_fdCxx, "/* [BeginMacro : erreur unreferenced macro] *************/\n" )) ;
      }
      while ( M_GetTypeInterpret((&p_stCurrentNode->stNode)) != E_ti_EndMacro && p_stCurrentNode<g_p_stLastNode) 
	      p_stCurrentNode++ ;
      CFast_fprintf_d( 2, ( g_fdCxx, "/* [BeginMacro : %d] ********** [%d]*/\n", 
			                      (p_stCurrentNode-p_stNode)/sizeof(CFast_tdstNode *), 
                            g_ulNbNodeInStack )) ;
      CFast_ThirdPassInitPseudoTree(-1) ;
      fflush (g_fdCxx) ;
      break ;
    case E_ti_EndMacro :
      CFast_fprintf_d( 2, ( g_fdCxx, "/* [EndMacro] ********** [%d]*/\n", g_ulNbNodeInStack )) ;
      fflush (g_fdCxx) ;
      break ;
    case E_ti_EndTree :
      CFast_fprintf_d( 2, ( g_fdCxx, "/* [EndTree] ************ [%d]*/\n", g_ulNbNodeInStack) ) ;
      fflush (g_fdCxx) ;
      break ;
    case E_ti_Field :
      if ( bAddVar || p_stCurrentNode->bIsABooleanDsgVarRef ) {
	      CFast_ThirdPassAddField (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_DsgVar :
      //    break ;
    case E_ti_DsgVarRef :
      if ( bAddVar || p_stCurrentNode->bIsABooleanDsgVarRef ) {
	      CFast_ThirdPassAddDsgVar (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Constant :
      if ( bAddVar || p_stCurrentNode->bIsABooleanDsgVarRef ) {
	      CFast_ThirdPassAddConstant (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Real :      
      if ( bAddVar || p_stCurrentNode->bIsABooleanDsgVarRef ) {
	      CFast_ThirdPassAddReal (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Button :
      if ( bAddVar ) {
	      CFast_ThirdPassAddButton (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_ConstantVector :   
    case E_ti_Vector:
      CFast_ThirdPassAddVector (p_stCurrentNode) ;
      break ;
    case E_ti_Mask :
      if ( bAddVar ) {
	      CFast_ThirdPassAddMask (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Module :
      if ( bAddVar ) {
	      CFast_ThirdPassAddModule (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_DsgVarId :
      break ;
    case E_ti_String :
      if ( bAddVar ) {
	      CFast_ThirdPassAddString (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_LipsSynchroRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddLipsSynchro (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_FamilyRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddFamily (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_PersoRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddPerso (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_ActionRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddAction (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_SuperObjectRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddObject (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_WayPointRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddWP (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_ComportRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddComport (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_ModuleRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddModule (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_SoundEventRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddSoundEvent (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_ObjectTableRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddObjectTable (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_GameMaterialRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddGameMaterial (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_ParticleGenerator :
      if ( bAddVar ) {
	      CFast_ThirdPassAddParticleGenerator (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Color :
      if ( bAddVar ) {
	      CFast_ThirdPassAddColor (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_ModelRef :
      if ( bAddVar ) {
	      CFast_ThirdPassAddModel (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Light :
      if ( bAddVar ) {
	      CFast_ThirdPassAddLight (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Caps :
      if ( bAddVar ) {
	      CFast_ThirdPassAddCaps (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Graph :
      if ( bAddVar ) {
	      CFast_ThirdPassAddGraph (p_stCurrentNode) ;
      }
      else {
	      CFast_ThirdPassPush (p_stCurrentNode) ;
      }
      break ;
    case E_ti_Unknown :
      break ;
    }
  }
  return (p_stCurrentNode+1) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassSkipNode
 * DESCRIPTION : skip some node including this one, execpt if it is an optimised
 *               one
 *******************************************************************************/
CFast_tdstNode *CFast_ThirdPassSkipNode ( CFast_tdstNode *p_stNode ) {
  CFast_tdstNode *p_stCurrentNode ;
  int i ;

  if ( p_stNode->d_cOptimisedNode ) {
    CFast_ThirdPassAddOptimisedNode (p_stNode) ;
  }
  p_stCurrentNode = p_stNode ;
  for ( i=0 ; i<p_stNode->ucNumberOfNodeToSkipAfterOptimisation ; i++, p_stCurrentNode ++ ) ;
  return (p_stCurrentNode) ;
}
/*******************************************************************************
 * FUNCTION    : CFast_ThirdPassParseTree
 * DESCRIPTION : parse the tree of a comportement 
 *******************************************************************************/
BOOL CFast_ThirdPassParseTree ( CFast_tdstNode *p_stNode, unsigned long ulNbNode ) {
  CFast_tdstNode *p_stCurrentNode, *p_stLastNode ;

  p_stCurrentNode = p_stNode ;
  g_p_stLastNode = p_stLastNode = p_stNode+ulNbNode ;
  while ( p_stCurrentNode < p_stLastNode ) {
    if ( p_stCurrentNode->ucNumberOfNodeToSkipAfterOptimisation ) {
      p_stCurrentNode = CFast_ThirdPassSkipNode ( p_stCurrentNode ) ;
    }
    else if ( p_stCurrentNode->d_cOptimisedNode ) {
      CFast_ThirdPassAddOptimisedNode (p_stCurrentNode) ;
      p_stCurrentNode++ ;
    }
    else {
      p_stCurrentNode = CFast_ThirdPassParseNode ( p_stCurrentNode, FALSE ) ;
    }
  }

  return (TRUE) ;
}


/*******************************************************************************
 * FUNCTION    : CFast_vMakeFileNameFromModel
 * DESCRIPTION : make a filename for DOS (8 letters)
 *               made with the 8 first letters of the model, but the 3 first 
 *               letters are replaced by a checksum on the model name 
 *               hope that's ok !!
 *******************************************************************************/
void CFast_vMakeFileNameFromModel (char *szFileName, char *szModelName) {
  int i ;
  char *tmp ;

  for ( tmp=szModelName, i=0 ; *tmp!=0 ; i+=*(tmp++) ) ;
  strncpy ( szFileName, szModelName, 8 ) ;
  szFileName[8] = 0 ;
  sprintf ( szFileName, "%0.3d%s", (i%1000), szFileName+3 ) ;
}






bool CFast_fn_vThirdPassField ( CFast_tdstNode *p_stPerso, CFast_tdstNode *p_stNode) {
  bool bRes;
  char szPersoString[2048] ;

  if ( M_GetTypeInterpret((&p_stNode->stNode)) != E_ti_Field) {
    assert (NULL); /* c'est pas un field !! */
    return (FALSE);
  }
  if ( p_stPerso == NULL ) {
   strcpy ( szPersoString, "g_hSuperObjectPerso" ) ;
  }
  else
  {
	  if ( M_GetTypeInterpret(&p_stPerso->stNode) == E_ti_PersoRef ) {
		sprintf ( szPersoString, "M_CFast_hGetPersoRef(%d)", p_stPerso->lIndexOfRef ) ;
	  }
	  else {
		if (p_stPerso->lIndexOfRef < 0 ) {
		  sprintf ( szPersoString, "(*((HIE_tdxHandleToSuperObject *)M_GetDsgVarAddr(p_stLocalMind0, %d)))", 
					M_lDsgVarIdInterpret(&p_stPerso->stNode) ) ;
		} 
		else {
		  sprintf ( szPersoString, "(*((HIE_tdxHandleToSuperObject *)M_GetDsgVarAddr(p_stLocalMind0, M_CFast_ucGetRealIndice(%d))))", 
					p_stPerso->lIndexOfRef ) ;
		}
	  }
  }


	switch (M_eFieldIdInterpret(&p_stNode->stNode))
	{
		case eField_Position:
		case eField_Orientation:
		case eField_Speed:
      bRes = FALSE ;
      MessageBox(NULL,  "Filed : Cas non traite!!", "CFAST 3", MB_ICONSTOP);
      break;
		case eField_NormSpeed:
			{
        fprintf ( g_fdCxx, "{\n  struct DNM_stDynamics *p_stDynam;\n\n" ) ;
        fprintf ( g_fdCxx, "  p_stDynam = fn_p_stDynamGetDynamicsSO(%s);\n ", szPersoString ) ;
        fprintf ( g_fdCxx, "  if (p_stDynam != NULL)\n" ) ;
        fprintf ( g_fdCxx, "    long%d = MTH_M_xRealToLong (MTH3D_M_xNormVector(DNM_M_pDynamicsGetPreviousSpeed(p_stDynam))) ;\n", g_lIndexForCondition+1 ) ;
        fprintf ( g_fdCxx, "  else\n" ) ;
        fprintf ( g_fdCxx, "    long%d = MTH_C_ZERO ;\n", g_lIndexForCondition+1 ) ;
        fprintf ( g_fdCxx, "}\n") ; 
			}
      bRes = TRUE ;
			break;
		case eField_AbsoluteAxisX:
		case eField_AbsoluteAxisY:
		case eField_AbsoluteAxisZ:
		case eField_PrevComportIntell:
		case eField_PrevComportReflex:
      bRes = FALSE ;
      MessageBox(NULL,  "Filed : Cas non traite!!", "CFAST 3", MB_ICONSTOP);
			break;
		case eField_ShadowScaleX:
      fprintf ( g_fdCxx,"long%d = fn_ucGetFieldShadowScaleXFromSO(%s)",g_lIndexForCondition+1 ,szPersoString);
      bRes = TRUE ;
			break;
		case eField_ShadowScaleY:
      fprintf ( g_fdCxx,"long%d = fn_ucGetFieldShadowScaleYFromSO(%s)",g_lIndexForCondition+1 ,szPersoString);
      bRes = TRUE ;
			break;
		default:
			// error
      bRes = FALSE ;
			MessageBox(NULL,  "Field : Cas non traite!!", "CFAST 3", MB_ICONSTOP);
			break;
	}
  return (bRes) ;
}
