/*everything to format texts with the following syntax: (all characters are lowercase)*/ /* /L: line break*/ /* /Wnnn: char width in millimeters*/ /* /Hnnn: line height in millimeters*/ /* /Cnnn: color code*/ /* /Rnnn: random positionning radius in millimeters*/ /* /JC/L/R: justification center/left/right*/ /* /Znnn: zoom factor in 1000th (will affect positioning)*/ /* //: '/' character*/ /* /:: ':' character*/ /* ANNECY CG MODIFICATIONS*/ #define D_ObjsTbls_Define /*ENDANNECY CG*/ #include "ToolsCPA.h" #include "GameEng.h" #include "Gam/TextFrmt.h" #include "Actions/AllActs.h" #include "Structur/Objects.h" #include "Structur/ObjsTbls.h" #include "ChanList.h" #include "Family.h" /*#include "Actions/3dData.h"*/ /* #include /*for toupper */ #include "actions\3ddata.h" #include "safe.h" #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ tdstInfoTextAffiche g_stInfoTextAffiche[MAX_TEXTAFFICHE]; HIE_tdxHandleToSuperObject gp_SuperObjPersoGenerated[MAX_TEXTAFFICHE]; BOOL g_bFreeTextAfficheBlocs[MAX_TEXTAFFICHE]; /*unsigned char g_ucTextAfficheId = 0;*/ #if defined(__cplusplus) } #endif /* __cplusplus */ /*global variables*/ static RND_tdxHandleToRandomIndex gs_hRandomHandleForTFMT = (RND_tdxHandleToRandomIndex) -1; /*should be invalid*/ /* Offset in object table */ int OffsetObjectTable = 0; typedef struct tdstDefaultValuesForCharacter_ { MTH_tdxReal m_xCharWidth; MTH_tdxReal m_xLineHeight; MTH_tdxReal m_xCharZoom; }tdstDefaultValuesForCharacter; tdstDefaultValuesForCharacter g_stDefaultValuesForCharacter = {MTH_C_ZERO, MTH_C_2, MTH_C_ZERO}; MTH_tdxReal TFMT_ga_fLetterSpacing[TFMT_MAX_WIDTHTABLEELMENT] ; MTH_tdxReal TFMT_ga_fLetterScale[TFMT_MAX_SCALEDPATTERN] ; unsigned long TFMT_ga_ulNbScale = 0 ; extern HIE_tdxHandleToSuperObject PLA_fn_hFindNextFreeSupObj(void); static __inline unsigned char fn_ucToTableElement ( int _n ) { if ( _n < ' ' ) _n = 0 ; else if ( _n >= 'a' && _n <= 'z' ) _n -= ' ' + ' ' ; else if ( _n >= 'A' && _n <= 'Z' ) _n -= ' ' ; else if ( _n >= 160 ) _n -= ' ' + ' ' ; else _n -= ' ' ; return ( unsigned char ) _n ; } /* -----------------10/03/98 10:34------------------- initialize all the global stuff --------------------------------------------------*/ void TFMT_vSetDefaultValuesCharacter ( MTH_tdxReal _xCharWidth, MTH_tdxReal _xLineHeight, MTH_tdxReal _xCharZoom ) { g_stDefaultValuesForCharacter.m_xCharWidth = MTH_C_ZERO ; if ( MTH_M_bGreaterEqual(_xLineHeight, MTH_C_ZERO) ) g_stDefaultValuesForCharacter.m_xLineHeight = _xLineHeight; if ( MTH_M_bGreaterEqual(_xCharZoom, MTH_C_ZERO) ) g_stDefaultValuesForCharacter.m_xCharZoom = _xCharZoom; TFMT_vInitScapingTable ( _xCharWidth ) ; } void TFMT_vInitFormatterStatus ( tdstTfmtStatus *_p_stStatus, HIE_tdxHandleToSuperObject _hSuperObjPerso, MTH_tdxReal _xScreenWidth ) { OffsetObjectTable = 0; /*this must be done only ONCE in the game!!!*/ if ( gs_hRandomHandleForTFMT == -1 ) gs_hRandomHandleForTFMT = RND_fn_hReserveANewHandleIndex(); _p_stStatus->xScreenWidth = _xScreenWidth; _p_stStatus->xBaseCharX = _p_stStatus->xBaseCharZ = MTH_C_ZERO; _p_stStatus->xBaseToAddX = MTH_C_ZERO; _p_stStatus->xCharWidth = g_stDefaultValuesForCharacter.m_xCharWidth; _p_stStatus->xLineHeight = g_stDefaultValuesForCharacter.m_xLineHeight; _p_stStatus->xCharZoom = g_stDefaultValuesForCharacter.m_xCharZoom; _p_stStatus->xCurCharZoom = MTH_C_ZERO ; _p_stStatus->cJustificationMode = 'l'; _p_stStatus->hSourceObjectTable = fn_hGetObjectsTableOfFamilyByIndex( fn_h3dDataGetFamily(M_GetMSHandle(_hSuperObjPerso,3dData)), 0 ); _p_stStatus->xRandomPosRadius = MTH_C_ZERO; } #pragma warning (disable : 4706) /* There are some voluntary assignment inside this function*/ /* -----------------10/03/98 10:46------------------- get next char, handle all escape sequences, and move the pointer to the next unread char that is not the beginning of an escape sequence --------------------------------------------------*/ char * TFMT_pszReadNextChar ( tdstTfmtStatus *_p_stStatus, HIE_tdxHandleToSuperObject _hSuperObjPerso, char *_pszCurrentChar, unsigned char *_p_ucReturnedChar, ACP_tdxBool *_p_bLineBreak ) { unsigned char ucChar ; * _p_bLineBreak = FALSE ; if ( _pszCurrentChar && ( ( ucChar = * ( _pszCurrentChar ++ ) ) != 0 ) ) /*THIS ASSIGNMENT IS INTENTIONAL!!!*/ { /*do we begin to scan one or nmore formatting sequences ?*/ while ( ucChar == '/' ) { switch ( *_pszCurrentChar ) { case 'L': case 'l': *_p_bLineBreak = TRUE; _p_stStatus->xBaseCharX = _p_stStatus->xBaseToAddX = MTH_C_ZERO; _p_stStatus->xBaseCharZ -= _p_stStatus->xLineHeight; break; case 'Z': case 'z': /*zoom factor of the following letters*/ _pszCurrentChar ++; _p_stStatus->xCharZoom = MTH_M_xDiv(MTH_M_xLongToReal(atoi(_pszCurrentChar)), MTH_M_xDoubleToReal(1000.0)); break; case 'W': case 'w': /*width of following letters in mm (format is nnn: )*/ _pszCurrentChar ++; _p_stStatus->xCharWidth = MTH_M_xMul(_p_stStatus->xCharZoom, MTH_M_xDiv(MTH_M_xLongToReal(atoi(_pszCurrentChar)), MTH_M_xDoubleToReal(1000.0))); break; case 'H': case 'h': /*height between lines in mm (format is nnn: )*/ _pszCurrentChar ++; _p_stStatus->xLineHeight = MTH_M_xMul(_p_stStatus->xCharZoom, MTH_M_xDiv(MTH_M_xLongToReal(atoi(_pszCurrentChar)), MTH_M_xDoubleToReal(1000.0))); break; case 'C': case 'c': /*color of following letters (format is n: )*/ _p_stStatus->hSourceObjectTable = fn_hGetObjectsTableOfFamilyByIndex( fn_h3dDataGetFamily(M_GetMSHandle(_hSuperObjPerso,3dData)), (ACP_tdxIndex) atoi(++ _pszCurrentChar) ); break; case 'o': case 'O': _pszCurrentChar ++; OffsetObjectTable = atoi(_pszCurrentChar); break; case 'J': case 'j': /*justification (format is C/L/R: )*/ _p_stStatus->cJustificationMode = *(++ _pszCurrentChar); break; case 'R': case 'r': /*set random positioning radius*/ { long lValue = atoi(++ _pszCurrentChar); _p_stStatus->xRandomPosRadius = MTH_M_xDiv(MTH_M_xLongToReal(lValue), MTH_M_xDoubleToReal(1000.0)); #ifndef U64 /*we use the radius */ RDN_fn_vSetRandomSeed(gs_hRandomHandleForTFMT, lValue); #endif } break; case '/': /*slash (format is //: )*/ ucChar = '/'; _pszCurrentChar ++; break; case ':': /*colon (format is /:: )*/ ucChar = ':'; _pszCurrentChar ++; break; } /*move pointer to the letter following the formatting sequence*/ while ( *(++ _pszCurrentChar) != ':' ); ucChar = *(++ _pszCurrentChar); /*if we did not get a line break, we want the pointer to be on the next char*/ if ( ! *_p_bLineBreak ) _pszCurrentChar ++; } /*skip whitespaces at the beginning of the line (after we got all the sequences)*/ if ( (_p_stStatus->xBaseCharX == MTH_C_ZERO) && (ucChar == ' ') ) while ( (ucChar = *(_pszCurrentChar ++)) == ' ' ); /*this is the base position of the char we are scanning*/ /*(we add the offset caused by the previous char)*/ _p_stStatus->xBaseCharX += _p_stStatus->xBaseToAddX; /*set the shift that will be applied to the next character relatively to the current one*/ if ( ! *_p_bLineBreak ) { if ( _p_stStatus->xCharWidth ) { _p_stStatus->xBaseToAddX = _p_stStatus->xCharWidth; } else { MTH_tdxReal xZoom ; unsigned char ucTemp ; xZoom = _p_stStatus->xCharZoom ; if ( MTH_M_bEqualZero (xZoom) ) { if ( TFMT_ga_ulNbScale ) xZoom = TFMT_ga_fLetterScale[0] ; else xZoom = MTH_C_ONE ; } ucTemp = fn_ucToTableElement ( ucChar ) ; _p_stStatus->xBaseToAddX = MTH_M_xMul ( xZoom , TFMT_ga_fLetterSpacing [ ucTemp ] ) ; } } } else { /*if we reached the end of the text, say it!*/ *_p_bLineBreak = TRUE; *_p_ucReturnedChar = '\0' ; return NULL; } *_p_ucReturnedChar = ucChar; return _pszCurrentChar; } #pragma warning (default : 4706) /* -----------------10/03/98 10:44------------------- returns the number of characters from the current position that will fit in a single line (random alterations are not relevant) --------------------------------------------------*/ unsigned short TFMT_uwGetNbCharsFillingALine ( tdstTfmtStatus *_p_stStatus, HIE_tdxHandleToSuperObject _hSuperObjPerso, char *_pszText, MTH_tdxReal *_p_xActualWidth ) { tdstTfmtStatus stTfmtStatusSave = *_p_stStatus; unsigned char ucCurrentChar; short wCharIndex = 0; ACP_tdxBool bLineBreak; MTH_tdxReal xCurrentWidth = MTH_C_ZERO, xScreenWidth = _p_stStatus->xScreenWidth; /*set an unlimited limit if the limit is negative*/ if ( MTH_M_bLessZero(xScreenWidth) ) xScreenWidth = MTH_M_xDoubleToReal(1000.0); do { /*read the next char, interpreting all escape sequences if relevant*/ _pszText = TFMT_pszReadNextChar(_p_stStatus, _hSuperObjPerso, _pszText, & ucCurrentChar, &bLineBreak); if ( !bLineBreak ) { MTH_tdxReal xNewWidth = xCurrentWidth + _p_stStatus->xCharWidth; if ( xNewWidth < xScreenWidth ) { xCurrentWidth = xNewWidth; wCharIndex ++; } else bLineBreak = 1; } } while ( !bLineBreak ); /*restore the current status, because reading the various chars changed it*/ *_p_stStatus = stTfmtStatusSave; /*and return the number of chars that fit in the line*/ *_p_xActualWidth = xCurrentWidth; return wCharIndex; } /* -----------------10/03/98 11:14------------------- position the specified channels of the current anim, and set the current object table from the text --------------------------------------------------*/ short TFMT_wPositionModulesAccordingToText ( tdstTfmtStatus *_p_stStatus, HIE_tdxHandleToSuperObject _hSuperObjPerso, char *_pszText, long _lStart, long _lEnd, MTH_tdxReal _xScreenWidth, tdstTfmtLineResults *_d_stLineResults, short _wNbLines ) { MTH_tdxReal xJustificationShift; short wNbCharsInCurrentLine, wCurrentChar = 0, wCurrentLine = 0; tdxHandleToObjectsTablesList hTargetObjectTable = fn_h3dDataGetCurrentObjectsTable(M_GetMSHandle(_hSuperObjPerso,3dData)); short wNbObjectsInTargetTable = fn_uwGetObjectTableNumberOfelements(hTargetObjectTable); /*get the pointer where the scanning stops*/ char *pszInitText = _pszText, *pszEndText = _pszText + (_lEnd >= 0 ? _lEnd : strlen(_pszText)); /*get the pointer where the scanning starts*/ _pszText += _lStart; /*initialize all the stuff*/ TFMT_vInitFormatterStatus(_p_stStatus, _hSuperObjPerso, _xScreenWidth); /*for each character in the text*/ while ( (_pszText < pszEndText) && *_pszText ) { /*get the width and number of chars of the first line in the text*/ wNbCharsInCurrentLine = TFMT_uwGetNbCharsFillingALine(_p_stStatus, _hSuperObjPerso, _pszText, &xJustificationShift); /*shift if the justification mode says so*/ switch ( _p_stStatus->cJustificationMode ) { case 'r': xJustificationShift = MTH_M_xSub(_p_stStatus->xScreenWidth, xJustificationShift); break; case 'c': xJustificationShift = MTH_M_xDiv(MTH_M_xSub(_p_stStatus->xScreenWidth, xJustificationShift), MTH_C_2); break; default: xJustificationShift = MTH_C_ZERO; } /* if we need some stats, record them*/ if ( _d_stLineResults && (_wNbLines >= 0) ) _d_stLineResults[wCurrentLine].wStartChar = (short) (_pszText - pszInitText); /*for each character of the line, set the geometric object in the object table, and position the channel in the anim*/ while ( (wNbCharsInCurrentLine --) && (_pszText < pszEndText) ) { unsigned char ucChar; ACP_tdxBool bLineBreak; short wSourceObject, wNbObjectsInSourceTable; /*read the next char in the text*/ _pszText = TFMT_pszReadNextChar ( _p_stStatus , _hSuperObjPerso , _pszText , & ucChar , & bLineBreak ) ; if ( ! _d_stLineResults ) /*do the deed on the object table and the animation channels if we are not here for the stats*/ { if ( ucChar < ' ' ) { wSourceObject = -1 ; } else { unsigned char ucTemp = fn_ucToTableElement ( ucChar ) ; wSourceObject = (short) ( ucTemp + OffsetObjectTable ) ; } /*since the source object table may change, we need to check the size each time*/ wNbObjectsInSourceTable = fn_uwGetObjectTableNumberOfelements(_p_stStatus->hSourceObjectTable); if ( wSourceObject < 0 || wSourceObject >= wNbObjectsInSourceTable ) { wSourceObject = 0; } else { POS_tdstCompletePosition *hChannelLocalMatrix; HIE_tdxHandleToSuperObject hChannelSuperObject; /*copy the current object from the source to the target*/ fn_vCopyObjectFromObjectTabletoAnother(hTargetObjectTable, _p_stStatus->hSourceObjectTable, wCurrentChar, wSourceObject); /*get the current channel's superobject*/ hChannelSuperObject = fn_hGetSuperObjectInChannel(fn_h3dDataGetChannelSOList(M_GetMSHandle(_hSuperObjPerso,3dData)), wCurrentChar); if ( hChannelSuperObject ) { MTH3D_tdstVector stV1, stV2, stV3; /*change its local position*/ hChannelLocalMatrix = HIE_fn_hGetSuperObjectMatrix(hChannelSuperObject); /*set the channel position according to the formatter status*/ MTH3D_M_vSetVectorElements( &stV1, MTH_M_xAdd(xJustificationShift, MTH_M_xAdd(_p_stStatus->xBaseCharX, RND_fn_xGetRealRandomValue(gs_hRandomHandleForTFMT, MTH_M_xNeg(_p_stStatus->xRandomPosRadius), _p_stStatus->xRandomPosRadius))), MTH_C_ZERO, MTH_M_xAdd(_p_stStatus->xBaseCharZ, RND_fn_xGetRealRandomValue(gs_hRandomHandleForTFMT, MTH_M_xNeg(_p_stStatus->xRandomPosRadius), _p_stStatus->xRandomPosRadius)) ); POS_fn_vSetTranslationVector(hChannelLocalMatrix, &stV1); /* and its local scale*/ if ( MTH_M_bDifferentWithEpsilon(_p_stStatus->xCharZoom, MTH_C_ONE, MTH_M_xDoubleToReal(0.0001)) ) { MTH3D_M_vSetVectorElements(&stV1, _p_stStatus->xCharZoom, MTH_C_ZERO, MTH_C_ZERO); MTH3D_M_vSetVectorElements(&stV2, MTH_C_ZERO, _p_stStatus->xCharZoom, MTH_C_ZERO); MTH3D_M_vSetVectorElements(&stV3, MTH_C_ZERO, MTH_C_ZERO, _p_stStatus->xCharZoom); POS_fn_vSetScaleMatrix(hChannelLocalMatrix, &stV1, &stV2, &stV3); } } } } wCurrentChar ++; } /* if we want stats, record them*/ if ( _d_stLineResults && (_wNbLines >= 0) ) { _d_stLineResults[wCurrentLine].wEndChar = (short) (_pszText - pszInitText); MTH3D_M_vSetVectorElements( &_d_stLineResults[wCurrentLine].stLineOrigin, xJustificationShift, MTH_C_ZERO, _p_stStatus->xBaseCharZ /* - _p_stStatus->xLineHeight //since we do it after the line change, account for the vertical offset properly*/ ); } /*here we are done with the current line, but if it ended with escape sequences, one of which breaking the text*/ /*we have not read it yet, so do it now*/ if ( _pszText < pszEndText ) { if ( *_pszText == '/' ) { ACP_tdxBool bLineBreak; do { unsigned char ucChar; /*read the next char in the text*/ _pszText = TFMT_pszReadNextChar(_p_stStatus, _hSuperObjPerso, _pszText, & ucChar, &bLineBreak); } while ( !bLineBreak ); /*until we reach the sequence that stops the current line*/ } else /*the EOL is reached because no more chars will fit on the specified width -> do the carriage return ourselves*/ { _p_stStatus->xBaseCharZ -= _p_stStatus->xLineHeight; _p_stStatus->xBaseCharX = _p_stStatus->xBaseToAddX = MTH_C_ZERO; } } /*one more line has gone by...*/ _wNbLines --; wCurrentLine ++; } /*now fill the rest of the target object table with empty objects*/ while ( wCurrentChar < wNbObjectsInTargetTable ) { fn_vCopyObjectFromObjectTabletoAnother(hTargetObjectTable, _p_stStatus->hSourceObjectTable, wCurrentChar, 0); wCurrentChar ++; } /*return the number of lines that got filled in the info array*/ return wCurrentLine; } /**************************************************************** * Jean-Marc Drouaud * Le 26/11/98 * traitement pour les caractères de formatage. ****************************************************************/ long TFMT_lProcessFormater ( tdstTfmtStatus * p_stStatus , char * szString , ACP_tdxBool * p_bLineBreak , ACP_tdxBool * p_bStartLine ) { long i = 1 ; #ifdef ACTIVE_EDITOR char * p_szInitString = szString ; #endif switch(*(szString++)) { case 'C': case 'c': p_stStatus->cJustificationMode = 'c'; break; case 'H': case 'h': /*height between lines in mm (format is nnn: ) */ p_stStatus->xLineHeight = MTH_M_xDiv(MTH_M_xLongToReal(atoi(szString)), MTH_M_xDoubleToReal(1000.0)) ; break; case 'L': case 'l': *p_bLineBreak = TRUE; *p_bStartLine = TRUE; p_stStatus->xBaseCharX = p_stStatus->xBaseToAddX = MTH_C_ZERO; p_stStatus->xBaseCharZ -= p_stStatus->xLineHeight; break; case 'W': case 'w': /*width of following letters in mm (format is nnn: )*/ p_stStatus->xCharWidth = MTH_M_xDiv(MTH_M_xLongToReal(atoi(szString)), MTH_M_xDoubleToReal(1000.0)) ; break; case 'Z': case 'z': /*zoom factor of the following letters*/ p_stStatus->xCharZoom = MTH_M_xDiv(MTH_M_xLongToReal(atoi(szString)), MTH_M_xDoubleToReal(1000.0)); break; case 'o': case 'O': OffsetObjectTable = atoi(szString); break; } while ( * szString != ':' ) { #ifdef ACTIVE_EDITOR if ( * szString == 0 ) { char szMsg [ 500 ] ; sprintf ( szMsg , "un formateur en fin de chaine ne se termine pas par ':'.\n" "Il est possible de le repérer en recharchant la chaîne %s\" dans les textes\n" "ou le cas échéant dans les scripts éditeurs des modèles" , p_szInitString ) ; SAF_M_AssertWithMsg( 0, szMsg ); } #endif szString ++ ; i ++; } return (++i) ; } /*---------------------------------------------------- - Christophe Giraud - - Le 09/09/98 - - compute length of string without code - ----------------------------------------------------*/ void TEXT_vComputeLengthOgString( char *p_szString, tdstTfmtStatus *p_stStatus ) { register long lNbChar = 0 ; MTH_tdxReal xZoom , xMaxScreenWidth = MTH_C_ZERO ; ACP_tdxBool bLineBreak = FALSE , bStartLine = FALSE; while( * p_szString ) { if ( * p_szString == '/' ) { p_szString += TFMT_lProcessFormater ( p_stStatus , ++ p_szString , & bLineBreak , & bStartLine ) ; if ( bLineBreak ) { xMaxScreenWidth = MTH_M_xMax ( xMaxScreenWidth , p_stStatus -> xScreenWidth ) ; p_stStatus -> xScreenWidth = MTH_C_ZERO ; bLineBreak = FALSE ; } } else { xZoom = p_stStatus -> xCharZoom ; if ( MTH_M_bEqualZero ( xZoom ) ) { if ( TFMT_ga_ulNbScale ) xZoom = TFMT_ga_fLetterScale [ ( lNbChar % TFMT_ga_ulNbScale ) ] ; else xZoom = MTH_C_ONE ; } lNbChar ++ ; if ( p_stStatus -> xCharWidth ) { p_stStatus -> xScreenWidth += MTH_M_xMul ( xZoom , p_stStatus -> xCharWidth ) ; } else { unsigned char ucTemp = fn_ucToTableElement ( * p_szString ) ; p_stStatus -> xScreenWidth += MTH_M_xMul ( xZoom , TFMT_ga_fLetterSpacing [ ucTemp ] ) ; } p_szString ++ ; } } p_stStatus->xScreenWidth = MTH_M_xMax(p_stStatus->xScreenWidth, xMaxScreenWidth); } /*---------------------------------------------------- - Christophe Giraud - - Le 01/08/98 - - !!! UNDER CONSTRUCTION !!! UNDER CONSTRUCTION !!! - ----------------------------------------------------*/ char *TFMT_pszReadNextChar2( tdstTfmtStatus *_p_stStatus, HIE_tdxHandleToSuperObject _hSuperObjPerso, char *_pszCurrentChar, unsigned char *_p_ucReturnedChar, ACP_tdxBool *_p_bLineBreak, BOOL bDisplayFullString, short *wCurrentChar, unsigned long *ulEvent, unsigned long **ulDelay, short *wCurrentChar4Channels, unsigned short *p_uwIndexOfChar ) { register unsigned char ucChar; register unsigned short uwLenString; long lNbChar = 0 ; MTH_tdxReal xPrevZoom, xPrevWidth = 0, xWidth = 0 ; MTH_tdxReal xZoom = 0 ; ACP_tdxBool bStartLine ; *_p_bLineBreak = FALSE; xPrevZoom = 0.0f ; /******************************** * Build String letter by letter * ********************************/ if (!bDisplayFullString) { register long i = 0; bStartLine = TRUE; uwLenString = (unsigned short) strlen(_pszCurrentChar); ucChar = ( unsigned char ) * ( _pszCurrentChar + * wCurrentChar ) ; /**** Pointe t'on de nouveau sur un évènement ? ****/ if ( * ulEvent ) { if ( ucChar == '/' ) { ucChar = (unsigned char) ( * ( _pszCurrentChar + * wCurrentChar ) + 1 ) ; if ( ( ucChar == 'E' ) || ( ucChar == 'e' ) ) { ( * wCurrentChar ) ++ ; /* Events (format is nnn: )*/ * ulEvent = ( unsigned long ) atoi( _pszCurrentChar + ( ++ ( * wCurrentChar ) ) ) ; while ( * ( _pszCurrentChar + ( * wCurrentChar ) ++ ) != ':' ) ; } else { * ulEvent = 0 ; } } else { * ulEvent = 0 ; } /* Retourner un caractère null*/ *_p_ucReturnedChar = 0 ; _pszCurrentChar += uwLenString ; return _pszCurrentChar ; } while ( ucChar == '/' ) { ucChar = ( unsigned char ) _pszCurrentChar [ ++ ( * wCurrentChar ) ] ; if ( ( ucChar == 'E' ) || ( ucChar == 'e' ) ) { /* Events (format is nnn: )*/ * ulEvent = ( unsigned long ) atoi ( _pszCurrentChar + ( ++ ( * wCurrentChar ) ) ) ; while ( * ( _pszCurrentChar + ( * wCurrentChar ) ++ ) != ':' ) ; /* Faire le return et retourner un caractere nul*/ * _p_ucReturnedChar = 0 ; _pszCurrentChar += uwLenString ; return _pszCurrentChar ; } else if ( ( ucChar == 'D' ) || ( ucChar == 'd' ) || ( ucChar == 'P' ) || ( ucChar == 'p' ) ) { /*Delay (format is nnn: )*/ * * ulDelay = ( unsigned long ) atoi( _pszCurrentChar + ( ++ ( * wCurrentChar ) ) ); if ( ( ucChar == 'P' ) || ( ucChar == 'p' ) ) { * * ulDelay = - ( ( int ) * * ulDelay ) ; } while ( * ( _pszCurrentChar + ( * wCurrentChar ) ++ ) != ':' ) ; /* Faire le return et retourner un caractere nul*/ * _p_ucReturnedChar = 0 ; _pszCurrentChar += uwLenString ; return _pszCurrentChar ; } else { while ( * ( _pszCurrentChar + ( * wCurrentChar ) ++ ) != ':' ) ; ucChar = * ( _pszCurrentChar + * wCurrentChar ) ; } } * wCurrentChar4Channels = -1 ; /* Parcours la chaîne du début jusqu'à la position courante pour récupérer les formatages*/ for ( ; i <= * wCurrentChar ; i ++ ) { ucChar = ( unsigned char ) * ( _pszCurrentChar + i) ; /* Faire le traitement pour les caractères de formatage.*/ if ( ucChar == '/' ) { i += TFMT_lProcessFormater ( _p_stStatus , _pszCurrentChar + i + 1 , _p_bLineBreak , & bStartLine ) ; } else { xZoom = _p_stStatus -> xCharZoom ; if ( MTH_M_bEqualZero ( xZoom ) ) { if ( TFMT_ga_ulNbScale ) xZoom = TFMT_ga_fLetterScale [ ( lNbChar % TFMT_ga_ulNbScale ) ] ; else xZoom = MTH_C_ONE ; } _p_stStatus -> xCurCharZoom = xZoom ; if ( _p_stStatus -> xCharWidth ) { xWidth = _p_stStatus -> xCharWidth ; } else { unsigned char ucTemp = fn_ucToTableElement ( ucChar ) ; xWidth = TFMT_ga_fLetterSpacing [ ucTemp ] ; } ( * wCurrentChar4Channels ) ++ ; if (! bStartLine ) { _p_stStatus -> xBaseToAddX += MTH_M_xMul ( xPrevZoom , xPrevWidth ) ; } else { bStartLine = FALSE ; } lNbChar ++ ; xPrevZoom = xZoom ; xPrevWidth = xWidth ; } } _p_stStatus -> xCurCharWidth = MTH_M_xMul ( xZoom , xWidth ) ; _p_stStatus -> xBaseCharX += _p_stStatus -> xBaseToAddX ; } /******************** * Build Full string * ********************/ else { bStartLine = FALSE; uwLenString = (unsigned short) strlen(_pszCurrentChar); lNbChar = * p_uwIndexOfChar ; while ( * _pszCurrentChar ++ == '/' ) { _pszCurrentChar += TFMT_lProcessFormater ( _p_stStatus , _pszCurrentChar , _p_bLineBreak , & bStartLine ) ; } ucChar = ( unsigned char ) * ( _pszCurrentChar - 1 ) ; xZoom = _p_stStatus -> xCharZoom ; if ( MTH_M_bEqualZero ( xZoom ) ) { if ( TFMT_ga_ulNbScale ) xZoom = TFMT_ga_fLetterScale [ ( lNbChar % TFMT_ga_ulNbScale ) ] ; else xZoom = MTH_C_ONE ; } _p_stStatus -> xCurCharZoom = xZoom ; if ( ! bStartLine ) { _p_stStatus -> xBaseCharX += _p_stStatus -> xBaseToAddX ; } else { bStartLine = FALSE ; } if ( _p_stStatus -> xCharWidth ) { _p_stStatus -> xBaseToAddX = MTH_M_xMul ( xZoom , _p_stStatus -> xCharWidth ) ; } else { unsigned char ucTemp = fn_ucToTableElement ( ucChar ) ; _p_stStatus -> xBaseToAddX = MTH_M_xMul ( xZoom , TFMT_ga_fLetterSpacing [ ucTemp ] ) ; } _p_stStatus -> xCurCharWidth = _p_stStatus -> xBaseToAddX ; lNbChar ++ ; } *_p_ucReturnedChar = ucChar ; if ( ! bDisplayFullString ) { _pszCurrentChar += uwLenString ; } * p_uwIndexOfChar = ( unsigned short ) lNbChar ; return _pszCurrentChar ; } /*----------------------------------------------------- - Christophe Giraud - - Le 02/07/98 - - !!! UNDER CONSTRUCTION !!! UNDER CONSTRUCTION !!! - -----------------------------------------------------*/ unsigned long TFMT_wPositionModulesAccordingToText2( tdstTfmtStatus *_p_stStatus, HIE_tdxHandleToSuperObject _hSuperObjPerso, char *_pszText, long _lStart, long _lEnd, ACP_tdxBool *bFirstTimeZ, short *pwCurrentChar, unsigned long *ulDelay ) { MS_tdxHandleTo3dData h_Current3dData = NULL; static CHN_tdxHandleToChannelArray hChannelArray = NULL; tdstAChannel *p_stChannel = NULL; POS_tdstCompletePosition *hChannelLocalMatrix = NULL; HIE_tdxHandleToSuperObject hChannelSuperObject = NULL; HIE_tdxHandleToSuperObject p_stSO_Child = NULL; struct tdstObjectsTableElement_ *d_stCurrentObjectsTable = NULL; MTH_tdxReal xJustificationShift = 0.0; short wCurrentLine = 0, wCurrentChar = 0, wCurrentChar4Channels = 0; unsigned short uwLenOfString = 0, uwIndexOfChar ; unsigned long ulEvent = 0; BOOL bDisplayFullString = FALSE; char *pszEndText = _pszText + (_lEnd >= 0 ? _lEnd : strlen(_pszText)); if (*bFirstTimeZ==TRUE) { uwLenOfString = (unsigned short) strlen(_pszText); } wCurrentChar = *pwCurrentChar; /* Display full string*/ if (wCurrentChar == -1) { bDisplayFullString = TRUE; wCurrentChar = 0; } /* Get the pointer where the scanning starts*/ _pszText += _lStart; uwIndexOfChar = (unsigned short)_lStart ; /* Initialize all the stuff*/ TFMT_vInitFormatterStatus(_p_stStatus, _hSuperObjPerso, MTH_C_ZERO); h_Current3dData = M_GetMSHandle(_hSuperObjPerso,3dData); d_stCurrentObjectsTable = fn_h3dDataGetCurrentObjectsTable(h_Current3dData)->d_stObjectsTable; /* For each character in the text*/ while ( (_pszText < pszEndText) && *_pszText ) { /* For each character of the line, set the geometric object in the object table, and position the channel in the anim*/ while ( _pszText < pszEndText ) { ACP_tdxBool bLineBreak; unsigned char ucChar ; short wSourceObject, wNbObjectsInSourceTable; /*read the next char in the text */ _pszText = TFMT_pszReadNextChar2(_p_stStatus, _hSuperObjPerso, _pszText, &ucChar, &bLineBreak, bDisplayFullString, &wCurrentChar, &ulEvent, &ulDelay, &wCurrentChar4Channels, &uwIndexOfChar ); /* Number of object in the object table*/ wNbObjectsInSourceTable = fn_uwGetObjectTableNumberOfelements(_p_stStatus->hSourceObjectTable); /* Source object in function of the value of the character*/ if ( ucChar < ' ' ) { wSourceObject = -1 ; } else { unsigned char ucTemp = fn_ucToTableElement ( ucChar ) ; wSourceObject = (short) ( ucTemp + OffsetObjectTable ) ; } if ( wSourceObject < 0 || wSourceObject >= wNbObjectsInSourceTable ) { wSourceObject = 0 ; *pwCurrentChar = wCurrentChar; return ulEvent; } else { /****************************** * Do this only the first time * ******************************/ if (*bFirstTimeZ==TRUE) { SAF_M_AssertWithMsg(!h_Current3dData->hArrayOfChannels, "Erreur interne dans TFMT_wPositionModulesAccordingToText2"); /* FQ TMP OVERFLOW BUG FIX */ #ifdef U64 if ((h_Current3dData) && (h_Current3dData->hArrayOfChannels)) { fn_vFreeCSOList(&h_Current3dData->hArrayOfChannels); } #endif /* Set the number of true caracters in string*/ fn_v3dDataSetNumberOfChannels(h_Current3dData, uwLenOfString ); /* Set number of channels*/ fn_vInitCSOList( &hChannelArray, fn_ul3dDataGetNumberOfChannels(h_Current3dData) ); fn_v3dDataSetChannelSOList( h_Current3dData, hChannelArray ); /* Set the first active channel*/ fn_v3dDataSetFirstActiveChannel(h_Current3dData, hChannelArray); *bFirstTimeZ=FALSE; } else { hChannelArray = h_Current3dData->hArrayOfChannels; } /* Build&Add child in channel*/ p_stSO_Child = PLA_fn_hFindNextFreeSupObj(); HIE_fn_vSuperObjectAddTail( _hSuperObjPerso, p_stSO_Child ); /* Get the channel*/ p_stChannel = &hChannelArray[wCurrentChar4Channels]; /* take control of matrix */ p_stChannel->bControlledChannel = TRUE; POS_fn_vSetIdentityMatrix(p_stSO_Child->hLocalMatrix); /*Mettre le SO dans le channel.*/ p_stChannel->hSupObject = p_stSO_Child; HIE_fn_vSetSuperObjectObjectAndType(p_stSO_Child,(d_stCurrentObjectsTable+wSourceObject)->h_Target,HIE_C_ulPO); HIE_fn_vSetSuperObjectTransparenceLevel( p_stSO_Child, 255.0f ); if( wCurrentChar4Channels ) { hChannelArray[wCurrentChar4Channels-1].p_stNextActiveChannel = p_stChannel; } /* Get the current channel's superobject*/ hChannelSuperObject = fn_hGetSuperObjectInChannel(fn_h3dDataGetChannelSOList(M_GetMSHandle(_hSuperObjPerso,3dData)), wCurrentChar4Channels); if ( hChannelSuperObject ) { MTH3D_tdstVector stV1, stV2, stV3; /* Change its local position*/ hChannelLocalMatrix = HIE_fn_hGetSuperObjectMatrix(hChannelSuperObject); MTH3D_M_vSetVectorElements( &stV1, MTH_M_xAdd( MTH_M_xAdd( xJustificationShift, MTH_M_xAdd( _p_stStatus->xBaseCharX, RND_fn_xGetRealRandomValue (gs_hRandomHandleForTFMT, MTH_M_xNeg(_p_stStatus->xRandomPosRadius), _p_stStatus->xRandomPosRadius) ) ), MTH_M_xMul(_p_stStatus->xCurCharWidth, MTH_M_xFloatToReal(0.5f)) ), MTH_C_ZERO, MTH_M_xAdd(_p_stStatus->xBaseCharZ, RND_fn_xGetRealRandomValue(gs_hRandomHandleForTFMT, MTH_M_xNeg(_p_stStatus->xRandomPosRadius), _p_stStatus->xRandomPosRadius)) ); POS_fn_vSetTranslationVector(hChannelLocalMatrix, &stV1); /* And its local scale*/ if ( MTH_M_bDifferentWithEpsilon(_p_stStatus->xCurCharZoom, MTH_C_ONE, MTH_M_xDoubleToReal(0.0001)) ) { MTH3D_M_vSetVectorElements(&stV1, _p_stStatus->xCurCharZoom, MTH_C_ZERO, MTH_C_ZERO); MTH3D_M_vSetVectorElements(&stV2, MTH_C_ZERO, _p_stStatus->xCurCharZoom, MTH_C_ZERO); MTH3D_M_vSetVectorElements(&stV3, MTH_C_ZERO, MTH_C_ZERO, _p_stStatus->xCurCharZoom); POS_fn_vSetScaleMatrix(hChannelLocalMatrix, &stV1, &stV2, &stV3); } } } wCurrentChar4Channels ++; *pwCurrentChar = ++wCurrentChar; } wCurrentLine ++; } /* Set the last active channel*/ /* begin Marc*/ if(p_stChannel != NULL) p_stChannel->p_stNextActiveChannel = NULL; /* end Marc*/ /*return the number of lines that got filled in the info array*/ return ulEvent; } /*----------------------------------------------------- - Christophe Giraud - - Le 11/07/98 - -----------------------------------------------------*/ void TFMT_vChangeLetter ( HIE_tdxHandleToSuperObject hSuperObjPerso , unsigned char ucPosLetter , unsigned char ucLetter ) { MS_tdxHandleTo3dData h_Current3dData = NULL ; CHN_tdxHandleToChannelArray hChannelArray = NULL ; tdstAChannel *p_stChannel = NULL ; /* XB 05/05/99 */ /* POS_tdstCompletePosition *hChannelLocalMatrix = NULL; */ /* HIE_tdxHandleToSuperObject hChannelSuperObject = NULL; */ /* HIE_tdxHandleToSuperObject p_stSO_Child = NULL; */ /* End XB 05/05/99 */ struct tdstObjectsTableElement_ * d_stCurrentObjectsTable = NULL ; short wSourceObject = 0 , wNbObjectsInSourceTable = 0 ; h_Current3dData = M_GetMSHandle(hSuperObjPerso,3dData); d_stCurrentObjectsTable = fn_h3dDataGetCurrentObjectsTable(h_Current3dData)->d_stObjectsTable; hChannelArray = h_Current3dData->hArrayOfChannels; /* Number of object in the object table*/ wNbObjectsInSourceTable = fn_uwGetObjectTableNumberOfelements( fn_hGetObjectsTableOfFamilyByIndex( fn_h3dDataGetFamily(h_Current3dData), 0 ) ); /* Source object in function of the value of the character */ if ( ucLetter < ' ' ) { wSourceObject = -1 ; } else { unsigned char ucTemp = fn_ucToTableElement ( ucLetter ) ; wSourceObject = (short) ( ucTemp + OffsetObjectTable ) ; } if ( ( wSourceObject < 0 ) || ( wSourceObject >= wNbObjectsInSourceTable ) ) { wSourceObject = 0 ; } else { /* Get the channel*/ p_stChannel = &hChannelArray[ucPosLetter]; HIE_fn_vSetSuperObjectObjectAndType( p_stChannel->hSupObject,(d_stCurrentObjectsTable+wSourceObject)->h_Target,HIE_C_ulPO); } } /******************************************************************** * Function : Init all datas for management of TEXT_Affiche function * * Autor : Giraud Christophe * * Historic : Created on 13/10/98 * ********************************************************************/ void TFMT_vInitTextAfficheStructure() { register int iCpt = 0; register int iSizeOfStructure = sizeof(tdstInfoTextAffiche); for(;iCpt