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

512 lines
20 KiB
C++

//
/*=============================================================================
*
* Filename: TexObj.cpp
* Version: 1.0
* Date: 06/11/96
* Author: B.G.
*
* Description: implementation of editor texture class
*
*===========================================================================*/
#include "stdafx.h"
#include "Acp_base.h"
#include "itf.h"
#include "inctex.h"
#include "VMatObj.hpp"
#include "x:\cpa\main\inc\_editid.h"
#include "_interf.hpp"
#include "TexObj.hpp"
extern Material_Interface *gs_p_oMaterialInterface;
extern FILE *g_xLogFile;
#define C_EntryTextureToLoad "Texture" //TODO: remove when declared by the GMT module
//=================================================================================
//to make sure we dont create an editor texture when one already exists that uses
//the specified bitmap, try to find it
//=================================================================================
/*
tdoEditorTexture *p_oFindEditorTextureForSimilarEngineTexture(GLI_tdstTexture *_p_stTexture)
{
tdoEditorTexture *p_oEditorTexture;
if ( !_p_stTexture )
return NULL;
//first, check if an editor texture has the same engine texture
p_oEditorTexture = gs_p_oMaterialInterface->m_p_oGetEditorMaterialForEngine(_p_stTexture);
if ( p_oEditorTexture )
return p_oEditorTexture;
//here there is no editor texture with the same engine data. Now lets try to find one which has
//an engine data that
CString csName;
//look in the linktable of texture bitmaps if we find it
SCR_tdst_Link_Value *p_stTextureEntry = SCR_fnp_st_Link_SearchValue(GLI_p_stGetLinkTableOfTexture(), (unsigned long) _p_stTexture)
char *pszKey = SCR_M_p_sz_Link_GetKey(p_stTextureEntry);
}
tdoEditorTexture *p_oFindEditorTextureForSimilarEngineTexture(CString _csName)
{
}
*/
//=================================================================================
//=================================================================================
//=================================================================================
//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
//=================================================================================
tdoEditorTexture::tdoEditorTexture(
CPA_FileObject *_p_oOwnerFile,
CString _csId,
BOOL _bSectionAlreadyExists,
GLI_tdstTexture *_hTemplateTexture
)
: CPA_SaveObject(
gs_p_oMaterialInterface, //editor
C_szTextureTypeName, //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_vCallBackSaveTexture//callback
)
{
//tell the file object that an object exists for its section
g_oCoherenceManager.m_fn_vAddALink(_p_oOwnerFile, this);
m_hTexture = NULL; //default value for insertion in list
// 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_EntryTextureToLoad,
(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() ;
m_vAssociateEngineMaterial(_hTemplateTexture, _bSectionAlreadyExists);
}
//=================================================================================
//=================================================================================
tdoEditorTexture::~tdoEditorTexture()
{
//remove myself totally from the coherence manager database
if ( !fn_bSectionExists() )
g_oCoherenceManager.m_fn_vRemoveAllLinks(this, C_cLinkedAsChild);
}
//=================================================================================
//=================================================================================
void tdoEditorTexture::m_vAssociateEngineMaterial(
GLI_tdstTexture *_hTemplateTexture,
BOOL _bSectionAlreadyExists
)
{
if ( m_hTexture == _hTemplateTexture )
return;
BOOL bIsAssociatedTextureValid = _hTemplateTexture ? TRUE : FALSE;
//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 texture is not loaded yet
SetAvailable(bIsAssociatedTextureValid);
//set the engine data
fn_vUpdateData(_hTemplateTexture);
m_hTexture = _hTemplateTexture;
if ( bIsAssociatedTextureValid )
{
//try to remember the texture file name
SCR_tdst_Link_Table *p_stTextureLinkTable = GLI_p_stGetLinkTableOfTexture();
SCR_tdst_Link_Value *p_stEntry = SCR_fnp_st_Link_SearchValue(p_stTextureLinkTable, (unsigned long) _hTemplateTexture);
if ( !p_stEntry )
{
if ( gs_p_oMaterialInterface->m_bLoadWarningsAreEnabled() )
AfxMessageBox(
CString("The name of the texture referenced by the section ") + GetReferencedSectionName() +
" cannot be resolved.\n"
"If you save your changes, this section will no longer reference the texture.\n"
"\nThere are two possible causes to this problem:\n"
"\t1 - The texture bitmap does not exist: check the name in the section, and the existence of the file.\n"
"\t2 - This is a known loading limitation of the engine. In this case, warn B. Germain if you read this.",
MB_OK
);
char szTextureName[100];
GLI_vGetTextureName(m_hTexture, szTextureName);
m_vRememberTextureName(szTextureName);
if ( g_xLogFile )
{
//log the error
CString csLogMessage("Unknown texture in section: ");
csLogMessage += GetReferencedSectionName() + " -> ";
csLogMessage += szTextureName;
fprintf(g_xLogFile, "%s\n", LPCTSTR(csLogMessage));
fflush(g_xLogFile);
}
}
else
m_vRememberTextureName(SCR_M_p_sz_Link_GetKey(p_stEntry) + SCR_M_ul_Link_GetAdditionalLong(p_stEntry, 1));
//now handle the supply texture: first try to find the associated editor texture by data
GLI_tdstTexture *p_stSupplyTexture = TEX_p_tdstGetSupplyTexture(_hTemplateTexture);
tdoEditorTexture *p_oEditorSupplyTexture = NULL;
if
(
p_stSupplyTexture
&& !(p_oEditorSupplyTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(p_stSupplyTexture))
)
{
CString csName;
CPA_FileObject *p_oFileObject = NULL;
SCR_tdst_Link_Value *p_stTextureEntry;
//try to find the supply texture name in the linktable
if ( p_stTextureEntry = SCR_fnp_st_Link_SearchValue(GLI_p_stGetLinkTableOfTextureSection(), (unsigned long) p_stSupplyTexture) )
{
char *pszKey = SCR_M_p_sz_Link_GetKey(p_stTextureEntry);
char szTextureFile[SCR_CV_ui_Cfg_MaxLenName], szTextureName[SCR_CV_ui_Cfg_MaxLenName];
//get the short name from the linktable entry
SCR_fn_v_RdL0_SplitSectionName(pszKey, szTextureFile, NULL, szTextureName);
//get the file object for this referenced path
p_oFileObject = p_oGetFileObjectForCompletePath(szTextureFile);
csName = szTextureName;
//try to find an editor texture based upon the name before creating a new one
p_oEditorSupplyTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->GetBaseObject(
csName,
C_szTextureTypeName,
p_oFileObject
);
if ( p_oEditorSupplyTexture )
// give the engine texture to the editor texture
p_oEditorSupplyTexture->m_vAssociateEngineMaterial(p_stSupplyTexture, TRUE);
else if ( p_stSupplyTexture )//we have to create an editor texture to handle this engine texture, if relevant, of course
p_oEditorSupplyTexture = new tdoEditorTexture(
p_oFileObject,
csName,
TRUE,
p_stSupplyTexture
);
ASSERT(p_oEditorSupplyTexture);
g_oCoherenceManager.m_fn_vAddALink(this, p_oEditorSupplyTexture);
}
else //a valid texture handle and no linktable entry ? that is not well!!!
{
if ( gs_p_oMaterialInterface->m_bLoadWarningsAreEnabled() ) //output a warning message if required
AfxMessageBox(
CString("The supply texture section of the main texture section ") + GetReferencedSectionName() +
" cannot be found in the link table, although it was analyzed.\n"
"If you edit a material using this texture and save your changes,\n"
"this section will no longer reference the supply texture.\n",
MB_OK
);
if ( g_xLogFile )
{
//log the error
char szTextureName[100];
GLI_vGetTextureName(p_stSupplyTexture, szTextureName);
CString csLogMessage("Unknown supply texture section: ");
csLogMessage += GetReferencedSectionName() + " -> ";
csLogMessage += szTextureName;
fprintf(g_xLogFile, "%s\n", LPCTSTR(csLogMessage));
fflush(g_xLogFile);
}
}
}
}
}
//=================================================================================
//=================================================================================
void tdoEditorTexture::m_vLoadAssociatedEngineTexture()
{
if ( !fn_bIsAvailable() )
{
//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
);
GLI_tdstTexture *hTexture = (GLI_tdstTexture *) 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(hTexture));
//create the association
m_vAssociateEngineMaterial(hTexture, TRUE);
}
}
//================================================================================
//================================================================================
BOOL tdoEditorTexture::m_bIsReferenced()
{
return g_oCoherenceManager.m_fn_iGetFatherCount(this) > 1;
}
//=================================================================================
//=================================================================================
void tdoEditorTexture::m_vRememberTextureName(CString _csTextureName)
{
m_csTextureName = _csTextureName;
}
//=================================================================================
//=================================================================================
void tdoEditorTexture::m_vReplaceHandle(GLI_tdstTexture *_hReplacingTexture)
{
if ( m_hTexture != _hReplacingTexture )
{
CPA_List<CPA_BaseObject> oFatherList;
g_oCoherenceManager.m_fn_iGetFatherList(this, &oFatherList);
POSITION xPos = oFatherList.GetHeadPosition();
while ( xPos )
{ //scan all the visual materials that uses our current handle
CPA_BaseObject *p_oFather = oFatherList.GetNext(xPos);
if ( !p_oFather->GetType().CompareNoCase(tdoEditorVisualMaterial::m_csGetMaterialType()) ) //if this father is a visual material
{
tdoEditorVisualMaterial *p_oVisual = (tdoEditorVisualMaterial *) p_oFather;
ACP_tdxHandleOfMaterial hVisual = p_oVisual->m_hGetEngineMaterial();
long lNbTextures = GLI_lGetMaterialNumberOfAnimatedTexture(hVisual);
for ( lNbTextures --; lNbTextures >= 0; lNbTextures -- ) //scan all the textures used by the material
{
float fDuration;
GLI_tdstTexture *p_stTexture;
GLI_vGetMaterialAnimatedTexture(hVisual, lNbTextures, &p_stTexture, &fDuration);
if ( p_stTexture == m_hTexture ) //if this is my current texture handle
{
GLI_vModifyMaterialAnimatedTexture(hVisual, lNbTextures, _hReplacingTexture, fDuration); //change it for the new one
if ( lNbTextures == 0 )
GLI_xSetMaterialTexture(hVisual, _hReplacingTexture);
//we did not need to rebuild cohemngr links for the main texture, since we just changed the handle
//in both places, but this is not true for the supply texture: since we changed the handle, we have to remove
//the link with the initial editor supply texture
p_stTexture = TEX_p_tdstGetSupplyTexture(p_stTexture);
tdoEditorTexture *p_oSupplyTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(p_stTexture);
if ( p_oSupplyTexture )
g_oCoherenceManager.m_fn_vRemoveALink(this, p_oSupplyTexture);
}
}
}
}
//make us reference the specified handle
m_vAssociateEngineMaterial(_hReplacingTexture, TRUE);
}
}
//=================================================================================
//=================================================================================
/*virtual*/ void tdoEditorTexture::fn_vNotifySave(void)
{
//because when the notification is done, we dont knwo for sure if the section exists or not
fn_vNotifySection(SCR_EA_Ntfy_AddOrRebuildSection);
}
/*=================================================================================
//save a section of the form:
{Texture:<name>
LoadTexture("bitmap file name")
Tiling(ON/OFF,ON/OFF)
Bilinear(ON/OFF,ON/OFF)
MipMapping(ON/OFF)
Chromakey( ENABLE , FILTERING_ON , 0 , 0 , 0 , 0 )
Quality(NORMAL)
Priority(NORMAL/LOW/HIGH)
}
//=================================================================================*/
void tdoEditorTexture::m_vCallBackSaveTexture(
SCR_tdst_File_Description *_p_stFile,
char *_p_szSectionName,
void *_p_vData,
SCR_tde_Ntfy_Action _eAction
)
{
tdoEditorTexture *p_oEditorTexture = (tdoEditorTexture *) _p_vData;
if ( _eAction == SCR_EA_Ntfy_DeleteSection )
//now the section exists, if this was not the case
p_oEditorTexture->fn_vSectionDeleted(); //the section does not exist, and has no pending nofitication
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);
}
GLI_tdstTexture *p_stTexture = (GLI_tdstTexture *) p_oEditorTexture->GetData();
if ( p_stTexture )
{
char szSectionName[SCR_CV_ui_Cfg_MaxLenName],szAction[SCR_CV_ui_Cfg_MaxLenName],szId[SCR_CV_ui_Cfg_MaxLenName];
// construct section name (hack: szSectionName is here as an anti-bug for ...Split...
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 (action == MechanicalMaterial)
SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL);
//referenced texture bitmap file, this must be the first entry in the section
CString csTextureName = p_oEditorTexture->m_csGetTextureName();
if ( !csTextureName.IsEmpty() ) //in case the texture bitmap did not exist, do not save it.
{
SCR_M_SvL0_SaveEntry(_p_stFile, "LoadTexture", SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, LPCTSTR(p_oEditorTexture->m_csGetTextureName()));
}
//texture tiling
BOOL bTilingX, bTilingY;
TEX_vGetTextureTilingMode(p_stTexture, &bTilingX, &bTilingY);
SCR_M_SvL0_SaveEntry(_p_stFile, "Tiling", SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 2, (bTilingX ? "ON" : "OFF"), (bTilingY ? "ON" : "OFF"));
//texture trilinear mipmapping
long lMipmapping = TEX_lGetTextureMipMappingMode(p_stTexture);
SCR_M_SvL0_SaveEntry(_p_stFile, "Mipmapping", SCR_CC_C_Cfg_NoChar);
if ( lMipmapping == TEX_C_NO_MIPMAPPING )
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, "OFF");
else //bilinear or trilinear mipmapping
{
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, (lMipmapping == TEX_C_TRILINEAR) ? "TRILINEAR" : "BILINEAR");
//texture bilinear filtering, save only if mipmapping is enabled
BOOL bFilterU = TRUE, bFilterV = TRUE; //TODO: read them when the acces function is available
SCR_M_SvL0_SaveEntry(_p_stFile, "Bilinear", SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 2, bFilterU ? "ON" : "OFF", bFilterV ? "ON" : "OFF");
}
//chromakey
BOOL bActive, bFiltering;
unsigned char ucR, ucG, ucB, ucA;
TEX_vGetTextureChromakey(p_stTexture, &bActive, &bFiltering, &ucR, &ucG, &ucB, &ucA);
SCR_M_SvL0_SaveEntry(_p_stFile, "Chromakey", SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(
_p_stFile, SCR_EF_SvL0_Scanf, 7, "%s,%s,%d,%d,%d,%d",
(bActive ? "ENABLE" : "DISABLE"),
(bFiltering ? "FILTERING_ON" : "FILTERING_OFF"),
ucR, ucG, ucB, ucA
);
//supply texture
GLI_tdstTexture *p_stSupplyTexture = TEX_p_tdstGetSupplyTexture(p_stTexture);
if ( p_stSupplyTexture )
{
tdoEditorTexture *p_oEditorSupplyTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(p_stSupplyTexture);
SCR_M_SvL0_SaveEntry(_p_stFile, "SupplyTexture", SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, LPCTSTR(p_oEditorSupplyTexture->GetReferencedSectionName()));
}
//quality
unsigned char ucQuality = TEX_ucGetTextureQualityLevel(p_stTexture);
char *pszQualityName;
SCR_M_SvL0_SaveEntry(_p_stFile, "Quality", SCR_CC_C_Cfg_NoChar);
switch ( ucQuality )
{
default:
case TEX_C_QNORMAL:
pszQualityName = "NORMAL";
break;
case TEX_C_QLOW:
pszQualityName = "LOW";
break;
case TEX_C_QHIGH:
pszQualityName = "HIGH";
break;
}
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, pszQualityName);
//TODO: priority
unsigned char ucPriority = 1;
char *pszPriorityName;
SCR_M_SvL0_SaveEntry(_p_stFile, "Priority", SCR_CC_C_Cfg_NoChar);
switch ( ucPriority )
{
case 0:
pszPriorityName = "LOW";
break;
case 1:
pszPriorityName = "NORMAL";
break;
case 2:
pszPriorityName = "HIGH";
break;
}
SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, pszPriorityName);
// End Section
SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL);
//now the section exists, if this was not the case
p_oEditorTexture->fn_vSectionSaved(); // the section is saved and has no pending notification
}
}
//=================================================================================
//=================================================================================
//=================================================================================
// static functions for the class
//=================================================================================
//=================================================================================
//=================================================================================
SCR_tdst_Link_Table *tdoEditorTexture::m_p_stGetAssociatedLinkTable()
{
return GLI_p_stGetLinkTableOfTextureSection();
}
BOOL tdoEditorTexture::m_bIsEngineMaterialValid(GLI_tdstTexture *_hTexture)
{
return _hTexture ? TRUE : FALSE;
}
void tdoEditorTexture::m_vInvalidateEngineMaterial(GLI_tdstTexture *&r_hTexture)
{
r_hTexture = NULL;
}
CString tdoEditorTexture::m_csGetMaterialType()
{
return C_szTextureTypeName;
}
CString tdoEditorTexture::m_csGetScriptExtension()
{
return ".tex";
}