/*========================================================================= * * SpoSave.c - Saving functions for SPO file * * Version 1.0 * Revision date * *=======================================================================*/ #include #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; ilNbChild; 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; ilNbChild; 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; }