// TextureDlg.cpp : implementation file // #include "stdafx.h" #include "matres.h" #include "acp_base.h" #include "itf.h" #include "dpt.h" #include "inctex.h" #include "_interf.hpp" #include "matlist.hpp" #include "VMatObj.hpp" #include "TexObj.hpp" #include "TextureDlg.h" #include "PatternList.hpp" #include "TGMdef.hpp" #include "_EditID.h" // Vérifier que le chemin Main\Inc est bien enregistré dans les settings, // ou bien écrire le chemin en dur : #include "..\Main\Inc\_EditID.h" #include "TUT.h" extern Material_Interface *gs_p_oMaterialInterface; //================================================================================= //================================================================================= tdoTextureName::tdoTextureName(CString _csName /*= ""*/) { m_csFileName = _csName; m_bIsReferenced = FALSE; } //================================================================================= //================================================================================= BOOL tdoTextureName::m_bIsReferencedInLinkTable() { //once we know it is true, it always will //false once, but it may change, so we have to check until it is true if ( !m_bIsReferenced ) m_bIsReferenced = m_bFindNameInLinkTable(); return m_bIsReferenced; } //================================================================================ //================================================================================ BOOL tdoTextureName::m_bFindNameInLinkTable() { SCR_tdst_Link_Table *p_stTextureLinkTable; SCR_tdst_Link_Value *p_stTextureEntry; unsigned int uiTexturePos; //start by searching in teh link table where the texture is referenced as is p_stTextureLinkTable = GLI_p_stGetLinkTableOfTexture(); uiTexturePos = 0; SCR_M_DyAr_GetNextElement( SCR_tdst_Link_Value, uiTexturePos, p_stTextureEntry, p_stTextureLinkTable->stLinkArray ); while ( p_stTextureEntry ) //scan the texture link table { // if the entry's short name is our name, then we are referenced in the link table... char *pszShortTextureName = SCR_M_p_sz_Link_GetKey(p_stTextureEntry) + SCR_M_ul_Link_GetAdditionalLong(p_stTextureEntry, 1); if ( !m_csFileName.CompareNoCase(pszShortTextureName) ) return TRUE; uiTexturePos ++; SCR_M_DyAr_GetNextElement( SCR_tdst_Link_Value, uiTexturePos, p_stTextureEntry, p_stTextureLinkTable->stLinkArray ); } /* //now look in the link table where the textures are referenced as sections p_stTextureLinkTable = GLI_p_stGetLinkTableOfTextureSection(); uiTexturePos = 0; SCR_M_DyAr_GetNextElement( SCR_tdst_Link_Value, uiTexturePos, p_stTextureEntry, p_stTextureLinkTable->stLinkArray ); while ( p_stTextureEntry ) //scan the texture link table { / // if the entry's short name is the our name, then we are referenced in the link table... char *pszShortTextureName = SCR_M_p_sz_Link_GetKey(p_stTextureEntry) + SCR_M_ul_Link_GetAdditionalLong(p_stTextureEntry, 1); if ( !m_csFileName.CompareNoCase(pszShortTextureName) ) return TRUE; / uiTexturePos ++; SCR_M_DyAr_GetNextElement( SCR_tdst_Link_Value, uiTexturePos, p_stTextureEntry, p_stTextureLinkTable->stLinkArray ); } */ return FALSE; } ///////////////////////////////////////////////////////////////////////////// // CTextureDlg dialog CTextureDlg::CTextureDlg(CWnd* pParent /*=NULL*/) : CDialog(CTextureDlg::IDD, pParent) { //{{AFX_DATA_INIT(CTextureDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_fn_vInitTextureList(); m_pFrame = NULL; m_bIsRefreshingTextureList = FALSE; } //================================================================================= //================================================================================= CTextureDlg::~CTextureDlg() { m_oTextureDirContents.RemoveAll(); } //================================================================================= //================================================================================= void CTextureDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTextureDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } //================================================================================= //================================================================================= BEGIN_MESSAGE_MAP(CTextureDlg, CDialog) //{{AFX_MSG_MAP(CTextureDlg) ON_BN_CLICKED(IDC_BUTTON_REFRESH, OnButtonRefresh) ON_WM_DESTROY() ON_WM_SIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() //================================================================================= // Description : initialize the TextureList //================================================================================= void CTextureDlg::m_fn_vInitTextureList(void) { m_bFirstInit = TRUE; m_p_oTextureListView = new CPatternedListView(); m_p_oTextureListView->m_fn_vSetBitmapList(gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()); m_p_oTextureListView->m_fn_vSetBox(C_cDisplayBitmapAndText, C_wListViewBTItemWidth + C_wListViewPlusPathWidth, C_wListViewBTItemHeight); m_p_oTextureListView->m_fn_vSetBox(C_cDisplayBitmap, C_wListViewBItemWidth, C_wListViewBItemHeight); m_p_oTextureListView->m_fn_vSetBox(C_cDisplayText, C_wListViewTItemWidth + C_wListViewPlusPathWidth, C_wListViewTItemHeight); m_p_oTextureListView->m_fn_vDisableMenuItem(TLVM_lOrder); } //================================================================================= //================================================================================= short CTextureDlg::m_wCountTextures(CString _csNamePrefix, BOOL _bForceDirScan /*= FALSE*/, BOOL bEmptyList /*= FALSE*/) { // static short wRecurseDepth = 0; if ( _bForceDirScan ) { //empty the list only at first entry in the recurse stack... if (bEmptyList) { fn_vGiveProgressInfo("counting loadable textures", -1); m_oTextureDirContents.RemoveAll(); } HANDLE hFind; WIN32_FIND_DATA stFind; //find files with at least a name and an extension hFind = FindFirstFile("?*.?*", &stFind); if ( hFind != INVALID_HANDLE_VALUE ) { CString csPrefix = ( _csNamePrefix.IsEmpty() ? "" : (_csNamePrefix + "\\") ); do { if ( strlen(stFind.cFileName) > 2 ) //do not handle "." and ".." { if ( stFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) //this is a directory { if ( SetCurrentDirectory(stFind.cFileName) ) { // wRecurseDepth ++; m_wCountTextures(csPrefix + stFind.cFileName, TRUE, FALSE); // wRecurseDepth --; SetCurrentDirectory(".."); } } else if ( CString(stFind.cFileName).Right(3).CompareNoCase(".gf") ) // do not handle UBI graphic files with .gf extensions { //this is a simple texture file, add it in the list m_oTextureDirContents.AddTail(*new tdoTextureName(csPrefix + stFind.cFileName)); } } } while ( FindNextFile(hFind, &stFind) ); FindClose(hFind); } } return (short) m_oTextureDirContents.GetCount(); } //================================================================================= //================================================================================= void CTextureDlg::m_fn_vRefreshTextureList(BOOL _bOnlyForLoadedMaterials, BOOL _bScanTextureDir) { int iImage; int iItem; char *d_cFoundBitmap; long lNumber; char szCurDir[_MAX_PATH]; long lCurDirLen = _MAX_PATH; lCurDirLen = GetCurrentDirectory(lCurDirLen, szCurDir); BOOL bNewBitmapsLoaded = FALSE; BOOL bOldBitmapsRemoved = FALSE; // find all directories char szVersion[255]; char szVersion0[255]; char szVersion1[255]; char szVersion2[255]; FILE *hIni; char *szCut; int iNumVersion, iNbVersions = 1; // common directory : get from path strcpy(szVersion0, fn_szGetTexturesDataPath()); strcpy(strchr(szVersion0, '\\'), "\0"); // specific directories : get from version.ini hIni = fopen("version.ini", "rt"); if(hIni == NULL) hIni = fopen("x:\\cpa\\exe\\main\\version.ini", "rt"); if(hIni) { fgets(szVersion, 49, hIni); while(!isalnum(szVersion[strlen(szVersion) - 1])) szVersion[strlen(szVersion) - 1] = '\0'; fclose(hIni); // if necessary get all specific directories strcpy(szVersion1, szVersion); iNbVersions = 2; szCut = strchr(szVersion1, ','); if (szCut) { strcpy(szVersion2, szCut+1 ); strcpy(szCut, "\0"); iNbVersions = 3; } } BOOL bFound = FALSE; char szPath[255]; if (_bScanTextureDir) { m_wNbTextures[0] = m_wNbTextures[1] = m_wNbTextures[2] = 0; m_oTextureDirContents.RemoveAll(); for (iNumVersion = 0; iNumVersion < iNbVersions; iNumVersion++) { // build specific path switch (iNumVersion) { case 0: strcpy(szPath, szVersion0); break; case 1: strcpy(szPath, szVersion1); break; case 2: strcpy(szPath, szVersion2); break; } strcat(szPath, strchr(fn_szGetTexturesDataPath(), '\\')); if (SetCurrentDirectory(szPath)) { bFound = TRUE; m_wNbTextures[iNumVersion] = m_wCountTextures("", _bScanTextureDir, FALSE); SetCurrentDirectory(szCurDir); } } if (!bFound) return; } if ((lNumber = gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_lGetCount()) == 0) d_cFoundBitmap = NULL; else { d_cFoundBitmap = (char *) malloc(lNumber); if ( d_cFoundBitmap ) memset(d_cFoundBitmap, 0, lNumber); } short wCurFile = 0, wNbFiles = m_wCountTextures("", FALSE); CString csStatusMessage; csStatusMessage.Format("loading %d textures", wNbFiles); POSITION xPos = m_oTextureDirContents.GetHeadPosition(); while ( xPos ) { tdoTextureName &r_oTextureName = m_oTextureDirContents.GetNext(xPos); char *p_szFoundFileName = (char *)LPCTSTR(r_oTextureName.m_csGetName()); fn_vGiveProgressInfo(csStatusMessage, (100 * wCurFile) / wNbFiles); BOOL bTextureLoadedByEngine = FALSE; if (wCurFile < m_wNbTextures[0]) { strcpy(szPath, szVersion0); strcat(szPath, strchr(fn_szGetTexturesDataPath(), '\\')); } else if (wCurFile < m_wNbTextures[1]) { strcpy(szPath, szVersion1); strcat(szPath, strchr(fn_szGetTexturesDataPath(), '\\')); } else if (wCurFile < m_wNbTextures[2]) { strcpy(szPath, szVersion2); strcat(szPath, strchr(fn_szGetTexturesDataPath(), '\\')); } SetCurrentDirectory(szPath); //if the current file is alowed for load if ( !_bOnlyForLoadedMaterials || (bTextureLoadedByEngine = r_oTextureName.m_bIsReferencedInLinkTable()) ) { //first check that we dont have it already if ( (iImage = gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_iGetBitmapIndex(p_szFoundFileName)) == -1 ) { iImage = gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_iAdd(p_szFoundFileName); //dont set with 0, because 0 means no texture is associated to the file. Later, when a //material with no texture is displayed, an image associated to the fact that there //is no texture is to be found by the value 0, so get another one if ( iImage != -1 ) { gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_vSetBitmapLong(iImage, 0); int iItem = m_p_oTextureListView->m_fn_iAddItem(p_szFoundFileName, (short) iImage); //make the view know if the image is referenced by the engine or not if ( bTextureLoadedByEngine ) m_p_oTextureListView->m_fn_vSetItemContent(iItem, TRUE); //a new bitmap was added bNewBitmapsLoaded = TRUE; } } else if ( d_cFoundBitmap ) d_cFoundBitmap[iImage] = 1; else d_cFoundBitmap = NULL; // just to put a breakpoint here! } SetCurrentDirectory(szCurDir); wCurFile ++; } fn_vGiveProgressInfo(csStatusMessage, 100); SetCurrentDirectory(szCurDir); if ( d_cFoundBitmap ) { for ( iImage = 0; iImage < lNumber; iImage ++ ) { CString csName = gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_csGetBitmapName(iImage); //ignore bitmaps loaded for editor purposes if ( csName != C_szNoBitmapName && csName != C_szUnviewableBitmapName ) if ( !d_cFoundBitmap[iImage] ) { bOldBitmapsRemoved = TRUE; //remove from the list the image for which we no longer find a file gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_vDelete(iImage); iItem = m_p_oTextureListView->m_fn_lFindImage(0, (short) iImage); //remove it from the listview too if ( iItem != -1 ) { m_p_oTextureListView->m_fn_bDeleteItem(iItem); } } } free(d_cFoundBitmap); d_cFoundBitmap = NULL; } //these 2 cannot be found because they are editor data, but we use them nonetheless, so //reload them... //add bitmaps to display materials with no texture, but do not create small versions, even if the list handles them if ( gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_iGetBitmapIndex(C_szNoBitmapName) == TSL_cItemNotFound ) { iImage = gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_iAdd(C_szNoBitmapName, 0, 0, FALSE, TRUE); gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_vSetBitmapLong(iImage, 0); //when an item using this image is displayed in text only, the text will be different than for the other images gs_p_oMaterialInterface->m_p_oGetMaterialListView()->m_vRememberSpecialImage((short) iImage); } //and those for which we cannot display their texture if ( gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_iGetBitmapIndex(C_szUnviewableBitmapName) == TSL_cItemNotFound ) { iImage = gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_iAdd(C_szUnviewableBitmapName, 0, 0, FALSE, TRUE); gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_vSetBitmapLong(iImage, 2); } //if new bitmaps were added or some were removed, the bitmap indexes may have changed, //so we must warn the material list to update the indexes for the materials if ( bNewBitmapsLoaded || bOldBitmapsRemoved ) { gs_p_oMaterialInterface->m_p_oGetMaterialListView()->m_vBitmapListWasRefreshed(); } fn_vGiveProgressInfo("", -1); } ///////////////////////////////////////////////////////////////////////////// // CTextureDlg message handlers DWORD __stdcall fn_vRefreshTextureListThread(LPVOID lpThreadParameter) { CTextureDlg *p_oDialog = (CTextureDlg *) lpThreadParameter; p_oDialog->m_bIsRefreshingTextureList = TRUE; p_oDialog->m_p_oTextureListView->EnableWindow(FALSE); p_oDialog->m_fn_vRefreshTextureList(FALSE, FALSE); p_oDialog->m_p_oTextureListView->EnableWindow(TRUE); p_oDialog->m_bIsRefreshingTextureList = FALSE; return 0; } //================================================================================= //================================================================================= void CTextureDlg::OnButtonRefresh() { /*if ( !m_bIsRefreshingTextureList ) //do not refresh if the list refresh thread is already active { DWORD xThreadId; CreateThread( NULL, //security attributes 0, //stack size fn_vRefreshTextureListThread, //start routine this, //parameter 0, //creation flags &xThreadId //variable where the thread id will be stored ); }*/ m_fn_vRefreshTextureList(FALSE, FALSE); } //================================================================================= //================================================================================= void CTextureDlg::OnDestroy() { if ( !m_bIsRefreshingTextureList ) //do not destriy if the list refresh thread is active { RECT rect; // save the current pos and size of window GetWindowRect( &rect); m_bPosWhenClose.x = rect.left; m_bPosWhenClose.y = rect.top; m_bSizeWhenClose.cx = rect.right - rect.left; m_bSizeWhenClose.cy = rect.bottom - rect.top; // set parent of texture list view to false (else structure is destroyed) m_p_oTextureListView->ShowWindow(FALSE); m_p_oTextureListView->SetParent( NULL ); // destroy frame m_pFrame->DestroyWindow(); m_pFrame = NULL; //control registration for tutorial and assistants TUT_M_vGetTutDll(); TUT_M_vUnregisterControl(m_p_oTextureListView->m_hWnd); TUT_M_vUnregisterControlID(IDOK); TUT_M_vUnregisterControlID(IDC_BUTTON_REFRESH); TUT_M_vUnregisterControlID(IDCANCEL); // destroy dialog CDialog::OnDestroy(); } } //================================================================================= //================================================================================= BOOL CTextureDlg::OnInitDialog() { CDialog::OnInitDialog(); // rect for creation but frame is resize when dialog appear RECT rect; rect.left = 5; rect.top = 5; rect.right = 100; rect.bottom = 100; // frame creation m_pFrame = new CFrameWnd(); m_pFrame->Create(NULL, NULL, WS_OVERLAPPED | WS_CLIPSIBLINGS | WS_VISIBLE | WS_CHILD, rect, this); if (m_bFirstInit) { // first overture of dialog, view isn't created m_p_oTextureListView->Create(NULL, NULL, WS_CHILD, rect, m_pFrame, 0); m_p_oTextureListView->m_fn_vChangeDisplayType(C_cDisplayBitmapAndText); m_bFirstInit = FALSE; } else { // at least the second overture, there's a saved position and view is already created MoveWindow( m_bPosWhenClose.x, m_bPosWhenClose.y, m_bSizeWhenClose.cx, m_bSizeWhenClose.cy ); m_p_oTextureListView->SetParent( m_pFrame ); } // show view and activate it in frame m_p_oTextureListView->ShowWindow(TRUE); m_pFrame->SetActiveView(m_p_oTextureListView); // set variable m_iSelectedImage = -1; //control registration for tutorial and assistants TUT_M_vGetTutDll(); TUT_M_vRegisterControl(m_p_oTextureListView->m_hWnd , "TGM_TextureListView" , TUT_e_Window); TUT_M_vRegisterControlID(IDOK, "TGM_TextureListViewOK", TUT_e_Button); TUT_M_vRegisterControlID(IDC_BUTTON_REFRESH, "TGM_TextureListViewRefresh", TUT_e_Button); TUT_M_vRegisterControlID(IDCANCEL, "TGM_TextureListViewCancel", TUT_e_Button); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } //================================================================================= //================================================================================= void CTextureDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); if (m_pFrame) { m_pFrame->MoveWindow( 5,5, cx - 10, cy - 35); m_p_oTextureListView->MoveWindow(1,1, cx - 15, cy - 40); GetDlgItem( IDOK )->MoveWindow( 0, cy - 24, cx/3, 20); GetDlgItem( IDC_BUTTON_REFRESH )->MoveWindow( cx/3, cy - 24, cx/3, 20); GetDlgItem( IDCANCEL )->MoveWindow( 2*cx/3, cy - 24, cx/3, 20); } } //================================================================================= //================================================================================= void CTextureDlg::OnOK() { if ( !m_bIsRefreshingTextureList ) //do not close if the list refresh thread is active { int iImage = m_iSelectedImage = m_p_oTextureListView->m_fn_wGetImage(m_p_oTextureListView->m_fn_lGetSelectedItem()); //get the pointer on the new texture CString csBitmapName = gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_csGetBitmapName(iImage); GLI_tdstTexture *p_stGliText = (GLI_tdstTexture *) gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_lGetBitmapLong(iImage); if ( p_stGliText == NULL ) //the texture is not loaded yet { //load the texture (the entry will be added in the linktable) char szFullName[SCR_CV_ui_Cfg_MaxLenName]; sprintf(szFullName, "%s\\%s", fn_szGetTexturesDataPath(), LPCTSTR(csBitmapName)); /*if( GLI_bGetTextureName(szFullName, szFullName) ) {*/ GLI_xLoadTexture(&p_stGliText, NULL, (char*)LPCTSTR(csBitmapName), 0, 0); //GLI_xLoadTextureHeader(&p_stGliText,NULL,szFullName,0,0); SCR_M_v_Link_SetAdditionalLong( SCR_fnp_st_Link_SetValue(GLI_p_stGetLinkTableOfTexture(), szFullName, (unsigned long)p_stGliText), 1, strlen(fn_szGetTexturesDataPath()) + 1 ); //load the texture in the graphic board vram GLI_vEndofGeometricLoad(); /*}*/ //associate the texture data to the bitmap index gs_p_oMaterialInterface->m_p_oGetMaterialsTextureList()->m_fn_vSetBitmapLong(iImage, (long) p_stGliText); //find the VMT file object associated to the current GMT file object CPA_FileObject *p_oFileObject = gs_p_oMaterialInterface->m_p_oGetCurrentFileObject(); //first, get the minimal name of the VMT file CString csFileObjectName = p_oFileObject->GetReferencedName(gs_p_oMaterialInterface, C_szFileMinimalNameKey); csFileObjectName = csFileObjectName.Left(csFileObjectName.ReverseFind('.')) + tdoEditorTexture::m_csGetScriptExtension(); //now retrieve the VMT file object p_oFileObject = p_oGetFileObjectForReferencedPath(csFileObjectName, C_szFileMinimalNameKey); //the section will be named from the texture it references, without the file extension CString csName = CString("TEX_") + fn_pszBaseName0(LPCTSTR(csBitmapName)); csName = csName.Left(csName.ReverseFind('.')); //now create the texture section object tdoEditorTexture *p_oEditorTexture = new tdoEditorTexture( p_oFileObject, //owner file csName, //section name FALSE, //the section does not exist p_stGliText //engine data ); //mark the texture as loaded by the engine now int iItem = m_p_oTextureListView->m_fn_lFindImage(TSL_cItemNotFound, iImage); m_p_oTextureListView->m_fn_vSetItemContent(iItem, TRUE); } CDialog::OnOK(); } }