// /*============================================================================= * * 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 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: 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"; }