reman3/Rayman_X/cpa/tempgrp/TGM/Src/GMatObj.cpp

492 lines
20 KiB
C++

/*=============================================================================
*
* Filename: GMatObj.cpp
* Version: 1.0
* Date: 06/11/96
* Author: B.G.
*
* Description: implementation of editor material class
*
*===========================================================================*/
#include "stdafx.h"
#include "Acp_base.h"
#include "itf.h"
#include "gmt.h"
#include "incgam.h"
#include "dpt.h"
#include "_interf.hpp"
#include "GMatObj.hpp"
#include "VMatObj.hpp"
#include "MMatObj.hpp"
#include "CMatObj.hpp"
#include "x:\cpa\main\inc\_editid.h"
//ROMTEAM WorldEditor (Cristi Petrescu 22/12/97)
#include "ozo.h"
//ENDROMTEAM WorldEditor (Cristi Petrescu)
extern Material_Interface *gs_p_oMaterialInterface;
//=================================================================================
//constructor. the object is name with the following rules
//1. it is not a clone but will directly handle the engine material
// -> will take the name from the section for the engine material
//2. it is a clone, and a name is specified
// -> an underscore is added to the original's name,
// because someday the base constructor will add a number there
//3. it is a clone, and no name is specified
// -> the default name is given by the base constructor
//=================================================================================
tdoEditorGameMaterial::tdoEditorGameMaterial(
CPA_FileObject *_p_oOwnerFile,
CString _csId,
BOOL _bSectionAlreadyExists,
GMT_tdxHandleToGameMaterial _hTemplateMaterial
)
: CPA_SaveObject(
gs_p_oMaterialInterface, //editor
C_szGameMaterialTypeName, //type
E_ss_Responsible, //responsibility
_p_oOwnerFile, //owner (the file containing the section)
FALSE, //availability
(char*)LPCTSTR(_p_oOwnerFile->GetCompletionPath(gs_p_oMaterialInterface, C_szFileReferencedNameKey)), //data path to complete the referenced section name
m_vCallBackSaveGMT//callback
)
{
//tell the file object that an object exists for its section
g_oCoherenceManager.m_fn_vAddALink(_p_oOwnerFile, this);
GMT_fn_vInvalidate(&m_hGameMaterial); //set with a default value before rename for first list sorting
// construct section name (hack: szSectionName is here as an anti-bug for ...Split...
char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
SCR_fn_v_RdL0_ComputeSectionName(
szSectionName,
(char*)LPCTSTR(_p_oOwnerFile->GetReferencedName(gs_p_oMaterialInterface, C_szFileReferencedNameKey)),
C_SectionGameMaterial,
(char*)LPCTSTR(_csId)
);
// section object
if ( _bSectionAlreadyExists )
fn_vSectionSaved(); //the section is saved, and has no pending notification
else
fn_vSectionDeleted(); //the section does not exist, and has no pending nofitication
SetSectionData(this);
SetReferencedSectionName(szSectionName);
// name
if ( fn_eRename(_csId) != E_mc_None )
SetDefaultValidName() ;
fn_vUpdateSectionName();
if ( fn_bCanBeNotified() && !fn_bSectionExists() )
fn_vNotifySave();
//if the handle is invalid, the engine material is not loaded yet
//SetAvailable(GMT_fn_b_ulIsValid(_hTemplateMaterial)); //done in m_vAssociateEngineMaterial()
//associate the material and create associated editor sub-materials as well
m_vAssociateEngineMaterial(_hTemplateMaterial, _bSectionAlreadyExists);
}
//=================================================================================
//=================================================================================
tdoEditorGameMaterial::~tdoEditorGameMaterial()
{
//remove myself totally from the coherence manager database
if ( !fn_bSectionExists() )
g_oCoherenceManager.m_fn_vRemoveAllLinks(this, C_cLinkedAsChildAndFather);
}
//=================================================================================
//=================================================================================
void tdoEditorGameMaterial::m_vAssociateEngineMaterial(
GMT_tdxHandleToGameMaterial _hGameMaterial,
BOOL _bSectionAlreadyExists
)
{
if ( m_hGameMaterial == _hGameMaterial )
return;
BOOL bIsAssociatedMaterialValid = GMT_fn_b_ulIsValid(_hGameMaterial);
//a section exists for this object, since we use it directly
if ( _bSectionAlreadyExists )
fn_vSectionSaved(); //the section is saved, and has no pending notification
else
fn_vSectionDeleted(); //the section does not exist, and has no pending nofitication
//if the handle is invalid, the engine material is not loaded yet
SetAvailable(bIsAssociatedMaterialValid);
//the editor object directly handles the engine object
fn_vUpdateData(_hGameMaterial);
m_hGameMaterial = _hGameMaterial;
//if the game material is valid, create editor materials for its sub-materials as well
if ( bIsAssociatedMaterialValid )
{
ACP_tdxHandleOfMaterial hMaterialVisual = GMT_fn_hGetVisualMaterial(m_hGameMaterial);
DNM_tdxHandleToMecMatCharacteristics hMaterialMechanics = GMT_fn_hGetMechanicsMaterial(m_hGameMaterial);
GMT_tdxHandleToCollideMaterial hMaterialCollide = GMT_fn_hGetCollideMaterial(m_hGameMaterial);
//now create editor objects for the materials that are in the handled engine game material
CPA_BaseObject *p_oEditorMaterial;
//create an editor visual material
//but verify that each game material references uniquely a visual material
ASSERT(hMaterialVisual);
if ( !(p_oEditorMaterial = gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hMaterialVisual)) )
{
CPA_FileObject *p_oFileObject;
char szVisualMaterialName[SCR_CV_ui_Cfg_MaxLenName];
//get the link table entry for the engine visual material
SCR_tdst_Link_Table *p_stVisualLinkTable = GLI_p_stGetLinkTableOfVisualMaterial();
//char *pszLinkName = GLI_p_cSearchValueInLinkTableOfGeometric((unsigned long) hMaterialVisual);
SCR_tdst_Link_Value *p_stVisualEntry = SCR_fnp_st_Link_SearchValue(p_stVisualLinkTable, (unsigned long) hMaterialVisual);
if ( p_stVisualEntry )
{
char szVisualMaterialFile[SCR_CV_ui_Cfg_MaxLenName];
//get the file and object name from the entry
char *pszLinkName = SCR_M_p_sz_Link_GetKey(p_stVisualEntry);
SCR_fn_v_RdL0_SplitSectionName(pszLinkName, szVisualMaterialFile, NULL, szVisualMaterialName);
//get the file object for this referenced path
p_oFileObject = p_oGetFileObjectForReferencedPath(szVisualMaterialFile, "");
}
else //this is a new game material -> we choose the file for the visual material from the game material's file name
{
char szVisualMaterialFile[SCR_CV_ui_Cfg_MaxLenName];
//get the minimal name of the game material's file
p_oFileObject = (CPA_FileObject *) GetOwner();
strcpy(szVisualMaterialFile, (char*)LPCTSTR(p_oFileObject->GetReferencedName(gs_p_oMaterialInterface, C_szFileMinimalNameKey)));
//change extension from gmt to vmt
strcpy(strrchr(szVisualMaterialFile, '.'), LPCTSTR(tdoEditorVisualMaterial::m_csGetScriptExtension()));
//find the file object with this minimal name
p_oFileObject = p_oGetFileObjectForReferencedPath(szVisualMaterialFile, C_szFileMinimalNameKey);
//the visual material will attempt to have the same name than its owner game material
strcpy(szVisualMaterialName, (char *)LPCTSTR(GetName()));
}
//create a new editor visual material that will be saved in this file
p_oEditorMaterial = new tdoEditorVisualMaterial(
p_oFileObject, //p_oGetFileObjectForReferencedPath(szVisualMaterialFile),
szVisualMaterialName,
_bSectionAlreadyExists,
hMaterialVisual
);
}
//there MUST exist an editor material for each referenced visual material!
ASSERT(p_oEditorMaterial);
//tell the cohemngr that the created game material uses the visual material
if ( p_oEditorMaterial )
g_oCoherenceManager.m_fn_vAddALink(this, p_oEditorMaterial);
//create an editor mechanics material if none exists for this handle
p_oEditorMaterial = NULL;
if
(
DNM_fn_bIsMatCharacteristicsValid(hMaterialMechanics)
&& !(p_oEditorMaterial = gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hMaterialMechanics))
)
{
char *pszKey = DNM_fn_p_cSearchValueInLinkTableOfMecMatCharacteristics((unsigned long) hMaterialMechanics);
SCR_tdst_Link_Value *p_stEntry = SCR_fnp_st_Link_SearchValue(DNM_fn_p_stGetLinkTableOfMecMatCharacteristics(), (unsigned long) hMaterialMechanics);
CString csName, csReferencedFileName;
CPA_FileObject *p_oFileObject;
if ( pszKey )
{
csReferencedFileName = gs_p_oMaterialInterface->m_csGetFilePartOfSectionName(pszKey + SCR_M_ul_Link_GetAdditionalLong(p_stEntry, 1));
csName = gs_p_oMaterialInterface->m_csGetIdPartOfSectionName(pszKey);
}
else
{
csReferencedFileName = CString("ED") + tdoEditorMechanicsMaterial::m_csGetScriptExtension();
csName = GetName();
}
p_oFileObject = p_oGetFileObjectForReferencedPath(csReferencedFileName);
//try to find an editor material based upon the name before creating a new one
p_oEditorMaterial = (tdoEditorMechanicsMaterial *) gs_p_oMaterialInterface->GetBaseObject(
csName,
C_szMechanicsMaterialTypeName,
p_oFileObject
);
if ( p_oEditorMaterial )
// give the engine material to the editor material
((tdoEditorMechanicsMaterial *) p_oEditorMaterial)->m_vAssociateEngineMaterial(hMaterialMechanics, TRUE);
else //we have to create an editor mechanics material to handle this engine mechanics material
p_oEditorMaterial = new tdoEditorMechanicsMaterial(
p_oFileObject, //p_oGetFileObjectForCompletePath(csFullPath),
csName,
_bSectionAlreadyExists,
hMaterialMechanics
);
//there MUST exist an editor material after the creation!
ASSERT(p_oEditorMaterial);
}
//tell the cohemngr that the created game material uses the mechanics material
if ( p_oEditorMaterial )
g_oCoherenceManager.m_fn_vAddALink(this, p_oEditorMaterial);
//create an editor collide material if none exists for this handle
p_oEditorMaterial = NULL;
if
(
hMaterialCollide != GMT_C_InvalidCollideMaterial
&& !(p_oEditorMaterial = gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hMaterialCollide))
)
{
SCR_tdst_Link_Table *p_stLinkTable = GMT_fn_p_stGetZoneLinkTable();
SCR_tdst_Link_Value *p_stEntry = SCR_fnp_st_Link_SearchValue(p_stLinkTable, (unsigned long) hMaterialCollide);
char *pszKey = SCR_M_p_sz_Link_GetKey(p_stEntry);
CString csName, csReferencedFileName;
CPA_FileObject *p_oFileObject;
if ( pszKey )
{
csReferencedFileName = gs_p_oMaterialInterface->m_csGetFilePartOfSectionName(pszKey + SCR_M_ul_Link_GetAdditionalLong(p_stEntry, 1));
csName = gs_p_oMaterialInterface->m_csGetIdPartOfSectionName(pszKey);
}
else
{
csReferencedFileName = CString("ED") + tdoEditorCollideMaterial::m_csGetScriptExtension();
csName = GetName();
}
p_oFileObject = p_oGetFileObjectForReferencedPath(csReferencedFileName);
//try to find an editor material based upon the name before creating a new one
p_oEditorMaterial = (tdoEditorCollideMaterial *) gs_p_oMaterialInterface->GetBaseObject(
csName,
C_szCollideMaterialTypeName,
p_oFileObject
);
if ( p_oEditorMaterial )
// give the engine material to the editor material
((tdoEditorCollideMaterial *) p_oEditorMaterial)->m_vAssociateEngineMaterial(hMaterialCollide, TRUE);
else //we have to create an editor mechanics material to handle this engine mechanics material
p_oEditorMaterial = new tdoEditorCollideMaterial(
p_oFileObject, //p_oGetFileObjectForCompletePath(csFullPath),
csName,
_bSectionAlreadyExists,
hMaterialCollide
);
//there MUST exist an editor material after the creation!
ASSERT(p_oEditorMaterial);
}
//tell the cohemngr that the created game material uses the collide material
if ( p_oEditorMaterial )
g_oCoherenceManager.m_fn_vAddALink(this, p_oEditorMaterial);
}
}
//=================================================================================
//=================================================================================
void tdoEditorGameMaterial::m_vLoadAssociatedEngineMaterial(BOOL _bEndOfLoad /*= TRUE*/)
{
//if the section name is not in the linktable, analyse the section
SCR_tdst_Cxt_Values *p_stAnalyzeResult = SCR_fnp_st_RdL0_AnalyseSection(
(char *) LPCTSTR(GetReferencedSectionName()),
SCR_CDF_uw_Anl_Normal
);
//load the texture in the graphic board vram, if not told otherwise (because we want to group analyzes before the upload)
if ( _bEndOfLoad )
GLI_vEndofGeometricLoad();
GMT_tdxHandleToGameMaterial hGameMaterial = (GMT_tdxHandleToGameMaterial) p_stAnalyzeResult->a_ulValues[0];
//there must not already exist an editor material for the loaded game material!
ASSERT(!gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hGameMaterial));
//create the association
m_vAssociateEngineMaterial(hGameMaterial, TRUE);
}
//================================================================================
//================================================================================
BOOL tdoEditorGameMaterial::m_bIsReferenced()
{
return g_oCoherenceManager.m_fn_iGetFatherCount(this) > 1;
}
//================================================================================
//================================================================================
void tdoEditorGameMaterial::m_vCallBackSaveGMT(
SCR_tdst_File_Description *_p_stFile,
char *_p_szSectionName,
void *_p_vData,
SCR_tde_Ntfy_Action _eAction
)
{
tdoEditorGameMaterial *p_oEditorMaterial = (tdoEditorGameMaterial *) _p_vData;
if ( _eAction == SCR_EA_Ntfy_DeleteSection )
//now the section exists, if this was not the case
p_oEditorMaterial->fn_vSectionDeleted(); // the section no longer exists, and has no pending notification
if ( _eAction != SCR_EA_Ntfy_AddSection && _eAction != SCR_EA_Ntfy_RebuildSection )
return;
if ( _eAction == SCR_EA_Ntfy_AddSection )
{
// go to end of file (we need all file directive to load this section)
SCR_fn_v_SvL1_ToEndSection(_p_stFile);
SCR_M_SvL0_SaveBlankLine (_p_stFile);
}
GMT_tdxHandleToGameMaterial hEngineMaterial = p_oEditorMaterial->m_hGetEngineMaterial();
// construct section name (hack: szSectionName is here as an anti-bug for ...Split...
char szSectionName[SCR_CV_ui_Cfg_MaxLenName],szAction[SCR_CV_ui_Cfg_MaxLenName],szId[SCR_CV_ui_Cfg_MaxLenName];
SCR_fn_v_RdL0_SplitSectionName(_p_szSectionName, szSectionName, szAction, szId);
SCR_fn_v_RdL0_ComputeSectionName(szSectionName, NULL, szAction, szId);
// save begin section for the game material
SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL);
// save each ministructure
ACP_tdxHandleOfMaterial hMaterialVisual = GMT_fn_hGetVisualMaterial(hEngineMaterial);
if ( hMaterialVisual )
{
CString csKey;
/*char *pszKey = GLI_p_cSearchValueInLinkTableOfGeometric((unsigned long) hMaterialVisual);
if ( pszKey )
csKey = pszKey;
else*/
csKey = gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hMaterialVisual)->GetReferencedSectionName();
SCR_M_SvL0_SaveEntry(_p_stFile, C_EntryVisualGameMaterialToLoad, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Normal, 1, (char *)LPCTSTR(csKey));
}
DNM_tdxHandleToMecMatCharacteristics hMaterialMechanics = GMT_fn_hGetMechanicsMaterial(hEngineMaterial);
if ( DNM_fn_bIsMatCharacteristicsValid(hMaterialMechanics) )
{
CString csKey;
/*char *pszKey = DNM_fn_p_cSearchValueInLinkTableOfMecMatCharacteristics((unsigned long) hMaterialMechanics);
if ( pszKey )
csKey = pszKey;
else*/
csKey = gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hMaterialMechanics)->GetReferencedSectionName();
SCR_M_SvL0_SaveEntry(_p_stFile, C_EntryMechanicalMaterialToLoad, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Normal, 1, (char *)LPCTSTR(csKey));
}
GMT_tdxHandleToCollideMaterial hMaterialCollide = GMT_fn_hGetCollideMaterial(hEngineMaterial);
if ( hMaterialCollide != GMT_C_InvalidCollideMaterial )
{
CString csKey;
/*SCR_tdst_Link_Table *p_stLinkTable = GMT_fn_p_stGetZoneLinkTable();
char *pszKey = SCR_M_p_sz_Link_GetKey(SCR_fnp_st_Link_SearchValue(p_stLinkTable, (unsigned long) hMaterialCollide));
if ( pszKey )
csKey = pszKey;
else*/
csKey = gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hMaterialCollide)->GetReferencedSectionName();
SCR_M_SvL0_SaveEntry(_p_stFile, C_EntryCollideMaterialToLoad, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Normal, 1, (char *)LPCTSTR(csKey));
}
SND_tdxHandleToSoundMaterial hMaterialSound = GMT_fn_hGetSoundMaterial(hEngineMaterial);
if ( hMaterialSound != GMT_C_InvalidSoundMaterial )
{
SCR_M_SvL0_SaveEntry(_p_stFile, C_EntrySoundMaterial, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_ArrayLong, 2, 1, &hMaterialSound);
}
// End Section
SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL);
// update Section name
//now the section exists, if this was not the case
p_oEditorMaterial->fn_vSectionSaved(); // the section is saved and has no pending notification
}
//=================================================================================
//=================================================================================
//=================================================================================
// static functions for the class
//=================================================================================
//=================================================================================
//=================================================================================
SCR_tdst_Link_Table *tdoEditorGameMaterial::m_p_stGetAssociatedLinkTable()
{
return GMT_fn_p_stGetLinkTable();
}
BOOL tdoEditorGameMaterial::m_bIsEngineMaterialValid(GMT_tdxHandleToGameMaterial _hGameMaterial)
{
return GMT_fn_b_ulIsValid(_hGameMaterial);
}
/*CString tdoEditorGameMaterial::m_csGetBaseDataPath()
{
return fn_szGetGameMaterialDataPath();
}*/
void tdoEditorGameMaterial::m_vInvalidateEngineMaterial(GMT_tdxHandleToGameMaterial &r_hGameMaterial)
{
GMT_fn_vInvalidate(&r_hGameMaterial);
}
CString tdoEditorGameMaterial::m_csGetMaterialType()
{
return C_szGameMaterialTypeName;
}
CString tdoEditorGameMaterial::m_csGetScriptExtension()
{
return ".gmt";
}
//ROMTEAM WorldEditor (Cristi Petrescu 11/12/97)
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : word tdoEditorGameMaterial::m_uwTypeOfZonesUsingMe (void)
// Date : 97.12.11
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Tells which zone types are using this material
// The result is a word of bit flags
// Uses the coherence manager to find the objects using the material
// Author : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date :
// By :
//////////////////////////////////////////////////////////////////////////////////////////////////////
WORD tdoEditorGameMaterial::m_uwTypeOfZonesUsingMe (void)
{
CList< CPA_BaseObject *, CPA_BaseObject *> oFatherList;
int iNoObjects;
WORD uwResult = 0;
iNoObjects = g_oCoherenceManager . m_fn_iGetFatherList (this, & oFatherList);
if (iNoObjects)
{
POSITION xPos;
CPA_BaseObject* poBaseObject;
//quite useless to do this inside the loop, eh ?
CPA_EditorBase *poZoneEditor = gs_p_oMaterialInterface -> GetMainWorld () -> GetEditorByName ("Zone");
ASSERT (poZoneEditor);
for ( xPos=oFatherList.GetHeadPosition(); xPos; oFatherList.GetNext(xPos) )
{
poBaseObject = oFatherList.GetAt (xPos);
// see Material_ApplyMaterialModif::Material_ApplyMaterialModif for comments
long lEngineType = poZoneEditor -> OnQueryAction (gs_p_oMaterialInterface, C_uiQueryTypeOfZoneByGeometricObject, (long) poBaseObject);
switch (lEngineType)
{
case C_lZDE:
uwResult |= GMT_C_uwZDE;
break;
case C_lZDM:
uwResult |= GMT_C_uwZDM;
break;
case C_lZDR:
uwResult |= GMT_C_uwZDR;
break;
// those last three are unused by the collision materials, but just in case...
case C_lZDD:
uwResult |= GMT_C_uwZDD;
break;
case C_lBoundingVolume:
uwResult |= GMT_C_uwBoundingVolume;
break;
}
}
}
return uwResult;
}
//ENDROMTEAM WorldEditor (Cristi Petrescu)