488 lines
16 KiB
C
488 lines
16 KiB
C
/*=========================================================================
|
|
*
|
|
* SpoSave.c - Saving functions for SPO file
|
|
*
|
|
* Version 1.0
|
|
* Revision date
|
|
*
|
|
*=======================================================================*/
|
|
#include <time.h>
|
|
|
|
#include "SpoSave.h"
|
|
|
|
#include "conventi.h"
|
|
#include "print.h"
|
|
#include "system.h"
|
|
|
|
#include "Levels.h"
|
|
#include "Submaps.h"
|
|
|
|
#include "SpoLoad.h"
|
|
|
|
#include "IpoSave.h"
|
|
#include "SctSave.h"
|
|
#include "SrfSave.h"
|
|
|
|
|
|
//--- Global defines --------------------------------------------------------
|
|
|
|
double g_fLimit1=0.1;
|
|
double g_fLimit2=0.01;
|
|
double g_fLimit3=0.001;
|
|
|
|
|
|
//--- header functions --------------------------------------------------------
|
|
|
|
void MLT_vSaveEmptySpoHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
|
|
{
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: save super-object in SPO file (recursive function)
|
|
*
|
|
* Parameters: p_stFile : script file pointer
|
|
* hSprObj : super-object
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vSaveSuperObject(SCR_tdst_File_Description *p_stFile, MLT_tdxHandleToSuperObject hSprObj)
|
|
{
|
|
MLT_tdxHandleToSuperObject hSprObjOld;
|
|
SCR_tdst_Cxt_Values *p_stVal;
|
|
xString sSection, sFile, sAction, sIdent, sFileSpo, sIdent2;
|
|
char *sName;
|
|
long i;
|
|
|
|
|
|
if (hSprObj == NULL)
|
|
return;
|
|
|
|
// save file name
|
|
sprintf(sFileSpo, "%s.spo", g_sFileIn);
|
|
|
|
// collision object must not be saved in the hierarchy
|
|
if ( strstr(MLT_p_cGetSectionName(hSprObj->sName), "!")
|
|
&&(!strstr(MLT_p_cGetSectionName(hSprObj->sName), "!nocol"))
|
|
&&(!strstr(MLT_p_cGetSectionName(hSprObj->sName), "!NOCOL"))
|
|
)
|
|
return;
|
|
|
|
// save begin section
|
|
if (strstr(MLT_p_cGetSectionName(hSprObj->sName), "!nocol")
|
|
|| strstr(MLT_p_cGetSectionName(hSprObj->sName), "!NOCOL"))
|
|
{
|
|
sName= MLT_vRemoveFromName(MLT_p_cGetSectionName(hSprObj->sName));
|
|
SCR_M_SvL0_SaveBeginSection(p_stFile, sName, SCR_CC_C_Cfg_EOL);
|
|
}
|
|
else
|
|
SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(hSprObj->sName), SCR_CC_C_Cfg_EOL);
|
|
|
|
// get file section
|
|
SCR_fn_v_RdL0_SplitSectionName(hSprObj->p_stMatrix->sName, sFile, sAction, sIdent);
|
|
if (stricmp(sFile, sFileSpo)==0)
|
|
sprintf(sFile, "*");
|
|
else
|
|
sprintf(sFile, "%s%s.spo", g_sDirectorySave, g_sFileIn);
|
|
|
|
// remove all flags from name
|
|
if (strstr(sIdent, "!nocol") || strstr(sIdent, "!NOCOL"))
|
|
{
|
|
sName = MLT_vRemoveFromName(sIdent);
|
|
MLT_vRemoveFlags(&sName);
|
|
MLT_vRemoveGeomProp(&sName);
|
|
}
|
|
else
|
|
{
|
|
sName = sIdent;
|
|
MLT_vRemoveFlags(&sName);
|
|
MLT_vRemoveGeomProp(&sName);
|
|
}
|
|
|
|
// save matrix entry
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_SPOActionPutMatrix, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, sAction, sName);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, sSection);
|
|
|
|
// save all child entries
|
|
for (i=0; i<hSprObj->lNbChild; i++)
|
|
{
|
|
// get file section
|
|
SCR_fn_v_RdL0_SplitSectionName(hSprObj->d_hChild[i]->sName, sFile, sAction, sIdent);
|
|
if(stricmp(sFile, sFileSpo)==0)
|
|
sprintf(sFile, "*");
|
|
else
|
|
sprintf(sFile, "%s%s.spo", g_sDirectorySave, g_sFileIn);
|
|
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, sAction, sIdent);
|
|
|
|
// remove collision flags
|
|
if (strstr(sSection, "!nocol")
|
|
|| strstr(sSection, "!NOCOL"))
|
|
{
|
|
sName= MLT_vRemoveFromName(sSection);
|
|
strcpy(sSection, sName);
|
|
}
|
|
|
|
// save entry
|
|
if (!strstr(sSection, "!") || strstr(sSection, "!nocol") || strstr(sSection, "!NOCOL"))
|
|
{
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_SPOActionAddChild, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, sSection);
|
|
}
|
|
}
|
|
|
|
// save linked object entry
|
|
if (strlen(hSprObj->sLinkedObject) != 0)
|
|
{
|
|
SCR_fn_v_RdL0_SplitSectionName(hSprObj->sLinkedObject, sFile, sAction, sIdent);
|
|
|
|
// save IPO entry
|
|
if (strcmp(sAction, M_Ipo) == 0)
|
|
{
|
|
char *p_char;
|
|
|
|
// build IPO name
|
|
sprintf(sFile, "%s%s.ipo", g_sDirectorySave, g_sFileIn);
|
|
if( (p_char=strstr(hSprObj->sName, "=")) != NULL )
|
|
{
|
|
sprintf(sIdent2, "IPO_%s%s", sIdent, p_char);
|
|
}
|
|
else
|
|
{
|
|
sprintf(sIdent2, "IPO_%s", sIdent);
|
|
}
|
|
if (hSprObj->iFlags & IS_MIRROR)
|
|
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, "IPO_MIRROR", sIdent2);
|
|
else
|
|
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, sAction, sIdent2);
|
|
// save entry
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_SPOActionLinkedObject, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, sSection);
|
|
// notify IPO section
|
|
sprintf(sFile, "%s.ipo", g_sFileIn);
|
|
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, sAction, sIdent2);
|
|
SCR_fn_v_SvL1_RegisterNotify(sSection, MLT_vSaveIpoSection, hSprObj, SCR_EA_Ntfy_AddOrModifySection);
|
|
}
|
|
}
|
|
|
|
// save geometric entry
|
|
else if(strlen(hSprObj->sGeometric) != 0)
|
|
{
|
|
SCR_fn_v_RdL0_SplitSectionName(hSprObj->sGeometric, sFile, sAction, sIdent);
|
|
sprintf(sFile, "%s%s.mod", g_sDirectorySave, g_sFileIn);
|
|
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, sAction, sIdent);
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_SPOActionGeometric, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, sSection);
|
|
}
|
|
|
|
// save sector entry
|
|
else if (strlen(hSprObj->stSector.sName) != 0)
|
|
{
|
|
SCR_fn_v_RdL0_SplitSectionName(hSprObj->stSector.sName, sFile, sAction, sIdent);
|
|
|
|
sprintf(sFile, "%s%s.sct", g_sDirectorySave, g_sFileIn);
|
|
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, sAction, sIdent);
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_SPOActionLinkedObject, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Normal, 1, sSection);
|
|
}
|
|
|
|
|
|
// if necessary, load previous SPO Flags
|
|
if (g_bCreatedSpo)
|
|
{
|
|
SCR_fn_v_RdL0_SplitSectionName(hSprObj->sName, sFile, sSection, sIdent);
|
|
sprintf(sFile, "%s.spo", "temp");
|
|
SCR_fn_v_RdL0_ComputeSectionName(sAction, sFile, M_SuperObject, sIdent);
|
|
if(SCR_fn_c_RdL0_IsSectionExists(sAction))
|
|
{
|
|
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(sAction, SCR_CDF_uw_Anl_Normal);
|
|
hSprObjOld = (MLT_tdxHandleToSuperObject)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
|
|
|
|
if (!g_bIgnoreSpo)
|
|
{
|
|
//take the flags from the .spo file
|
|
hSprObj->ulSPOFlags = hSprObjOld->ulSPOFlags;
|
|
hSprObj->fTransparency = hSprObjOld->fTransparency;
|
|
}
|
|
else
|
|
{
|
|
// take only the editor flags
|
|
for (i=0; i < g_iNbEditorSPOFlags; i++)
|
|
{
|
|
if (g_iEditorSPOFlags[i] != -1)
|
|
{
|
|
unsigned long ulEditorFlag = 1 << g_stSPOFlags[g_iEditorSPOFlags[i]].sFlag;
|
|
|
|
if (hSprObjOld->ulSPOFlags & ulEditorFlag)
|
|
hSprObj->ulSPOFlags |= ulEditorFlag;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// if the flags are different from 0, save the entry in the .spo file
|
|
if (hSprObj->ulSPOFlags)
|
|
{
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_SPOActionFlags, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d",hSprObj->ulSPOFlags);
|
|
}
|
|
//if there is a transparency, save the entry
|
|
if (hSprObj->fTransparency >= 0.0)
|
|
{
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_SPOActionTransparency, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%f",hSprObj->fTransparency);
|
|
}
|
|
|
|
|
|
// save end section
|
|
SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL);
|
|
|
|
// save matrix section
|
|
MLT_vSaveMatrix(p_stFile, hSprObj->p_stMatrix);
|
|
|
|
// save all child sections
|
|
for(i=0; i<hSprObj->lNbChild; i++)
|
|
MLT_vSaveSuperObject(p_stFile, hSprObj->d_hChild[i]);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Description: save matrix in SPO file
|
|
*
|
|
* Parameters: p_stFile : script file pointer
|
|
* p_stMatrix : matrix to save
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vSaveMatrix(SCR_tdst_File_Description *p_stFile, MLT_tdstMatrix *p_stMatrix)
|
|
{
|
|
MTH_tdxReal RotMatrixComp[3][3];
|
|
char *sName;
|
|
int i,j;
|
|
|
|
// make the identity matrix
|
|
for (i=0; i<3; i++)
|
|
{
|
|
for (j=0; j<3; j++)
|
|
{
|
|
if (i!=j)
|
|
RotMatrixComp[i][j]=0;
|
|
else
|
|
RotMatrixComp[i][j]=1;
|
|
}
|
|
}
|
|
|
|
// remove all flags from the name
|
|
if (strstr (MLT_p_cGetSectionName(p_stMatrix->sName), "!nocol")
|
|
|| strstr(MLT_p_cGetSectionName(p_stMatrix->sName), "!NOCOL"))
|
|
{
|
|
sName = MLT_vRemoveFromName(MLT_p_cGetSectionName(p_stMatrix->sName));
|
|
MLT_vRemoveFlags(&sName);
|
|
MLT_vRemoveGeomProp(&sName);
|
|
SCR_M_SvL0_SaveBeginSection(p_stFile, sName, SCR_CC_C_Cfg_EOL);
|
|
}
|
|
else
|
|
{
|
|
sName = MLT_p_cGetSectionName(p_stMatrix->sName);
|
|
MLT_vRemoveFlags(&sName);
|
|
MLT_vRemoveGeomProp(&sName);
|
|
SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(p_stMatrix->sName), SCR_CC_C_Cfg_EOL);
|
|
}
|
|
|
|
// check if the translation must be saved
|
|
if ((fabs(p_stMatrix->stTranslation.xX) > g_fLimit2) ||
|
|
(fabs(p_stMatrix->stTranslation.xY) > g_fLimit2) ||
|
|
(fabs(p_stMatrix->stTranslation.xZ) > g_fLimit2))
|
|
{
|
|
// save corresponding entry
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_MATActionTranslation, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 4, "%.6f,%.6f,%.6f",
|
|
p_stMatrix->stTranslation.xX,
|
|
p_stMatrix->stTranslation.xY,
|
|
p_stMatrix->stTranslation.xZ);
|
|
}
|
|
|
|
// check if the scale must be saved
|
|
if (!MLT_vCompareMatrix(p_stMatrix->a9_xScaleMatrix, RotMatrixComp))
|
|
{
|
|
// save corresponding entry
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_MATActionScale, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 10, "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f",
|
|
p_stMatrix->a9_xScaleMatrix[0][0],
|
|
p_stMatrix->a9_xScaleMatrix[1][0],
|
|
p_stMatrix->a9_xScaleMatrix[2][0],
|
|
p_stMatrix->a9_xScaleMatrix[0][1],
|
|
p_stMatrix->a9_xScaleMatrix[1][1],
|
|
p_stMatrix->a9_xScaleMatrix[2][1],
|
|
p_stMatrix->a9_xScaleMatrix[0][2],
|
|
p_stMatrix->a9_xScaleMatrix[1][2],
|
|
p_stMatrix->a9_xScaleMatrix[2][2]);
|
|
}
|
|
|
|
// check if the rotation must be saved
|
|
if (!MLT_vCompareMatrix(p_stMatrix->a9_xRotMatrix, RotMatrixComp))
|
|
{
|
|
// save corresponding entry
|
|
SCR_M_SvL0_SaveEntry(p_stFile, M_MATActionRotation, SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 10, "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f",
|
|
p_stMatrix->a9_xRotMatrix[0][0],
|
|
p_stMatrix->a9_xRotMatrix[1][0],
|
|
p_stMatrix->a9_xRotMatrix[2][0],
|
|
p_stMatrix->a9_xRotMatrix[0][1],
|
|
p_stMatrix->a9_xRotMatrix[1][1],
|
|
p_stMatrix->a9_xRotMatrix[2][1],
|
|
p_stMatrix->a9_xRotMatrix[0][2],
|
|
p_stMatrix->a9_xRotMatrix[1][2],
|
|
p_stMatrix->a9_xRotMatrix[2][2]);
|
|
}
|
|
|
|
SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL);
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: save the hierarhcy in the SPO file
|
|
*
|
|
* Parameters: hRoot : hierarchy root
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vSaveSpoFile (MLT_tdxHandleToSuperObject hRoot)
|
|
{
|
|
SCR_tdst_File_Description stFile;
|
|
xString sDate, sTime, mes, sComment;
|
|
|
|
|
|
// remove previous SPO file
|
|
sprintf(stFile.a_szFileName,"%s.spo", g_sFileIn);
|
|
remove(stFile.a_szFileName);
|
|
|
|
// create new SPO file
|
|
strcpy(stFile.a_szOpenFileName, stFile.a_szFileName);
|
|
stFile.p_stHandle = (SCR_tdst_File_Handle*)malloc(sizeof(SCR_tdst_File_Handle));
|
|
stFile.p_stHandle->xHandle = (FILE*)_open(stFile.a_szFileName, O_WRONLY | O_CREAT | _O_TEXT, S_IREAD | S_IWRITE);
|
|
stFile.p_stHandle->p_cBase = stFile.p_stHandle->p_cCurrent = NULL;
|
|
stFile.p_stHandle->iCnt = 0;
|
|
stFile.d_stFirstPage = stFile.d_stLastPage = stFile.d_stCurPage = NULL;
|
|
stFile.iCurPosInPage = 0;
|
|
if(stFile.p_stHandle->xHandle == 0)
|
|
{
|
|
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't open file %s", stFile.a_szFileName);
|
|
return;
|
|
}
|
|
|
|
// save file header
|
|
SCR_M_SvL0_SaveScriptFileHeader(&stFile);
|
|
sprintf(sComment, ".SPO (SuperObject hierarchy) : %s", stFile.a_szFileName);
|
|
SCR_M_SvL0_SaveComment(&stFile, sComment);
|
|
SCR_M_SvL0_SaveBlankLine(&stFile);
|
|
sprintf(sComment, "Generated by Max23Dos Moulinette");
|
|
SCR_M_SvL0_SaveComment(&stFile, sComment);
|
|
SCR_M_SvL0_SaveBlankLine(&stFile);
|
|
_strtime(sTime);
|
|
_strdate(sDate);
|
|
sprintf(sComment, "Created date : %s %s", sDate, sTime);
|
|
SCR_M_SvL0_SaveComment(&stFile, sComment);
|
|
SCR_M_SvL0_SaveBlankLine(&stFile);
|
|
sprintf(sComment, "File of SuperObject for the Mod File : %s.mod", g_sFileIn);
|
|
SCR_M_SvL0_SaveComment(&stFile, sComment);
|
|
SCR_M_SvL0_SaveBlankLine(&stFile);
|
|
sprintf(sComment, "Version directive, the version number is stored in file result 0");
|
|
SCR_M_SvL0_SaveComment(&stFile, sComment);
|
|
SCR_M_SvL0_SaveDirective(&stFile, M_SetCurrentFileDouble,SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(&stFile, SCR_EF_SvL0_Scanf, 3, "%d,%.2f", 0, 5.0);
|
|
SCR_M_SvL0_SaveBlankLine(&stFile);
|
|
sprintf(sComment, "Unit directive, the unit is stored in file result 1");
|
|
SCR_M_SvL0_SaveComment(&stFile, sComment);
|
|
sprintf(sComment, "And correspond to the value of one unit exprimed in meter");
|
|
SCR_M_SvL0_SaveComment(&stFile, sComment);
|
|
SCR_M_SvL0_SaveDirective(&stFile, M_SetCurrentFileDouble,SCR_CC_C_Cfg_NoChar);
|
|
SCR_fn_v_SvL0_SaveParameters_MP(&stFile, SCR_EF_SvL0_Scanf, 3, "%d,%.2f", 1, 1.0);
|
|
SCR_M_SvL0_SaveBlankLine(&stFile);
|
|
|
|
// save modif list
|
|
sprintf(mes, "%s%s", M_Edit_ListModifSuperObject, SCR_CC_sz_Cfg_SectionIdMark);
|
|
SCR_M_SvL0_SaveBeginSection(&stFile, mes, SCR_CC_C_Cfg_EOL);
|
|
SCR_M_SvL0_SaveEndSection(&stFile, SCR_CC_C_Cfg_EOL);
|
|
|
|
|
|
// save map center
|
|
MLT_vSaveMatrix(&stFile, &g_stMatrixCenter);
|
|
|
|
// save hierarchy
|
|
MLT_vSaveSuperObject(&stFile, hRoot);
|
|
|
|
// close SPO file
|
|
_close((int)stFile.p_stHandle->xHandle);
|
|
free(stFile.p_stHandle);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Description: save the hierarhcy (SPO + SCT files)
|
|
*
|
|
* Parameters: hRoot : hierarchy root
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
void MLT_vSaveHierarchy (MLT_tdxHandleToSuperObject hRoot)
|
|
{
|
|
xString sFile;
|
|
|
|
// save SPO file
|
|
MLT_vSaveSpoFile(hRoot);
|
|
|
|
// save normal SCT file
|
|
sprintf(sFile, "%s.sct", g_sFileIn);
|
|
MLT_vSaveSctFile(hRoot, sFile);
|
|
|
|
// if necessary save submaps SCT file
|
|
if (g_hRoot2)
|
|
{
|
|
sprintf(sFile, "%s_Submap.sct", g_sFileIn);
|
|
MLT_vSaveSctFile(hRoot, sFile);
|
|
}
|
|
|
|
// save SRF file
|
|
MLT_vSaveSrfFile(hRoot);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Description: compare 2 3*3 matrix
|
|
*
|
|
* Parameters: hRoot : hierarchy root
|
|
*---------------------------------------------------------------------------
|
|
* Revision date: Author:
|
|
*****************************************************************************/
|
|
BOOL MLT_vCompareMatrix(MTH_tdxReal RotMatrix[3][3], MTH_tdxReal RotMatrixComp[3][3])
|
|
{
|
|
int i,j;
|
|
BOOL bTrue=TRUE;
|
|
|
|
for (i=0; i<3; i++)
|
|
{
|
|
for (j=0; j<3; j++)
|
|
{
|
|
if (fabs(RotMatrix[i][j]-RotMatrixComp[i][j])>g_fLimit2)
|
|
bTrue = FALSE;
|
|
}
|
|
}
|
|
return bTrue;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|