reman3/Rayman_X/cpa/Appli/Max23Dos/src/Levels.c

2080 lines
70 KiB
C
Raw Blame History

/*=========================================================================
*
* Levels.c - Level conversion
*
* Version 1.0
* Revision date
*
*=======================================================================*/
#include <Windows.h>
#include "Levels.h"
#include "SCR.h"
#include "conventi.h"
#include "defines.h"
#include "main.h"
#include "print.h"
#include "system.h"
#include "util.h"
#include "ModLib.h"
#include "LgtLoad.h"
#include "PlgLoad.h"
#include "SpoLoad.h"
#include "IpoSave.h"
#include "ModSave.h"
#include "PhySave.h"
#include "RliSave.h"
#include "SctSave.h"
#include "SpoSave.h"
#include "VseSave.h"
#include "ZooSave.h"
#include "Actors.h"
#include "Borders.h"
#include "Normals.h"
#include "Submaps.h"
#include "MatStack.h"
#include "Merge.h"
#include "SaveModifLst.h"
//--- Global defines --------------------------------------------------------
MLT_tdxHandleToSuperObject g_hRoot;
MLT_tdstMatrix g_stMatrixCenter;
xString g_sLevelFileIn;
BOOL g_bLevel = FALSE;
// multitextures
BOOL g_bExistTex;
//--- Global statics --------------------------------------------------------
MTH3D_tdstVector gs_stMinPointOfMap;
MTH3D_tdstVector gs_stMaxPointOfMap;
//--- header functions --------------------------------------------------------
void MLT_vSaveEmptyLg2Header(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyLvlHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyWayHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyWpHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyPgbHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyDscHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyAlwHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyAiHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyDecHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyEdeHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyEmaHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyEmcHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyErfHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyEruHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyEsbHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyMacHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyRfxHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
void MLT_vSaveEmptyRulHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction)
{
}
//--------------------------------------------------------------------
/****************************************************************************
* Description: compute all the levels found in the source directory
*
* Parameters: sRawData : source directory
* sGameData : destination directory
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeAllLevels (char *sRawData, char *sGameData)
{
xString sDirectory;
HANDLE hHandle;
WIN32_FIND_DATA stFindFileData;
// change directory
GetCurrentDirectory(256, sDirectory);
SetCurrentDirectory(sRawData);
// search all the levels files
memset(&stFindFileData,0,sizeof(stFindFileData));
hHandle = FindFirstFile("World\\Levels\\*.*", &stFindFileData);
if( hHandle == INVALID_HANDLE_VALUE)
{
SetCurrentDirectory(sDirectory);
fprintf(stderr, "\nError : Can't find Levels directory\n");
return;
}
do if(stFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(strlen(stFindFileData.cFileName) == 0) break;
if(strcmp(stFindFileData.cFileName, ".") == 0) continue;
if(strcmp(stFindFileData.cFileName, "..") == 0) continue;
// compute the level
MLT_vComputeOneLevel(stFindFileData.cFileName, sRawData, sGameData);
}
while(FindNextFile(hHandle, &stFindFileData));
FindClose(hHandle);
// restore directory
SetCurrentDirectory(sDirectory);
}
/****************************************************************************
* Description: compute the specified level
*
* Parameters: sLevelName : level to convert
* sRawData : source directory
* sGameData : destination directory
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeOneLevel (char *sLevelName, char *sRawData, char *sGameData)
{
char *sTmp;
BOOL bIsOK = FALSE;
xString sFileSearch;
HANDLE hHandle;
WIN32_FIND_DATA stFindFileData;
// WIN version
#ifdef _WINDOWS
char szInterm[50];
if( ((sTmp=strstr(sLevelName, "\\")) == NULL)
&& ((sTmp=strstr(sLevelName, "/")) == NULL) )
{
if (g_bStandardConfig)
{
// get SPO name
sprintf(sFileSearch, "World\\Levels\\%s\\*.spo", sLevelName);
// change directory
SetCurrentDirectory(sRawData);
}
else
sprintf(sFileSearch, "%s\\%s\\*.spo", g_szLevels, sLevelName);
// search for the level file
memset(&stFindFileData,0,sizeof(stFindFileData));
hHandle = FindFirstFile(sFileSearch, &stFindFileData);
if( hHandle == INVALID_HANDLE_VALUE)
{
sprintf(szInterm, "\nError : Can't find %s level\n", sLevelName);
fn_vAfxOutputStringRes( szInterm, C_ComRes_cErrorLine);
return;
}
do
{
if(strlen(stFindFileData.cFileName) == 0) break;
// compute the SPO file
MLT_vComputeOneSpo(sLevelName, MLT_p_cGetFileNameWithoutExt(stFindFileData.cFileName), sRawData, sGameData);
bIsOK = TRUE;
}
while(FindNextFile(hHandle, &stFindFileData));
FindClose(hHandle);
// if file was not found raise an error
if (!bIsOK)
{
sprintf(szInterm, "\nError : Can't find %s\n", sFileSearch);
fn_vAfxOutputStringRes( szInterm, C_ComRes_cErrorLine);
return;
}
}
else
MLT_vComputeOneSpo(sLevelName, sLevelName, sRawData, sGameData);
// DOS version
#else
// get SPO name
if( ((sTmp=strstr(sLevelName, "\\")) == NULL)
&& ((sTmp=strstr(sLevelName, "/")) == NULL) )
sprintf(sFileSearch, "World\\Levels\\%s\\*.spo", sLevelName);
else
{
sprintf(sFileSearch, "World\\Levels\\%s", sLevelName);
*sTmp = 0;
}
// change directory
SetCurrentDirectory(sRawData);
// search for the level file
memset(&stFindFileData,0,sizeof(stFindFileData));
hHandle = FindFirstFile(sFileSearch, &stFindFileData);
if( hHandle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "\nError : Can't find %s level\n", sLevelName);
return;
}
do
{
if(strlen(stFindFileData.cFileName) == 0) break;
// compute the SPO file
MLT_vComputeOneSpo(sLevelName, MLT_p_cGetFileNameWithoutExt(stFindFileData.cFileName), sRawData, sGameData);
bIsOK = TRUE;
}
while(FindNextFile(hHandle, &stFindFileData));
FindClose(hHandle);
// if file was not found raise an error
if(! bIsOK)
{
fprintf(stderr, "\nError : Can't find %s\n", sFileSearch);
return;
}
#endif
}
/****************************************************************************
* Description: compute the SPO file in the specified level
*
* Parameters: sLevelName : level to convert
* sFileSpo : file to convert
* sRawData : source directory
* sGameData : destination directory
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeOneSpo (char *sLevelName, char *sFileSpo, char *sRawData, char *sGameData)
{
int i, f;
char szFile[256], szLev[256];
BOOL bRLI = FALSE;
FILE *file;
xString sDirectory, sDir, sRawDir, sRead;
xString sRawLevel, sGameLevel, sFile, sFileM, sFile1;
// init min and max point of the map
MTH3D_M_vSetVectorElements(&gs_stMinPointOfMap, MLT_C_InfinitPlus, MLT_C_InfinitPlus, MLT_C_InfinitPlus);
MTH3D_M_vSetVectorElements(&gs_stMaxPointOfMap, MLT_C_InfinitMinus, MLT_C_InfinitMinus, MLT_C_InfinitMinus);
// register globals
sprintf(g_sFileIn, "%s", sFileSpo);
sprintf(g_sLevelFileIn, "%s", sFileSpo);
sprintf(g_sFileMaterial, "%s", sLevelName);
sprintf(g_sDirectorySave, "%s\\", sLevelName);
// init directories
if (g_bStandardConfig)
sprintf(sRawLevel, "%s\\World\\Levels\\%s", sRawData, g_sDirectorySave);
else
sprintf(sRawLevel, "%s\\%s", g_szLevels, g_sDirectorySave);
sprintf(sGameLevel, "%s\\World\\Levels\\%s", sGameData, g_sDirectorySave);
// DISPLAY
MLT_vOutput( C_ComRes_cTitleLine, "\nLevel %s\\%s.spo",sLevelName, sFileSpo);
// change directory
GetCurrentDirectory(256, sDirectory);
CreateDirectory(sGameLevel, NULL);
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tCopy...");
// change directory
SetCurrentDirectory(sGameLevel);
// update or create level world
MLT_vUpdateLevelWorld(sGameLevel, sLevelName, sGameData);
// notify and update all static files of the level
MLT_vUpdateLevelStaticFiles(sGameLevel);
// notify and update all dynamyc files of the level
MLT_vUpdateLevelDynamicFiles(sGameLevel, sRawLevel, sLevelName);
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tLoad...");
// change directory
SetCurrentDirectory(sRawLevel);
// init loading parameters
g_lNbSector = 0;
MLT_xInitMatrixStack();
// load MOD file
MLT_vLoadModFileInLib();
MLT_vEraseDuplicatedPoints();
// load PLG file
MLT_vLoadPLGFileInLib();
// load SPO file
MLT_vLoadHierarchy(&g_hRoot);
// check hierarchy for submaps
MLT_vCheckHierarchyForSubmaps(g_hRoot, sGameLevel, sRawLevel);
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tCompute normals...");
// get the indexes of the faces for each geometric objects
for (i=0; i<g_lGeometricIndex; i++)
MLT_vIndexFace(g_hGeometricInFile[i]);
// compute the normals
MLT_xComputeAllNormals();
// if necessary load the lights for RLI
if (g_bGenerateRLI)
{
switch (g_iData)
{
case 0:
sprintf(sRawDir, "%s\\World\\Levels\\%s", g_sGameCommon, g_sFileIn);
break;
case 1:
sprintf(sRawDir, "%s\\World\\Levels\\%s", g_sGameSpecific1, g_sFileIn);
break;
case 2:
sprintf(sRawDir, "%s\\World\\Levels\\%s", g_sGameSpecific2, g_sFileIn);
break;
}
GetCurrentDirectory(256, sDir);
SetCurrentDirectory(sRawDir);
MLT_LoadLGT();
SetCurrentDirectory(sDir);
}
// check hierarchy to manage mirror objects
MLT_vCheckHierarchy(&g_hRoot);
// force matrix to identity on first level
if (g_bVersionN64)
{
MLT_vSearchAllSector(g_hRoot);
}
else
{
SCR_fn_v_RdL0_RegisterPath(sGameLevel);
MLT_vOutput( C_ComRes_cNormalLine, "\n\tConvert Matrix...");
MLT_vMatrixIdentityHierarchy(g_hRoot);
}
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tConvert Sectors and Surfaces...");
// build the sector structure
MLT_vMakeSectorInHierarchy(g_hRoot);
// check the maximal size of the map
if ((gs_stMaxPointOfMap.xX - gs_stMinPointOfMap.xX >= 1024.0) ||
(gs_stMaxPointOfMap.xY - gs_stMinPointOfMap.xY >= 1024.0) ||
(gs_stMaxPointOfMap.xZ - gs_stMinPointOfMap.xZ >= 1024.0))
{
MLT_vOutput( C_ComRes_cErrorLine, "\n\n !!! Warning N64 : The map is too big for N64 (> 512m) !!!\n");
}
// save center of the map in SPO
MLT_xSetIdentityMatrix(&g_stMatrixCenter);
strcpy(g_stMatrixCenter.sName, M_MatrixCenter);
g_stMatrixCenter.stTranslation.xX = (gs_stMaxPointOfMap.xX + gs_stMinPointOfMap.xX)/2;
g_stMatrixCenter.stTranslation.xY = (gs_stMaxPointOfMap.xY + gs_stMinPointOfMap.xY)/2;
g_stMatrixCenter.stTranslation.xZ = (gs_stMaxPointOfMap.xZ + gs_stMinPointOfMap.xZ)/2;
// DISPLAY
if (!g_bRaymanII)
MLT_vOutput( C_ComRes_cNormalLine, "\n\tErase Borders...");
// clean borders in hierarchy
MLT_xInitMatrixStack();
MLT_vEraseBorderInHierarchy(g_hRoot, "");
// erase unused points
MLT_vEraseUnusedPoints();
// DISPLAY
if (!g_bRaymanII)
MLT_vOutput( C_ComRes_cNormalLine, "\n\tCreate Gothroughs...");
// build borders in library
MLT_vMakeGoThroughInLib(g_hRoot);
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tCreate Instantiated Physicals...");
// merge all the splitted objects
MLT_vMergeObjectsInHierarchy(g_hRoot);
// compute RLIs
if (g_bGenerateRLI)
{
//test if the LGT file exist
strcpy(szFile, sGameLevel);
strcat(szFile, "\\");
strcpy(szLev, g_sDirectorySave);
szLev[strlen(szLev)-1]='\0';
strcat(szFile, szLev);
strcat(szFile, ".lgt");
if (!(file=fopen(szFile, "r")))
bRLI = FALSE;
else
{
fclose(file);
bRLI= TRUE;
//test if the SCT file exist
strcpy(szFile, sGameLevel);
strcat(szFile, "\\");
strcpy(szLev, g_sDirectorySave);
szLev[strlen(szLev)-1]='\0';
strcat(szFile, szLev);
strcat(szFile, ".sct");
if (!(file=fopen(szFile, "r")))
bRLI = FALSE;
else
{
fclose(file);
bRLI = TRUE;
}
}
if (bRLI)
{
MLT_vLoadLGTFileInLib();
//compute the RLI
g_bLevel = TRUE;
MLT_vCreateRLI();
g_bLevel = FALSE;
}
}
// create IPOs
MLT_vMakeIpoInHierarchy(g_hRoot);
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tCreate Physicals...");
// create POs
MLT_vMakePhysicalInLib();
// change directory
SetCurrentDirectory(sGameLevel);
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tSave...");
// save SPO file
MLT_vSaveHierarchy(g_hRoot);
// save MOD file
MLT_vSaveLibInModFile(TRUE, FALSE, TRUE, TRUE);
// save PLG file
MLT_vSaveLibInPLGFile();
// if necessary, remove modification files
g_bExistMdf = FALSE;
g_bExistMdt = FALSE;
if (g_bEraseMdf)
{
strcpy (sFile, sGameLevel);
sprintf(sFileM, "%s.mdf", sLevelName);
strcat(sFile, sFileM);
_chmod(sFile, _S_IREAD | _S_IWRITE );
f=remove(sFile);
if (f != -1)
g_bExistMdf = TRUE;
strcpy (sFile, sGameLevel);
sprintf(sFileM, "%s.mdt", sLevelName);
strcat(sFile, sFileM);
_chmod(sFile, _S_IREAD | _S_IWRITE );
f=remove(sFile);
if (f != -1)
g_bExistMdt = TRUE;
}
// save all notified sections
SCR_fn_v_SvL1_UpdateAllNotify();
// update SCT file
sprintf(sFile, "%s.sct", g_sFileIn);
MLT_vUpdateSctFile(sFile);
// if necessary, update submap SCT file
if (g_hRoot2)
{
sprintf(sFile, "%s_Submap.sct", g_sFileIn);
MLT_vUpdateSctFile(sFile);
}
// clean MOD library
MLT_vEraseLib();
// clean PLG library
MLT_vErasePLGLib();
// clean ALW library
MLT_vEraseALWLib();
// clean LGT library
if (bRLI && g_bGenerateRLI )
MLT_vEraseLGTLib();
// clean SPO hierarchy
MLT_vDeleteHierarchy(g_hRoot);
// change directory
SetCurrentDirectory(sDirectory);
// update ModifLst file
MLT_vUpdatePathInModifFile(sGameLevel);
// remove temporary files
MLT_vRemoveLevelTemporaryFiles(sGameLevel);
// DISPLAY
MLT_vOutput( C_ComRes_cResultLine, "\nLevel %s converted\n",sLevelName);
// clean all opened structures
for (i=3; i<256; i++)
_close((int)i);
MLT_vInitSystem();
// multitextures
if (g_bIgnoreTex && g_bExistTex)
{
FILE *fileR;
strcpy (sFile, sGameLevel);
sprintf(sFileM, "%s.tex", sLevelName);
strcat(sFile, sFileM);
strcpy (sFile1, sGameLevel);
strcat(sFile1, "temp.tex");
fileR=fopen(sFile1, "rt");
file =fopen(sFile, "r+");
if (!fileR) return;
if (!file) return;
while (!feof(fileR))
{
fgets(sRead, 256, fileR);
if (strstr(sRead, "Texture"))
{ //a new section begins
MLT_vSearch(sRead, file);
fputs(sRead, file);
fgets(sRead, 256, fileR);
while (!strstr(sRead, "}"))
{ fputs(sRead, file);
fgets(sRead, 256, fileR);
}
}
}
fclose(file);
fclose(fileR);
remove(sFile1);
}
}
/****************************************************************************
* Description: create or update the world character of the level
*
* Parameters: sGameLevel : directory of the level
* sLevelName : level to convert
* sGameData : destination directory
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vUpdateLevelWorld (char *sGameLevel, char *sLevelName, char *sGameData)
{
xString sDirectory;
xString sDir, sName;
xString sGameLevelMy, sGameLevelMyChar;
xString sLevelDefaultDir, sDefaultCharDir;
// change directory
GetCurrentDirectory(256, sDirectory);
// create or update the world associated to the level
sprintf(sDir, "%s\\World\\Levels\\_Common\\Families\\World", sGameData);
CreateDirectory(sDir, NULL);
// create world level directory
strcat(sDir, "\\Level");
strcat(sDir, sLevelName);
CreateDirectory(sDir, NULL);
strcpy(sGameLevelMy, sDir);
// create world character directory
strcat(sDir,"\\Charact" );
CreateDirectory(sDir, NULL);
strcpy(sGameLevelMyChar, sDir);
// change directory
SetCurrentDirectory(sGameLevel);
// get default world files
strcpy(sLevelDefaultDir, g_sGameCommon);
strcat(sLevelDefaultDir, "\\default\\LevelDefault");
strcpy(sDefaultCharDir, sLevelDefaultDir);
strcat(sDefaultCharDir, "\\Charact");
// update character file
sprintf(sName, "world.car");
MLT_vCopyAndUpdateFile("world.car", sDefaultCharDir, "world.car", sGameLevelMyChar, "<nomdulevel>", sLevelName, FALSE);
// change directory
SetCurrentDirectory(sGameLevel);
sprintf(sDir, "%s\\Default\\LevelDefault", sGameData);
// update AI file
sprintf(sName, "Level%s.ai", sLevelName);
MLT_vCopyAndUpdateFile("LevelDefault.ai", sDir, sName, sGameLevelMy, "<nomdulevel>", sLevelName, FALSE);
// update DEC file
sprintf(sName, "Level%s.dec", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.dec", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update EDE file
sprintf(sName, "Level%s.ede", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.ede", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update EMA file
sprintf(sName, "Level%s.ema", sLevelName);
MLT_vCopyAndUpdateFile("LevelDefault.ema", sLevelDefaultDir, sName, sGameLevelMy, "<nomdulevel>", sLevelName, FALSE);
// update EMC file
sprintf(sName, "Level%s.emc", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.emc", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update ERF file
sprintf(sName, "Level%s.erf", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.erf", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update ERU file
sprintf(sName, "Level%s.eru", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.eru", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update ESB file
sprintf(sName, "Level%s.esb", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.esb", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update MAC file
sprintf(sName, "Level%s.mac", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.mac", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update RFX file
sprintf(sName, "Level%s.rfx", sLevelName);
MLT_vCopyAndRenameFile("LevelDefault.rfx", sLevelDefaultDir, sName, sGameLevelMy, FALSE);
// update RUL file
sprintf(sName, "Level%s.rul", sLevelName);
MLT_vCopyAndUpdateFile("LevelDefault.rul", sLevelDefaultDir, sName, sGameLevelMy, "<nomdulevel>", sLevelName, FALSE);
// restore directory
SetCurrentDirectory(sDirectory);
}
/****************************************************************************
* Description: notify and update the static files of the level
*
* Parameters: sGameLevel : directory of the level
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vUpdateLevelStaticFiles (char *sGameLevel)
{
xString sDirectory;
xString sFile;
int i;
// change directory
GetCurrentDirectory(256, sDirectory);
SetCurrentDirectory(sGameLevel);
// check if the destination SPO file already exist
strcpy(sFile, g_sFileIn);
strcat(sFile, ".spo");
if(! SCR_fn_c_RdL0_IsSectionExists(sFile))
g_bCreatedSpo=FALSE;
else
g_bCreatedSpo=TRUE;
// if necessary, save it as temporary file
if (g_bCreatedSpo)
CopyFile(sFile, "temp.spo", FALSE);
else
remove(sFile);
// Notify SPO file
sprintf(sFile, "%s.spo", g_sFileIn);
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveEmptySpoHeader, NULL, SCR_EA_Ntfy_AddOrModifySection);
// Notify MOD file
sprintf(sFile, "%s.mod", g_sFileIn);
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveEmptyModHeader, NULL, SCR_EA_Ntfy_AddOrModifySection);
// multitextures
// Notify TEX file
sprintf(sFile, "%s.tex", g_sFileIn);
if (! SCR_fn_c_RdL0_IsSectionExists(sFile))
{
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveTexFile, NULL, SCR_EA_Ntfy_AddOrModifySection);
g_bExistTex = FALSE;
}
else
g_bExistTex= TRUE;
// Notify VMT file
sprintf(sFile, "%s.vmt", g_sFileIn);
if (! SCR_fn_c_RdL0_IsSectionExists(sFile))
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveVmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection);
// Notify GMT file
sprintf(sFile, "%s.gmt", g_sFileIn);
if (! SCR_fn_c_RdL0_IsSectionExists(sFile))
{
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveGmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection);
g_bCreatedGmt=FALSE;
}
else
g_bCreatedGmt=TRUE;
// if the .gmt file exist, check if it must be rebuilt
if (g_bCreatedGmt)
{
//remove it is we want to ignore it
if (g_bIgnoreGmt)
{
remove(sFile);
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveGmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection);
}
// else save it as temporary file
else
{
CopyFile(sFile, "temp.gmt", FALSE);
remove(sFile);
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveGmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection);
}
}
// Notify IPO file
sprintf(sFile, "%s.ipo", g_sFileIn);
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveIpoFile, NULL, SCR_EA_Ntfy_AddSection);
// Notify PHY file
sprintf(sFile, "%s.phy", g_sFileIn);
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSavePhyFile, NULL, SCR_EA_Ntfy_AddSection);
// Notify VSE file
sprintf(sFile, "%s.vse", g_sFileIn);
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveVseFile, NULL, SCR_EA_Ntfy_AddSection);
// Notify ZOO file
sprintf(sFile, "%s.zoo", g_sFileIn);
if (! SCR_fn_c_RdL0_IsSectionExists(sFile))
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveZooFile, NULL, SCR_EA_Ntfy_AddSection);
// if the ZOO file exists, check if it must be rebuilt
else
{
if (g_bIgnoreZoo)
{
i=remove(sFile);
if (!i)
SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveZooFile, NULL, SCR_EA_Ntfy_AddSection);
}
else
{
xString sSection;
CopyFile(sFile, "temp.zoo", FALSE);
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_AllCollideSets, "");
SCR_fn_v_SvL1_RegisterNotify(sSection/*sFile*/, MLT_vSaveAllCollideSetsSection, NULL, SCR_EA_Ntfy_RebuildSection);
}
}
// save all notified sections
SCR_fn_v_SvL1_UpdateAllNotify();
// restore directory
SetCurrentDirectory(sDirectory);
}
/****************************************************************************
* Description: notify and update the dynamic files of the level
*
* Parameters: sGameLevel : destination directory of the level
* sRawLevel : source directory of the level
* sLevelName : level to convert
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vUpdateLevelDynamicFiles (char *sGameLevel, char *sRawLevel, char *sLevelName)
{
xString sDirectory;
xString sDefaultDir, sGameDefault;
xString sFileMem, sGameLevelMem;
xString sName, sRoot;
HANDLE hHandle;
WIN32_FIND_DATA stFindFileData;
SCR_tdst_Cxt_Values *p_stVal;
MLT_tdstInsertCharacter *hInsert;
// change directory
GetCurrentDirectory(256, sDirectory);
SetCurrentDirectory(sGameLevel);
// get level default directory
strcpy(sDefaultDir, g_sGameCommon);
strcat(sDefaultDir, "\\default");
// compute the name of the level MEM file
strcpy(sFileMem, g_sDirectorySave);
sFileMem[strlen(sFileMem)-1]='\0';
strcat(sFileMem, ".mem");
strcpy(sGameLevelMem, sGameLevel);
// compute the name of the default MEM file
strcat(sGameLevelMem, sFileMem);
strcpy(sGameDefault, g_sGameCommon);
strcat(sGameDefault, "\\Default\\");
// change directory
SetCurrentDirectory(sGameDefault);
// search for default MEM file
memset(&stFindFileData,0,sizeof(stFindFileData));
hHandle = FindFirstFile("Default.mem", &stFindFileData);
if( hHandle == INVALID_HANDLE_VALUE)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError: No Default.mem file in the Default directory");
FindClose(hHandle);
}
else
{
FindClose(hHandle);
CopyFile("Default.mem", sGameLevelMem, FALSE);
}
// ALW file
sprintf(sName, "%s.alw", sLevelName);
// if necessary, create ALW file
if (! SCR_fn_c_RdL0_IsSectionExists(sName))
{
MLT_vCopyAndRenameFile("Default.alw", sDefaultDir, sName, sGameLevel, FALSE);
SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyAlwHeader, NULL, SCR_EA_Ntfy_AddSection);
}
// otherwise, load it
else
{
MLT_vLoadALWFileInLib();
MLT_vSaveLibInALWFile();
}
// DSC file
sprintf(sName, "%s.dsc", sLevelName);
MLT_vCopyAndRenameFile("Default.dsc", sDefaultDir, sName, sGameLevel, FALSE);
SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyDscHeader, NULL, SCR_EA_Ntfy_AddSection);
// PGB file
sprintf(sName, "%s.pgb", sLevelName);
MLT_vCopyAndRenameFile("Default.pgb", sDefaultDir, sName, sGameLevel, FALSE);
SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyPgbHeader, NULL, SCR_EA_Ntfy_AddSection);
// WP file
sprintf(sName, "%s.wp", sLevelName);
MLT_vCopyAndRenameFile("Default.wp", sDefaultDir, sName, sGameLevel, FALSE);
SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyWpHeader, NULL, SCR_EA_Ntfy_AddSection);
// WAY file
sprintf(sName, "%s.way", sLevelName);
MLT_vCopyAndRenameFile("Default.way", sDefaultDir, sName, sGameLevel, FALSE);
SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyWayHeader, NULL, SCR_EA_Ntfy_AddSection);
// LVL file
sprintf(sName, "%s.lvl", sLevelName);
MLT_vCopyAndRenameFile("Default.lvl", sDefaultDir, sName, sGameLevel, FALSE);
SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyLvlHeader, NULL, SCR_EA_Ntfy_AddSection);
// LG2 file
sprintf(sName, "%s.lg2", sLevelName);
MLT_vCopyAndRenameFile(sName, sRawLevel, sName, sGameLevel, TRUE);
SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyLg2Header, NULL, SCR_EA_Ntfy_AddSection);
// DISPLAY
MLT_vOutput( C_ComRes_cNormalLine, "\n\tDelete RLI...");
// remove the RLI file
SetCurrentDirectory(sGameLevel);
sprintf(sName, "%s.rli", sLevelName);
remove(sName);
// if necessary, update world character in LVL file
SetCurrentDirectory(sGameLevel);
sprintf(sName, "%s.lvl", sLevelName);
SCR_fn_v_RdL0_ComputeSectionName(sRoot, sName, "InsertCharacter", "W<nomdulevel>");
// load module hierarchy
if (SCR_fn_c_RdL0_IsSectionExists(sRoot))
{
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(sRoot, SCR_CDF_uw_Anl_Normal);
hInsert = (MLT_tdstInsertCharacter *)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
SCR_fn_v_SvL1_RegisterNotify(hInsert->sName, MLT_vSaveInsertCharacter, hInsert, SCR_EA_Ntfy_AddOrModifySection);
}
// restore directory
SetCurrentDirectory(sDirectory);
}
/****************************************************************************
* Description: remove the temporary files created for the level
*
* Parameters: sGameLevel : destination directory of the level
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vRemoveLevelTemporaryFiles (char *sGameLevel)
{
xString sDirectory, sFile;
// if necessary, remove temporary SPO file
if (g_bCreatedSpo)
{
GetCurrentDirectory(256, sDirectory);
SetCurrentDirectory(sGameLevel);
remove("temp.spo");
SetCurrentDirectory(sDirectory);
}
// if necessary, remove temporary GMT file
if (g_bCreatedGmt && !g_bIgnoreGmt)
{
SCR_fn_v_RdL0_Close();
strcpy (sFile, sGameLevel);
strcat(sFile, "temp.gmt");
_chmod(sFile, _S_IREAD | _S_IWRITE );
remove(sFile);
MLT_vInitSystem();
}
// remove temporary VSE file
SCR_fn_v_RdL0_Close();
strcpy(sFile, sGameLevel);
strcat(sFile, "temp.vse");
remove(sFile);
MLT_vInitSystem();
// if necessary, remove temporary ZOO file
if (!g_bIgnoreZoo)
{
SCR_fn_v_RdL0_Close();
strcpy (sFile, sGameLevel);
strcat(sFile, "temp.zoo");
remove(sFile);
MLT_vInitSystem();
}
// if necessary, remove temporary SUB file
if (g_bSubmaps)
{
SCR_fn_v_RdL0_Close();
strcpy (sFile, sGameLevel);
strcat(sFile, "temp.sub");
remove(sFile);
MLT_vInitSystem();
}
// clean root1 for submaps
if (g_hRoot1)
{
free(g_hRoot1);
g_hRoot1 = NULL;
}
// clean root2 for submaps
if (g_hRoot2)
{
free(g_hRoot2);
g_hRoot2 = NULL;
g_iUnivSectors = 0;
}
}
/****************************************************************************
* Description: search for all the sectors in first level of the hierarchy
*
* Parameters: hRoot : root of the hierarchy
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vSearchAllSector(MLT_tdxHandleToSuperObject hRoot)
{
xString sFile, sAction, sIdent, sIdent2;
long i;
// there must at least one sector
if(hRoot->lNbChild == 0)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : No sector");
}
// cover the sectors (first level in the hierarchy)
for(i=0; i<hRoot->lNbChild; i++)
{
SCR_fn_v_RdL0_SplitSectionName(hRoot->d_hChild[i]->sName, sFile, sAction, sIdent);
sprintf(sIdent2, "%s", sIdent+strlen(M_SPO_));
MLT_vAddSector(sIdent2);
}
}
/****************************************************************************
* Description: set the identity matrix for all the objects on the first level
*
* Parameters: hRoot : root of the hierarchy
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vMatrixIdentityHierarchy(MLT_tdxHandleToSuperObject hRoot)
{
xString sName, sFile, sAction, sIdent, sIdent2;
long i;
// there must at least one sector
if(hRoot->lNbChild == 0)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : No sector");
}
// cover the sectors (first floor in the hierarchy)
for(i=0; i<hRoot->lNbChild; i++)
{
SCR_fn_v_RdL0_SplitSectionName(hRoot->d_hChild[i]->sName, sFile, sAction, sIdent);
sprintf(sIdent2, "%s", sIdent+strlen(M_SPO_));
MLT_vAddSector(sIdent2);
// update the matrix
sprintf(sName, "%s", hRoot->d_hChild[i]->p_stMatrix->sName);
MLT_xMulMatrixMatrix(hRoot->d_hChild[i]->p_stMatrix, hRoot->p_stMatrix, hRoot->d_hChild[i]->p_stMatrix);
sprintf(hRoot->d_hChild[i]->p_stMatrix->sName, "%s", sName);
// the sector's matrix must be no identity
if(strstr(hRoot->d_hChild[i]->sName, M_Surface) == NULL)
{
MLT_vMatrixIdentitySector(hRoot->d_hChild[i]);
}
}
MLT_xSetIdentityMatrix (hRoot->p_stMatrix);
}
/****************************************************************************
* Description: force the sector's matrix to be identity
*
* Parameters: hRoot : sector super object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vMatrixIdentitySector(MLT_tdxHandleToSuperObject hSprObj)
{
xString sName;
long i;
// there must at least one child in the sector
if(hSprObj->lNbChild == 0)
{
if (g_bRaymanII)
MLT_vOutput( C_ComRes_cErrorLine, "\nError : No object or bounding box in sector %s", hSprObj->sName);
else
MLT_vOutput( C_ComRes_cErrorLine, "\nError : No object in sector %s", hSprObj->sName);
}
// cover the visibles borders (second floor in the hierarchy)
for(i=0; i<hSprObj->lNbChild; i++)
{
// sector's matrix not identity
sprintf(sName, "%s", hSprObj->d_hChild[i]->p_stMatrix->sName);
MLT_xMulMatrixMatrix(hSprObj->d_hChild[i]->p_stMatrix, hSprObj->p_stMatrix, hSprObj->d_hChild[i]->p_stMatrix);
sprintf(hSprObj->d_hChild[i]->p_stMatrix->sName, "%s", sName);
// manage special objects
if(strstr(hSprObj->d_hChild[i]->sName, M_Surface) == NULL)
{
if (strstr(hSprObj->d_hChild[i]->sName, "=") == NULL)
MLT_vMatrixIdentityFronteer(hSprObj->d_hChild[i]);
}
}
MLT_xSetIdentityMatrix (hSprObj->p_stMatrix);
}
/****************************************************************************
* Description: force the border's matrix to be identity
*
* Parameters: hRoot : fronteer super object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vMatrixIdentityFronteer (MLT_tdxHandleToSuperObject hSprObj)
{
MLT_tdstGeometricObject *p_stObj;
xString sName;
long i;
// cover the statics objets (third floor in the hierarchy)
for(i=0; i<hSprObj->lNbChild; i++)
{
sprintf(sName, "%s", hSprObj->d_hChild[i]->p_stMatrix->sName);
MLT_xMulMatrixMatrix(hSprObj->d_hChild[i]->p_stMatrix, hSprObj->p_stMatrix, hSprObj->d_hChild[i]->p_stMatrix);
sprintf(hSprObj->d_hChild[i]->p_stMatrix->sName, "%s", sName);
}
// spread to the geometric object
if(strlen(hSprObj->sGeometric) != 0)
{
p_stObj = MLT_pFindInLib(hSprObj->sGeometric);
if(p_stObj == NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hSprObj->sGeometric);
}
else
{
// compute absolute vertex
for(i=0; i<p_stObj->xNbPoints; i++)
{
MLT_xMulMatrixVertex(p_stObj->d_stListOfPoints+i, hSprObj->p_stMatrix, p_stObj->d_stListOfPoints+i);
}
}
}
// specific case : spo is a dummy grouping several elements
else
{
int j;
// compute the minmax points for each element
for (j=0; j<hSprObj->lNbChild; j++)
{
if (strstr(hSprObj->d_hChild[j]->sName, "&") != NULL)
{
p_stObj = MLT_pFindInLib(hSprObj->d_hChild[j]->sGeometric);
if(p_stObj == NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hSprObj->d_hChild[j]->sGeometric);
}
else
{
// compute absolute vertex
for(i=0; i<p_stObj->xNbPoints; i++)
{
MLT_xMulMatrixVertex(p_stObj->d_stListOfPoints+i, hSprObj->d_hChild[j]->p_stMatrix, p_stObj->d_stListOfPoints+i);
}
}
}
}
}
MLT_xSetIdentityMatrix (hSprObj->p_stMatrix);
}
/****************************************************************************
* Description: create the sectors in the hierarchy
*
* Parameters: hSprObj : root super-object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vMakeSectorInHierarchy(MLT_tdxHandleToSuperObject hSprObj)
{
long i, lNbChild;
xString sFile, sAction, sIdent;
lNbChild = 0;
// check all children
for (i=0; i<hSprObj->lNbChild; i++ )
{
lNbChild++;
// detect a bad border among the sector
if (strstr(hSprObj->d_hChild[i]->sName, "frt") != NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : No frontier among the sectors : %s", hSprObj->d_hChild[i]->sName);
continue;
}
// init the flag for the sector telling if it has a new or old frontier
hSprObj->d_hChild[i]->stSector.iFlag |= 0x00;
// create sector
MLT_vCreateSector(hSprObj->d_hChild[i]);
// if in a sector, we have both types of frontier generate a warning
if ((hSprObj->d_hChild[i]->stSector.iFlag & IS_OLDFRONTIER) && (hSprObj->d_hChild[i]->stSector.iFlag & IS_NEWFRONTIER))
{
SCR_fn_v_RdL0_SplitSectionName(hSprObj->d_hChild[i]->stSector.sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, "\nWarning : New and old frontier for the %s sector", sIdent);
}
// compute the surfaces
if (strstr(hSprObj->d_hChild[i]->sName, M_Surface) != NULL)
{
MLT_bAttachSurfaceToSector(hSprObj, hSprObj->d_hChild[i], g_sDirectorySave);
// delete the surface from the hierarchy
MLT_vDeleteHierarchy(hSprObj->d_hChild[i]);
hSprObj->d_hChild[i] = NULL;
lNbChild--;
}
}
// for submaps : create Univers sectors
for (i=0; i<g_iUnivSectors; i++)
{
SCR_fn_v_RdL0_SplitSectionName(g_hRoot2->d_hChild[i]->sName, sFile, sAction, sIdent);
MLT_vCreateUniversSector(hSprObj, sIdent+7);
lNbChild++;
}
// insert Univers sector
MLT_vCreateUniversSector(hSprObj, "");
lNbChild++;
// update sub hierarchy
for(i=0; i<lNbChild; i++)
{
MLT_tdxHandleToSuperObject hTemp;
int j;
j=i;
while (hSprObj->d_hChild[j] == NULL)
j++;
hTemp = hSprObj->d_hChild[j];
hSprObj->d_hChild[j] = NULL;
hSprObj->d_hChild[i] = hTemp;
}
hSprObj->lNbChild = lNbChild;
}
/****************************************************************************
* Description: create the sector structure
*
* Parameters: hSprObj : sector super-object
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vCreateSector (MLT_tdxHandleToSuperObject hSprObj)
{
MLT_tdxHandleToSuperObject hChild;
MLT_tdstGeometricObject *p_stObj;
MTH3D_tdstVector stPointMin;
MTH3D_tdstVector stPointMax;
xString sAction, sIdent, sFile, sIdent2;
xString sName1, sIdent1;
long i, lNbChild;
//set the initial values for the minimum and maximum of the bounding box
MTH3D_M_vSetVectorElements(&stPointMin, MLT_C_InfinitPlus, MLT_C_InfinitPlus, MLT_C_InfinitPlus);
MTH3D_M_vSetVectorElements(&stPointMax, MLT_C_InfinitMinus, MLT_C_InfinitMinus, MLT_C_InfinitMinus);
// the super-object must not be a surface
if (strstr(hSprObj->sName, M_Surface) == NULL)
{
// get super-object name
SCR_fn_v_RdL0_SplitSectionName(hSprObj->sName, sFile, sAction, sIdent);
// build corresponding sector name
sprintf(sFile, "%s.sct", g_sFileIn);
sprintf(sIdent2, "%s", sIdent+strlen(M_SPO_));
SCR_fn_v_RdL0_ComputeSectionName(hSprObj->stSector.sName, sFile, M_Sector, sIdent2);
// init sectr parameter
hSprObj->stSector.lNbSurface = 0;
// (Rayman2 version only)
if (g_bRaymanII)
{
//set the initial values for the min and max of the bounding box
MTH3D_M_vSetVectorElements(&hSprObj->stSector.stPointMin, MLT_C_InfinitPlus, MLT_C_InfinitPlus, MLT_C_InfinitPlus);
MTH3D_M_vSetVectorElements(&hSprObj->stSector.stPointMax, MLT_C_InfinitMinus, MLT_C_InfinitMinus, MLT_C_InfinitMinus);
}
// (TonicTrouble version only)
else
{
// detect surfaces under the sector
lNbChild = 0;
SCR_fn_v_RdL0_SplitSectionName(hSprObj->stSector.sName, sFile, sAction, sIdent);
for(i=0; i<hSprObj->lNbChild; i++ )
{
lNbChild++;
// add the surface : the test is in the function
MLT_vAddSurfaceToSector(g_hRoot, hSprObj->d_hChild[i]->sName, sIdent, g_sDirectorySave);
//set the flag to tell if it is a new or old frontier
if(strstr(hSprObj->d_hChild[i]->sName, M_NewFronRever) != NULL)
hSprObj->stSector.iFlag |= IS_NEWFRONTIER;
if(strstr(hSprObj->d_hChild[i]->sName, M_FronRever) != NULL)
hSprObj->stSector.iFlag |= IS_OLDFRONTIER;
// delete the surface from the hierarchy
if(strstr(hSprObj->d_hChild[i]->sName, M_Surface) != NULL)
{
MLT_vDeleteHierarchy(hSprObj->d_hChild[i]);
hSprObj->d_hChild[i] = NULL;
lNbChild--;
}
}
// reorganization of the sub hierarchy
for (i=0; i<lNbChild; i++)
{
MLT_tdxHandleToSuperObject hTemp;
long j;
j=i;
while (hSprObj->d_hChild[j] == NULL)
j++;
hTemp = hSprObj->d_hChild[j];
hSprObj->d_hChild[j] = NULL;
hSprObj->d_hChild[i] = hTemp;
}
hSprObj->lNbChild = lNbChild;
}
}
else
{
sprintf(hSprObj->stSector.sName, "");
}
// (Rayman2 version only)
if (g_bRaymanII)
{
//for all the children of the sector
for(i=0; i<hSprObj->lNbChild; i++ )
{
hChild = hSprObj->d_hChild[i];
// if there is a bouding box, use it
if (strstr(hChild->sName, M_BoundingBox) != NULL)
{
p_stObj = MLT_pFindInLib(hChild->sGeometric);
if(p_stObj == NULL)
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->sGeometric);
else
MLT_vComputeMinMaxPointOfBorder (p_stObj, &hSprObj->stSector.stPointMin, &hSprObj->stSector.stPointMax);
}
// use geometric children to compute the real bouding box
else
{
// instance
if (strstr(hChild->sName, "=") != NULL)
{
// save name
strcpy(sName1, hChild->sName);
// create dummy name
SCR_fn_v_RdL0_SplitSectionName(sName1, sFile, sAction, sIdent);
strcpy(sIdent1, "SPO_dum_");
if (!strstr(sIdent, "SPO_"))
strcat(sIdent1, sIdent);
else
strcat(sIdent1, sIdent+4);
SCR_fn_v_RdL0_ComputeSectionName(hChild->sName, sFile, sAction, sIdent1);
// create new child and copy instance
hChild->d_hChild[0] = (MLT_tdxHandleToSuperObject)malloc(sizeof(MLT_tdstSprObj));
strcpy(hChild->d_hChild[0]->sName, sName1);
strcpy(hChild->d_hChild[0]->sGeometric, hChild->sGeometric);
strcpy(hChild->d_hChild[0]->sLinkedObject, hChild->sLinkedObject);
hChild->d_hChild[0]->fTransparency = hChild->fTransparency;
hChild->d_hChild[0]->p_stMatrix = hChild->p_stMatrix;
hChild->d_hChild[0]->ulSPOFlags = hChild->ulSPOFlags;
hChild->d_hChild[0]->stSector = hChild->stSector;
hChild->d_hChild[0]->lNbChild = 0;
hChild->d_hChild[0]->iFlags = hChild->iFlags;
// update dummy
hChild->lNbChild=1;
strcpy(hChild->sGeometric, "");
hChild->p_stMatrix = (MLT_tdstMatrix*)malloc(sizeof(MLT_tdstMatrix));
MLT_xSetIdentityMatrix(hChild->p_stMatrix);
SCR_fn_v_RdL0_SplitSectionName(hChild->sName, sFile, sAction, sIdent);
SCR_fn_v_RdL0_ComputeSectionName(hChild->p_stMatrix->sName, sFile, M_Matrix, sIdent);
// compute minmax from the instance
p_stObj = MLT_pFindInLib(hChild->d_hChild[0]->sGeometric);
if(p_stObj == NULL)
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->d_hChild[0]->sGeometric);
else
MLT_vComputeMinMaxPointWithMatrix (p_stObj, &stPointMin, &stPointMax, hChild->d_hChild[0]->p_stMatrix);
}
// dummy grouping some elements
else if (strlen(hChild->sGeometric) == 0)
{
int j;
// compute the minmax points for each element
for (j=0; j<hChild->lNbChild; j++)
{
if (strstr(hChild->d_hChild[j]->sName, "&") != NULL)
{
p_stObj = MLT_pFindInLib(hChild->d_hChild[j]->sGeometric);
if(p_stObj == NULL)
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->d_hChild[j]->sGeometric);
else
MLT_vComputeMinMaxPointOfBorder (p_stObj, &stPointMin, &stPointMax);
}
}
}
// normal case : child is a geometric one
else
{
p_stObj = MLT_pFindInLib(hChild->sGeometric);
if(p_stObj == NULL)
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->sGeometric);
else
MLT_vComputeMinMaxPointOfBorder (p_stObj, &stPointMin, &stPointMax);
}
}
}
// set the final values of the bounding box : max size of frtb and graphic children
if (hSprObj->stSector.stPointMin.xX == MLT_C_InfinitPlus)
MTH3D_M_vSetXofVector(&hSprObj->stSector.stPointMin, stPointMin.xX);
if (hSprObj->stSector.stPointMin.xY == MLT_C_InfinitPlus)
MTH3D_M_vSetYofVector(&hSprObj->stSector.stPointMin, stPointMin.xY);
if (hSprObj->stSector.stPointMin.xZ == MLT_C_InfinitPlus)
MTH3D_M_vSetZofVector(&hSprObj->stSector.stPointMin, stPointMin.xZ);
if (hSprObj->stSector.stPointMax.xX == MLT_C_InfinitMinus)
MTH3D_M_vSetXofVector(&hSprObj->stSector.stPointMax, stPointMax.xX);
if (hSprObj->stSector.stPointMax.xY == MLT_C_InfinitMinus)
MTH3D_M_vSetYofVector(&hSprObj->stSector.stPointMax, stPointMax.xY);
if (hSprObj->stSector.stPointMax.xZ == MLT_C_InfinitMinus)
MTH3D_M_vSetZofVector(&hSprObj->stSector.stPointMax, stPointMax.xZ);
// check min and max points for the map
if (gs_stMinPointOfMap.xX > stPointMin.xX)
MTH3D_M_vSetXofVector(&gs_stMinPointOfMap, stPointMin.xX);
if (gs_stMinPointOfMap.xY > stPointMin.xY)
MTH3D_M_vSetYofVector(&gs_stMinPointOfMap, stPointMin.xY);
if (gs_stMinPointOfMap.xZ > stPointMin.xZ)
MTH3D_M_vSetZofVector(&gs_stMinPointOfMap, stPointMin.xZ);
if (gs_stMaxPointOfMap.xX < stPointMax.xX)
MTH3D_M_vSetXofVector(&gs_stMaxPointOfMap, stPointMax.xX);
if (gs_stMaxPointOfMap.xY < stPointMax.xY)
MTH3D_M_vSetYofVector(&gs_stMaxPointOfMap, stPointMax.xY);
if (gs_stMaxPointOfMap.xZ < stPointMax.xZ)
MTH3D_M_vSetZofVector(&gs_stMaxPointOfMap, stPointMax.xZ);
}
}
/****************************************************************************
* Description: create the Univers sector, for global or for submap
*
* Parameters: hSprObj : root super-object
* sSubmapName : name of submap, or empty string for global
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vCreateUniversSector (MLT_tdxHandleToSuperObject hSprObj, xString sSubmapName)
{
xString sFile, sSuperObject, sSector;
// build the name of the sector accroding to its status (submap or global)
if (strcmp(sSubmapName, ""))
{
sprintf(sSuperObject, "%s_%s", M_SPO_Univers, sSubmapName);
sprintf(sSector, "%s_%s", M_Univers, sSubmapName);
}
else
{
strcpy(sSuperObject, M_SPO_Univers);
strcpy(sSector, M_Univers);
}
// allocate Univers super-object as last child of the root
hSprObj->d_hChild[hSprObj->lNbChild] = (MLT_tdxHandleToSuperObject)calloc(1, sizeof(MLT_tdstSprObj));
// compute corresponding section name
sprintf(sFile, "%s.spo", g_sFileIn);
SCR_fn_v_RdL0_ComputeSectionName(hSprObj->d_hChild[hSprObj->lNbChild]->sName, sFile, M_SuperObject, sSuperObject);
// allocate Univers matrix (default value : identity)
hSprObj->d_hChild[hSprObj->lNbChild]->p_stMatrix = (MLT_tdstMatrix*)calloc(1, sizeof(MLT_tdstMatrix));
MLT_xSetIdentityMatrix(hSprObj->d_hChild[hSprObj->lNbChild]->p_stMatrix);
// compute corresponding section name
sprintf(sFile, "%s.spo", g_sFileIn);
SCR_fn_v_RdL0_ComputeSectionName(hSprObj->d_hChild[hSprObj->lNbChild]->p_stMatrix->sName, sFile, M_Matrix, sSuperObject);
// init Univers sector
hSprObj->d_hChild[hSprObj->lNbChild]->stSector.lNbSurface = 0;
// compute corresponding section name
sprintf(sFile, "%s.sct", g_sFileIn);
SCR_fn_v_RdL0_ComputeSectionName(hSprObj->d_hChild[hSprObj->lNbChild]->stSector.sName, sFile, M_Sector, sSector);
// update the number of children
hSprObj->lNbChild++;
}
/****************************************************************************
* Description: Insert an Ipo between SuperObject and Geometric
*
* Parameters: hSprObj : root of the hierarchy
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vMakeIpoInHierarchy (MLT_tdxHandleToSuperObject hSprObj)
{
long i;
// check if super-object encapsulate a geometric object
if (strlen(hSprObj->sGeometric) != 0)
{
xString sFile, sAction, sIdent, sForme, sHabillage, sSection, sName;
long lNoPhy, lNoLod;
// get minimal geometric name
SCR_fn_v_RdL0_SplitSectionName(hSprObj->sGeometric, sFile, sAction, sIdent);
MLT_vSplitModuleSectionName(sIdent, sForme, sHabillage, &lNoPhy, &lNoLod, sName);
// compute corresponding PO name
MLT_vComputePhysicalSectionName(sSection, sForme, sHabillage, lNoPhy, sName);
// compute corresponding IPO section name
sprintf(sFile, "%s.ipo", g_sFileIn);
SCR_fn_v_RdL0_ComputeSectionName(hSprObj->sLinkedObject, sFile, M_Ipo, sSection);
// remove the geometric entry
sprintf(hSprObj->sGeometric, "");
}
// iteration on next level
for (i=0; i<hSprObj->lNbChild; i++)
{
MLT_vMakeIpoInHierarchy(hSprObj->d_hChild[i]);
}
}
/****************************************************************************
* Description: compute the name of Physical from the name of Geometric
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vMakePhysicalInLib ()
{
MLT_tdstGeometricObject *p_stObj;
xString sFile, sAction, sIdent, sForme ,sHabillage, sName;
long i, lNbObjInLib, lNoPhy, lNoLod;
// search the library
lNbObjInLib = MLT_lGetNumberObjectInLib();
for(i=0; i<lNbObjInLib; i++)
{
p_stObj = MLT_lGetObjectFromLib(i);
if (!p_stObj)
continue;
// No Physical for the borders
if(strstr(p_stObj->sName, M_NameGothrough) != NULL)
{
sprintf(p_stObj->sComment, "");
sprintf(p_stObj->sPhysicalSection, "");
continue;
}
// No Physical for the surfaces
if(strstr(p_stObj->sName, M_Surface) != NULL)
{
sprintf(p_stObj->sPhysicalSection, "");
continue;
}
// get minimal geometric name
SCR_fn_v_RdL0_SplitSectionName(p_stObj->sName, sFile, sAction, sIdent);
MLT_vSplitModuleSectionName(sIdent, sForme, sHabillage, &lNoPhy, &lNoLod, sName);
// compute corresponding physical name
MLT_vComputePhysicalSectionName(sIdent, sForme, sHabillage, lNoPhy, "");
// compute corresponding section name
sprintf(sFile, "%s.phy", g_sFileIn);
SCR_fn_v_RdL0_ComputeSectionName(p_stObj->sPhysicalSection, sFile, M_Phy, sIdent);
// register index in library
p_stObj->lNumberInTable = i;
}
}
/****************************************************************************
* Description: Detect and erase the unused points in all geometric objects of the hierarchy
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vEraseUnusedPoints ()
{
MLT_tdstElementIndexedTriangles *p_stLocalElement;
MLT_tdstElementFaceMapDescriptors *p_stLocalElementFMD;
xString sFile, sAction, sIdent;
BOOL bIsSprite;
char buf[5];
int xIndex, iIndexM=0;
int i, j, m, n, k;
// check all the geometric objects
for (i=0; i<g_lGeometricIndex; i++)
{
// the object still exist in the hierarchy
if (g_hGeometricInFile[i])
{
MTH3D_tdstVector *p_stListOfPoints;
MTH3D_tdstVector *p_stListOfPointsNormals;
MLT_tdstColor *p_stListOfColors;
int *p_iIndex;
bIsSprite = FALSE;
n=0;
// check if the unused points must be deleted
if (g_bEraseUnused)
{
p_stListOfPoints = (MTH3D_tdstVector *) malloc(g_hGeometricInFile[i]->xNbPoints*sizeof(MTH3D_tdstVector));
p_stListOfPointsNormals = (MTH3D_tdstVector *) malloc(g_hGeometricInFile[i]->xNbPoints*sizeof(MTH3D_tdstVector));
p_stListOfColors = (MLT_tdstColor *) malloc(g_hGeometricInFile[i]->xNbPoints*sizeof(MLT_tdstColor));
p_iIndex=(int *)malloc(sizeof(int) * g_hGeometricInFile[i]->xNbPoints);
}
for (m=0; m<g_hGeometricInFile[i]->xNbPoints; m++)
{
iIndexM = 0;
for (xIndex=0; xIndex<g_hGeometricInFile[i]->xNbElements; xIndex++)
{
if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles )
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
for (j=0; j<p_stLocalElement->xNbFaces; j++) //for all faces
{
if ((m == p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[0])
||(m == p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[1])
||(m == p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[2]))
iIndexM++;
}
}
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors)
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
for (j=0; j<p_stLocalElementFMD->xNbFaces; j++)
{
if ((m == p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[0])
||(m == p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[1])
||(m == p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[2]))
iIndexM++;
}
}
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementSprites)
bIsSprite = TRUE;
}
// the point m is not used in any face
if (!iIndexM && !bIsSprite)
{
if (g_bEraseUnused)
{
MLT_vOutput( C_ComRes_cWarningLine, "\n\tFrom the object ");
//MLT_vOutput( C_ComRes_cWarningLine, g_hGeometricInFile[i]->sName);
SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, " was deleted the unused point n<>");
sprintf(buf, "%d", m);
MLT_vOutput( C_ComRes_cErrorLine, buf);
p_iIndex[m] = -1; //the point is not anymore
}
else
{
MLT_vOutput( C_ComRes_cErrorLine, "\n\tIn the object ");
//MLT_vOutput( C_ComRes_cErrorLine, g_hGeometricInFile[i]->sName);
SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, " the point n<>");
sprintf(buf, "%d", m);
MLT_vOutput( C_ComRes_cWarningLine, buf);
MLT_vOutput( C_ComRes_cErrorLine, " is not used.");
}
}
//the points is still used, so completye the new structure
else
{
if (g_bEraseUnused)
{
MTH3D_M_vSetVectorElements(&p_stListOfPoints[n],
g_hGeometricInFile[i]->d_stListOfPoints[m].xX,
g_hGeometricInFile[i]->d_stListOfPoints[m].xY,
g_hGeometricInFile[i]->d_stListOfPoints[m].xZ);
MTH3D_M_vSetVectorElements(&p_stListOfPointsNormals[n],
g_hGeometricInFile[i]->d_stListOfPointsNormals[m].xX,
g_hGeometricInFile[i]->d_stListOfPointsNormals[m].xY,
g_hGeometricInFile[i]->d_stListOfPointsNormals[m].xZ);
p_stListOfColors[n].xR = g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xR;
p_stListOfColors[n].xG = g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xG;
p_stListOfColors[n].xB = g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xB;
p_iIndex[m] = n;
n++;
}
}
}
if (g_bEraseUnused)
{
g_hGeometricInFile[i]->xNbPoints = n;
for (m=0; m<n; m++)
{
MTH3D_M_vSetVectorElements(&g_hGeometricInFile[i]->d_stListOfPoints[m],
p_stListOfPoints[m].xX,
p_stListOfPoints[m].xY,
p_stListOfPoints[m].xZ);
MTH3D_M_vSetVectorElements(&g_hGeometricInFile[i]->d_stListOfPointsNormals[m],
p_stListOfPointsNormals[m].xX,
p_stListOfPointsNormals[m].xY,
p_stListOfPointsNormals[m].xZ);
g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xR = p_stListOfColors[m].xR;
g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xG = p_stListOfColors[m].xG;
g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xB = p_stListOfColors[m].xB;
}
for (xIndex=0; xIndex < g_hGeometricInFile[i]->xNbElements; xIndex++)
{
if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles )
{
MLT_tdstTripledIndex *p_stListOfFacesTripled;
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
p_stListOfFacesTripled = (MLT_tdstTripledIndex *)malloc(sizeof(MLT_tdstTripledIndex)* p_stLocalElement->xNbFaces);
for (j=0; j<p_stLocalElement->xNbFaces; j++)
{
for (k=0; k<3; k++)
p_stListOfFacesTripled[j].a3_xIndex[k] = p_iIndex[p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]];
}
for (j=0; j<p_stLocalElement->xNbFaces; j++)
{
for (k=0; k<3; k++)
p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k] = p_stListOfFacesTripled[j].a3_xIndex[k];
}
free(p_stListOfFacesTripled);
}
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors)
{
MLT_tdstTripledIndex *p_stListOfFacesTripled;
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
p_stListOfFacesTripled = (MLT_tdstTripledIndex *)malloc(sizeof(MLT_tdstTripledIndex)* p_stLocalElement->xNbFaces);
for (j=0; j<p_stLocalElement->xNbFaces; j++)
{
for (k=0; k<3; k++)
p_stListOfFacesTripled[j].a3_xIndex[k] = p_iIndex[p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k]];
}
for (j=0; j<p_stLocalElement->xNbFaces; j++)
{
for (k=0; k<3; k++)
p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k] = p_stListOfFacesTripled[j].a3_xIndex[k];
}
free(p_stListOfFacesTripled);
}
}
free(p_stListOfPoints);
free(p_stListOfPointsNormals);
free(p_stListOfColors);
}
}
}
}
/****************************************************************************
* Description: Detect and erase the duplicated points in all geometric objects of the hierarchy
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vEraseDuplicatedPoints ()
{
MLT_tdstElementIndexedTriangles *p_stLocalElement;
MLT_tdstElementFaceMapDescriptors *p_stLocalElementFMD;
xString sFile, sAction, sIdent;
char buf[5];
int xIndex;
int i, j, k, l, m, n, p, p1;
// check all geometric objects
for (i=0; i<g_lGeometricIndex; i++)
{
m = 0;
for (xIndex=0; xIndex < g_hGeometricInFile[i]->xNbElements; xIndex++)
{
MLT_tdstTripledIndex *p_stListOfFacesTripled = NULL;
MLT_tdstTripledIndex *p_stListOfFacesTripledIndexUV = NULL;
MTH3D_tdstVector *p_stListOfFaceNormals = NULL;
n=0;
if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles )
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
p_stListOfFacesTripled = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex));
p_stListOfFacesTripledIndexUV = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex));
p_stListOfFaceNormals = (MTH3D_tdstVector *) malloc(p_stLocalElement->xNbFaces*sizeof(MTH3D_tdstVector));
//for all faces
for (j=0; j<p_stLocalElement->xNbFaces; j++)
{
MTH3D_tdstVector stPoint[3];
BOOL bNot = FALSE;
for (k=0; k<3; k++)
MTH3D_M_vSetVectorElements(&stPoint[k], // k -> pk
(g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k])->xX,
(g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k])->xY,
(g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k])->xZ);
for (k=0; k<3; k++)
{
for (l=k+1; l<3; l++)
{
if ((fabs(stPoint[k].xX - stPoint[l].xX) <= g_fLimit3) &&
(fabs(stPoint[k].xY - stPoint[l].xY) <= g_fLimit3) &&
(fabs(stPoint[k].xZ - stPoint[l].xZ) <= g_fLimit3)) //duplicate points
{
if (g_bEraseDuplicated)
{ //erase the face from the object
bNot = TRUE;
MLT_vOutput( C_ComRes_cWarningLine, "\nWarning: From the object ");
//MLT_vOutput( C_ComRes_cWarningLine, g_hGeometricInFile[i]->sName);
SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, " in the element ");
//MLT_vOutput( C_ComRes_cWarningLine, p_stLocalElement->sName);
SCR_fn_v_RdL0_SplitSectionName(p_stLocalElement->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, " was deleted the face n<> ");
sprintf(buf, "%d", j);
MLT_vOutput( C_ComRes_cErrorLine, buf);
MLT_vOutput( C_ComRes_cWarningLine, " which contained the duplicated points n<> ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]);
MLT_vOutput( C_ComRes_cErrorLine, buf);
MLT_vOutput( C_ComRes_cWarningLine, " and ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]);
MLT_vOutput( C_ComRes_cErrorLine, buf);
}
else
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError: In the object ");
//MLT_vOutput( C_ComRes_cErrorLine, g_hGeometricInFile[i]->sName);
SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, " in the element ");
//MLT_vOutput( C_ComRes_cErrorLine, p_stLocalElement->sName);
SCR_fn_v_RdL0_SplitSectionName(p_stLocalElement->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, " was detected the face n<> ");
sprintf(buf, "%d", j);
MLT_vOutput( C_ComRes_cWarningLine, buf);
MLT_vOutput( C_ComRes_cErrorLine, " which contains the duplicated points n<> ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]);
MLT_vOutput( C_ComRes_cWarningLine, buf);
MLT_vOutput( C_ComRes_cErrorLine, " and ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]);
MLT_vOutput( C_ComRes_cWarningLine, buf);
}
}
}
}
if (!bNot) // the face remains, complete the new structures
{
for (p=0; p<3; p++)
{ p_stListOfFacesTripled[n].a3_xIndex[p] = p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[p];
p_stListOfFacesTripledIndexUV[n].a3_xIndex[p] = p_stLocalElement->d_stListOfFacesTripledIndexUV[j].a3_xIndex[p];
}
MTH3D_M_vSetVectorElements(&p_stListOfFaceNormals[n],
p_stLocalElement->d_stListOfFacesNormals[j].xX,
p_stLocalElement->d_stListOfFacesNormals[j].xY,
p_stLocalElement->d_stListOfFacesNormals[j].xZ);
n++;
}
}
}
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors)
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
p_stListOfFacesTripled = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex));
p_stListOfFacesTripledIndexUV = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex));
p_stListOfFaceNormals = (MTH3D_tdstVector *) malloc(p_stLocalElement->xNbFaces*sizeof(MTH3D_tdstVector));
for (j=0; j<p_stLocalElementFMD->xNbFaces; j++)
{
MTH3D_tdstVector stPoint[3];
BOOL bNot = FALSE;
for (k=0; k<3; k++)
MTH3D_M_vSetVectorElements(&stPoint[k], // k -> pk
(g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k])->xX,
(g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k])->xY,
(g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k])->xZ);
for (k=0; k<3; k++)
{
for (l=k+1; l<3; l++)
{
if ((fabs(stPoint[k].xX - stPoint[l].xX) <= g_fLimit3)&&
(fabs(stPoint[k].xY - stPoint[l].xY) <= g_fLimit3)&&
(fabs(stPoint[k].xZ - stPoint[l].xZ) <= g_fLimit3)) //duplicate points
{
if (g_bEraseDuplicated)
{ //erase the face from the object
bNot = TRUE;
MLT_vOutput( C_ComRes_cWarningLine, "\nError: From the object ");
//MLT_vOutput( C_ComRes_cWarningLine, g_hGeometricInFile[i]->sName);
SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, " in the element ");
//MLT_vOutput( C_ComRes_cWarningLine, p_stLocalElementFMD->sName);
SCR_fn_v_RdL0_SplitSectionName(p_stLocalElementFMD->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, " was deleted the face n<> ");
sprintf(buf, "%d", j);
MLT_vOutput( C_ComRes_cErrorLine, buf);
MLT_vOutput( C_ComRes_cWarningLine, " which contained the duplicated points n<> ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]);
MLT_vOutput( C_ComRes_cErrorLine, buf);
MLT_vOutput( C_ComRes_cWarningLine, " and ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]);
MLT_vOutput( C_ComRes_cErrorLine, buf);
}
else
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError: In the object ");
//MLT_vOutput( C_ComRes_cErrorLine, g_hGeometricInFile[i]->sName);
SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, " in the element ");
//MLT_vOutput( C_ComRes_cErrorLine, p_stLocalElementFMD->sName);
SCR_fn_v_RdL0_SplitSectionName(p_stLocalElementFMD->sName, sFile, sAction, sIdent);
MLT_vOutput( C_ComRes_cWarningLine, sIdent);
MLT_vOutput( C_ComRes_cErrorLine, " was detected the face n<> ");
sprintf(buf, "%d", j);
MLT_vOutput( C_ComRes_cWarningLine, buf);
MLT_vOutput( C_ComRes_cErrorLine, " which contains the duplicated points n<> ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]);
MLT_vOutput( C_ComRes_cWarningLine, buf);
MLT_vOutput( C_ComRes_cErrorLine, " and ");
sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]);
MLT_vOutput( C_ComRes_cWarningLine, buf);
}
}
}
}
if (!bNot) // the face remains
{
for (p=0; p<3; p++)
p_stListOfFacesTripled[n].a3_xIndex[p] = p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[p];
MTH3D_M_vSetVectorElements(&p_stListOfFaceNormals[n],
p_stLocalElementFMD->d_stListOfFacesNormals[j].xX,
p_stLocalElementFMD->d_stListOfFacesNormals[j].xY,
p_stLocalElementFMD->d_stListOfFacesNormals[j].xZ);
n++;
}
}
}
if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles )
{
p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
for (p=0; p<n; p++)
{
for (p1=0; p1<3; p1++)
{ p_stLocalElement->d_stListOfFacesTripled[p].a3_xIndex[p1] = p_stListOfFacesTripled[p].a3_xIndex[p1];
p_stLocalElement->d_stListOfFacesTripledIndexUV[p].a3_xIndex[p1] = p_stListOfFacesTripledIndexUV[p].a3_xIndex[p1];
}
MTH3D_M_vSetVectorElements(&p_stLocalElement->d_stListOfFacesNormals[p],
p_stListOfFaceNormals[p].xX,
p_stListOfFaceNormals[p].xY,
p_stListOfFaceNormals[p].xZ);
}
p_stLocalElement->xNbFaces = n;
}
else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors)
{
p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]);
for (p=0; p<n; p++)
{
for (p1=0; p1<3; p1++)
p_stLocalElementFMD->d_stListOfFacesQuadrupled[p].stFaceTripled.a3_xIndex[p1] = p_stListOfFacesTripled[p].a3_xIndex[p1];
MTH3D_M_vSetVectorElements(&p_stLocalElementFMD->d_stListOfFacesNormals[p],
p_stListOfFaceNormals[p].xX,
p_stListOfFaceNormals[p].xY,
p_stListOfFaceNormals[p].xZ);
}
p_stLocalElementFMD->xNbFaces = n;
}
if (p_stListOfFacesTripled)
free(p_stListOfFacesTripled);
if (p_stListOfFacesTripledIndexUV)
free(p_stListOfFacesTripledIndexUV);
if (p_stListOfFaceNormals)
free(p_stListOfFaceNormals);
}
}
}
// multitextures
void MLT_vSearch (char *sRead, FILE*file)
{
long lIndex;
char sRead1[256];
fseek(file, 0L, 0);
fgets(sRead1, 256, file);
while(!strstr(sRead1, sRead))
{ lIndex=ftell(file);
fgets(sRead1, 256, file);
}
fseek(file, lIndex, 0);
}