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

1228 lines
42 KiB
C
Raw Blame History

/*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 <ctype.h> /*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<63>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<65>rer en recharchant la cha<68>ne %s\" dans les textes\n"
"ou le cas <20>ch<63>ant dans les scripts <20>diteurs des mod<6F>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 <20>v<EFBFBD>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<63>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<68>ne du d<>but jusqu'<27> la position courante pour r<>cup<75>rer les formatages*/
for ( ; i <= * wCurrentChar ; i ++ )
{
ucChar = ( unsigned char ) * ( _pszCurrentChar + i) ;
/* Faire le traitement pour les caract<63>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<MAX_TEXTAFFICHE;iCpt++)
{
memset( &g_stInfoTextAffiche[iCpt], 0x00, iSizeOfStructure );
g_stInfoTextAffiche[iCpt].bFirstInit = TRUE;
g_bFreeTextAfficheBlocs[iCpt] = TRUE;
gp_SuperObjPersoGenerated[iCpt] = NULL;
}
/*g_ucTextAfficheId = 0;*/
}
/********************************************************************
* Function : return a free number of TEXT_Affiche function *
* Autor : Giraud Christophe *
* Historic : Created on 13/10/98 *
********************************************************************/
unsigned char TFMT_ucNumberOfCurrentTextAffiche( HIE_tdxHandleToSuperObject p_SuperObjPersoTreated )
{
register unsigned char i;
for(i=0;i<MAX_TEXTAFFICHE;i++)
{
if( p_SuperObjPersoTreated == gp_SuperObjPersoGenerated[i] )
{
return i;
}
}
SAF_M_AssertWithMsg(FALSE, "Erreur interne dans TFMT_ucNumberOfCurrentTextAffiche!" );
/* prevent a compilation warning, but we should NEVER get here! */
return i ;
}
/**************************************************************************
* Function : Search and assign a number for the new TEXT_Affiche function *
* Autor : Giraud Christophe *
* Historic : Created on 13/10/98 *
**************************************************************************/
unsigned char TFMT_ucSetNumber4CurrentTextAffiche( void )
{
register unsigned char i;
for(i=0;i<MAX_TEXTAFFICHE;i++)
{
if( g_bFreeTextAfficheBlocs[i] )
{
g_bFreeTextAfficheBlocs[i] = FALSE;
return i;
}
}
/* If we are here there is a number of Text_Affiche Id greater than MAX_TEXTAFFICHE*/
/* Then we overwrite the last Id !!!*/
return i;
}
/***************************************************************
* Function : Clear the Id of the current TEXT_Affiche function *
* Autor : Giraud Christophe *
* Historic : Created on 13/10/98 *
***************************************************************/
void TFMT_ucClearNumberOfCurrentTextAffiche( HIE_tdxHandleToSuperObject p_SuperObjPersoTreated )
{
register unsigned char i;
for(i=0;i<MAX_TEXTAFFICHE;i++)
{
if( p_SuperObjPersoTreated == gp_SuperObjPersoGenerated[i] )
{
g_bFreeTextAfficheBlocs[i] = TRUE;
gp_SuperObjPersoGenerated[i] = NULL ;
memset( &g_stInfoTextAffiche[i], 0x00, sizeof(tdstInfoTextAffiche) );
g_stInfoTextAffiche[i].bFirstInit = TRUE;
break;
}
}
}
/************************************************************************************************
* misc functions for text table managment
************************************************************************************************/
void TFMT_vInitScapingTable ( MTH_tdxReal xValue ) {
long i ;
for (i=0 ; i<TFMT_MAX_WIDTHTABLEELMENT ; i++ ) {
TFMT_ga_fLetterSpacing[i] = xValue ;
}
}
void TFMT_vUpdateSpacingTable ( char *szText ) {
char *szCur ;
int i ;
szCur = strtok (szText, ":") ;
TFMT_ga_fLetterSpacing[0] = MTH_M_xDiv(MTH_M_xLongToReal(atol ( szCur )), MTH_M_xDoubleToReal(1000.0)) ;
i=1 ;
while ( szCur != NULL && i<TFMT_MAX_WIDTHTABLEELMENT ) {
szCur = strtok (NULL, ":") ;
if ( szCur != NULL ) {
TFMT_ga_fLetterSpacing[i++] = MTH_M_xDiv(MTH_M_xLongToReal(atol ( szCur )), MTH_M_xDoubleToReal(1000.0)) ;
*(szCur-1) = ':' ;
}
}
}
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void TFMT_vInitScaleTable ( MTH_tdxReal xValue ) {
long i ;
for (i=0 ; i<TFMT_MAX_WIDTHTABLEELMENT ; i++ ) {
TFMT_ga_fLetterScale[i] = xValue ;
}
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
void TFMT_vUpdateScaleTable ( char *szText ) {
char *szCur ;
int i ;
szCur = strtok (szText, ":") ;
TFMT_ga_fLetterScale[0] = MTH_M_xDiv(MTH_M_xLongToReal(atol ( szCur )), MTH_M_xDoubleToReal(1000.0)) ;
i=1 ;
while ( szCur != NULL && i<TFMT_MAX_WIDTHTABLEELMENT ) {
szCur = strtok (NULL, ":") ;
if ( szCur != NULL ) {
TFMT_ga_fLetterScale[i++] = MTH_M_xDiv(MTH_M_xLongToReal(atol ( szCur )), MTH_M_xDoubleToReal(1000.0)) ;
*(szCur-1) = ':' ;
}
}
TFMT_ga_ulNbScale = i ;
}