reman3/Rayman_X/cpa/Appli/Max23Dos/src/SpoSave.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;
}