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

603 lines
21 KiB
C++

// 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();
}
}